mc146818rtc.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686
  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 "hw.h"
  25. #include "qemu-timer.h"
  26. #include "sysemu.h"
  27. #include "pc.h"
  28. #include "apic.h"
  29. #include "isa.h"
  30. #include "mc146818rtc.h"
  31. //#define DEBUG_CMOS
  32. //#define DEBUG_COALESCED
  33. #ifdef DEBUG_CMOS
  34. # define CMOS_DPRINTF(format, ...) printf(format, ## __VA_ARGS__)
  35. #else
  36. # define CMOS_DPRINTF(format, ...) do { } while (0)
  37. #endif
  38. #ifdef DEBUG_COALESCED
  39. # define DPRINTF_C(format, ...) printf(format, ## __VA_ARGS__)
  40. #else
  41. # define DPRINTF_C(format, ...) do { } while (0)
  42. #endif
  43. #define RTC_REINJECT_ON_ACK_COUNT 20
  44. #define RTC_SECONDS 0
  45. #define RTC_SECONDS_ALARM 1
  46. #define RTC_MINUTES 2
  47. #define RTC_MINUTES_ALARM 3
  48. #define RTC_HOURS 4
  49. #define RTC_HOURS_ALARM 5
  50. #define RTC_ALARM_DONT_CARE 0xC0
  51. #define RTC_DAY_OF_WEEK 6
  52. #define RTC_DAY_OF_MONTH 7
  53. #define RTC_MONTH 8
  54. #define RTC_YEAR 9
  55. #define RTC_REG_A 10
  56. #define RTC_REG_B 11
  57. #define RTC_REG_C 12
  58. #define RTC_REG_D 13
  59. #define REG_A_UIP 0x80
  60. #define REG_B_SET 0x80
  61. #define REG_B_PIE 0x40
  62. #define REG_B_AIE 0x20
  63. #define REG_B_UIE 0x10
  64. #define REG_B_SQWE 0x08
  65. #define REG_B_DM 0x04
  66. #define REG_B_24H 0x02
  67. #define REG_C_UF 0x10
  68. #define REG_C_IRQF 0x80
  69. #define REG_C_PF 0x40
  70. #define REG_C_AF 0x20
  71. typedef struct RTCState {
  72. ISADevice dev;
  73. MemoryRegion io;
  74. uint8_t cmos_data[128];
  75. uint8_t cmos_index;
  76. struct tm current_tm;
  77. int32_t base_year;
  78. qemu_irq irq;
  79. qemu_irq sqw_irq;
  80. int it_shift;
  81. /* periodic timer */
  82. QEMUTimer *periodic_timer;
  83. int64_t next_periodic_time;
  84. /* second update */
  85. int64_t next_second_time;
  86. uint16_t irq_reinject_on_ack_count;
  87. uint32_t irq_coalesced;
  88. uint32_t period;
  89. QEMUTimer *coalesced_timer;
  90. QEMUTimer *second_timer;
  91. QEMUTimer *second_timer2;
  92. Notifier clock_reset_notifier;
  93. } RTCState;
  94. static void rtc_set_time(RTCState *s);
  95. static void rtc_copy_date(RTCState *s);
  96. #ifdef TARGET_I386
  97. static void rtc_coalesced_timer_update(RTCState *s)
  98. {
  99. if (s->irq_coalesced == 0) {
  100. qemu_del_timer(s->coalesced_timer);
  101. } else {
  102. /* divide each RTC interval to 2 - 8 smaller intervals */
  103. int c = MIN(s->irq_coalesced, 7) + 1;
  104. int64_t next_clock = qemu_get_clock_ns(rtc_clock) +
  105. muldiv64(s->period / c, get_ticks_per_sec(), 32768);
  106. qemu_mod_timer(s->coalesced_timer, next_clock);
  107. }
  108. }
  109. static void rtc_coalesced_timer(void *opaque)
  110. {
  111. RTCState *s = opaque;
  112. if (s->irq_coalesced != 0) {
  113. apic_reset_irq_delivered();
  114. s->cmos_data[RTC_REG_C] |= 0xc0;
  115. DPRINTF_C("cmos: injecting from timer\n");
  116. qemu_irq_raise(s->irq);
  117. if (apic_get_irq_delivered()) {
  118. s->irq_coalesced--;
  119. DPRINTF_C("cmos: coalesced irqs decreased to %d\n",
  120. s->irq_coalesced);
  121. }
  122. }
  123. rtc_coalesced_timer_update(s);
  124. }
  125. #endif
  126. static void rtc_timer_update(RTCState *s, int64_t current_time)
  127. {
  128. int period_code, period;
  129. int64_t cur_clock, next_irq_clock;
  130. period_code = s->cmos_data[RTC_REG_A] & 0x0f;
  131. if (period_code != 0
  132. && ((s->cmos_data[RTC_REG_B] & REG_B_PIE)
  133. || ((s->cmos_data[RTC_REG_B] & REG_B_SQWE) && s->sqw_irq))) {
  134. if (period_code <= 2)
  135. period_code += 7;
  136. /* period in 32 Khz cycles */
  137. period = 1 << (period_code - 1);
  138. #ifdef TARGET_I386
  139. if (period != s->period) {
  140. s->irq_coalesced = (s->irq_coalesced * s->period) / period;
  141. DPRINTF_C("cmos: coalesced irqs scaled to %d\n", s->irq_coalesced);
  142. }
  143. s->period = period;
  144. #endif
  145. /* compute 32 khz clock */
  146. cur_clock = muldiv64(current_time, 32768, get_ticks_per_sec());
  147. next_irq_clock = (cur_clock & ~(period - 1)) + period;
  148. s->next_periodic_time =
  149. muldiv64(next_irq_clock, get_ticks_per_sec(), 32768) + 1;
  150. qemu_mod_timer(s->periodic_timer, s->next_periodic_time);
  151. } else {
  152. #ifdef TARGET_I386
  153. s->irq_coalesced = 0;
  154. #endif
  155. qemu_del_timer(s->periodic_timer);
  156. }
  157. }
  158. static void rtc_periodic_timer(void *opaque)
  159. {
  160. RTCState *s = opaque;
  161. rtc_timer_update(s, s->next_periodic_time);
  162. if (s->cmos_data[RTC_REG_B] & REG_B_PIE) {
  163. s->cmos_data[RTC_REG_C] |= 0xc0;
  164. #ifdef TARGET_I386
  165. if(rtc_td_hack) {
  166. if (s->irq_reinject_on_ack_count >= RTC_REINJECT_ON_ACK_COUNT)
  167. s->irq_reinject_on_ack_count = 0;
  168. apic_reset_irq_delivered();
  169. qemu_irq_raise(s->irq);
  170. if (!apic_get_irq_delivered()) {
  171. s->irq_coalesced++;
  172. rtc_coalesced_timer_update(s);
  173. DPRINTF_C("cmos: coalesced irqs increased to %d\n",
  174. s->irq_coalesced);
  175. }
  176. } else
  177. #endif
  178. qemu_irq_raise(s->irq);
  179. }
  180. if (s->cmos_data[RTC_REG_B] & REG_B_SQWE) {
  181. /* Not square wave at all but we don't want 2048Hz interrupts!
  182. Must be seen as a pulse. */
  183. qemu_irq_raise(s->sqw_irq);
  184. }
  185. }
  186. static void cmos_ioport_write(void *opaque, uint32_t addr, uint32_t data)
  187. {
  188. RTCState *s = opaque;
  189. if ((addr & 1) == 0) {
  190. s->cmos_index = data & 0x7f;
  191. } else {
  192. CMOS_DPRINTF("cmos: write index=0x%02x val=0x%02x\n",
  193. s->cmos_index, data);
  194. switch(s->cmos_index) {
  195. case RTC_SECONDS_ALARM:
  196. case RTC_MINUTES_ALARM:
  197. case RTC_HOURS_ALARM:
  198. s->cmos_data[s->cmos_index] = data;
  199. break;
  200. case RTC_SECONDS:
  201. case RTC_MINUTES:
  202. case RTC_HOURS:
  203. case RTC_DAY_OF_WEEK:
  204. case RTC_DAY_OF_MONTH:
  205. case RTC_MONTH:
  206. case RTC_YEAR:
  207. s->cmos_data[s->cmos_index] = data;
  208. /* if in set mode, do not update the time */
  209. if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
  210. rtc_set_time(s);
  211. }
  212. break;
  213. case RTC_REG_A:
  214. /* UIP bit is read only */
  215. s->cmos_data[RTC_REG_A] = (data & ~REG_A_UIP) |
  216. (s->cmos_data[RTC_REG_A] & REG_A_UIP);
  217. rtc_timer_update(s, qemu_get_clock_ns(rtc_clock));
  218. break;
  219. case RTC_REG_B:
  220. if (data & REG_B_SET) {
  221. /* set mode: reset UIP mode */
  222. s->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
  223. data &= ~REG_B_UIE;
  224. } else {
  225. /* if disabling set mode, update the time */
  226. if (s->cmos_data[RTC_REG_B] & REG_B_SET) {
  227. rtc_set_time(s);
  228. }
  229. }
  230. if (((s->cmos_data[RTC_REG_B] ^ data) & (REG_B_DM | REG_B_24H)) &&
  231. !(data & REG_B_SET)) {
  232. /* If the time format has changed and not in set mode,
  233. update the registers immediately. */
  234. s->cmos_data[RTC_REG_B] = data;
  235. rtc_copy_date(s);
  236. } else {
  237. s->cmos_data[RTC_REG_B] = data;
  238. }
  239. rtc_timer_update(s, qemu_get_clock_ns(rtc_clock));
  240. break;
  241. case RTC_REG_C:
  242. case RTC_REG_D:
  243. /* cannot write to them */
  244. break;
  245. default:
  246. s->cmos_data[s->cmos_index] = data;
  247. break;
  248. }
  249. }
  250. }
  251. static inline int rtc_to_bcd(RTCState *s, int a)
  252. {
  253. if (s->cmos_data[RTC_REG_B] & REG_B_DM) {
  254. return a;
  255. } else {
  256. return ((a / 10) << 4) | (a % 10);
  257. }
  258. }
  259. static inline int rtc_from_bcd(RTCState *s, int a)
  260. {
  261. if (s->cmos_data[RTC_REG_B] & REG_B_DM) {
  262. return a;
  263. } else {
  264. return ((a >> 4) * 10) + (a & 0x0f);
  265. }
  266. }
  267. static void rtc_set_time(RTCState *s)
  268. {
  269. struct tm *tm = &s->current_tm;
  270. tm->tm_sec = rtc_from_bcd(s, s->cmos_data[RTC_SECONDS]);
  271. tm->tm_min = rtc_from_bcd(s, s->cmos_data[RTC_MINUTES]);
  272. tm->tm_hour = rtc_from_bcd(s, s->cmos_data[RTC_HOURS] & 0x7f);
  273. if (!(s->cmos_data[RTC_REG_B] & REG_B_24H) &&
  274. (s->cmos_data[RTC_HOURS] & 0x80)) {
  275. tm->tm_hour += 12;
  276. }
  277. tm->tm_wday = rtc_from_bcd(s, s->cmos_data[RTC_DAY_OF_WEEK]) - 1;
  278. tm->tm_mday = rtc_from_bcd(s, s->cmos_data[RTC_DAY_OF_MONTH]);
  279. tm->tm_mon = rtc_from_bcd(s, s->cmos_data[RTC_MONTH]) - 1;
  280. tm->tm_year = rtc_from_bcd(s, s->cmos_data[RTC_YEAR]) + s->base_year - 1900;
  281. rtc_change_mon_event(tm);
  282. }
  283. static void rtc_copy_date(RTCState *s)
  284. {
  285. const struct tm *tm = &s->current_tm;
  286. int year;
  287. s->cmos_data[RTC_SECONDS] = rtc_to_bcd(s, tm->tm_sec);
  288. s->cmos_data[RTC_MINUTES] = rtc_to_bcd(s, tm->tm_min);
  289. if (s->cmos_data[RTC_REG_B] & REG_B_24H) {
  290. /* 24 hour format */
  291. s->cmos_data[RTC_HOURS] = rtc_to_bcd(s, tm->tm_hour);
  292. } else {
  293. /* 12 hour format */
  294. s->cmos_data[RTC_HOURS] = rtc_to_bcd(s, tm->tm_hour % 12);
  295. if (tm->tm_hour >= 12)
  296. s->cmos_data[RTC_HOURS] |= 0x80;
  297. }
  298. s->cmos_data[RTC_DAY_OF_WEEK] = rtc_to_bcd(s, tm->tm_wday + 1);
  299. s->cmos_data[RTC_DAY_OF_MONTH] = rtc_to_bcd(s, tm->tm_mday);
  300. s->cmos_data[RTC_MONTH] = rtc_to_bcd(s, tm->tm_mon + 1);
  301. year = (tm->tm_year - s->base_year) % 100;
  302. if (year < 0)
  303. year += 100;
  304. s->cmos_data[RTC_YEAR] = rtc_to_bcd(s, year);
  305. }
  306. /* month is between 0 and 11. */
  307. static int get_days_in_month(int month, int year)
  308. {
  309. static const int days_tab[12] = {
  310. 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
  311. };
  312. int d;
  313. if ((unsigned )month >= 12)
  314. return 31;
  315. d = days_tab[month];
  316. if (month == 1) {
  317. if ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0))
  318. d++;
  319. }
  320. return d;
  321. }
  322. /* update 'tm' to the next second */
  323. static void rtc_next_second(struct tm *tm)
  324. {
  325. int days_in_month;
  326. tm->tm_sec++;
  327. if ((unsigned)tm->tm_sec >= 60) {
  328. tm->tm_sec = 0;
  329. tm->tm_min++;
  330. if ((unsigned)tm->tm_min >= 60) {
  331. tm->tm_min = 0;
  332. tm->tm_hour++;
  333. if ((unsigned)tm->tm_hour >= 24) {
  334. tm->tm_hour = 0;
  335. /* next day */
  336. tm->tm_wday++;
  337. if ((unsigned)tm->tm_wday >= 7)
  338. tm->tm_wday = 0;
  339. days_in_month = get_days_in_month(tm->tm_mon,
  340. tm->tm_year + 1900);
  341. tm->tm_mday++;
  342. if (tm->tm_mday < 1) {
  343. tm->tm_mday = 1;
  344. } else if (tm->tm_mday > days_in_month) {
  345. tm->tm_mday = 1;
  346. tm->tm_mon++;
  347. if (tm->tm_mon >= 12) {
  348. tm->tm_mon = 0;
  349. tm->tm_year++;
  350. }
  351. }
  352. }
  353. }
  354. }
  355. }
  356. static void rtc_update_second(void *opaque)
  357. {
  358. RTCState *s = opaque;
  359. int64_t delay;
  360. /* if the oscillator is not in normal operation, we do not update */
  361. if ((s->cmos_data[RTC_REG_A] & 0x70) != 0x20) {
  362. s->next_second_time += get_ticks_per_sec();
  363. qemu_mod_timer(s->second_timer, s->next_second_time);
  364. } else {
  365. rtc_next_second(&s->current_tm);
  366. if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
  367. /* update in progress bit */
  368. s->cmos_data[RTC_REG_A] |= REG_A_UIP;
  369. }
  370. /* should be 244 us = 8 / 32768 seconds, but currently the
  371. timers do not have the necessary resolution. */
  372. delay = (get_ticks_per_sec() * 1) / 100;
  373. if (delay < 1)
  374. delay = 1;
  375. qemu_mod_timer(s->second_timer2,
  376. s->next_second_time + delay);
  377. }
  378. }
  379. static void rtc_update_second2(void *opaque)
  380. {
  381. RTCState *s = opaque;
  382. if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
  383. rtc_copy_date(s);
  384. }
  385. /* check alarm */
  386. if (s->cmos_data[RTC_REG_B] & REG_B_AIE) {
  387. if (((s->cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0 ||
  388. rtc_from_bcd(s, s->cmos_data[RTC_SECONDS_ALARM]) == s->current_tm.tm_sec) &&
  389. ((s->cmos_data[RTC_MINUTES_ALARM] & 0xc0) == 0xc0 ||
  390. rtc_from_bcd(s, s->cmos_data[RTC_MINUTES_ALARM]) == s->current_tm.tm_min) &&
  391. ((s->cmos_data[RTC_HOURS_ALARM] & 0xc0) == 0xc0 ||
  392. rtc_from_bcd(s, s->cmos_data[RTC_HOURS_ALARM]) == s->current_tm.tm_hour)) {
  393. s->cmos_data[RTC_REG_C] |= 0xa0;
  394. qemu_irq_raise(s->irq);
  395. }
  396. }
  397. /* update ended interrupt */
  398. s->cmos_data[RTC_REG_C] |= REG_C_UF;
  399. if (s->cmos_data[RTC_REG_B] & REG_B_UIE) {
  400. s->cmos_data[RTC_REG_C] |= REG_C_IRQF;
  401. qemu_irq_raise(s->irq);
  402. }
  403. /* clear update in progress bit */
  404. s->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
  405. s->next_second_time += get_ticks_per_sec();
  406. qemu_mod_timer(s->second_timer, s->next_second_time);
  407. }
  408. static uint32_t cmos_ioport_read(void *opaque, uint32_t addr)
  409. {
  410. RTCState *s = opaque;
  411. int ret;
  412. if ((addr & 1) == 0) {
  413. return 0xff;
  414. } else {
  415. switch(s->cmos_index) {
  416. case RTC_SECONDS:
  417. case RTC_MINUTES:
  418. case RTC_HOURS:
  419. case RTC_DAY_OF_WEEK:
  420. case RTC_DAY_OF_MONTH:
  421. case RTC_MONTH:
  422. case RTC_YEAR:
  423. ret = s->cmos_data[s->cmos_index];
  424. break;
  425. case RTC_REG_A:
  426. ret = s->cmos_data[s->cmos_index];
  427. break;
  428. case RTC_REG_C:
  429. ret = s->cmos_data[s->cmos_index];
  430. qemu_irq_lower(s->irq);
  431. #ifdef TARGET_I386
  432. if(s->irq_coalesced &&
  433. s->irq_reinject_on_ack_count < RTC_REINJECT_ON_ACK_COUNT) {
  434. s->irq_reinject_on_ack_count++;
  435. apic_reset_irq_delivered();
  436. DPRINTF_C("cmos: injecting on ack\n");
  437. qemu_irq_raise(s->irq);
  438. if (apic_get_irq_delivered()) {
  439. s->irq_coalesced--;
  440. DPRINTF_C("cmos: coalesced irqs decreased to %d\n",
  441. s->irq_coalesced);
  442. }
  443. break;
  444. }
  445. #endif
  446. s->cmos_data[RTC_REG_C] = 0x00;
  447. break;
  448. default:
  449. ret = s->cmos_data[s->cmos_index];
  450. break;
  451. }
  452. CMOS_DPRINTF("cmos: read index=0x%02x val=0x%02x\n",
  453. s->cmos_index, ret);
  454. return ret;
  455. }
  456. }
  457. void rtc_set_memory(ISADevice *dev, int addr, int val)
  458. {
  459. RTCState *s = DO_UPCAST(RTCState, dev, dev);
  460. if (addr >= 0 && addr <= 127)
  461. s->cmos_data[addr] = val;
  462. }
  463. void rtc_set_date(ISADevice *dev, const struct tm *tm)
  464. {
  465. RTCState *s = DO_UPCAST(RTCState, dev, dev);
  466. s->current_tm = *tm;
  467. rtc_copy_date(s);
  468. }
  469. /* PC cmos mappings */
  470. #define REG_IBM_CENTURY_BYTE 0x32
  471. #define REG_IBM_PS2_CENTURY_BYTE 0x37
  472. static void rtc_set_date_from_host(ISADevice *dev)
  473. {
  474. RTCState *s = DO_UPCAST(RTCState, dev, dev);
  475. struct tm tm;
  476. int val;
  477. /* set the CMOS date */
  478. qemu_get_timedate(&tm, 0);
  479. rtc_set_date(dev, &tm);
  480. val = rtc_to_bcd(s, (tm.tm_year / 100) + 19);
  481. rtc_set_memory(dev, REG_IBM_CENTURY_BYTE, val);
  482. rtc_set_memory(dev, REG_IBM_PS2_CENTURY_BYTE, val);
  483. }
  484. static int rtc_post_load(void *opaque, int version_id)
  485. {
  486. #ifdef TARGET_I386
  487. RTCState *s = opaque;
  488. if (version_id >= 2) {
  489. if (rtc_td_hack) {
  490. rtc_coalesced_timer_update(s);
  491. }
  492. }
  493. #endif
  494. return 0;
  495. }
  496. static const VMStateDescription vmstate_rtc = {
  497. .name = "mc146818rtc",
  498. .version_id = 2,
  499. .minimum_version_id = 1,
  500. .minimum_version_id_old = 1,
  501. .post_load = rtc_post_load,
  502. .fields = (VMStateField []) {
  503. VMSTATE_BUFFER(cmos_data, RTCState),
  504. VMSTATE_UINT8(cmos_index, RTCState),
  505. VMSTATE_INT32(current_tm.tm_sec, RTCState),
  506. VMSTATE_INT32(current_tm.tm_min, RTCState),
  507. VMSTATE_INT32(current_tm.tm_hour, RTCState),
  508. VMSTATE_INT32(current_tm.tm_wday, RTCState),
  509. VMSTATE_INT32(current_tm.tm_mday, RTCState),
  510. VMSTATE_INT32(current_tm.tm_mon, RTCState),
  511. VMSTATE_INT32(current_tm.tm_year, RTCState),
  512. VMSTATE_TIMER(periodic_timer, RTCState),
  513. VMSTATE_INT64(next_periodic_time, RTCState),
  514. VMSTATE_INT64(next_second_time, RTCState),
  515. VMSTATE_TIMER(second_timer, RTCState),
  516. VMSTATE_TIMER(second_timer2, RTCState),
  517. VMSTATE_UINT32_V(irq_coalesced, RTCState, 2),
  518. VMSTATE_UINT32_V(period, RTCState, 2),
  519. VMSTATE_END_OF_LIST()
  520. }
  521. };
  522. static void rtc_notify_clock_reset(Notifier *notifier, void *data)
  523. {
  524. RTCState *s = container_of(notifier, RTCState, clock_reset_notifier);
  525. int64_t now = *(int64_t *)data;
  526. rtc_set_date_from_host(&s->dev);
  527. s->next_second_time = now + (get_ticks_per_sec() * 99) / 100;
  528. qemu_mod_timer(s->second_timer2, s->next_second_time);
  529. rtc_timer_update(s, now);
  530. #ifdef TARGET_I386
  531. if (rtc_td_hack) {
  532. rtc_coalesced_timer_update(s);
  533. }
  534. #endif
  535. }
  536. static void rtc_reset(void *opaque)
  537. {
  538. RTCState *s = opaque;
  539. s->cmos_data[RTC_REG_B] &= ~(REG_B_PIE | REG_B_AIE | REG_B_SQWE);
  540. s->cmos_data[RTC_REG_C] &= ~(REG_C_UF | REG_C_IRQF | REG_C_PF | REG_C_AF);
  541. qemu_irq_lower(s->irq);
  542. #ifdef TARGET_I386
  543. if (rtc_td_hack)
  544. s->irq_coalesced = 0;
  545. #endif
  546. }
  547. static const MemoryRegionPortio cmos_portio[] = {
  548. {0, 2, 1, .read = cmos_ioport_read, .write = cmos_ioport_write },
  549. PORTIO_END_OF_LIST(),
  550. };
  551. static const MemoryRegionOps cmos_ops = {
  552. .old_portio = cmos_portio
  553. };
  554. static int rtc_initfn(ISADevice *dev)
  555. {
  556. RTCState *s = DO_UPCAST(RTCState, dev, dev);
  557. int base = 0x70;
  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. rtc_set_date_from_host(dev);
  563. s->periodic_timer = qemu_new_timer_ns(rtc_clock, rtc_periodic_timer, s);
  564. #ifdef TARGET_I386
  565. if (rtc_td_hack)
  566. s->coalesced_timer =
  567. qemu_new_timer_ns(rtc_clock, rtc_coalesced_timer, s);
  568. #endif
  569. s->second_timer = qemu_new_timer_ns(rtc_clock, rtc_update_second, s);
  570. s->second_timer2 = qemu_new_timer_ns(rtc_clock, rtc_update_second2, s);
  571. s->clock_reset_notifier.notify = rtc_notify_clock_reset;
  572. qemu_register_clock_reset_notifier(rtc_clock, &s->clock_reset_notifier);
  573. s->next_second_time =
  574. qemu_get_clock_ns(rtc_clock) + (get_ticks_per_sec() * 99) / 100;
  575. qemu_mod_timer(s->second_timer2, s->next_second_time);
  576. memory_region_init_io(&s->io, &cmos_ops, s, "rtc", 2);
  577. isa_register_ioport(dev, &s->io, base);
  578. qdev_set_legacy_instance_id(&dev->qdev, base, 2);
  579. qemu_register_reset(rtc_reset, s);
  580. return 0;
  581. }
  582. ISADevice *rtc_init(int base_year, qemu_irq intercept_irq)
  583. {
  584. ISADevice *dev;
  585. RTCState *s;
  586. dev = isa_create("mc146818rtc");
  587. s = DO_UPCAST(RTCState, dev, dev);
  588. qdev_prop_set_int32(&dev->qdev, "base_year", base_year);
  589. qdev_init_nofail(&dev->qdev);
  590. if (intercept_irq) {
  591. s->irq = intercept_irq;
  592. } else {
  593. isa_init_irq(dev, &s->irq, RTC_ISA_IRQ);
  594. }
  595. return dev;
  596. }
  597. static ISADeviceInfo mc146818rtc_info = {
  598. .qdev.name = "mc146818rtc",
  599. .qdev.size = sizeof(RTCState),
  600. .qdev.no_user = 1,
  601. .qdev.vmsd = &vmstate_rtc,
  602. .init = rtc_initfn,
  603. .qdev.props = (Property[]) {
  604. DEFINE_PROP_INT32("base_year", RTCState, base_year, 1980),
  605. DEFINE_PROP_END_OF_LIST(),
  606. }
  607. };
  608. static void mc146818rtc_register(void)
  609. {
  610. isa_qdev_register(&mc146818rtc_info);
  611. }
  612. device_init(mc146818rtc_register)