diff mbox

pseries: Implement set-time-of-day RTAS function

Message ID 1317264796-26000-1-git-send-email-david@gibson.dropbear.id.au
State New
Headers show

Commit Message

David Gibson Sept. 29, 2011, 2:53 a.m. UTC
From: Breno Leitao <brenohl@br.ibm.com>

Currently there is no implementation for set-time-of-day rtas function,
which causes the following warning "setting the clock failed (-1)" on
the guest.

This patch just creates this function, get the timedate diff and store in
the papr environment, so that the correct value will be returned by
get-time-of-day.

In order to try it, just adjust the hardware time, run hwclock --systohc,
so that, on when the system runs hwclock --hctosys, the value is correctly
adjusted, i.e. the host time plus the timediff.

Signed-off-by: Breno Leitao <brenohl@br.ibm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/spapr.h      |    1 +
 hw/spapr_rtas.c |   24 +++++++++++++++++++++++-
 2 files changed, 24 insertions(+), 1 deletions(-)

Comments

Alexander Graf Sept. 29, 2011, 1:12 p.m. UTC | #1
On 29.09.2011, at 04:53, David Gibson wrote:

> From: Breno Leitao <brenohl@br.ibm.com>
> 
> Currently there is no implementation for set-time-of-day rtas function,
> which causes the following warning "setting the clock failed (-1)" on
> the guest.
> 
> This patch just creates this function, get the timedate diff and store in
> the papr environment, so that the correct value will be returned by
> get-time-of-day.
> 
> In order to try it, just adjust the hardware time, run hwclock --systohc,
> so that, on when the system runs hwclock --hctosys, the value is correctly
> adjusted, i.e. the host time plus the timediff.
> 
> Signed-off-by: Breno Leitao <brenohl@br.ibm.com>
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>

Thanks, applied to ppc-next.


Alex
diff mbox

Patch

diff --git a/hw/spapr.h b/hw/spapr.h
index ec910de..6657c33 100644
--- a/hw/spapr.h
+++ b/hw/spapr.h
@@ -18,6 +18,7 @@  typedef struct sPAPREnvironment {
     void *fdt_skel;
     target_ulong entry_point;
     int next_irq;
+    int rtc_offset;
 } sPAPREnvironment;
 
 #define H_SUCCESS         0
diff --git a/hw/spapr_rtas.c b/hw/spapr_rtas.c
index 00c8ce5..d1ac74c 100644
--- a/hw/spapr_rtas.c
+++ b/hw/spapr_rtas.c
@@ -67,7 +67,7 @@  static void rtas_get_time_of_day(sPAPREnvironment *spapr,
         return;
     }
 
-    qemu_get_timedate(&tm, 0);
+    qemu_get_timedate(&tm, spapr->rtc_offset);
 
     rtas_st(rets, 0, 0); /* Success */
     rtas_st(rets, 1, tm.tm_year + 1900);
@@ -79,6 +79,27 @@  static void rtas_get_time_of_day(sPAPREnvironment *spapr,
     rtas_st(rets, 7, 0); /* we don't do nanoseconds */
 }
 
+static void rtas_set_time_of_day(sPAPREnvironment *spapr,
+                                 uint32_t token, uint32_t nargs,
+                                 target_ulong args,
+                                 uint32_t nret, target_ulong rets)
+{
+    struct tm tm;
+
+    tm.tm_year = rtas_ld(args, 0) - 1900;
+    tm.tm_mon = rtas_ld(args, 1) - 1;
+    tm.tm_mday = rtas_ld(args, 2);
+    tm.tm_hour = rtas_ld(args, 3);
+    tm.tm_min = rtas_ld(args, 4);
+    tm.tm_sec = rtas_ld(args, 5);
+
+    /* Just generate a monitor event for the change */
+    rtc_change_mon_event(&tm);
+    spapr->rtc_offset = qemu_timedate_diff(&tm);
+
+    rtas_st(rets, 0, 0); /* Success */
+}
+
 static void rtas_power_off(sPAPREnvironment *spapr,
                            uint32_t token, uint32_t nargs, target_ulong args,
                            uint32_t nret, target_ulong rets)
@@ -271,6 +292,7 @@  static void register_core_rtas(void)
 {
     spapr_rtas_register("display-character", rtas_display_character);
     spapr_rtas_register("get-time-of-day", rtas_get_time_of_day);
+    spapr_rtas_register("set-time-of-day", rtas_set_time_of_day);
     spapr_rtas_register("power-off", rtas_power_off);
     spapr_rtas_register("query-cpu-stopped-state",
                         rtas_query_cpu_stopped_state);