summary refs log tree commit diff stats
path: root/hw/spapr_rtas.c
diff options
context:
space:
mode:
authorBreno Leitao <brenohl@br.ibm.com>2011-09-28 16:53:16 +0000
committerAlexander Graf <agraf@suse.de>2011-10-06 09:48:09 +0200
commitac26f8c3891dde7a3fc7f24a3a87905df843d905 (patch)
tree094e85b6026005b5df614a9921089fd15432e84c /hw/spapr_rtas.c
parente6c866d417d1a09536f489e66c21cf49b7ec60b6 (diff)
downloadfocaccia-qemu-ac26f8c3891dde7a3fc7f24a3a87905df843d905.tar.gz
focaccia-qemu-ac26f8c3891dde7a3fc7f24a3a87905df843d905.zip
pseries: Implement set-time-of-day RTAS function
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>
Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'hw/spapr_rtas.c')
-rw-r--r--hw/spapr_rtas.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/hw/spapr_rtas.c b/hw/spapr_rtas.c
index 00c8ce5a15..d1ac74cfbd 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);