Unify RTCs that use host time, fix M48t59 alarm.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3984 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
a0d69e0097
commit
f650305967
124
hw/m48t59.c
124
hw/m48t59.c
@ -53,7 +53,7 @@ struct m48t59_t {
|
|||||||
time_t time_offset;
|
time_t time_offset;
|
||||||
time_t stop_time;
|
time_t stop_time;
|
||||||
/* Alarm & watchdog */
|
/* Alarm & watchdog */
|
||||||
time_t alarm;
|
struct tm alarm;
|
||||||
struct QEMUTimer *alrm_timer;
|
struct QEMUTimer *alrm_timer;
|
||||||
struct QEMUTimer *wd_timer;
|
struct QEMUTimer *wd_timer;
|
||||||
/* NVRAM storage */
|
/* NVRAM storage */
|
||||||
@ -74,35 +74,10 @@ static inline uint8_t fromBCD (uint8_t BCD)
|
|||||||
return ((BCD >> 4) * 10) + (BCD & 0x0F);
|
return ((BCD >> 4) * 10) + (BCD & 0x0F);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* RTC management helpers */
|
|
||||||
static void get_time (m48t59_t *NVRAM, struct tm *tm)
|
|
||||||
{
|
|
||||||
time_t t;
|
|
||||||
|
|
||||||
t = time(NULL) + NVRAM->time_offset;
|
|
||||||
#ifdef _WIN32
|
|
||||||
memcpy(tm,localtime(&t),sizeof(*tm));
|
|
||||||
#else
|
|
||||||
if (rtc_utc)
|
|
||||||
gmtime_r (&t, tm);
|
|
||||||
else
|
|
||||||
localtime_r (&t, tm) ;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static void set_time (m48t59_t *NVRAM, struct tm *tm)
|
|
||||||
{
|
|
||||||
time_t now, new_time;
|
|
||||||
|
|
||||||
new_time = mktime(tm);
|
|
||||||
now = time(NULL);
|
|
||||||
NVRAM->time_offset = new_time - now;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Alarm management */
|
/* Alarm management */
|
||||||
static void alarm_cb (void *opaque)
|
static void alarm_cb (void *opaque)
|
||||||
{
|
{
|
||||||
struct tm tm, tm_now;
|
struct tm tm;
|
||||||
uint64_t next_time;
|
uint64_t next_time;
|
||||||
m48t59_t *NVRAM = opaque;
|
m48t59_t *NVRAM = opaque;
|
||||||
|
|
||||||
@ -111,64 +86,64 @@ static void alarm_cb (void *opaque)
|
|||||||
(NVRAM->buffer[0x1FF4] & 0x80) == 0 &&
|
(NVRAM->buffer[0x1FF4] & 0x80) == 0 &&
|
||||||
(NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
|
(NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
|
||||||
(NVRAM->buffer[0x1FF2] & 0x80) == 0) {
|
(NVRAM->buffer[0x1FF2] & 0x80) == 0) {
|
||||||
/* Repeat once a month */
|
/* Repeat once a month */
|
||||||
get_time(NVRAM, &tm_now);
|
qemu_get_timedate(&tm, NVRAM->time_offset);
|
||||||
memcpy(&tm, &tm_now, sizeof(struct tm));
|
tm.tm_mon++;
|
||||||
tm.tm_mon++;
|
if (tm.tm_mon == 13) {
|
||||||
if (tm.tm_mon == 13) {
|
tm.tm_mon = 1;
|
||||||
tm.tm_mon = 1;
|
tm.tm_year++;
|
||||||
tm.tm_year++;
|
}
|
||||||
}
|
next_time = qemu_timedate_diff(&tm) - NVRAM->time_offset;
|
||||||
next_time = mktime(&tm);
|
|
||||||
} else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&
|
} else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&
|
||||||
(NVRAM->buffer[0x1FF4] & 0x80) == 0 &&
|
(NVRAM->buffer[0x1FF4] & 0x80) == 0 &&
|
||||||
(NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
|
(NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
|
||||||
(NVRAM->buffer[0x1FF2] & 0x80) == 0) {
|
(NVRAM->buffer[0x1FF2] & 0x80) == 0) {
|
||||||
/* Repeat once a day */
|
/* Repeat once a day */
|
||||||
next_time = 24 * 60 * 60 + mktime(&tm_now);
|
next_time = 24 * 60 * 60;
|
||||||
} else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&
|
} else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&
|
||||||
(NVRAM->buffer[0x1FF4] & 0x80) != 0 &&
|
(NVRAM->buffer[0x1FF4] & 0x80) != 0 &&
|
||||||
(NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
|
(NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
|
||||||
(NVRAM->buffer[0x1FF2] & 0x80) == 0) {
|
(NVRAM->buffer[0x1FF2] & 0x80) == 0) {
|
||||||
/* Repeat once an hour */
|
/* Repeat once an hour */
|
||||||
next_time = 60 * 60 + mktime(&tm_now);
|
next_time = 60 * 60;
|
||||||
} else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&
|
} else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&
|
||||||
(NVRAM->buffer[0x1FF4] & 0x80) != 0 &&
|
(NVRAM->buffer[0x1FF4] & 0x80) != 0 &&
|
||||||
(NVRAM->buffer[0x1FF3] & 0x80) != 0 &&
|
(NVRAM->buffer[0x1FF3] & 0x80) != 0 &&
|
||||||
(NVRAM->buffer[0x1FF2] & 0x80) == 0) {
|
(NVRAM->buffer[0x1FF2] & 0x80) == 0) {
|
||||||
/* Repeat once a minute */
|
/* Repeat once a minute */
|
||||||
next_time = 60 + mktime(&tm_now);
|
next_time = 60;
|
||||||
} else {
|
} else {
|
||||||
/* Repeat once a second */
|
/* Repeat once a second */
|
||||||
next_time = 1 + mktime(&tm_now);
|
next_time = 1;
|
||||||
}
|
}
|
||||||
qemu_mod_timer(NVRAM->alrm_timer, next_time * 1000);
|
qemu_mod_timer(NVRAM->alrm_timer, qemu_get_clock(vm_clock) +
|
||||||
|
next_time * 1000);
|
||||||
qemu_set_irq(NVRAM->IRQ, 0);
|
qemu_set_irq(NVRAM->IRQ, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void set_alarm (m48t59_t *NVRAM)
|
||||||
static void get_alarm (m48t59_t *NVRAM, struct tm *tm)
|
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
int diff;
|
||||||
memcpy(tm,localtime(&NVRAM->alarm),sizeof(*tm));
|
|
||||||
#else
|
|
||||||
if (rtc_utc)
|
|
||||||
gmtime_r (&NVRAM->alarm, tm);
|
|
||||||
else
|
|
||||||
localtime_r (&NVRAM->alarm, tm);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static void set_alarm (m48t59_t *NVRAM, struct tm *tm)
|
|
||||||
{
|
|
||||||
NVRAM->alarm = mktime(tm);
|
|
||||||
if (NVRAM->alrm_timer != NULL) {
|
if (NVRAM->alrm_timer != NULL) {
|
||||||
qemu_del_timer(NVRAM->alrm_timer);
|
qemu_del_timer(NVRAM->alrm_timer);
|
||||||
if (NVRAM->alarm - time(NULL) > 0)
|
diff = qemu_timedate_diff(&NVRAM->alarm) - NVRAM->time_offset;
|
||||||
qemu_mod_timer(NVRAM->alrm_timer, NVRAM->alarm * 1000);
|
if (diff > 0)
|
||||||
|
qemu_mod_timer(NVRAM->alrm_timer, diff * 1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* RTC management helpers */
|
||||||
|
static inline void get_time (m48t59_t *NVRAM, struct tm *tm)
|
||||||
|
{
|
||||||
|
qemu_get_timedate(tm, NVRAM->time_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_time (m48t59_t *NVRAM, struct tm *tm)
|
||||||
|
{
|
||||||
|
NVRAM->time_offset = qemu_timedate_diff(tm);
|
||||||
|
set_alarm(NVRAM);
|
||||||
|
}
|
||||||
|
|
||||||
/* Watchdog management */
|
/* Watchdog management */
|
||||||
static void watchdog_cb (void *opaque)
|
static void watchdog_cb (void *opaque)
|
||||||
{
|
{
|
||||||
@ -229,40 +204,36 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val)
|
|||||||
/* alarm seconds */
|
/* alarm seconds */
|
||||||
tmp = fromBCD(val & 0x7F);
|
tmp = fromBCD(val & 0x7F);
|
||||||
if (tmp >= 0 && tmp <= 59) {
|
if (tmp >= 0 && tmp <= 59) {
|
||||||
get_alarm(NVRAM, &tm);
|
NVRAM->alarm.tm_sec = tmp;
|
||||||
tm.tm_sec = tmp;
|
|
||||||
NVRAM->buffer[0x1FF2] = val;
|
NVRAM->buffer[0x1FF2] = val;
|
||||||
set_alarm(NVRAM, &tm);
|
set_alarm(NVRAM);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x1FF3:
|
case 0x1FF3:
|
||||||
/* alarm minutes */
|
/* alarm minutes */
|
||||||
tmp = fromBCD(val & 0x7F);
|
tmp = fromBCD(val & 0x7F);
|
||||||
if (tmp >= 0 && tmp <= 59) {
|
if (tmp >= 0 && tmp <= 59) {
|
||||||
get_alarm(NVRAM, &tm);
|
NVRAM->alarm.tm_min = tmp;
|
||||||
tm.tm_min = tmp;
|
|
||||||
NVRAM->buffer[0x1FF3] = val;
|
NVRAM->buffer[0x1FF3] = val;
|
||||||
set_alarm(NVRAM, &tm);
|
set_alarm(NVRAM);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x1FF4:
|
case 0x1FF4:
|
||||||
/* alarm hours */
|
/* alarm hours */
|
||||||
tmp = fromBCD(val & 0x3F);
|
tmp = fromBCD(val & 0x3F);
|
||||||
if (tmp >= 0 && tmp <= 23) {
|
if (tmp >= 0 && tmp <= 23) {
|
||||||
get_alarm(NVRAM, &tm);
|
NVRAM->alarm.tm_hour = tmp;
|
||||||
tm.tm_hour = tmp;
|
|
||||||
NVRAM->buffer[0x1FF4] = val;
|
NVRAM->buffer[0x1FF4] = val;
|
||||||
set_alarm(NVRAM, &tm);
|
set_alarm(NVRAM);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x1FF5:
|
case 0x1FF5:
|
||||||
/* alarm date */
|
/* alarm date */
|
||||||
tmp = fromBCD(val & 0x1F);
|
tmp = fromBCD(val & 0x1F);
|
||||||
if (tmp != 0) {
|
if (tmp != 0) {
|
||||||
get_alarm(NVRAM, &tm);
|
NVRAM->alarm.tm_mday = tmp;
|
||||||
tm.tm_mday = tmp;
|
|
||||||
NVRAM->buffer[0x1FF5] = val;
|
NVRAM->buffer[0x1FF5] = val;
|
||||||
set_alarm(NVRAM, &tm);
|
set_alarm(NVRAM);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x1FF6:
|
case 0x1FF6:
|
||||||
@ -288,7 +259,7 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val)
|
|||||||
tm.tm_sec = tmp;
|
tm.tm_sec = tmp;
|
||||||
set_time(NVRAM, &tm);
|
set_time(NVRAM, &tm);
|
||||||
}
|
}
|
||||||
if ((val & 0x80) ^ (NVRAM->buffer[addr] & 0x80)) {
|
if ((val & 0x80) ^ (NVRAM->buffer[addr] & 0x80)) {
|
||||||
if (val & 0x80) {
|
if (val & 0x80) {
|
||||||
NVRAM->stop_time = time(NULL);
|
NVRAM->stop_time = time(NULL);
|
||||||
} else {
|
} else {
|
||||||
@ -296,7 +267,7 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val)
|
|||||||
NVRAM->stop_time = 0;
|
NVRAM->stop_time = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NVRAM->buffer[addr] = val & 0x80;
|
NVRAM->buffer[addr] = val & 0x80;
|
||||||
break;
|
break;
|
||||||
case 0x1FFA:
|
case 0x1FFA:
|
||||||
case 0x07FA:
|
case 0x07FA:
|
||||||
@ -682,6 +653,7 @@ m48t59_t *m48t59_init (qemu_irq IRQ, target_phys_addr_t mem_base,
|
|||||||
s->wd_timer = qemu_new_timer(vm_clock, &watchdog_cb, s);
|
s->wd_timer = qemu_new_timer(vm_clock, &watchdog_cb, s);
|
||||||
}
|
}
|
||||||
s->lock = 0;
|
s->lock = 0;
|
||||||
|
qemu_get_timedate(&s->alarm, 0);
|
||||||
|
|
||||||
qemu_register_reset(m48t59_reset, s);
|
qemu_register_reset(m48t59_reset, s);
|
||||||
save_base = mem_base ? mem_base : io_base;
|
save_base = mem_base ? mem_base : io_base;
|
||||||
|
@ -392,24 +392,14 @@ void rtc_set_date(RTCState *s, const struct tm *tm)
|
|||||||
|
|
||||||
static void rtc_set_date_from_host(RTCState *s)
|
static void rtc_set_date_from_host(RTCState *s)
|
||||||
{
|
{
|
||||||
time_t ti;
|
struct tm tm;
|
||||||
struct tm *tm;
|
|
||||||
int val;
|
int val;
|
||||||
|
|
||||||
/* set the CMOS date */
|
/* set the CMOS date */
|
||||||
if (rtc_start_date == -1) {
|
qemu_get_timedate(&tm, 0);
|
||||||
time(&ti);
|
rtc_set_date(s, &tm);
|
||||||
if (rtc_utc)
|
|
||||||
tm = gmtime(&ti);
|
|
||||||
else
|
|
||||||
tm = localtime(&ti);
|
|
||||||
} else {
|
|
||||||
ti = rtc_start_date;
|
|
||||||
tm = gmtime(&ti);
|
|
||||||
}
|
|
||||||
rtc_set_date(s, tm);
|
|
||||||
|
|
||||||
val = to_bcd(s, (tm->tm_year / 100) + 19);
|
val = to_bcd(s, (tm.tm_year / 100) + 19);
|
||||||
rtc_set_memory(s, REG_IBM_CENTURY_BYTE, val);
|
rtc_set_memory(s, REG_IBM_CENTURY_BYTE, val);
|
||||||
rtc_set_memory(s, REG_IBM_PS2_CENTURY_BYTE, val);
|
rtc_set_memory(s, REG_IBM_PS2_CENTURY_BYTE, val);
|
||||||
}
|
}
|
||||||
|
10
hw/omap.c
10
hw/omap.c
@ -4345,7 +4345,6 @@ struct omap_rtc_s {
|
|||||||
int pm_am;
|
int pm_am;
|
||||||
int auto_comp;
|
int auto_comp;
|
||||||
int round;
|
int round;
|
||||||
struct tm *(*convert)(const time_t *timep, struct tm *result);
|
|
||||||
struct tm alarm_tm;
|
struct tm alarm_tm;
|
||||||
time_t alarm_ti;
|
time_t alarm_ti;
|
||||||
|
|
||||||
@ -4668,7 +4667,7 @@ static void omap_rtc_tick(void *opaque)
|
|||||||
s->round = 0;
|
s->round = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
localtime_r(&s->ti, &s->current_tm);
|
memcpy(&s->current_tm, localtime(&s->ti), sizeof(s->current_tm));
|
||||||
|
|
||||||
if ((s->interrupts & 0x08) && s->ti == s->alarm_ti) {
|
if ((s->interrupts & 0x08) && s->ti == s->alarm_ti) {
|
||||||
s->status |= 0x40;
|
s->status |= 0x40;
|
||||||
@ -4719,6 +4718,8 @@ static void omap_rtc_tick(void *opaque)
|
|||||||
|
|
||||||
static void omap_rtc_reset(struct omap_rtc_s *s)
|
static void omap_rtc_reset(struct omap_rtc_s *s)
|
||||||
{
|
{
|
||||||
|
struct tm tm;
|
||||||
|
|
||||||
s->interrupts = 0;
|
s->interrupts = 0;
|
||||||
s->comp_reg = 0;
|
s->comp_reg = 0;
|
||||||
s->running = 0;
|
s->running = 0;
|
||||||
@ -4729,8 +4730,8 @@ static void omap_rtc_reset(struct omap_rtc_s *s)
|
|||||||
memset(&s->alarm_tm, 0, sizeof(s->alarm_tm));
|
memset(&s->alarm_tm, 0, sizeof(s->alarm_tm));
|
||||||
s->alarm_tm.tm_mday = 0x01;
|
s->alarm_tm.tm_mday = 0x01;
|
||||||
s->status = 1 << 7;
|
s->status = 1 << 7;
|
||||||
time(&s->ti);
|
qemu_get_timedate(&tm, 0);
|
||||||
s->ti = mktime(s->convert(&s->ti, &s->current_tm));
|
s->ti = mktime(&tm);
|
||||||
|
|
||||||
omap_rtc_alarm_update(s);
|
omap_rtc_alarm_update(s);
|
||||||
omap_rtc_tick(s);
|
omap_rtc_tick(s);
|
||||||
@ -4747,7 +4748,6 @@ struct omap_rtc_s *omap_rtc_init(target_phys_addr_t base,
|
|||||||
s->irq = irq[0];
|
s->irq = irq[0];
|
||||||
s->alarm = irq[1];
|
s->alarm = irq[1];
|
||||||
s->clk = qemu_new_timer(rt_clock, omap_rtc_tick, s);
|
s->clk = qemu_new_timer(rt_clock, omap_rtc_tick, s);
|
||||||
s->convert = rtc_utc ? gmtime_r : localtime_r;
|
|
||||||
|
|
||||||
omap_rtc_reset(s);
|
omap_rtc_reset(s);
|
||||||
|
|
||||||
|
11
hw/pl031.c
11
hw/pl031.c
@ -195,8 +195,7 @@ void pl031_init(uint32_t base, qemu_irq irq)
|
|||||||
{
|
{
|
||||||
int iomemtype;
|
int iomemtype;
|
||||||
pl031_state *s;
|
pl031_state *s;
|
||||||
time_t ti;
|
struct tm tm;
|
||||||
struct tm *tm;
|
|
||||||
|
|
||||||
s = qemu_mallocz(sizeof(pl031_state));
|
s = qemu_mallocz(sizeof(pl031_state));
|
||||||
if (!s)
|
if (!s)
|
||||||
@ -211,12 +210,8 @@ void pl031_init(uint32_t base, qemu_irq irq)
|
|||||||
s->base = base;
|
s->base = base;
|
||||||
s->irq = irq;
|
s->irq = irq;
|
||||||
/* ??? We assume vm_clock is zero at this point. */
|
/* ??? We assume vm_clock is zero at this point. */
|
||||||
time(&ti);
|
qemu_get_timedate(&tm, 0);
|
||||||
if (rtc_utc)
|
s->tick_offset = mktime(&tm);
|
||||||
tm = gmtime(&ti);
|
|
||||||
else
|
|
||||||
tm = localtime(&ti);
|
|
||||||
s->tick_offset = mktime(tm);
|
|
||||||
|
|
||||||
s->timer = qemu_new_timer(vm_clock, pl031_interrupt, s);
|
s->timer = qemu_new_timer(vm_clock, pl031_interrupt, s);
|
||||||
}
|
}
|
||||||
|
25
hw/pxa2xx.c
25
hw/pxa2xx.c
@ -1183,27 +1183,22 @@ static CPUWriteMemoryFunc *pxa2xx_rtc_writefn[] = {
|
|||||||
|
|
||||||
static void pxa2xx_rtc_init(struct pxa2xx_state_s *s)
|
static void pxa2xx_rtc_init(struct pxa2xx_state_s *s)
|
||||||
{
|
{
|
||||||
struct tm *tm;
|
struct tm tm;
|
||||||
time_t ti;
|
|
||||||
int wom;
|
int wom;
|
||||||
|
|
||||||
s->rttr = 0x7fff;
|
s->rttr = 0x7fff;
|
||||||
s->rtsr = 0;
|
s->rtsr = 0;
|
||||||
|
|
||||||
time(&ti);
|
qemu_get_timedate(&tm, 0);
|
||||||
if (rtc_utc)
|
wom = ((tm.tm_mday - 1) / 7) + 1;
|
||||||
tm = gmtime(&ti);
|
|
||||||
else
|
|
||||||
tm = localtime(&ti);
|
|
||||||
wom = ((tm->tm_mday - 1) / 7) + 1;
|
|
||||||
|
|
||||||
s->last_rcnr = (uint32_t) ti;
|
s->last_rcnr = (uint32_t) mktime(&tm);
|
||||||
s->last_rdcr = (wom << 20) | ((tm->tm_wday + 1) << 17) |
|
s->last_rdcr = (wom << 20) | ((tm.tm_wday + 1) << 17) |
|
||||||
(tm->tm_hour << 12) | (tm->tm_min << 6) | tm->tm_sec;
|
(tm.tm_hour << 12) | (tm.tm_min << 6) | tm.tm_sec;
|
||||||
s->last_rycr = ((tm->tm_year + 1900) << 9) |
|
s->last_rycr = ((tm.tm_year + 1900) << 9) |
|
||||||
((tm->tm_mon + 1) << 5) | tm->tm_mday;
|
((tm.tm_mon + 1) << 5) | tm.tm_mday;
|
||||||
s->last_swcr = (tm->tm_hour << 19) |
|
s->last_swcr = (tm.tm_hour << 19) |
|
||||||
(tm->tm_min << 13) | (tm->tm_sec << 7);
|
(tm.tm_min << 13) | (tm.tm_sec << 7);
|
||||||
s->last_rtcpicr = 0;
|
s->last_rtcpicr = 0;
|
||||||
s->last_hz = s->last_sw = s->last_pi = qemu_get_clock(rt_clock);
|
s->last_hz = s->last_sw = s->last_pi = qemu_get_clock(rt_clock);
|
||||||
|
|
||||||
|
@ -76,6 +76,9 @@ int qemu_bh_poll(void);
|
|||||||
|
|
||||||
uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c);
|
uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c);
|
||||||
|
|
||||||
|
void qemu_get_timedate(struct tm *tm, int offset);
|
||||||
|
int qemu_timedate_diff(struct tm *tm);
|
||||||
|
|
||||||
/* cutils.c */
|
/* cutils.c */
|
||||||
void pstrcpy(char *buf, int buf_size, const char *str);
|
void pstrcpy(char *buf, int buf_size, const char *str);
|
||||||
char *pstrcat(char *buf, int buf_size, const char *s);
|
char *pstrcat(char *buf, int buf_size, const char *s);
|
||||||
|
2
sysemu.h
2
sysemu.h
@ -71,8 +71,6 @@ void do_info_slirp(void);
|
|||||||
|
|
||||||
extern int ram_size;
|
extern int ram_size;
|
||||||
extern int bios_size;
|
extern int bios_size;
|
||||||
extern int rtc_utc;
|
|
||||||
extern int rtc_start_date;
|
|
||||||
extern int cirrus_vga_enabled;
|
extern int cirrus_vga_enabled;
|
||||||
extern int vmsvga_enabled;
|
extern int vmsvga_enabled;
|
||||||
extern int graphic_width;
|
extern int graphic_width;
|
||||||
|
45
vl.c
45
vl.c
@ -180,8 +180,8 @@ int pit_min_timer_count = 0;
|
|||||||
int nb_nics;
|
int nb_nics;
|
||||||
NICInfo nd_table[MAX_NICS];
|
NICInfo nd_table[MAX_NICS];
|
||||||
int vm_running;
|
int vm_running;
|
||||||
int rtc_utc = 1;
|
static int rtc_utc = 1;
|
||||||
int rtc_start_date = -1; /* -1 means now */
|
static int rtc_date_offset = -1; /* -1 means no change */
|
||||||
int cirrus_vga_enabled = 1;
|
int cirrus_vga_enabled = 1;
|
||||||
int vmsvga_enabled = 0;
|
int vmsvga_enabled = 0;
|
||||||
#ifdef TARGET_SPARC
|
#ifdef TARGET_SPARC
|
||||||
@ -1564,6 +1564,43 @@ static void quit_timers(void)
|
|||||||
alarm_timer = NULL;
|
alarm_timer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************/
|
||||||
|
/* host time/date access */
|
||||||
|
void qemu_get_timedate(struct tm *tm, int offset)
|
||||||
|
{
|
||||||
|
time_t ti;
|
||||||
|
struct tm *ret;
|
||||||
|
|
||||||
|
time(&ti);
|
||||||
|
ti += offset;
|
||||||
|
if (rtc_date_offset == -1) {
|
||||||
|
if (rtc_utc)
|
||||||
|
ret = gmtime(&ti);
|
||||||
|
else
|
||||||
|
ret = localtime(&ti);
|
||||||
|
} else {
|
||||||
|
ti -= rtc_date_offset;
|
||||||
|
ret = gmtime(&ti);
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(tm, ret, sizeof(struct tm));
|
||||||
|
}
|
||||||
|
|
||||||
|
int qemu_timedate_diff(struct tm *tm)
|
||||||
|
{
|
||||||
|
time_t seconds;
|
||||||
|
|
||||||
|
if (rtc_date_offset == -1)
|
||||||
|
if (rtc_utc)
|
||||||
|
seconds = mktimegm(tm);
|
||||||
|
else
|
||||||
|
seconds = mktime(tm);
|
||||||
|
else
|
||||||
|
seconds = mktimegm(tm) + rtc_date_offset;
|
||||||
|
|
||||||
|
return seconds - time(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************/
|
/***********************************************************/
|
||||||
/* character device */
|
/* character device */
|
||||||
|
|
||||||
@ -8698,8 +8735,9 @@ int main(int argc, char **argv)
|
|||||||
case QEMU_OPTION_startdate:
|
case QEMU_OPTION_startdate:
|
||||||
{
|
{
|
||||||
struct tm tm;
|
struct tm tm;
|
||||||
|
time_t rtc_start_date;
|
||||||
if (!strcmp(optarg, "now")) {
|
if (!strcmp(optarg, "now")) {
|
||||||
rtc_start_date = -1;
|
rtc_date_offset = -1;
|
||||||
} else {
|
} else {
|
||||||
if (sscanf(optarg, "%d-%d-%dT%d:%d:%d",
|
if (sscanf(optarg, "%d-%d-%dT%d:%d:%d",
|
||||||
&tm.tm_year,
|
&tm.tm_year,
|
||||||
@ -8728,6 +8766,7 @@ int main(int argc, char **argv)
|
|||||||
"'now' or '2006-06-17T16:01:21' or '2006-06-17'\n");
|
"'now' or '2006-06-17T16:01:21' or '2006-06-17'\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
rtc_date_offset = time(NULL) - rtc_start_date;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user