From f80237d45032fbc429aba3b597175fb544a11378 Mon Sep 17 00:00:00 2001 From: Blue Swirl Date: Mon, 14 Sep 2009 15:33:28 +0000 Subject: [PATCH] Add an ISA bus version of m48t59 Many thanks to Gerd Hoffmann for finding and fixing a bug in the initial version. Signed-off-by: Blue Swirl --- hw/m48t59.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++---------- hw/nvram.h | 1 + hw/sun4u.c | 3 +- 3 files changed, 80 insertions(+), 17 deletions(-) diff --git a/hw/m48t59.c b/hw/m48t59.c index 0fcf4f8ae3..b9892cc1f8 100644 --- a/hw/m48t59.c +++ b/hw/m48t59.c @@ -26,6 +26,7 @@ #include "qemu-timer.h" #include "sysemu.h" #include "sysbus.h" +#include "isa.h" //#define DEBUG_NVRAM @@ -41,7 +42,6 @@ * PPC platform there is also a nvram lock function. */ struct m48t59_t { - SysBusDevice busdev; /* Model parameters */ uint32_t type; // 2 = m48t02, 8 = m48t08, 59 = m48t59 /* Hardware parameters */ @@ -61,6 +61,16 @@ struct m48t59_t { uint8_t *buffer; }; +typedef struct M48t59ISAState { + ISADevice busdev; + m48t59_t state; +} M48t59ISAState; + +typedef struct M48t59SysBusState { + SysBusDevice busdev; + m48t59_t state; +} M48t59SysBusState; + /* Fake timer functions */ /* Generic helpers for BCD */ static inline uint8_t toBCD (uint8_t value) @@ -620,7 +630,7 @@ m48t59_t *m48t59_init (qemu_irq IRQ, target_phys_addr_t mem_base, { DeviceState *dev; SysBusDevice *s; - m48t59_t *d; + M48t59SysBusState *d; dev = qdev_create(NULL, "m48t59"); qdev_prop_set_uint32(dev, "type", type); @@ -637,22 +647,36 @@ m48t59_t *m48t59_init (qemu_irq IRQ, target_phys_addr_t mem_base, sysbus_mmio_map(s, 0, mem_base); } - d = FROM_SYSBUS(m48t59_t, s); + d = FROM_SYSBUS(M48t59SysBusState, s); - return d; + return &d->state; } -static int m48t59_init1(SysBusDevice *dev) +m48t59_t *m48t59_init_isa(uint32_t io_base, uint16_t size, int type) { - m48t59_t *s = FROM_SYSBUS(m48t59_t, dev); - int mem_index; + M48t59ISAState *d; + ISADevice *dev; + m48t59_t *s; + + dev = isa_create("m48t59_isa"); + qdev_prop_set_uint32(&dev->qdev, "type", type); + qdev_prop_set_uint32(&dev->qdev, "size", size); + qdev_prop_set_uint32(&dev->qdev, "io_base", io_base); + qdev_init(&dev->qdev); + d = DO_UPCAST(M48t59ISAState, busdev, dev); + s = &d->state; - s->buffer = qemu_mallocz(s->size); - sysbus_init_irq(dev, &s->IRQ); + if (io_base != 0) { + register_ioport_read(io_base, 0x04, 1, NVRAM_readb, s); + register_ioport_write(io_base, 0x04, 1, NVRAM_writeb, s); + } - mem_index = cpu_register_io_memory(nvram_read, nvram_write, s); - sysbus_init_mmio(dev, s->size, mem_index); + return s; +} +static void m48t59_init_common(m48t59_t *s) +{ + s->buffer = qemu_mallocz(s->size); if (s->type == 59) { s->alrm_timer = qemu_new_timer(vm_clock, &alarm_cb, s); s->wd_timer = qemu_new_timer(vm_clock, &watchdog_cb, s); @@ -661,17 +685,55 @@ static int m48t59_init1(SysBusDevice *dev) qemu_register_reset(m48t59_reset, s); register_savevm("m48t59", -1, 1, m48t59_save, m48t59_load, s); +} + +static int m48t59_init_isa1(ISADevice *dev) +{ + M48t59ISAState *d = DO_UPCAST(M48t59ISAState, busdev, dev); + m48t59_t *s = &d->state; + + isa_init_irq(dev, &s->IRQ, 8); + m48t59_init_common(s); + return 0; } +static int m48t59_init1(SysBusDevice *dev) +{ + M48t59SysBusState *d = FROM_SYSBUS(M48t59SysBusState, dev); + m48t59_t *s = &d->state; + int mem_index; + + sysbus_init_irq(dev, &s->IRQ); + + mem_index = cpu_register_io_memory(nvram_read, nvram_write, s); + sysbus_init_mmio(dev, s->size, mem_index); + m48t59_init_common(s); + + return 0; +} + +static ISADeviceInfo m48t59_isa_info = { + .init = m48t59_init_isa1, + .qdev.name = "m48t59_isa", + .qdev.size = sizeof(M48t59ISAState), + .qdev.no_user = 1, + .qdev.props = (Property[]) { + DEFINE_PROP_UINT32("size", M48t59ISAState, state.size, -1), + DEFINE_PROP_UINT32("type", M48t59ISAState, state.type, -1), + DEFINE_PROP_HEX32( "io_base", M48t59ISAState, state.io_base, 0), + DEFINE_PROP_END_OF_LIST(), + } +}; + static SysBusDeviceInfo m48t59_info = { .init = m48t59_init1, .qdev.name = "m48t59", - .qdev.size = sizeof(m48t59_t), + .qdev.size = sizeof(M48t59SysBusState), .qdev.props = (Property[]) { - DEFINE_PROP_UINT32("size", m48t59_t, size, -1), - DEFINE_PROP_UINT32("type", m48t59_t, type, -1), - DEFINE_PROP_HEX32( "io_base", m48t59_t, io_base, 0), + DEFINE_PROP_UINT32("size", M48t59SysBusState, state.size, -1), + DEFINE_PROP_UINT32("type", M48t59SysBusState, state.type, -1), + DEFINE_PROP_HEX32( "io_base", M48t59SysBusState, state.io_base, 0), DEFINE_PROP_END_OF_LIST(), } }; @@ -679,6 +741,7 @@ static SysBusDeviceInfo m48t59_info = { static void m48t59_register_devices(void) { sysbus_register_withprop(&m48t59_info); + isa_qdev_register(&m48t59_isa_info); } device_init(m48t59_register_devices) diff --git a/hw/nvram.h b/hw/nvram.h index b346822c22..c63fd5f095 100644 --- a/hw/nvram.h +++ b/hw/nvram.h @@ -34,6 +34,7 @@ typedef struct m48t59_t m48t59_t; void m48t59_write (void *private, uint32_t addr, uint32_t val); uint32_t m48t59_read (void *private, uint32_t addr); void m48t59_toggle_lock (void *private, int lock); +m48t59_t *m48t59_init_isa(uint32_t io_base, uint16_t size, int type); m48t59_t *m48t59_init (qemu_irq IRQ, target_phys_addr_t mem_base, uint32_t io_base, uint16_t size, int type); diff --git a/hw/sun4u.c b/hw/sun4u.c index ffda4cda1e..427ee764ce 100644 --- a/hw/sun4u.c +++ b/hw/sun4u.c @@ -623,8 +623,7 @@ static void sun4uv_init(ram_addr_t RAM_size, fd[i] = dinfo ? dinfo->bdrv : NULL; } fdctrl_init_isa(fd); - /* FIXME: wire up interrupts. */ - nvram = m48t59_init(NULL/*8*/, 0, 0x0074, NVRAM_SIZE, 59); + nvram = m48t59_init_isa(0x0074, NVRAM_SIZE, 59); initrd_size = 0; kernel_size = sun4u_load_kernel(kernel_filename, initrd_filename, -- 2.11.4.GIT