Move date/time init to the RTC implementation.
[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     int irq;
58     /* periodic timer */
59     QEMUTimer *periodic_timer;
60     int64_t next_periodic_time;
61     /* second update */
62     int64_t next_second_time;
63     QEMUTimer *second_timer;
64     QEMUTimer *second_timer2;
65 };
66
67 static void rtc_set_time(RTCState *s);
68 static void rtc_copy_date(RTCState *s);
69
70 static void rtc_timer_update(RTCState *s, int64_t current_time)
71 {
72     int period_code, period;
73     int64_t cur_clock, next_irq_clock;
74
75     period_code = s->cmos_data[RTC_REG_A] & 0x0f;
76     if (period_code != 0 && 
77         (s->cmos_data[RTC_REG_B] & REG_B_PIE)) {
78         if (period_code <= 2)
79             period_code += 7;
80         /* period in 32 Khz cycles */
81         period = 1 << (period_code - 1);
82         /* compute 32 khz clock */
83         cur_clock = muldiv64(current_time, 32768, ticks_per_sec);
84         next_irq_clock = (cur_clock & ~(period - 1)) + period;
85         s->next_periodic_time = muldiv64(next_irq_clock, ticks_per_sec, 32768) + 1;
86         qemu_mod_timer(s->periodic_timer, s->next_periodic_time);
87     } else {
88         qemu_del_timer(s->periodic_timer);
89     }
90 }
91
92 static void rtc_periodic_timer(void *opaque)
93 {
94     RTCState *s = opaque;
95
96     rtc_timer_update(s, s->next_periodic_time);
97     s->cmos_data[RTC_REG_C] |= 0xc0;
98     pic_set_irq(s->irq, 1);
99 }
100
101 static void cmos_ioport_write(void *opaque, uint32_t addr, uint32_t data)
102 {
103     RTCState *s = opaque;
104
105     if ((addr & 1) == 0) {
106         s->cmos_index = data & 0x7f;
107     } else {
108 #ifdef DEBUG_CMOS
109         printf("cmos: write index=0x%02x val=0x%02x\n",
110                s->cmos_index, data);
111 #endif        
112         switch(s->cmos_index) {
113         case RTC_SECONDS_ALARM:
114         case RTC_MINUTES_ALARM:
115         case RTC_HOURS_ALARM:
116             /* XXX: not supported */
117             s->cmos_data[s->cmos_index] = data;
118             break;
119         case RTC_SECONDS:
120         case RTC_MINUTES:
121         case RTC_HOURS:
122         case RTC_DAY_OF_WEEK:
123         case RTC_DAY_OF_MONTH:
124         case RTC_MONTH:
125         case RTC_YEAR:
126             s->cmos_data[s->cmos_index] = data;
127             /* if in set mode, do not update the time */
128             if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
129                 rtc_set_time(s);
130             }
131             break;
132         case RTC_REG_A:
133             /* UIP bit is read only */
134             s->cmos_data[RTC_REG_A] = (data & ~REG_A_UIP) |
135                 (s->cmos_data[RTC_REG_A] & REG_A_UIP);
136             rtc_timer_update(s, qemu_get_clock(vm_clock));
137             break;
138         case RTC_REG_B:
139             if (data & REG_B_SET) {
140                 /* set mode: reset UIP mode */
141                 s->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
142                 data &= ~REG_B_UIE;
143             } else {
144                 /* if disabling set mode, update the time */
145                 if (s->cmos_data[RTC_REG_B] & REG_B_SET) {
146                     rtc_set_time(s);
147                 }
148             }
149             s->cmos_data[RTC_REG_B] = data;
150             rtc_timer_update(s, qemu_get_clock(vm_clock));
151             break;
152         case RTC_REG_C:
153         case RTC_REG_D:
154             /* cannot write to them */
155             break;
156         default:
157             s->cmos_data[s->cmos_index] = data;
158             break;
159         }
160     }
161 }
162
163 static inline int to_bcd(RTCState *s, int a)
164 {
165     if (s->cmos_data[RTC_REG_B] & 0x04) {
166         return a;
167     } else {
168         return ((a / 10) << 4) | (a % 10);
169     }
170 }
171
172 static inline int from_bcd(RTCState *s, int a)
173 {
174     if (s->cmos_data[RTC_REG_B] & 0x04) {
175         return a;
176     } else {
177         return ((a >> 4) * 10) + (a & 0x0f);
178     }
179 }
180
181 static void rtc_set_time(RTCState *s)
182 {
183     struct tm *tm = &s->current_tm;
184
185     tm->tm_sec = from_bcd(s, s->cmos_data[RTC_SECONDS]);
186     tm->tm_min = from_bcd(s, s->cmos_data[RTC_MINUTES]);
187     tm->tm_hour = from_bcd(s, s->cmos_data[RTC_HOURS] & 0x7f);
188     if (!(s->cmos_data[RTC_REG_B] & 0x02) &&
189         (s->cmos_data[RTC_HOURS] & 0x80)) {
190         tm->tm_hour += 12;
191     }
192     tm->tm_wday = from_bcd(s, s->cmos_data[RTC_DAY_OF_WEEK]);
193     tm->tm_mday = from_bcd(s, s->cmos_data[RTC_DAY_OF_MONTH]);
194     tm->tm_mon = from_bcd(s, s->cmos_data[RTC_MONTH]) - 1;
195     tm->tm_year = from_bcd(s, s->cmos_data[RTC_YEAR]) + 100;
196 }
197
198 static void rtc_copy_date(RTCState *s)
199 {
200     const struct tm *tm = &s->current_tm;
201
202     s->cmos_data[RTC_SECONDS] = to_bcd(s, tm->tm_sec);
203     s->cmos_data[RTC_MINUTES] = to_bcd(s, tm->tm_min);
204     if (s->cmos_data[RTC_REG_B] & 0x02) {
205         /* 24 hour format */
206         s->cmos_data[RTC_HOURS] = to_bcd(s, tm->tm_hour);
207     } else {
208         /* 12 hour format */
209         s->cmos_data[RTC_HOURS] = to_bcd(s, tm->tm_hour % 12);
210         if (tm->tm_hour >= 12)
211             s->cmos_data[RTC_HOURS] |= 0x80;
212     }
213     s->cmos_data[RTC_DAY_OF_WEEK] = to_bcd(s, tm->tm_wday);
214     s->cmos_data[RTC_DAY_OF_MONTH] = to_bcd(s, tm->tm_mday);
215     s->cmos_data[RTC_MONTH] = to_bcd(s, tm->tm_mon + 1);
216     s->cmos_data[RTC_YEAR] = to_bcd(s, tm->tm_year % 100);
217 }
218
219 /* month is between 0 and 11. */
220 static int get_days_in_month(int month, int year)
221 {
222     static const int days_tab[12] = { 
223         31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 
224     };
225     int d;
226     if ((unsigned )month >= 12)
227         return 31;
228     d = days_tab[month];
229     if (month == 1) {
230         if ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0))
231             d++;
232     }
233     return d;
234 }
235
236 /* update 'tm' to the next second */
237 static void rtc_next_second(struct tm *tm)
238 {
239     int days_in_month;
240
241     tm->tm_sec++;
242     if ((unsigned)tm->tm_sec >= 60) {
243         tm->tm_sec = 0;
244         tm->tm_min++;
245         if ((unsigned)tm->tm_min >= 60) {
246             tm->tm_min = 0;
247             tm->tm_hour++;
248             if ((unsigned)tm->tm_hour >= 24) {
249                 tm->tm_hour = 0;
250                 /* next day */
251                 tm->tm_wday++;
252                 if ((unsigned)tm->tm_wday >= 7)
253                     tm->tm_wday = 0;
254                 days_in_month = get_days_in_month(tm->tm_mon, 
255                                                   tm->tm_year + 1900);
256                 tm->tm_mday++;
257                 if (tm->tm_mday < 1) {
258                     tm->tm_mday = 1;
259                 } else if (tm->tm_mday > days_in_month) {
260                     tm->tm_mday = 1;
261                     tm->tm_mon++;
262                     if (tm->tm_mon >= 12) {
263                         tm->tm_mon = 0;
264                         tm->tm_year++;
265                     }
266                 }
267             }
268         }
269     }
270 }
271
272
273 static void rtc_update_second(void *opaque)
274 {
275     RTCState *s = opaque;
276     int64_t delay;
277
278     /* if the oscillator is not in normal operation, we do not update */
279     if ((s->cmos_data[RTC_REG_A] & 0x70) != 0x20) {
280         s->next_second_time += ticks_per_sec;
281         qemu_mod_timer(s->second_timer, s->next_second_time);
282     } else {
283         rtc_next_second(&s->current_tm);
284         
285         if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
286             /* update in progress bit */
287             s->cmos_data[RTC_REG_A] |= REG_A_UIP;
288         }
289         /* should be 244 us = 8 / 32768 seconds, but currently the
290            timers do not have the necessary resolution. */
291         delay = (ticks_per_sec * 1) / 100;
292         if (delay < 1)
293             delay = 1;
294         qemu_mod_timer(s->second_timer2, 
295                        s->next_second_time + delay);
296     }
297 }
298
299 static void rtc_update_second2(void *opaque)
300 {
301     RTCState *s = opaque;
302
303     if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
304         rtc_copy_date(s);
305     }
306
307     /* check alarm */
308     if (s->cmos_data[RTC_REG_B] & REG_B_AIE) {
309         if (((s->cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0 ||
310              s->cmos_data[RTC_SECONDS_ALARM] == s->current_tm.tm_sec) &&
311             ((s->cmos_data[RTC_MINUTES_ALARM] & 0xc0) == 0xc0 ||
312              s->cmos_data[RTC_MINUTES_ALARM] == s->current_tm.tm_mon) &&
313             ((s->cmos_data[RTC_HOURS_ALARM] & 0xc0) == 0xc0 ||
314              s->cmos_data[RTC_HOURS_ALARM] == s->current_tm.tm_hour)) {
315
316             s->cmos_data[RTC_REG_C] |= 0xa0; 
317             pic_set_irq(s->irq, 1);
318         }
319     }
320
321     /* update ended interrupt */
322     if (s->cmos_data[RTC_REG_B] & REG_B_UIE) {
323         s->cmos_data[RTC_REG_C] |= 0x90; 
324         pic_set_irq(s->irq, 1);
325     }
326
327     /* clear update in progress bit */
328     s->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
329
330     s->next_second_time += ticks_per_sec;
331     qemu_mod_timer(s->second_timer, s->next_second_time);
332 }
333
334 static uint32_t cmos_ioport_read(void *opaque, uint32_t addr)
335 {
336     RTCState *s = opaque;
337     int ret;
338     if ((addr & 1) == 0) {
339         return 0xff;
340     } else {
341         switch(s->cmos_index) {
342         case RTC_SECONDS:
343         case RTC_MINUTES:
344         case RTC_HOURS:
345         case RTC_DAY_OF_WEEK:
346         case RTC_DAY_OF_MONTH:
347         case RTC_MONTH:
348         case RTC_YEAR:
349             ret = s->cmos_data[s->cmos_index];
350             break;
351         case RTC_REG_A:
352             ret = s->cmos_data[s->cmos_index];
353             break;
354         case RTC_REG_C:
355             ret = s->cmos_data[s->cmos_index];
356             pic_set_irq(s->irq, 0);
357             s->cmos_data[RTC_REG_C] = 0x00; 
358             break;
359         default:
360             ret = s->cmos_data[s->cmos_index];
361             break;
362         }
363 #ifdef DEBUG_CMOS
364         printf("cmos: read index=0x%02x val=0x%02x\n",
365                s->cmos_index, ret);
366 #endif
367         return ret;
368     }
369 }
370
371 void rtc_set_memory(RTCState *s, int addr, int val)
372 {
373     if (addr >= 0 && addr <= 127)
374         s->cmos_data[addr] = val;
375 }
376
377 void rtc_set_date(RTCState *s, const struct tm *tm)
378 {
379     s->current_tm = *tm;
380     rtc_copy_date(s);
381 }
382
383 /* PC cmos mappings */
384 #define REG_IBM_CENTURY_BYTE        0x32
385 #define REG_IBM_PS2_CENTURY_BYTE    0x37
386
387 void rtc_set_date_from_host(RTCState *s)
388 {
389     time_t ti;
390     struct tm *tm;
391     int val;
392
393     /* set the CMOS date */
394     time(&ti);
395     if (rtc_utc)
396         tm = gmtime(&ti);
397     else
398         tm = localtime(&ti);
399     rtc_set_date(s, tm);
400
401     val = to_bcd(s, (tm->tm_year / 100) + 19);
402     rtc_set_memory(s, REG_IBM_CENTURY_BYTE, val);
403     rtc_set_memory(s, REG_IBM_PS2_CENTURY_BYTE, val);
404 }
405
406 static void rtc_save(QEMUFile *f, void *opaque)
407 {
408     RTCState *s = opaque;
409
410     qemu_put_buffer(f, s->cmos_data, 128);
411     qemu_put_8s(f, &s->cmos_index);
412     
413     qemu_put_be32s(f, &s->current_tm.tm_sec);
414     qemu_put_be32s(f, &s->current_tm.tm_min);
415     qemu_put_be32s(f, &s->current_tm.tm_hour);
416     qemu_put_be32s(f, &s->current_tm.tm_wday);
417     qemu_put_be32s(f, &s->current_tm.tm_mday);
418     qemu_put_be32s(f, &s->current_tm.tm_mon);
419     qemu_put_be32s(f, &s->current_tm.tm_year);
420
421     qemu_put_timer(f, s->periodic_timer);
422     qemu_put_be64s(f, &s->next_periodic_time);
423
424     qemu_put_be64s(f, &s->next_second_time);
425     qemu_put_timer(f, s->second_timer);
426     qemu_put_timer(f, s->second_timer2);
427 }
428
429 static int rtc_load(QEMUFile *f, void *opaque, int version_id)
430 {
431     RTCState *s = opaque;
432
433     if (version_id != 1)
434         return -EINVAL;
435
436     qemu_get_buffer(f, s->cmos_data, 128);
437     qemu_get_8s(f, &s->cmos_index);
438
439     qemu_get_be32s(f, &s->current_tm.tm_sec);
440     qemu_get_be32s(f, &s->current_tm.tm_min);
441     qemu_get_be32s(f, &s->current_tm.tm_hour);
442     qemu_get_be32s(f, &s->current_tm.tm_wday);
443     qemu_get_be32s(f, &s->current_tm.tm_mday);
444     qemu_get_be32s(f, &s->current_tm.tm_mon);
445     qemu_get_be32s(f, &s->current_tm.tm_year);
446
447     qemu_get_timer(f, s->periodic_timer);
448     qemu_get_be64s(f, &s->next_periodic_time);
449
450     qemu_get_be64s(f, &s->next_second_time);
451     qemu_get_timer(f, s->second_timer);
452     qemu_get_timer(f, s->second_timer2);
453     return 0;
454 }
455
456 RTCState *rtc_init(int base, int irq)
457 {
458     RTCState *s;
459
460     s = qemu_mallocz(sizeof(RTCState));
461     if (!s)
462         return NULL;
463
464     s->irq = irq;
465     s->cmos_data[RTC_REG_A] = 0x26;
466     s->cmos_data[RTC_REG_B] = 0x02;
467     s->cmos_data[RTC_REG_C] = 0x00;
468     s->cmos_data[RTC_REG_D] = 0x80;
469
470     rtc_set_date_from_host(s);
471
472     s->periodic_timer = qemu_new_timer(vm_clock, 
473                                        rtc_periodic_timer, s);
474     s->second_timer = qemu_new_timer(vm_clock, 
475                                      rtc_update_second, s);
476     s->second_timer2 = qemu_new_timer(vm_clock, 
477                                       rtc_update_second2, s);
478
479     s->next_second_time = qemu_get_clock(vm_clock) + (ticks_per_sec * 99) / 100;
480     qemu_mod_timer(s->second_timer2, s->next_second_time);
481
482     register_ioport_write(base, 2, 1, cmos_ioport_write, s);
483     register_ioport_read(base, 2, 1, cmos_ioport_read, s);
484
485     register_savevm("mc146818rtc", base, 1, rtc_save, rtc_load, s);
486     return s;
487 }
488