📄 m48t59.c
字号:
tmp = fromBCD(val & 0x07); get_time(NVRAM, &tm); tm.tm_wday = tmp; set_time(NVRAM, &tm); NVRAM->buffer[0x1FFC] = val & 0x40; break; case 0x1FFD: /* date */ tmp = fromBCD(val & 0x1F); if (tmp != 0) { get_time(NVRAM, &tm); tm.tm_mday = tmp; set_time(NVRAM, &tm); } break; case 0x1FFE: /* month */ tmp = fromBCD(val & 0x1F); if (tmp >= 1 && tmp <= 12) { get_time(NVRAM, &tm); tm.tm_mon = tmp - 1; set_time(NVRAM, &tm); } break; case 0x1FFF: /* year */ tmp = fromBCD(val); if (tmp >= 0 && tmp <= 99) { get_time(NVRAM, &tm); tm.tm_year = fromBCD(val); set_time(NVRAM, &tm); } break; default: /* Check lock registers state */ if (addr >= 0x20 && addr <= 0x2F && (NVRAM->lock & 1)) break; if (addr >= 0x30 && addr <= 0x3F && (NVRAM->lock & 2)) break; do_write: if (addr < NVRAM->size) { NVRAM->buffer[addr] = val & 0xFF; } break; }}uint32_t m48t59_read (m48t59_t *NVRAM, uint32_t addr){ struct tm tm; uint32_t retval = 0xFF; if (NVRAM->type == 8 && (addr >= 0x1ff0 && addr <= 0x1ff7)) goto do_read; switch (addr) { case 0x1FF0: /* flags register */ goto do_read; case 0x1FF1: /* unused */ retval = 0; break; case 0x1FF2: /* alarm seconds */ goto do_read; case 0x1FF3: /* alarm minutes */ goto do_read; case 0x1FF4: /* alarm hours */ goto do_read; case 0x1FF5: /* alarm date */ goto do_read; case 0x1FF6: /* interrupts */ goto do_read; case 0x1FF7: /* A read resets the watchdog */ set_up_watchdog(NVRAM, NVRAM->buffer[0x1FF7]); goto do_read; case 0x1FF8: /* control */ goto do_read; case 0x1FF9: /* seconds (BCD) */ get_time(NVRAM, &tm); retval = (NVRAM->buffer[0x1FF9] & 0x80) | toBCD(tm.tm_sec); break; case 0x1FFA: /* minutes (BCD) */ get_time(NVRAM, &tm); retval = toBCD(tm.tm_min); break; case 0x1FFB: /* hours (BCD) */ get_time(NVRAM, &tm); retval = toBCD(tm.tm_hour); break; case 0x1FFC: /* day of the week / century */ get_time(NVRAM, &tm); retval = NVRAM->buffer[0x1FFC] | tm.tm_wday; break; case 0x1FFD: /* date */ get_time(NVRAM, &tm); retval = toBCD(tm.tm_mday); break; case 0x1FFE: /* month */ get_time(NVRAM, &tm); retval = toBCD(tm.tm_mon + 1); break; case 0x1FFF: /* year */ get_time(NVRAM, &tm); retval = toBCD(tm.tm_year); break; default: /* Check lock registers state */ if (addr >= 0x20 && addr <= 0x2F && (NVRAM->lock & 1)) break; if (addr >= 0x30 && addr <= 0x3F && (NVRAM->lock & 2)) break; do_read: if (addr < NVRAM->size) { retval = NVRAM->buffer[addr]; } break; } if (addr > 0x1FF9 && addr < 0x2000) NVRAM_PRINTF("0x%08x <= 0x%08x\n", addr, retval); return retval;}void m48t59_set_addr (m48t59_t *NVRAM, uint32_t addr){ NVRAM->addr = addr;}void m48t59_toggle_lock (m48t59_t *NVRAM, int lock){ NVRAM->lock ^= 1 << lock;}/* IO access to NVRAM */static void NVRAM_writeb (void *opaque, uint32_t addr, uint32_t val){ m48t59_t *NVRAM = opaque; addr -= NVRAM->io_base; NVRAM_PRINTF("0x%08x => 0x%08x\n", addr, val); switch (addr) { case 0: NVRAM->addr &= ~0x00FF; NVRAM->addr |= val; break; case 1: NVRAM->addr &= ~0xFF00; NVRAM->addr |= val << 8; break; case 3: m48t59_write(NVRAM, val, NVRAM->addr); NVRAM->addr = 0x0000; break; default: break; }}static uint32_t NVRAM_readb (void *opaque, uint32_t addr){ m48t59_t *NVRAM = opaque; uint32_t retval; addr -= NVRAM->io_base; switch (addr) { case 3: retval = m48t59_read(NVRAM, NVRAM->addr); break; default: retval = -1; break; } NVRAM_PRINTF("0x%08x <= 0x%08x\n", addr, retval); return retval;}static void nvram_writeb (void *opaque, target_phys_addr_t addr, uint32_t value){ m48t59_t *NVRAM = opaque; addr -= NVRAM->mem_base; m48t59_write(NVRAM, addr, value & 0xff);}static void nvram_writew (void *opaque, target_phys_addr_t addr, uint32_t value){ m48t59_t *NVRAM = opaque; addr -= NVRAM->mem_base; m48t59_write(NVRAM, addr, (value >> 8) & 0xff); m48t59_write(NVRAM, addr + 1, value & 0xff);}static void nvram_writel (void *opaque, target_phys_addr_t addr, uint32_t value){ m48t59_t *NVRAM = opaque; addr -= NVRAM->mem_base; m48t59_write(NVRAM, addr, (value >> 24) & 0xff); m48t59_write(NVRAM, addr + 1, (value >> 16) & 0xff); m48t59_write(NVRAM, addr + 2, (value >> 8) & 0xff); m48t59_write(NVRAM, addr + 3, value & 0xff);}static uint32_t nvram_readb (void *opaque, target_phys_addr_t addr){ m48t59_t *NVRAM = opaque; uint32_t retval; addr -= NVRAM->mem_base; retval = m48t59_read(NVRAM, addr); return retval;}static uint32_t nvram_readw (void *opaque, target_phys_addr_t addr){ m48t59_t *NVRAM = opaque; uint32_t retval; addr -= NVRAM->mem_base; retval = m48t59_read(NVRAM, addr) << 8; retval |= m48t59_read(NVRAM, addr + 1); return retval;}static uint32_t nvram_readl (void *opaque, target_phys_addr_t addr){ m48t59_t *NVRAM = opaque; uint32_t retval; addr -= NVRAM->mem_base; retval = m48t59_read(NVRAM, addr) << 24; retval |= m48t59_read(NVRAM, addr + 1) << 16; retval |= m48t59_read(NVRAM, addr + 2) << 8; retval |= m48t59_read(NVRAM, addr + 3); return retval;}static CPUWriteMemoryFunc *nvram_write[] = { &nvram_writeb, &nvram_writew, &nvram_writel,};static CPUReadMemoryFunc *nvram_read[] = { &nvram_readb, &nvram_readw, &nvram_readl,};/* Initialisation routine */m48t59_t *m48t59_init (int IRQ, target_ulong mem_base, uint32_t io_base, uint16_t size, int type){ m48t59_t *s; s = qemu_mallocz(sizeof(m48t59_t)); if (!s) return NULL; s->buffer = qemu_mallocz(size); if (!s->buffer) { qemu_free(s); return NULL; } s->IRQ = IRQ; s->size = size; s->mem_base = mem_base; s->io_base = io_base; s->addr = 0; s->type = type; if (io_base != 0) { register_ioport_read(io_base, 0x04, 1, NVRAM_readb, s); register_ioport_write(io_base, 0x04, 1, NVRAM_writeb, s); } if (mem_base != 0) { s->mem_index = cpu_register_io_memory(0, nvram_read, nvram_write, s); cpu_register_physical_memory(mem_base, 0x4000, s->mem_index); } if (type == 59) { s->alrm_timer = qemu_new_timer(vm_clock, &alarm_cb, s); s->wd_timer = qemu_new_timer(vm_clock, &watchdog_cb, s); } s->lock = 0; return s;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -