[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-ppc] [PULL 13/38] pseries: Move rtc_offset into RTC device's state
From: |
Alexander Graf |
Subject: |
[Qemu-ppc] [PULL 13/38] pseries: Move rtc_offset into RTC device's state structure |
Date: |
Sun, 8 Mar 2015 09:44:32 +0100 |
From: David Gibson <address@hidden>
The initial creation of the PAPR RTC qdev class left a wart - the rtc's
offset was left in the sPAPREnvironment structure, accessed via a global.
This patch moves it into the RTC device's own state structure, were it
belongs. This requires a small change to the migration stream format. In
order to handle incoming streams from older versions, we also need to
retain the rtc_offset field in the sPAPREnvironment structure, so that it
can be loaded into via the vmsd, then pushed into the RTC device.
Since we're changing the migration format, this also takes the opportunity
to:
* Change the rtc offset from a value in seconds to a value in
nanoseconds, allowing nanosecond offsets between host and guest
rtc time, if desired.
* Remove both the already unused "next_irq" field and now unused
"rtc_offset" field from the new version of the spapr migration
stream
Signed-off-by: David Gibson <address@hidden>
Signed-off-by: Alexander Graf <address@hidden>
---
hw/ppc/spapr.c | 30 +++++++++++++++++++++++++++---
hw/ppc/spapr_rtc.c | 41 +++++++++++++++++++++++++++++++++++++----
include/hw/ppc/spapr.h | 3 ++-
3 files changed, 66 insertions(+), 8 deletions(-)
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 1908988..6e8248d 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1019,15 +1019,39 @@ static int spapr_vga_init(PCIBus *pci_bus)
}
}
+static int spapr_post_load(void *opaque, int version_id)
+{
+ sPAPREnvironment *spapr = (sPAPREnvironment *)opaque;
+ int err = 0;
+
+ /* In earlier versions, there was no seperate qdev for the PAPR
+ * RTC, so the RTC offset was stored directly in sPAPREnvironment.
+ * So when migrating from those versions, poke the incoming offset
+ * value into the RTC device */
+ if (version_id < 3) {
+ err = spapr_rtc_import_offset(spapr->rtc, spapr->rtc_offset);
+ }
+
+ return err;
+}
+
+static bool version_before_3(void *opaque, int version_id)
+{
+ return version_id < 3;
+}
+
static const VMStateDescription vmstate_spapr = {
.name = "spapr",
- .version_id = 2,
+ .version_id = 3,
.minimum_version_id = 1,
+ .post_load = spapr_post_load,
.fields = (VMStateField[]) {
- VMSTATE_UNUSED(4), /* used to be @next_irq */
+ /* used to be @next_irq */
+ VMSTATE_UNUSED_BUFFER(version_before_3, 0, 4),
/* RTC offset */
- VMSTATE_UINT64(rtc_offset, sPAPREnvironment),
+ VMSTATE_UINT64_TEST(rtc_offset, sPAPREnvironment, version_before_3),
+
VMSTATE_PPC_TIMEBASE_V(tb, sPAPREnvironment, 2),
VMSTATE_END_OF_LIST()
},
diff --git a/hw/ppc/spapr_rtc.c b/hw/ppc/spapr_rtc.c
index b9f4704..5ad0823 100644
--- a/hw/ppc/spapr_rtc.c
+++ b/hw/ppc/spapr_rtc.c
@@ -37,6 +37,7 @@ typedef struct sPAPRRTCState sPAPRRTCState;
struct sPAPRRTCState {
/*< private >*/
SysBusDevice parent_obj;
+ int64_t ns_offset;
};
#define NSEC_PER_SEC 1000000000LL
@@ -45,20 +46,37 @@ void spapr_rtc_read(DeviceState *dev, struct tm *tm,
uint32_t *ns)
{
sPAPRRTCState *rtc = SPAPR_RTC(dev);
int64_t host_ns = qemu_clock_get_ns(rtc_clock);
+ int64_t guest_ns;
time_t guest_s;
assert(rtc);
- guest_s = host_ns / NSEC_PER_SEC + spapr->rtc_offset;
+ guest_ns = host_ns + rtc->ns_offset;
+ guest_s = guest_ns / NSEC_PER_SEC;
if (tm) {
gmtime_r(&guest_s, tm);
}
if (ns) {
- *ns = host_ns % NSEC_PER_SEC;
+ *ns = guest_ns;
}
}
+int spapr_rtc_import_offset(DeviceState *dev, int64_t legacy_offset)
+{
+ sPAPRRTCState *rtc;
+
+ if (!dev) {
+ return -ENODEV;
+ }
+
+ rtc = SPAPR_RTC(dev);
+
+ rtc->ns_offset = legacy_offset * NSEC_PER_SEC;
+
+ return 0;
+}
+
static void rtas_get_time_of_day(PowerPCCPU *cpu, sPAPREnvironment *spapr,
uint32_t token, uint32_t nargs,
target_ulong args,
@@ -94,6 +112,7 @@ static void rtas_set_time_of_day(PowerPCCPU *cpu,
sPAPREnvironment *spapr,
target_ulong args,
uint32_t nret, target_ulong rets)
{
+ sPAPRRTCState *rtc;
struct tm tm;
time_t new_s;
int64_t host_ns;
@@ -124,15 +143,18 @@ static void rtas_set_time_of_day(PowerPCCPU *cpu,
sPAPREnvironment *spapr,
/* Generate a monitor event for the change */
qapi_event_send_rtc_change(qemu_timedate_diff(&tm), &error_abort);
+ rtc = SPAPR_RTC(spapr->rtc);
+
host_ns = qemu_clock_get_ns(rtc_clock);
- spapr->rtc_offset = new_s - host_ns / NSEC_PER_SEC;
+ rtc->ns_offset = (new_s * NSEC_PER_SEC) - host_ns;
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
}
static void spapr_rtc_realize(DeviceState *dev, Error **errp)
{
+ sPAPRRTCState *rtc = SPAPR_RTC(dev);
struct tm tm;
time_t host_s;
int64_t rtc_ns;
@@ -142,14 +164,25 @@ static void spapr_rtc_realize(DeviceState *dev, Error
**errp)
qemu_get_timedate(&tm, 0);
host_s = mktimegm(&tm);
rtc_ns = qemu_clock_get_ns(rtc_clock);
- spapr->rtc_offset = host_s - rtc_ns / NSEC_PER_SEC;
+ rtc->ns_offset = host_s * NSEC_PER_SEC - rtc_ns;
}
+static const VMStateDescription vmstate_spapr_rtc = {
+ .name = "spapr/rtc",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_INT64(ns_offset, sPAPRRTCState),
+ VMSTATE_END_OF_LIST()
+ },
+};
+
static void spapr_rtc_class_init(ObjectClass *oc, void *data)
{
DeviceClass *dc = DEVICE_CLASS(oc);
dc->realize = spapr_rtc_realize;
+ dc->vmsd = &vmstate_spapr_rtc;
spapr_rtas_register(RTAS_GET_TIME_OF_DAY, "get-time-of-day",
rtas_get_time_of_day);
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 80c6e4f..a8e6817 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -27,7 +27,7 @@ typedef struct sPAPREnvironment {
void *rtas_blob;
void *fdt_skel;
target_ulong entry_point;
- uint64_t rtc_offset;
+ uint64_t rtc_offset; /* Now used only during incoming migration */
struct PPCTimebase tb;
bool has_graphics;
@@ -485,5 +485,6 @@ int spapr_tcet_dma_dt(void *fdt, int node_off, const char
*propname,
#define TYPE_SPAPR_RTC "spapr-rtc"
void spapr_rtc_read(DeviceState *dev, struct tm *tm, uint32_t *ns);
+int spapr_rtc_import_offset(DeviceState *dev, int64_t legacy_offset);
#endif /* !defined (__HW_SPAPR_H__) */
--
1.8.1.4
- [Qemu-ppc] [PULL 01/38] spapr_vio/spapr_iommu: Move VIO bypass where it belongs, (continued)
- [Qemu-ppc] [PULL 01/38] spapr_vio/spapr_iommu: Move VIO bypass where it belongs, Alexander Graf, 2015/03/08
- [Qemu-ppc] [PULL 38/38] sPAPR: Implement sPAPRPHBClass EEH callbacks, Alexander Graf, 2015/03/08
- [Qemu-ppc] [PULL 28/38] openpic: switch IRQQueue queue from inline to bitmap, Alexander Graf, 2015/03/08
- [Qemu-ppc] [PULL 31/38] Revert "default-configs/ppc64: add all components of i82378 SuperIO chip used by prep", Alexander Graf, 2015/03/08
- [Qemu-ppc] [PULL 18/38] pseries: Switch VGA endian on H_SET_MODE, Alexander Graf, 2015/03/08
- [Qemu-ppc] [PULL 10/38] pseries: Add spapr_rtc_read() helper function, Alexander Graf, 2015/03/08
- [Qemu-ppc] [PULL 35/38] PPC: Introduce the Virtual Time Base (VTB) SPR register, Alexander Graf, 2015/03/08
- [Qemu-ppc] [PULL 11/38] pseries: Make RTAS time of day functions respect -rtc options, Alexander Graf, 2015/03/08
- [Qemu-ppc] [PULL 19/38] Openpic: check that cpu id is within the number of cpus, Alexander Graf, 2015/03/08
- [Qemu-ppc] [PULL 12/38] pseries: Make the PAPR RTC a qdev device, Alexander Graf, 2015/03/08
- [Qemu-ppc] [PULL 13/38] pseries: Move rtc_offset into RTC device's state structure,
Alexander Graf <=
- [Qemu-ppc] [PULL 21/38] macio.c: include parent PCIDevice state in VMStateDescription, Alexander Graf, 2015/03/08
- [Qemu-ppc] [PULL 32/38] ppc64-softmmu: Remove unsupported FDC from config, Alexander Graf, 2015/03/08
- [Qemu-ppc] [PULL 08/38] pseries: Move sPAPR RTC code into its own file, Alexander Graf, 2015/03/08
- [Qemu-ppc] [PULL 04/38] spapr: Add pseries-2.3 machine, Alexander Graf, 2015/03/08
- [Qemu-ppc] [PULL 22/38] adb.c: include ADBDevice parent state in KBDState and MouseState, Alexander Graf, 2015/03/08
- [Qemu-ppc] [PULL 03/38] pseries: Limit PCI host bridge "index" value, Alexander Graf, 2015/03/08
- [Qemu-ppc] [PULL 17/38] vga: Expose framebuffer byteorder as a QOM property, Alexander Graf, 2015/03/08
- [Qemu-ppc] [PULL 07/38] Add more VMSTATE_*_TEST variants for integers, Alexander Graf, 2015/03/08
- [Qemu-ppc] [PULL 34/38] PPC: Remove duplicate OPENPIC defines in default-configs, Alexander Graf, 2015/03/08
- [Qemu-ppc] [PULL 36/38] target-ppc: Add versions to server CPU descriptions, Alexander Graf, 2015/03/08