Memory-mapped interface for RTC, by Herve Poussineau.
[qemu] / hw / mc146818rtc.c
1 /*
2  * QEMU MC146818 RTC emulation
3  * 
4  * Copyright (c) 2003-2004 Fabrice Bellard
5  * 
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 #include "vl.h"
25
26 //#define DEBUG_CMOS
27
28 #define RTC_SECONDS             0
29 #define RTC_SECONDS_ALARM       1
30 #define RTC_MINUTES             2
31 #define RTC_MINUTES_ALARM       3
32 #define RTC_HOURS               4
33 #define RTC_HOURS_ALARM         5
34 #define RTC_ALARM_DONT_CARE    0xC0
35
36 #define RTC_DAY_OF_WEEK         6
37 #define RTC_DAY_OF_MONTH        7
38 #define RTC_MONTH               8
39 #define RTC_YEAR                9
40
41 #define RTC_REG_A               10
42 #define RTC_REG_B               11
43 #define RTC_REG_C               12
44 #define RTC_REG_D               13
45
46 #define REG_A_UIP 0x80
47
48 #define REG_B_SET 0x80
49 #define REG_B_PIE 0x40
50 #define REG_B_AIE 0x20
51 #define REG_B_UIE 0x10
52
53 struct RTCState {
54     uint8_t cmos_data[128];
55     uint8_t cmos_index;
56     struct tm current_tm;
57     qemu_irq irq;
58     target_phys_addr_t base;
59     /* periodic timer */
60     QEMUTimer *periodic_timer;
61     int64_t next_periodic_time;
62     /* second update */
63     int64_t next_second_time;
64     QEMUTimer *second_timer;
65     QEMUTimer *second_timer2;
66 };
67
68 static void rtc_set_time(RTCState *s);
69 static void rtc_copy_date(RTCState *s);
70
71 static void rtc_timer_update(RTCState *s, int64_t current_time)
72 {
73     int period_code, period;
74     int64_t cur_clock, next_irq_clock;
75
76     period_code = s->cmos_data[RTC_REG_A] & 0x0f;
77     if (period_code != 0 && 
78         (s->cmos_data[RTC_REG_B] & REG_B_PIE)) {
79         if (period_code <= 2)
80             period_code += 7;
81         /* period in 32 Khz cycles */
82         period = 1 << (period_code - 1);
83         /* compute 32 khz clock */
84         cur_clock = muldiv64(current_time, 32768, ticks_per_sec);
85         next_irq_clock = (cur_clock & ~(period - 1)) + period;
86         s->next_periodic_time = muldiv64(next_irq_clock, ticks_per_sec, 32768) + 1;
87         qemu_mod_timer(s->periodic_timer, s->next_periodic_time);
88     } else {
89         qemu_del_timer(s->periodic_timer);
90     }
91 }
92
93 static void rtc_periodic_timer(void *opaque)
94 {
95     RTCState *s = opaque;
96
97     rtc_timer_update(s, s->next_periodic_time);
98     s->cmos_data[RTC_REG_C] |= 0xc0;
99     qemu_irq_raise(s->irq);
100 }
101
102 static void cmos_ioport_write(void *opaque, uint32_t addr, uint32_t data)
103 {
104     RTCState *s = opaque;
105
106     if ((addr & 1) == 0) {
107         s->cmos_index = data & 0x7f;
108     } else {
109 #ifdef DEBUG_CMOS
110         printf("cmos: write index=0x%02x val=0x%02x\n",
111                s->cmos_index, data);
112 #endif        
113         switch(s->cmos_index) {
114         case RTC_SECONDS_ALARM:
115         case RTC_MINUTES_ALARM:
116         case RTC_HOURS_ALARM:
117             /* XXX: not supported */
118             s->cmos_data[s->cmos_index] = data;
119             break;
120         case RTC_SECONDS:
121         case RTC_MINUTES:
122         case RTC_HOURS:
123         case RTC_DAY_OF_WEEK:
124         case RTC_DAY_OF_MONTH:
125         case RTC_MONTH:
126         case RTC_YEAR:
127             s->cmos_data[s->cmos_index] = data;
128             /* if in set mode, do not update the time */
129             if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
130                 rtc_set_time(s);
131             }
132             break;
133         case RTC_REG_A:
134             /* UIP bit is read only */
135             s->cmos_data[RTC_REG_A] = (data & ~REG_A_UIP) |
136                 (s->cmos_data[RTC_REG_A] & REG_A_UIP);
137             rtc_timer_update(s, qemu_get_clock(vm_clock));
138             break;
139         case RTC_REG_B:
140             if (data & REG_B_SET) {
141                 /* set mode: reset UIP mode */
142                 s->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
143                 data &= ~REG_B_UIE;
144             } else {
145                 /* if disabling set mode, update the time */
146                 if (s->cmos_data[RTC_REG_B] & REG_B_SET) {
147                     rtc_set_time(s);
148                 }
149             }
150             s->cmos_data[RTC_REG_B] = data;
151             rtc_timer_update(s, qemu_get_clock(vm_clock));
152             break;
153         case RTC_REG_C:
154         case RTC_REG_D:
155             /* cannot write to them */
156             break;
157         default:
158             s->cmos_data[s->cmos_index] = data;
159             break;
160         }
161     }
162 }
163
164 static inline int to_bcd(RTCState *s, int a)
165 {
166     if (s->cmos_data[RTC_REG_B] & 0x04) {
167         return a;
168     } else {
169         return ((a / 10) << 4) | (a % 10);
170     }
171 }
172
173 static inline int from_bcd(RTCState *s, int a)
174 {
175     if (s->cmos_data[RTC_REG_B] & 0x04) {
176         return a;
177     } else {
178         return ((a >> 4) * 10) + (a & 0x0f);
179     }
180 }
181
182 static void rtc_set_time(RTCState *s)
183 {
184     struct tm *tm = &s->current_tm;
185
186     tm->tm_sec = from_bcd(s, s->cmos_data[RTC_SECONDS]);
187     tm->tm_min = from_bcd(s, s->cmos_data[RTC_MINUTES]);
188     tm->tm_hour = from_bcd(s, s->cmos_data[RTC_HOURS] & 0x7f);
189     if (!(s->cmos_data[RTC_REG_B] & 0x02) &&
190         (s->cmos_data[RTC_HOURS] & 0x80)) {
191         tm->tm_hour += 12;
192     }
193     tm->tm_wday = from_bcd(s, s->cmos_data[RTC_DAY_OF_WEEK]);
194     tm->tm_mday = from_bcd(s, s->cmos_data[RTC_DAY_OF_MONTH]);
195     tm->tm_mon = from_bcd(s, s->cmos_data[RTC_MONTH]) - 1;
196     tm->tm_year = from_bcd(s, s->cmos_data[RTC_YEAR]) + 100;
197 }
198
199 static void rtc_copy_date(RTCState *s)
200 {
201     const struct tm *tm = &s->current_tm;
202
203     s->cmos_data[RTC_SECONDS] = to_bcd(s, tm->tm_sec);
204     s->cmos_data[RTC_MINUTES] = to_bcd(s, tm->tm_min);
205     if (s->cmos_data[RTC_REG_B] & 0x02) {
206         /* 24 hour format */
207         s->cmos_data[RTC_HOURS] = to_bcd(s, tm->tm_hour);
208     } else {
209         /* 12 hour format */
210         s->cmos_data[RTC_HOURS] = to_bcd(s, tm->tm_hour % 12);
211         if (tm->tm_hour >= 12)
212             s->cmos_data[RTC_HOURS] |= 0x80;
213     }
214     s->cmos_data[RTC_DAY_OF_WEEK] = to_bcd(s, tm->tm_wday);
215     s->cmos_data[RTC_DAY_OF_MONTH] = to_bcd(s, tm->tm_mday);
216     s->cmos_data[RTC_MONTH] = to_bcd(s, tm->tm_mon + 1);
217     s->cmos_data[RTC_YEAR] = to_bcd(s, tm->tm_year % 100);
218 }
219
220 /* month is between 0 and 11. */
221 static int get_days_in_month(int month, int year)
222 {
223     static const int days_tab[12] = { 
224         31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 
225     };
226     int d;
227     if ((unsigned )month >= 12)
228         return 31;
229     d = days_tab[month];
230     if (month == 1) {
231         if ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0))
232             d++;
233     }
234     return d;
235 }
236
237 /* update 'tm' to the next second */
238 static void rtc_next_second(struct tm *tm)
239 {
240     int days_in_month;
241
242     tm->tm_sec++;
243     if ((unsigned)tm->tm_sec >= 60) {
244         tm->tm_sec = 0;
245         tm->tm_min++;
246         if ((unsigned)tm->tm_min >= 60) {
247             tm->tm_min = 0;
248             tm->tm_hour++;
249             if ((unsigned)tm->tm_hour >= 24) {
250                 tm->tm_hour = 0;
251                 /* next day */
252                 tm->tm_wday++;
253                 if ((unsigned)tm->tm_wday >= 7)
254                     tm->tm_wday = 0;
255                 days_in_month = get_days_in_month(tm->tm_mon, 
256                                                   tm->tm_year + 1900);
257                 tm->tm_mday++;
258                 if (tm->tm_mday < 1) {
259                     tm->tm_mday = 1;
260                 } else if (tm->tm_mday > days_in_month) {
261                     tm->tm_mday = 1;
262                     tm->tm_mon++;
263                     if (tm->tm_mon >= 12) {
264                         tm->tm_mon = 0;
265                         tm->tm_year++;
266                     }
267                 }
268             }
269         }
270     }
271 }
272
273
274 static void rtc_update_second(void *opaque)
275 {
276     RTCState *s = opaque;
277     int64_t delay;
278
279     /* if the oscillator is not in normal operation, we do not update */
280     if ((s->cmos_data[RTC_REG_A] & 0x70) != 0x20) {
281         s->next_second_time += ticks_per_sec;
282         qemu_mod_timer(s->second_timer, s->next_second_time);
283     } else {
284         rtc_next_second(&s->current_tm);
285         
286         if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
287             /* update in progress bit */
288             s->cmos_data[RTC_REG_A] |= REG_A_UIP;
289         }
290         /* should be 244 us = 8 / 32768 seconds, but currently the
291            timers do not have the necessary resolution. */
292         delay = (ticks_per_sec * 1) / 100;
293         if (delay < 1)
294             delay = 1;
295         qemu_mod_timer(s->second_timer2, 
296                        s->next_second_time + delay);
297     }
298 }
299
300 static void rtc_update_second2(void *opaque)
301 {
302     RTCState *s = opaque;
303
304     if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
305         rtc_copy_date(s);
306     }
307
308     /* check alarm */
309     if (s->cmos_data[RTC_REG_B] & REG_B_AIE) {
310         if (((s->cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0 ||
311              s->cmos_data[RTC_SECONDS_ALARM] == s->current_tm.tm_sec) &&
312             ((s->cmos_data[RTC_MINUTES_ALARM] & 0xc0) == 0xc0 ||
313              s->cmos_data[RTC_MINUTES_ALARM] == s->current_tm.tm_mon) &&
314             ((s->cmos_data[RTC_HOURS_ALARM] & 0xc0) == 0xc0 ||
315              s->cmos_data[RTC_HOURS_ALARM] == s->current_tm.tm_hour)) {
316
317             s->cmos_data[RTC_REG_C] |= 0xa0; 
318             qemu_irq_raise(s->irq);
319         }
320     }
321
322     /* update ended interrupt */
323     if (s->cmos_data[RTC_REG_B] & REG_B_UIE) {
324         s->cmos_data[RTC_REG_C] |= 0x90; 
325         qemu_irq_raise(s->irq);
326     }
327
328     /* clear update in progress bit */
329     s->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
330
331     s->next_second_time += ticks_per_sec;
332     qemu_mod_timer(s->second_timer, s->next_second_time);
333 }
334
335 static uint32_t cmos_ioport_read(void *opaque, uint32_t addr)
336 {
337     RTCState *s = opaque;
338     int ret;
339     if ((addr & 1) == 0) {
340         return 0xff;
341     } else {
342         switch(s->cmos_index) {
343         case RTC_SECONDS:
344         case RTC_MINUTES:
345         case RTC_HOURS:
346         case RTC_DAY_OF_WEEK:
347         case RTC_DAY_OF_MONTH:
348         case RTC_MONTH:
349         case RTC_YEAR:
350             ret = s->cmos_data[s->cmos_index];
351             break;
352         case RTC_REG_A:
353             ret = s->cmos_data[s->cmos_index];
354             break;
355         case RTC_REG_C:
356             ret = s->cmos_data[s->cmos_index];
357             qemu_irq_lower(s->irq);
358             s->cmos_data[RTC_REG_C] = 0x00; 
359             break;
360         default:
361             ret = s->cmos_data[s->cmos_index];
362             break;
363         }
364 #ifdef DEBUG_CMOS
365         printf("cmos: read index=0x%02x val=0x%02x\n",
366                s->cmos_index, ret);
367 #endif
368         return ret;
369     }
370 }
371
372 void rtc_set_memory(RTCState *s, int addr, int val)
373 {
374     if (addr >= 0 && addr <= 127)
375         s->cmos_data[addr] = val;
376 }
377
378 void rtc_set_date(RTCState *s, const struct tm *tm)
379 {
380     s->current_tm = *tm;
381     rtc_copy_date(s);
382 }
383
384 /* PC cmos mappings */
385 #define REG_IBM_CENTURY_BYTE        0x32
386 #define REG_IBM_PS2_CENTURY_BYTE    0x37
387
388 void rtc_set_date_from_host(RTCState *s)
389 {
390     time_t ti;
391     struct tm *tm;
392     int val;
393
394     /* set the CMOS date */
395     time(&ti);
396     if (rtc_utc)
397         tm = gmtime(&ti);
398     else
399         tm = localtime(&ti);
400     rtc_set_date(s, tm);
401
402     val = to_bcd(s, (tm->tm_year / 100) + 19);
403     rtc_set_memory(s, REG_IBM_CENTURY_BYTE, val);
404     rtc_set_memory(s, REG_IBM_PS2_CENTURY_BYTE, val);
405 }
406
407 static void rtc_save(QEMUFile *f, void *opaque)
408 {
409     RTCState *s = opaque;
410
411     qemu_put_buffer(f, s->cmos_data, 128);
412     qemu_put_8s(f, &s->cmos_index);
413     
414     qemu_put_be32s(f, &s->current_tm.tm_sec);
415     qemu_put_be32s(f, &s->current_tm.tm_min);
416     qemu_put_be32s(f, &s->current_tm.tm_hour);
417     qemu_put_be32s(f, &s->current_tm.tm_wday);
418     qemu_put_be32s(f, &s->current_tm.tm_mday);
419     qemu_put_be32s(f, &s->current_tm.tm_mon);
420     qemu_put_be32s(f, &s->current_tm.tm_year);
421
422     qemu_put_timer(f, s->periodic_timer);
423     qemu_put_be64s(f, &s->next_periodic_time);
424
425     qemu_put_be64s(f, &s->next_second_time);
426     qemu_put_timer(f, s->second_timer);
427     qemu_put_timer(f, s->second_timer2);
428 }
429
430 static int rtc_load(QEMUFile *f, void *opaque, int version_id)
431 {
432     RTCState *s = opaque;
433
434     if (version_id != 1)
435         return -EINVAL;
436
437     qemu_get_buffer(f, s->cmos_data, 128);
438     qemu_get_8s(f, &s->cmos_index);
439
440     qemu_get_be32s(f, &s->current_tm.tm_sec);
441     qemu_get_be32s(f, &s->current_tm.tm_min);
442     qemu_get_be32s(f, &s->current_tm.tm_hour);
443     qemu_get_be32s(f, &s->current_tm.tm_wday);
444     qemu_get_be32s(f, &s->current_tm.tm_mday);
445     qemu_get_be32s(f, &s->current_tm.tm_mon);
446     qemu_get_be32s(f, &s->current_tm.tm_year);
447
448     qemu_get_timer(f, s->periodic_timer);
449     qemu_get_be64s(f, &s->next_periodic_time);
450
451     qemu_get_be64s(f, &s->next_second_time);
452     qemu_get_timer(f, s->second_timer);
453     qemu_get_timer(f, s->second_timer2);
454     return 0;
455 }
456
457 RTCState *rtc_init(int base, qemu_irq irq)
458 {
459     RTCState *s;
460
461     s = qemu_mallocz(sizeof(RTCState));
462     if (!s)
463         return NULL;
464
465     s->irq = irq;
466     s->cmos_data[RTC_REG_A] = 0x26;
467     s->cmos_data[RTC_REG_B] = 0x02;
468     s->cmos_data[RTC_REG_C] = 0x00;
469     s->cmos_data[RTC_REG_D] = 0x80;
470
471     rtc_set_date_from_host(s);
472
473     s->periodic_timer = qemu_new_timer(vm_clock, 
474                                        rtc_periodic_timer, s);
475     s->second_timer = qemu_new_timer(vm_clock, 
476                                      rtc_update_second, s);
477     s->second_timer2 = qemu_new_timer(vm_clock, 
478                                       rtc_update_second2, s);
479
480     s->next_second_time = qemu_get_clock(vm_clock) + (ticks_per_sec * 99) / 100;
481     qemu_mod_timer(s->second_timer2, s->next_second_time);
482
483     register_ioport_write(base, 2, 1, cmos_ioport_write, s);
484     register_ioport_read(base, 2, 1, cmos_ioport_read, s);
485
486     register_savevm("mc146818rtc", base, 1, rtc_save, rtc_load, s);
487     return s;
488 }
489
490 /* Memory mapped interface */
491 uint32_t cmos_mm_readb (void *opaque, target_phys_addr_t addr)
492 {
493     RTCState *s = opaque;
494
495     return cmos_ioport_read(s, addr - s->base) & 0xFF;
496 }
497
498 void cmos_mm_writeb (void *opaque,
499                      target_phys_addr_t addr, uint32_t value)
500 {
501     RTCState *s = opaque;
502
503     cmos_ioport_write(s, addr - s->base, value & 0xFF);
504 }
505
506 uint32_t cmos_mm_readw (void *opaque, target_phys_addr_t addr)
507 {
508     RTCState *s = opaque;
509
510     return cmos_ioport_read(s, addr - s->base) & 0xFFFF;
511 }
512
513 void cmos_mm_writew (void *opaque,
514                      target_phys_addr_t addr, uint32_t value)
515 {
516     RTCState *s = opaque;
517
518     cmos_ioport_write(s, addr - s->base, value & 0xFFFF);
519 }
520
521 uint32_t cmos_mm_readl (void *opaque, target_phys_addr_t addr)
522 {
523     RTCState *s = opaque;
524
525     return cmos_ioport_read(s, addr - s->base);
526 }
527
528 void cmos_mm_writel (void *opaque,
529                      target_phys_addr_t addr, uint32_t value)
530 {
531     RTCState *s = opaque;
532
533     cmos_ioport_write(s, addr - s->base, value);
534 }
535
536 static CPUReadMemoryFunc *rtc_mm_read[] = {
537     &cmos_mm_readb,
538     &cmos_mm_readw,
539     &cmos_mm_readl,
540 };
541
542 static CPUWriteMemoryFunc *rtc_mm_write[] = {
543     &cmos_mm_writeb,
544     &cmos_mm_writew,
545     &cmos_mm_writel,
546 };
547
548 RTCState *rtc_mm_init(target_phys_addr_t base, qemu_irq irq)
549 {
550     RTCState *s;
551     int io_memory;
552
553     s = qemu_mallocz(sizeof(RTCState));
554     if (!s)
555         return NULL;
556
557     s->irq = irq;
558     s->cmos_data[RTC_REG_A] = 0x26;
559     s->cmos_data[RTC_REG_B] = 0x02;
560     s->cmos_data[RTC_REG_C] = 0x00;
561     s->cmos_data[RTC_REG_D] = 0x80;
562     s->base = base;
563
564     rtc_set_date_from_host(s);
565
566     s->periodic_timer = qemu_new_timer(vm_clock,
567                                        rtc_periodic_timer, s);
568     s->second_timer = qemu_new_timer(vm_clock,
569                                      rtc_update_second, s);
570     s->second_timer2 = qemu_new_timer(vm_clock,
571                                       rtc_update_second2, s);
572
573     s->next_second_time = qemu_get_clock(vm_clock) + (ticks_per_sec * 99) / 100;
574     qemu_mod_timer(s->second_timer2, s->next_second_time);
575
576     io_memory = cpu_register_io_memory(0, rtc_mm_read, rtc_mm_write, s);
577     cpu_register_physical_memory(base, 2, io_memory);
578
579     register_savevm("mc146818rtc", base, 1, rtc_save, rtc_load, s);
580     return s;
581 }