Revision 100d9891 hw/mc146818rtc.c

b/hw/mc146818rtc.c
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
{

Also available in: Unified diff