[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v3 6/7] RTC:Add alarm support
From: |
Zhang, Yang Z |
Subject: |
[Qemu-devel] [PATCH v3 6/7] RTC:Add alarm support |
Date: |
Fri, 2 Mar 2012 07:00:27 +0000 |
Add the alarm check when update cycle ended. If alarm is fired,
also AIE bit is setting, then raise a interrupt
Signed-off-by: Yang Zhang <address@hidden>
---
hw/mc146818rtc.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 46 insertions(+), 2 deletions(-)
diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c
index fae049e..384bdc1 100644
--- a/hw/mc146818rtc.c
+++ b/hw/mc146818rtc.c
@@ -114,6 +114,7 @@ typedef struct RTCState {
static void rtc_set_time(RTCState *s);
static void rtc_calibrate_time(RTCState *s);
static void rtc_set_cmos(RTCState *s);
+static inline int rtc_from_bcd(RTCState *s, int a);
static int32_t divider_reset;
@@ -267,15 +268,58 @@ static void rtc_update_timer(void *opaque)
}
}
+static inline uint8_t convert_hour(RTCState *s, uint8_t hour)
+{
+ if (!(s->cmos_data[RTC_REG_B] & REG_B_24H)) {
+ hour %= 12;
+ if (s->cmos_data[RTC_HOURS] & 0x80) {
+ hour += 12;
+ }
+ }
+ return hour;
+}
+static uint32_t check_alarm(RTCState *s)
+{
+ uint8_t alarm_hour, alarm_min, alarm_sec;
+ uint8_t cur_hour, cur_min, cur_sec;
+
+ rtc_calibrate_time(s);
+ rtc_set_cmos(s);
+
+ alarm_sec = rtc_from_bcd(s, s->cmos_data[RTC_SECONDS_ALARM]);
+ alarm_min = rtc_from_bcd(s, s->cmos_data[RTC_MINUTES_ALARM]);
+ alarm_hour = rtc_from_bcd(s, s->cmos_data[RTC_HOURS_ALARM]);
+ alarm_hour = convert_hour(s, alarm_hour);
+
+ cur_sec = rtc_from_bcd(s, s->cmos_data[RTC_SECONDS]);
+ cur_min = rtc_from_bcd(s, s->cmos_data[RTC_MINUTES]);
+ cur_hour = rtc_from_bcd(s, s->cmos_data[RTC_HOURS]);
+ cur_hour = convert_hour(s, cur_hour);
+
+ if (((alarm_sec & 0xc0) == 0xc0 || alarm_sec == cur_sec) &&
+ ((alarm_min & 0xc0) == 0xc0 || alarm_min == cur_min) &&
+ ((alarm_hour & 0xc0) == 0xc0 || alarm_hour == cur_hour)) {
+ return 1;
+ }
+ return 0;
+
+}
+
static void rtc_update_timer2(void *opaque)
{
RTCState *s = opaque;
if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
s->cmos_data[RTC_REG_C] |= REG_C_UF;
+ if (check_alarm(s)) {
+ s->cmos_data[RTC_REG_C] |= REG_C_AF;
+ }
+
s->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
- s->cmos_data[RTC_REG_C] |= REG_C_IRQF;
- qemu_irq_raise(s->irq);
+ if (s->cmos_data[RTC_REG_B] & (REG_B_AIE | REG_B_UIE)) {
+ s->cmos_data[RTC_REG_C] |= REG_C_IRQF;
+ qemu_irq_raise(s->irq);
+ }
}
check_update_timer(s);
}
--
1.7.1
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Qemu-devel] [PATCH v3 6/7] RTC:Add alarm support,
Zhang, Yang Z <=