50 |
50 |
|
51 |
51 |
#define REG_A_UIP 0x80
|
52 |
52 |
|
53 |
|
#define REG_B_SET 0x80
|
54 |
|
#define REG_B_PIE 0x40
|
55 |
|
#define REG_B_AIE 0x20
|
56 |
|
#define REG_B_UIE 0x10
|
57 |
|
#define REG_B_DM 0x04
|
|
53 |
#define REG_B_SET 0x80
|
|
54 |
#define REG_B_PIE 0x40
|
|
55 |
#define REG_B_AIE 0x20
|
|
56 |
#define REG_B_UIE 0x10
|
|
57 |
#define REG_B_SQWE 0x08
|
|
58 |
#define REG_B_DM 0x04
|
58 |
59 |
|
59 |
60 |
struct RTCState {
|
60 |
61 |
uint8_t cmos_data[128];
|
... | ... | |
62 |
63 |
struct tm current_tm;
|
63 |
64 |
int base_year;
|
64 |
65 |
qemu_irq irq;
|
|
66 |
qemu_irq sqw_irq;
|
65 |
67 |
int it_shift;
|
66 |
68 |
/* periodic timer */
|
67 |
69 |
QEMUTimer *periodic_timer;
|
... | ... | |
95 |
97 |
{
|
96 |
98 |
int period_code, period;
|
97 |
99 |
int64_t cur_clock, next_irq_clock;
|
|
100 |
int enable_pie;
|
98 |
101 |
|
99 |
102 |
period_code = s->cmos_data[RTC_REG_A] & 0x0f;
|
100 |
103 |
#if defined TARGET_I386 || defined TARGET_X86_64
|
101 |
104 |
/* disable periodic timer if hpet is in legacy mode, since interrupts are
|
102 |
105 |
* disabled anyway.
|
103 |
106 |
*/
|
104 |
|
if (period_code != 0 && (s->cmos_data[RTC_REG_B] & REG_B_PIE) && !hpet_in_legacy_mode()) {
|
|
107 |
enable_pie = hpet_in_legacy_mode();
|
105 |
108 |
#else
|
106 |
|
if (period_code != 0 && (s->cmos_data[RTC_REG_B] & REG_B_PIE)) {
|
|
109 |
enable_pie = 1;
|
107 |
110 |
#endif
|
|
111 |
if (period_code != 0
|
|
112 |
&& (((s->cmos_data[RTC_REG_B] & REG_B_PIE) && enable_pie)
|
|
113 |
|| ((s->cmos_data[RTC_REG_B] & REG_B_SQWE) && s->sqw_irq))) {
|
108 |
114 |
if (period_code <= 2)
|
109 |
115 |
period_code += 7;
|
110 |
116 |
/* period in 32 Khz cycles */
|
... | ... | |
138 |
144 |
return;
|
139 |
145 |
}
|
140 |
146 |
#endif
|
141 |
|
s->cmos_data[RTC_REG_C] |= 0xc0;
|
142 |
|
rtc_irq_raise(s->irq);
|
|
147 |
if (s->cmos_data[RTC_REG_B] & REG_B_PIE) {
|
|
148 |
s->cmos_data[RTC_REG_C] |= 0xc0;
|
|
149 |
rtc_irq_raise(s->irq);
|
|
150 |
}
|
|
151 |
if (s->cmos_data[RTC_REG_B] & REG_B_SQWE) {
|
|
152 |
/* Not square wave at all but we don't want 2048Hz interrupts!
|
|
153 |
Must be seen as a pulse. */
|
|
154 |
qemu_irq_raise(s->sqw_irq);
|
|
155 |
}
|
143 |
156 |
}
|
144 |
157 |
|
145 |
158 |
static void cmos_ioport_write(void *opaque, uint32_t addr, uint32_t data)
|
... | ... | |
527 |
540 |
}
|
528 |
541 |
#endif
|
529 |
542 |
|
530 |
|
RTCState *rtc_init(int base, qemu_irq irq, int base_year)
|
|
543 |
RTCState *rtc_init_sqw(int base, qemu_irq irq, qemu_irq sqw_irq, int base_year)
|
531 |
544 |
{
|
532 |
545 |
RTCState *s;
|
533 |
546 |
|
534 |
547 |
s = qemu_mallocz(sizeof(RTCState));
|
535 |
548 |
|
536 |
549 |
s->irq = irq;
|
|
550 |
s->sqw_irq = sqw_irq;
|
537 |
551 |
s->cmos_data[RTC_REG_A] = 0x26;
|
538 |
552 |
s->cmos_data[RTC_REG_B] = 0x02;
|
539 |
553 |
s->cmos_data[RTC_REG_C] = 0x00;
|
... | ... | |
563 |
577 |
return s;
|
564 |
578 |
}
|
565 |
579 |
|
|
580 |
RTCState *rtc_init(int base, qemu_irq irq, int base_year)
|
|
581 |
{
|
|
582 |
return rtc_init_sqw(base, irq, NULL, base_year);
|
|
583 |
}
|
|
584 |
|
566 |
585 |
/* Memory mapped interface */
|
567 |
586 |
static uint32_t cmos_mm_readb (void *opaque, target_phys_addr_t addr)
|
568 |
587 |
{
|