Commit 2ca9d01385dd5e24938eb15147f9072825217d21
1 parent
b92bb99b
Memory-mapped interface for RTC, by Herve Poussineau.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2686 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
94 additions
and
0 deletions
hw/mc146818rtc.c
| ... | ... | @@ -55,6 +55,7 @@ struct RTCState { |
| 55 | 55 | uint8_t cmos_index; |
| 56 | 56 | struct tm current_tm; |
| 57 | 57 | qemu_irq irq; |
| 58 | + target_phys_addr_t base; | |
| 58 | 59 | /* periodic timer */ |
| 59 | 60 | QEMUTimer *periodic_timer; |
| 60 | 61 | int64_t next_periodic_time; |
| ... | ... | @@ -486,3 +487,95 @@ RTCState *rtc_init(int base, qemu_irq irq) |
| 486 | 487 | return s; |
| 487 | 488 | } |
| 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 | +} | ... | ... |
vl.h
| ... | ... | @@ -1043,6 +1043,7 @@ void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq, target_ulong base, int |
| 1043 | 1043 | typedef struct RTCState RTCState; |
| 1044 | 1044 | |
| 1045 | 1045 | RTCState *rtc_init(int base, qemu_irq irq); |
| 1046 | +RTCState *rtc_mm_init(target_phys_addr_t base, qemu_irq irq); | |
| 1046 | 1047 | void rtc_set_memory(RTCState *s, int addr, int val); |
| 1047 | 1048 | void rtc_set_date(RTCState *s, const struct tm *tm); |
| 1048 | 1049 | ... | ... |