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 | ... | ... |