aboutsummaryrefslogtreecommitdiff
path: root/hw/rtc
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2019-10-27 19:44:59 +0000
committerPeter Maydell <peter.maydell@linaro.org>2019-10-27 19:44:59 +0000
commit88c1fd4cba1103653fac4d9393b0832e446b593f (patch)
tree53888acf7d140d8187528239332da605d04c7b6c /hw/rtc
parent187f35512106501fe9a11057f4d8705431e0026d (diff)
parentbf13bfab0840d34a74938ddf567d52e9010dbdc6 (diff)
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* Bulgarian translation update (Alexander) * RTC and PC refactorings (Hervé, Philippe, Sergio) * RTC fix (Marcelo) * More comprehensive MCE logging (Mario) * x86 IGNNE implementation (Paolo) * Microvm machine type (Sergio) * Support for UMONITOR/UMWAIT/TPAUSE (Tao) * Do not use %m in common code (Thomas) * NoNonArchitecturalCoreSharing Hyper-V enlightenment (Vitaly) * getpagesize cleanups (Wei) # gpg: Signature made Sat 26 Oct 2019 14:39:56 BST # gpg: using RSA key BFFBD25F78C7AE83 # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full] # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" [full] # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * remotes/bonzini/tags/for-upstream: (39 commits) i386: implement IGNNE target/i386: introduce cpu_set_fpus target/i386: move FERR handling to target/i386 core: replace getpagesize() with qemu_real_host_page_size audio: fix missing break mc146818rtc: always register rtc to rtc list mc146818rtc: Include mc146818rtc_regs.h directly in mc146818rtc.c mc146818rtc: Move RTC_ISA_IRQ definition mc146818rtc: move structure to header file hw/i386/pc: Remove kvm_i386.h include hw/i386/pc: Extract pc_i8259_create() hw/i386/pc: Move gsi_state creation code hw/i386/pc: Extract pc_gsi_create() target/i386: Add support for save/load IA32_UMWAIT_CONTROL MSR x86/cpu: Add support for UMONITOR/UMWAIT/TPAUSE hw/timer/mc146818rtc: Only include qapi-commands-misc on I386 runstate: ignore exit request in finish migrate state checkpatch: suggest qemu_real_host_page_size instead of getpagesize() or sysconf(_SC_PAGESIZE) MAINTAINERS: add microvm related files hw/i386: Introduce the microvm machine type ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/rtc')
-rw-r--r--hw/rtc/mc146818rtc.c94
1 files changed, 31 insertions, 63 deletions
diff --git a/hw/rtc/mc146818rtc.c b/hw/rtc/mc146818rtc.c
index 9d4ed54f65..ee6bf82b40 100644
--- a/hw/rtc/mc146818rtc.c
+++ b/hw/rtc/mc146818rtc.c
@@ -38,12 +38,13 @@
#include "hw/rtc/mc146818rtc_regs.h"
#include "migration/vmstate.h"
#include "qapi/error.h"
-#include "qapi/qapi-commands-misc-target.h"
#include "qapi/qapi-events-misc-target.h"
#include "qapi/visitor.h"
#include "exec/address-spaces.h"
+#include "hw/rtc/mc146818rtc_regs.h"
#ifdef TARGET_I386
+#include "qapi/qapi-commands-misc-target.h"
#include "hw/i386/apic.h"
#endif
@@ -72,36 +73,6 @@
#define RTC_CLOCK_RATE 32768
#define UIP_HOLD_LENGTH (8 * NANOSECONDS_PER_SECOND / 32768)
-#define MC146818_RTC(obj) OBJECT_CHECK(RTCState, (obj), TYPE_MC146818_RTC)
-
-typedef struct RTCState {
- ISADevice parent_obj;
-
- MemoryRegion io;
- MemoryRegion coalesced_io;
- uint8_t cmos_data[128];
- uint8_t cmos_index;
- int32_t base_year;
- uint64_t base_rtc;
- uint64_t last_update;
- int64_t offset;
- qemu_irq irq;
- int it_shift;
- /* periodic timer */
- QEMUTimer *periodic_timer;
- int64_t next_periodic_time;
- /* update-ended timer */
- QEMUTimer *update_timer;
- uint64_t next_alarm_time;
- uint16_t irq_reinject_on_ack_count;
- uint32_t irq_coalesced;
- uint32_t period;
- QEMUTimer *coalesced_timer;
- LostTickPolicy lost_tick_policy;
- Notifier suspend_notifier;
- QLIST_ENTRY(RTCState) link;
-} RTCState;
-
static void rtc_set_time(RTCState *s);
static void rtc_update_time(RTCState *s);
static void rtc_set_cmos(RTCState *s, const struct tm *tm);
@@ -204,24 +175,28 @@ periodic_timer_update(RTCState *s, int64_t current_time, uint32_t old_period)
period = rtc_periodic_clock_ticks(s);
- if (period) {
- /* compute 32 khz clock */
- cur_clock =
- muldiv64(current_time, RTC_CLOCK_RATE, NANOSECONDS_PER_SECOND);
+ if (!period) {
+ s->irq_coalesced = 0;
+ timer_del(s->periodic_timer);
+ return;
+ }
- /*
- * if the periodic timer's update is due to period re-configuration,
- * we should count the clock since last interrupt.
- */
- if (old_period) {
- int64_t last_periodic_clock, next_periodic_clock;
-
- next_periodic_clock = muldiv64(s->next_periodic_time,
- RTC_CLOCK_RATE, NANOSECONDS_PER_SECOND);
- last_periodic_clock = next_periodic_clock - old_period;
- lost_clock = cur_clock - last_periodic_clock;
- assert(lost_clock >= 0);
- }
+ /* compute 32 khz clock */
+ cur_clock =
+ muldiv64(current_time, RTC_CLOCK_RATE, NANOSECONDS_PER_SECOND);
+
+ /*
+ * if the periodic timer's update is due to period re-configuration,
+ * we should count the clock since last interrupt.
+ */
+ if (old_period) {
+ int64_t last_periodic_clock, next_periodic_clock;
+
+ next_periodic_clock = muldiv64(s->next_periodic_time,
+ RTC_CLOCK_RATE, NANOSECONDS_PER_SECOND);
+ last_periodic_clock = next_periodic_clock - old_period;
+ lost_clock = cur_clock - last_periodic_clock;
+ assert(lost_clock >= 0);
/*
* s->irq_coalesced can change for two reasons:
@@ -252,22 +227,19 @@ periodic_timer_update(RTCState *s, int64_t current_time, uint32_t old_period)
rtc_coalesced_timer_update(s);
}
} else {
- /*
+ /*
* no way to compensate the interrupt if LOST_TICK_POLICY_SLEW
* is not used, we should make the time progress anyway.
*/
lost_clock = MIN(lost_clock, period);
}
+ }
- assert(lost_clock >= 0 && lost_clock <= period);
+ assert(lost_clock >= 0 && lost_clock <= period);
- next_irq_clock = cur_clock + period - lost_clock;
- s->next_periodic_time = periodic_clock_to_ns(next_irq_clock) + 1;
- timer_mod(s->periodic_timer, s->next_periodic_time);
- } else {
- s->irq_coalesced = 0;
- timer_del(s->periodic_timer);
- }
+ next_irq_clock = cur_clock + period - lost_clock;
+ s->next_periodic_time = periodic_clock_to_ns(next_irq_clock) + 1;
+ timer_mod(s->periodic_timer, s->next_periodic_time);
}
static void rtc_periodic_timer(void *opaque)
@@ -993,17 +965,16 @@ static void rtc_realizefn(DeviceState *dev, Error **errp)
object_property_add_tm(OBJECT(s), "date", rtc_get_date, NULL);
qdev_init_gpio_out(dev, &s->irq, 1);
+ QLIST_INSERT_HEAD(&rtc_devices, s, link);
}
ISADevice *mc146818_rtc_init(ISABus *bus, int base_year, qemu_irq intercept_irq)
{
DeviceState *dev;
ISADevice *isadev;
- RTCState *s;
isadev = isa_create(bus, TYPE_MC146818_RTC);
dev = DEVICE(isadev);
- s = MC146818_RTC(isadev);
qdev_prop_set_int32(dev, "base_year", base_year);
qdev_init_nofail(dev);
if (intercept_irq) {
@@ -1011,9 +982,8 @@ ISADevice *mc146818_rtc_init(ISABus *bus, int base_year, qemu_irq intercept_irq)
} else {
isa_connect_gpio_out(isadev, 0, RTC_ISA_IRQ);
}
- QLIST_INSERT_HEAD(&rtc_devices, s, link);
- object_property_add_alias(qdev_get_machine(), "rtc-time", OBJECT(s),
+ object_property_add_alias(qdev_get_machine(), "rtc-time", OBJECT(isadev),
"date", NULL);
return isadev;
@@ -1045,8 +1015,6 @@ static void rtc_class_initfn(ObjectClass *klass, void *data)
dc->reset = rtc_resetdev;
dc->vmsd = &vmstate_rtc;
dc->props = mc146818rtc_properties;
- /* Reason: needs to be wired up by rtc_init() */
- dc->user_creatable = false;
}
static const TypeInfo mc146818rtc_info = {