* [Qemu-devel] [PATCH 0/4] qdev: add isa bus support @ 2009-07-15 12:56 Gerd Hoffmann 2009-07-15 12:56 ` [Qemu-devel] [PATCH 1/4] qdev/isa: add isa bus support to qdev Gerd Hoffmann ` (3 more replies) 0 siblings, 4 replies; 8+ messages in thread From: Gerd Hoffmann @ 2009-07-15 12:56 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann Hi, This series adds isa bus support to qdev and converts one device (pc kbd controller). cheers, Gerd ^ permalink raw reply [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 1/4] qdev/isa: add isa bus support to qdev. 2009-07-15 12:56 [Qemu-devel] [PATCH 0/4] qdev: add isa bus support Gerd Hoffmann @ 2009-07-15 12:56 ` Gerd Hoffmann 2009-07-17 18:12 ` Filip Navara 2009-07-15 12:56 ` [Qemu-devel] [PATCH 2/4] qdev/isa: add qdev support to i8042 (aka ps/2 kbd+mouse) Gerd Hoffmann ` (2 subsequent siblings) 3 siblings, 1 reply; 8+ messages in thread From: Gerd Hoffmann @ 2009-07-15 12:56 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann Wrong mmio stuff from previous version ripped out. Pretty simple and straigt forward now. IRQs modeled simliar to sysbus. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- Makefile.target | 8 +++--- hw/isa-bus.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ hw/isa.h | 25 +++++++++++++++++ 3 files changed, 111 insertions(+), 4 deletions(-) create mode 100644 hw/isa-bus.c diff --git a/Makefile.target b/Makefile.target index 1a71f3a..3395dee 100644 --- a/Makefile.target +++ b/Makefile.target @@ -563,7 +563,7 @@ obj-y += wdt_ib700.o wdt_i6300esb.o ifeq ($(TARGET_BASE_ARCH), i386) # Hardware support -obj-y += ide.o pckbd.o vga.o $(sound-obj-y) dma.o +obj-y += ide.o pckbd.o vga.o $(sound-obj-y) dma.o isa-bus.o obj-y += fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o obj-y += cirrus_vga.o apic.o ioapic.o parallel.o acpi.o piix_pci.o obj-y += usb-uhci.o vmmouse.o vmport.o vmware_vga.o hpet.o @@ -573,7 +573,7 @@ endif ifeq ($(TARGET_BASE_ARCH), ppc) CPPFLAGS += -DHAS_AUDIO -DHAS_AUDIO_CHOICE # shared objects -obj-y += ppc.o ide.o vga.o $(sound-obj-y) dma.o openpic.o +obj-y += ppc.o ide.o vga.o $(sound-obj-y) dma.o isa-bus.o openpic.o # PREP target obj-y += pckbd.o serial.o i8259.o i8254.o fdc.o mc146818rtc.o obj-y += prep_pci.o ppc_prep.o @@ -599,7 +599,7 @@ obj-y += mips_r4k.o mips_jazz.o mips_malta.o mips_mipssim.o obj-y += mips_timer.o mips_int.o dma.o vga.o serial.o i8254.o i8259.o rc4030.o obj-y += g364fb.o jazz_led.o dp8393x.o obj-y += ide.o gt64xxx.o pckbd.o fdc.o mc146818rtc.o usb-uhci.o acpi.o ds1225y.o -obj-y += piix_pci.o parallel.o cirrus_vga.o pcspk.o $(sound-obj-y) +obj-y += piix_pci.o parallel.o cirrus_vga.o isa-bus.o pcspk.o $(sound-obj-y) obj-y += mipsnet.o obj-y += pflash_cfi01.o obj-y += vmware_vga.o @@ -635,7 +635,7 @@ obj-y += pflash_cfi02.o endif ifeq ($(TARGET_BASE_ARCH), sparc) ifeq ($(TARGET_ARCH), sparc64) -obj-y += sun4u.o ide.o pckbd.o vga.o apb_pci.o +obj-y += sun4u.o ide.o isa-bus.o pckbd.o vga.o apb_pci.o obj-y += fdc.o mc146818rtc.o serial.o obj-y += cirrus_vga.o parallel.o else diff --git a/hw/isa-bus.c b/hw/isa-bus.c new file mode 100644 index 0000000..c0a6447 --- /dev/null +++ b/hw/isa-bus.c @@ -0,0 +1,82 @@ +#include "hw.h" +#include "sysemu.h" +#include "isa.h" + +struct ISABus { + BusState qbus; +}; +static ISABus *isabus; + +static struct BusInfo isa_bus_info = { + .name = "ISA", + .size = sizeof(ISABus), + .props = (Property[]) { + { + .name = "iobase", + .info = &qdev_prop_hex32, + .offset = offsetof(ISADevice, iobase[0]), + .defval = (uint32_t[]) { -1 }, + },{ + .name = "iobase2", + .info = &qdev_prop_hex32, + .offset = offsetof(ISADevice, iobase[1]), + .defval = (uint32_t[]) { -1 }, + }, + {/* end of list */} + } +}; + +ISABus *isa_bus_new(DeviceState *dev) +{ + if (isabus) { + fprintf(stderr, "Can't create a second ISA bus\n"); + return NULL; + } + + isabus = FROM_QBUS(ISABus, qbus_create(&isa_bus_info, dev, NULL)); + return isabus; +} + +void isa_connect_irq(ISADevice *dev, int n, qemu_irq irq) +{ + assert(n >= 0 && n < dev->nirqs); + if (dev->irqs[n]) + *dev->irqs[n] = irq; +} + +void isa_init_irq(ISADevice *dev, qemu_irq *p) +{ + assert(dev->nirqs < ARRAY_SIZE(dev->irqs)); + dev->irqs[dev->nirqs] = p; + dev->nirqs++; +} + +static void isa_qdev_init(DeviceState *qdev, DeviceInfo *base) +{ + ISADevice *dev = DO_UPCAST(ISADevice, qdev, qdev); + ISADeviceInfo *info = DO_UPCAST(ISADeviceInfo, qdev, base); + + info->init(dev); +} + +void isa_qdev_register(ISADeviceInfo *info) +{ + info->qdev.init = isa_qdev_init; + info->qdev.bus_info = &isa_bus_info; + qdev_register(&info->qdev); +} + +ISADevice *isa_create_simple(const char *name, uint32_t iobase, uint32_t iobase2) +{ + DeviceState *dev; + ISADevice *isa; + + if (!isabus) + return NULL; + dev = qdev_create(&isabus->qbus, name); + isa = DO_UPCAST(ISADevice, qdev, dev); + isa->iobase[0] = iobase; + isa->iobase[1] = iobase2; + qdev_init(dev); + return isa; +} diff --git a/hw/isa.h b/hw/isa.h index f126ecc..49c58f8 100644 --- a/hw/isa.h +++ b/hw/isa.h @@ -1,8 +1,33 @@ #ifndef HW_ISA_H #define HW_ISA_H + /* ISA bus */ #include "ioport.h" +#include "qdev.h" + +typedef struct ISABus ISABus; +typedef struct ISADevice ISADevice; +typedef struct ISADeviceInfo ISADeviceInfo; + +struct ISADevice { + DeviceState qdev; + uint32_t iobase[2]; + qemu_irq *irqs[2]; + int nirqs; +}; + +typedef void (*isa_qdev_initfn)(ISADevice *dev); +struct ISADeviceInfo { + DeviceInfo qdev; + isa_qdev_initfn init; +}; + +ISABus *isa_bus_new(DeviceState *dev); +void isa_connect_irq(ISADevice *dev, int n, qemu_irq irq); +void isa_init_irq(ISADevice *dev, qemu_irq *p); +void isa_qdev_register(ISADeviceInfo *info); +ISADevice *isa_create_simple(const char *name, uint32_t iobase, uint32_t iobase2); extern target_phys_addr_t isa_mem_base; -- 1.6.2.5 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] [PATCH 1/4] qdev/isa: add isa bus support to qdev. 2009-07-15 12:56 ` [Qemu-devel] [PATCH 1/4] qdev/isa: add isa bus support to qdev Gerd Hoffmann @ 2009-07-17 18:12 ` Filip Navara 2009-07-21 7:11 ` Gerd Hoffmann 0 siblings, 1 reply; 8+ messages in thread From: Filip Navara @ 2009-07-17 18:12 UTC (permalink / raw) To: Gerd Hoffmann; +Cc: qemu-devel 2009/7/15 Gerd Hoffmann <kraxel@redhat.com>: > +static struct BusInfo isa_bus_info = { > + .name = "ISA", > + .size = sizeof(ISABus), > + .props = (Property[]) { > + { > + .name = "iobase", > + .info = &qdev_prop_hex32, > + .offset = offsetof(ISADevice, iobase[0]), > + .defval = (uint32_t[]) { -1 }, > + },{ > + .name = "iobase2", > + .info = &qdev_prop_hex32, > + .offset = offsetof(ISADevice, iobase[1]), > + .defval = (uint32_t[]) { -1 }, > + }, > + {/* end of list */} > + } > +}; Why exactly two IO bases? That sounds like bad design to me. IMHO it should be handled more like sysbus_init_mmio (or sysbus_init_mmio_cb) and sysbus_mmio_map and the number of IO bases should be virtually unlimited (something like QDEV_MAX_MMIO is acceptable). Best regards, Filip Navara ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] [PATCH 1/4] qdev/isa: add isa bus support to qdev. 2009-07-17 18:12 ` Filip Navara @ 2009-07-21 7:11 ` Gerd Hoffmann 0 siblings, 0 replies; 8+ messages in thread From: Gerd Hoffmann @ 2009-07-21 7:11 UTC (permalink / raw) To: Filip Navara; +Cc: qemu-devel On 07/17/09 20:12, Filip Navara wrote: > 2009/7/15 Gerd Hoffmann<kraxel@redhat.com>: >> +static struct BusInfo isa_bus_info = { >> + .name = "ISA", >> + .size = sizeof(ISABus), >> + .props = (Property[]) { >> + { >> + .name = "iobase", >> + .name = "iobase2", > > Why exactly two IO bases? That sounds like bad design to me. IMHO it > should be handled more like sysbus_init_mmio (or sysbus_init_mmio_cb) > and sysbus_mmio_map and the number of IO bases should be virtually > unlimited (something like QDEV_MAX_MMIO is acceptable). Do we really need that? As new isa devices most likely wouldn't show up looking at the existing ones should give us a pretty complete picture ;) Most devices use one iobase. A few (ide, ps/2) need two. Any devices which need more? cheers, Gerd ^ permalink raw reply [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 2/4] qdev/isa: add qdev support to i8042 (aka ps/2 kbd+mouse). 2009-07-15 12:56 [Qemu-devel] [PATCH 0/4] qdev: add isa bus support Gerd Hoffmann 2009-07-15 12:56 ` [Qemu-devel] [PATCH 1/4] qdev/isa: add isa bus support to qdev Gerd Hoffmann @ 2009-07-15 12:56 ` Gerd Hoffmann 2009-07-15 12:56 ` [Qemu-devel] [PATCH 3/4] qdev/isa: make the piix isa bridge register an isa bus Gerd Hoffmann 2009-07-15 12:56 ` [Qemu-devel] [PATCH 4/4] qdev/isa: make pc use qdev for i8042 setup Gerd Hoffmann 3 siblings, 0 replies; 8+ messages in thread From: Gerd Hoffmann @ 2009-07-15 12:56 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- hw/pckbd.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 files changed, 40 insertions(+), 0 deletions(-) diff --git a/hw/pckbd.c b/hw/pckbd.c index d50cd6e..bb4cc0e 100644 --- a/hw/pckbd.c +++ b/hw/pckbd.c @@ -440,3 +440,43 @@ void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq, #endif qemu_register_reset(kbd_reset, s); } + +typedef struct ISAKBDState { + ISADevice dev; + KBDState kbd; +} ISAKBDState; + +static void i8042_initfn(ISADevice *dev) +{ + KBDState *s = &(DO_UPCAST(ISAKBDState, dev, dev)->kbd); + + isa_init_irq(dev, &s->irq_kbd); + isa_init_irq(dev, &s->irq_mouse); + + kbd_reset(s); + register_savevm("pckbd", 0, 3, kbd_save, kbd_load, s); + register_ioport_read(dev->iobase[0], 1, 1, kbd_read_data, s); + register_ioport_write(dev->iobase[0], 1, 1, kbd_write_data, s); + register_ioport_read(dev->iobase[1], 1, 1, kbd_read_status, s); + register_ioport_write(dev->iobase[1], 1, 1, kbd_write_command, s); + + s->kbd = ps2_kbd_init(kbd_update_kbd_irq, s); + s->mouse = ps2_mouse_init(kbd_update_aux_irq, s); +#ifdef TARGET_I386 + vmmouse_init(s->mouse); +#endif + qemu_register_reset(kbd_reset, s); +} + +static ISADeviceInfo i8042_info = { + .qdev.name = "i8042", + .qdev.size = sizeof(ISAKBDState), + .qdev.no_user = 1, + .init = i8042_initfn, +}; + +static void i8042_register(void) +{ + isa_qdev_register(&i8042_info); +} +device_init(i8042_register) -- 1.6.2.5 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 3/4] qdev/isa: make the piix isa bridge register an isa bus. 2009-07-15 12:56 [Qemu-devel] [PATCH 0/4] qdev: add isa bus support Gerd Hoffmann 2009-07-15 12:56 ` [Qemu-devel] [PATCH 1/4] qdev/isa: add isa bus support to qdev Gerd Hoffmann 2009-07-15 12:56 ` [Qemu-devel] [PATCH 2/4] qdev/isa: add qdev support to i8042 (aka ps/2 kbd+mouse) Gerd Hoffmann @ 2009-07-15 12:56 ` Gerd Hoffmann 2009-07-15 12:56 ` [Qemu-devel] [PATCH 4/4] qdev/isa: make pc use qdev for i8042 setup Gerd Hoffmann 3 siblings, 0 replies; 8+ messages in thread From: Gerd Hoffmann @ 2009-07-15 12:56 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- hw/piix_pci.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/hw/piix_pci.c b/hw/piix_pci.c index 91cebc9..c4f304b 100644 --- a/hw/piix_pci.c +++ b/hw/piix_pci.c @@ -25,6 +25,7 @@ #include "hw.h" #include "pc.h" #include "pci.h" +#include "isa.h" #include "sysbus.h" typedef uint32_t pci_addr_t; @@ -342,6 +343,7 @@ static void piix3_initfn(PCIDevice *d) { uint8_t *pci_conf; + isa_bus_new(&d->qdev); register_savevm("PIIX3", 0, 2, piix_save, piix_load, d); pci_conf = d->config; -- 1.6.2.5 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 4/4] qdev/isa: make pc use qdev for i8042 setup. 2009-07-15 12:56 [Qemu-devel] [PATCH 0/4] qdev: add isa bus support Gerd Hoffmann ` (2 preceding siblings ...) 2009-07-15 12:56 ` [Qemu-devel] [PATCH 3/4] qdev/isa: make the piix isa bridge register an isa bus Gerd Hoffmann @ 2009-07-15 12:56 ` Gerd Hoffmann 3 siblings, 0 replies; 8+ messages in thread From: Gerd Hoffmann @ 2009-07-15 12:56 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- hw/pc.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/hw/pc.c b/hw/pc.c index 8be1277..0dd03df 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -1095,6 +1095,7 @@ static void pc_init1(ram_addr_t ram_size, int bios_size, isa_bios_size, oprom_area_size; PCIBus *pci_bus; PCIDevice *pci_dev; + ISADevice *isa_dev; int piix3_devfn = -1; CPUState *env; qemu_irq *cpu_irq; @@ -1344,7 +1345,9 @@ static void pc_init1(ram_addr_t ram_size, } } - i8042_init(i8259[1], i8259[12], 0x60); + isa_dev = isa_create_simple("i8042", 0x60, 0x64); + isa_connect_irq(isa_dev, 0, i8259[1]); + isa_connect_irq(isa_dev, 1, i8259[12]); DMA_init(0); #ifdef HAS_AUDIO audio_init(pci_enabled ? pci_bus : NULL, i8259); -- 1.6.2.5 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 0/4] qdev: isa bus. @ 2009-07-09 13:02 Gerd Hoffmann 2009-07-09 13:02 ` [Qemu-devel] [PATCH 1/4] qdev/isa: add isa bus support to qdev Gerd Hoffmann 0 siblings, 1 reply; 8+ messages in thread From: Gerd Hoffmann @ 2009-07-09 13:02 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann Hi, This is a proof-of-concept / RfC patch series to add isa bus support to qdev. It adds isa-bus.c and converts one user (pc keyboard+mouse). I've tried to also handle isa-via-mmio used by certain architectures and hide that in isa-bus.c, so the individual drivers don't have to care once everything is converted over to qdev. Reviews especially from people knowing non-pc archs better than I do are very welcome. thanks, Gerd ^ permalink raw reply [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 1/4] qdev/isa: add isa bus support to qdev. 2009-07-09 13:02 [Qemu-devel] [PATCH 0/4] qdev: isa bus Gerd Hoffmann @ 2009-07-09 13:02 ` Gerd Hoffmann 0 siblings, 0 replies; 8+ messages in thread From: Gerd Hoffmann @ 2009-07-09 13:02 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann The implementation tries to cover both the pc-ish ioport case and the mmio-based isa port access found in other architectures. The common code in isa-bus.c handles mmio internally, so the separate init path for mmio present in many drivers can go away once all users are switched over to qdev. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- Makefile.target | 8 +- hw/isa-bus.c | 216 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ hw/isa.h | 31 ++++++++ 3 files changed, 251 insertions(+), 4 deletions(-) create mode 100644 hw/isa-bus.c diff --git a/Makefile.target b/Makefile.target index a593503..1a865fa 100644 --- a/Makefile.target +++ b/Makefile.target @@ -562,7 +562,7 @@ obj-y += wdt_ib700.o wdt_i6300esb.o ifeq ($(TARGET_BASE_ARCH), i386) # Hardware support -obj-y += ide.o pckbd.o vga.o $(sound-obj-y) dma.o +obj-y += ide.o pckbd.o vga.o $(sound-obj-y) dma.o isa-bus.o obj-y += fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o obj-y += cirrus_vga.o apic.o ioapic.o parallel.o acpi.o piix_pci.o obj-y += usb-uhci.o vmmouse.o vmport.o vmware_vga.o hpet.o @@ -572,7 +572,7 @@ endif ifeq ($(TARGET_BASE_ARCH), ppc) CPPFLAGS += -DHAS_AUDIO -DHAS_AUDIO_CHOICE # shared objects -obj-y += ppc.o ide.o vga.o $(sound-obj-y) dma.o openpic.o +obj-y += ppc.o ide.o vga.o $(sound-obj-y) dma.o isa-bus.o openpic.o # PREP target obj-y += pckbd.o serial.o i8259.o i8254.o fdc.o mc146818rtc.o obj-y += prep_pci.o ppc_prep.o @@ -598,7 +598,7 @@ obj-y += mips_r4k.o mips_jazz.o mips_malta.o mips_mipssim.o obj-y += mips_timer.o mips_int.o dma.o vga.o serial.o i8254.o i8259.o rc4030.o obj-y += g364fb.o jazz_led.o dp8393x.o obj-y += ide.o gt64xxx.o pckbd.o fdc.o mc146818rtc.o usb-uhci.o acpi.o ds1225y.o -obj-y += piix_pci.o parallel.o cirrus_vga.o pcspk.o $(sound-obj-y) +obj-y += piix_pci.o parallel.o cirrus_vga.o isa-bus.o pcspk.o $(sound-obj-y) obj-y += mipsnet.o obj-y += pflash_cfi01.o obj-y += vmware_vga.o @@ -634,7 +634,7 @@ obj-y += pflash_cfi02.o endif ifeq ($(TARGET_BASE_ARCH), sparc) ifeq ($(TARGET_ARCH), sparc64) -obj-y += sun4u.o ide.o pckbd.o vga.o apb_pci.o +obj-y += sun4u.o ide.o isa-bus.o pckbd.o vga.o apb_pci.o obj-y += fdc.o mc146818rtc.o serial.o obj-y += cirrus_vga.o parallel.o else diff --git a/hw/isa-bus.c b/hw/isa-bus.c new file mode 100644 index 0000000..96f95a9 --- /dev/null +++ b/hw/isa-bus.c @@ -0,0 +1,216 @@ +#include "hw.h" +#include "sysemu.h" +#include "isa.h" + +typedef struct ISAMMIO { + ISADevice *dev; + ISADeviceInfo *info; + int region; + int io_memory; +} ISAMMIO; + +struct ISABus { + BusState qbus; + int mmio; + int it_shift; +}; +static ISABus *isabus; + +static struct BusInfo isa_bus_info = { + .name = "ISA", + .size = sizeof(ISABus), + .props = (Property[]) { + { + .name = "iobase", + .info = &qdev_prop_hex32, + .offset = offsetof(ISADevice, iobase[0]), + .defval = (uint32_t[]) { -1 }, + },{ + .name = "iobase2", + .info = &qdev_prop_hex32, + .offset = offsetof(ISADevice, iobase[1]), + .defval = (uint32_t[]) { -1 }, + }, + {/* end of list */} + } +}; + +ISABus *isa_bus_new(DeviceState *dev, int mmio, int it_shift) +{ + if (isabus) { + fprintf(stderr, "Can't create a second ISA bus\n"); + return NULL; + } + + isabus = FROM_QBUS(ISABus, qbus_create(&isa_bus_info, dev, "isa")); + isabus->mmio = mmio; + isabus->it_shift = it_shift; + return isabus; +} + +void isa_connect_irq(ISADevice *dev, int n, qemu_irq irq) +{ + assert(n >= 0 && n < dev->nirqs); + if (dev->irqs[n]) + *dev->irqs[n] = irq; +} + +void isa_init_irq(ISADevice *dev, qemu_irq *p) +{ + assert(dev->nirqs < ARRAY_SIZE(dev->irqs)); + dev->irqs[dev->nirqs] = p; + dev->nirqs++; +} + +static uint32_t isa_mm_readb(void *opaque, target_phys_addr_t addr) +{ + ISAMMIO *mm = opaque; + IOPortReadFunc *ioread = mm->info->io[mm->region].read; + + return ioread(mm->dev, addr >> isabus->it_shift) & 0xFF; +} + +static void isa_mm_writeb(void *opaque, + target_phys_addr_t addr, uint32_t value) +{ + ISAMMIO *mm = opaque; + IOPortWriteFunc *iowrite = mm->info->io[mm->region].write; + + iowrite(mm->dev, addr >> isabus->it_shift, value & 0xFF); +} + +static uint32_t isa_mm_readw(void *opaque, target_phys_addr_t addr) +{ + ISAMMIO *mm = opaque; + IOPortReadFunc *ioread = mm->info->io[mm->region].read; + uint32_t value; + + value = ioread(mm->dev, addr >> isabus->it_shift) & 0xFFFF; +#ifdef TARGET_WORDS_BIGENDIAN + value = bswap16(value); +#endif + return value; +} + +static void isa_mm_writew(void *opaque, + target_phys_addr_t addr, uint32_t value) +{ + ISAMMIO *mm = opaque; + IOPortWriteFunc *iowrite = mm->info->io[mm->region].write; + +#ifdef TARGET_WORDS_BIGENDIAN + value = bswap16(value); +#endif + iowrite(mm->dev, addr >> isabus->it_shift, value & 0xFFFF); +} + +static uint32_t isa_mm_readl(void *opaque, target_phys_addr_t addr) +{ + ISAMMIO *mm = opaque; + IOPortReadFunc *ioread = mm->info->io[mm->region].read; + uint32_t value; + + value = ioread(mm->dev, addr >> isabus->it_shift); +#ifdef TARGET_WORDS_BIGENDIAN + value = bswap32(value); +#endif + return value; +} + +static void isa_mm_writel(void *opaque, + target_phys_addr_t addr, uint32_t value) +{ + ISAMMIO *mm = opaque; + IOPortWriteFunc *iowrite = mm->info->io[mm->region].write; + +#ifdef TARGET_WORDS_BIGENDIAN + value = bswap32(value); +#endif + iowrite(mm->dev, addr >> isabus->it_shift, value & 0xFFFF); +} + +static CPUReadMemoryFunc *isa_mm_read[] = { + &isa_mm_readb, + &isa_mm_readw, + &isa_mm_readl, +}; + +static CPUWriteMemoryFunc *isa_mm_write[] = { + &isa_mm_writeb, + &isa_mm_writew, + &isa_mm_writel, +}; + +static void isa_setup_ioport(ISADevice *dev, ISADeviceInfo *info) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(dev->iobase); i++) { + if (!dev->iobase[i]) + continue; + if (info->io[i].read) + register_ioport_read(dev->iobase[i], info->io[i].length, 1, + info->io[i].read, dev); + if (info->io[i].write) + register_ioport_write(dev->iobase[i], info->io[i].length, 1, + info->io[i].write, dev); + fprintf(stderr, "%s: ioport 0x%x (+%d) %c%c for %s\n", __FUNCTION__, + dev->iobase[i], info->io[i].length, + info->io[i].read ? 'r' : '-', + info->io[i].write ? 'w' : '-', + info->qdev.name); + } +} + +static void isa_setup_mmio(ISADevice *dev, ISADeviceInfo *info) +{ + struct ISAMMIO *mm; + int i; + + for (i = 0; i < ARRAY_SIZE(dev->iobase); i++) { + if (!dev->iobase[i]) + continue; + mm = qemu_mallocz(sizeof(*mm)); + mm->dev = dev; + mm->info = info; + mm->region = i; + mm->io_memory = cpu_register_io_memory(isa_mm_read, isa_mm_write, mm); + cpu_register_physical_memory(dev->iobase[i], info->io[i].length, mm->io_memory); + } +} + +static void isa_qdev_init(DeviceState *qdev, DeviceInfo *base) +{ + ISADevice *dev = DO_UPCAST(ISADevice, qdev, qdev); + ISADeviceInfo *info = DO_UPCAST(ISADeviceInfo, qdev, base); + + if (isabus->mmio) { + isa_setup_mmio(dev, info); + } else { + isa_setup_ioport(dev, info); + } + + info->init(dev); +} + +void isa_qdev_register(ISADeviceInfo *info) +{ + info->qdev.init = isa_qdev_init; + info->qdev.bus_info = &isa_bus_info; + qdev_register(&info->qdev); +} + +ISADevice *isa_create_simple(const char *name, uint32_t iobase, uint32_t iobase2) +{ + DeviceState *dev; + ISADevice *isa; + + if (!isabus) + return NULL; + dev = qdev_create(&isabus->qbus, name); + isa = DO_UPCAST(ISADevice, qdev, dev); + isa->iobase[0] = iobase; + isa->iobase[1] = iobase2; + qdev_init(dev); + return isa; +} diff --git a/hw/isa.h b/hw/isa.h index a8c1a56..941bfe3 100644 --- a/hw/isa.h +++ b/hw/isa.h @@ -1,7 +1,38 @@ #ifndef HW_ISA_H #define HW_ISA_H + /* ISA bus */ +#include "qdev.h" + +typedef struct ISABus ISABus; +typedef struct ISADevice ISADevice; +typedef struct ISADeviceInfo ISADeviceInfo; + +struct ISADevice { + DeviceState qdev; + uint32_t iobase[2]; + qemu_irq *irqs[2]; + int nirqs; +}; + +typedef void (*isa_qdev_initfn)(ISADevice *dev); +struct ISADeviceInfo { + DeviceInfo qdev; + isa_qdev_initfn init; + struct { + IOPortReadFunc *read; + IOPortWriteFunc *write; + uint32_t length; + } io[2]; +}; + +ISABus *isa_bus_new(DeviceState *dev, int mmio, int it_shift); +void isa_connect_irq(ISADevice *dev, int n, qemu_irq irq); +void isa_init_irq(ISADevice *dev, qemu_irq *p); +void isa_qdev_register(ISADeviceInfo *info); +ISADevice *isa_create_simple(const char *name, uint32_t iobase, uint32_t iobase2); + extern target_phys_addr_t isa_mem_base; int register_ioport_read(int start, int length, int size, -- 1.6.2.5 ^ permalink raw reply related [flat|nested] 8+ messages in thread
end of thread, other threads:[~2009-07-21 7:11 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2009-07-15 12:56 [Qemu-devel] [PATCH 0/4] qdev: add isa bus support Gerd Hoffmann 2009-07-15 12:56 ` [Qemu-devel] [PATCH 1/4] qdev/isa: add isa bus support to qdev Gerd Hoffmann 2009-07-17 18:12 ` Filip Navara 2009-07-21 7:11 ` Gerd Hoffmann 2009-07-15 12:56 ` [Qemu-devel] [PATCH 2/4] qdev/isa: add qdev support to i8042 (aka ps/2 kbd+mouse) Gerd Hoffmann 2009-07-15 12:56 ` [Qemu-devel] [PATCH 3/4] qdev/isa: make the piix isa bridge register an isa bus Gerd Hoffmann 2009-07-15 12:56 ` [Qemu-devel] [PATCH 4/4] qdev/isa: make pc use qdev for i8042 setup Gerd Hoffmann -- strict thread matches above, loose matches on Subject: below -- 2009-07-09 13:02 [Qemu-devel] [PATCH 0/4] qdev: isa bus Gerd Hoffmann 2009-07-09 13:02 ` [Qemu-devel] [PATCH 1/4] qdev/isa: add isa bus support to qdev Gerd Hoffmann
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).