Message ID | AANLkTim5y9JcKEduGP4A5rtGDaGW1dCngczppNXvItQz@mail.gmail.com |
---|---|
State | New |
Headers | show |
On Wed, Jul 07, 2010 at 05:53:08PM +0000, Blue Swirl wrote: > Add I/O port registration functions which separate registration > from the mapping stage. > > Move IOIO and MMIO BAR mapping to pci.c. > > TODO: fix dirty logging, coalesced MMIO and base address comparisons > (eepro100 etc). Bridge filtering may be broken. Broke virtio-pci and MSIX. legacy vga regions too? > Signed-off-by: Blue Swirl <blauwirbel@gmail.com> Looks like a good direction to take. > --- > i386 boots but resets. PPC and Sparc64 can't even start. > > Patch also available at > git://repo.or.cz/qemu/blueswirl.git > > It may be worthwhile to break this into some kind of smaller steps. Definitely.
On Wed, Jul 7, 2010 at 5:55 PM, Michael S. Tsirkin <mst@redhat.com> wrote: > On Wed, Jul 07, 2010 at 05:53:08PM +0000, Blue Swirl wrote: >> Add I/O port registration functions which separate registration >> from the mapping stage. >> >> Move IOIO and MMIO BAR mapping to pci.c. >> >> TODO: fix dirty logging, coalesced MMIO and base address comparisons >> (eepro100 etc). Bridge filtering may be broken. Broke virtio-pci and MSIX. > > legacy vga regions too? Probably not, because VGA still works nicely at PC boot. > >> Signed-off-by: Blue Swirl <blauwirbel@gmail.com> > > Looks like a good direction to take. > >> --- >> i386 boots but resets. PPC and Sparc64 can't even start. >> >> Patch also available at >> git://repo.or.cz/qemu/blueswirl.git >> >> It may be worthwhile to break this into some kind of smaller steps. > > Definitely. > One way could be to leave map_func in place but if it's NULL, use newer system. When all callers have converted cleanly, remove extra NULL argument and map_func. It would be nice to have some plan how to convert KVM stuff like dirty logging and coalescing. Any ideas?
On Wed, 7 Jul 2010, Blue Swirl wrote: > Add I/O port registration functions which separate registration > from the mapping stage. Why? [..snip..]
On 07/07/2010 12:53 PM, Blue Swirl wrote: > Add I/O port registration functions which separate registration > from the mapping stage. > > Move IOIO and MMIO BAR mapping to pci.c. > > TODO: fix dirty logging, coalesced MMIO and base address comparisons > (eepro100 etc). Bridge filtering may be broken. Broke virtio-pci and MSIX. > > Signed-off-by: Blue Swirl<blauwirbel@gmail.com> > --- > i386 boots but resets. PPC and Sparc64 can't even start. > > Patch also available at > git://repo.or.cz/qemu/blueswirl.git > > It may be worthwhile to break this into some kind of smaller steps. > > hw/ac97.c | 60 +++++++++++--------- > hw/cirrus_vga.c | 40 +++----------- > hw/e1000.c | 37 +----------- > hw/eepro100.c | 77 ++++++++++---------------- > hw/es1370.c | 32 +++++------ > hw/ide/cmd646.c | 149 +++++++++++++++++++++++++++++++------------------- > hw/ide/piix.c | 74 ++++++++++++++++--------- > hw/ide/via.c | 67 ++++++++++++++-------- > hw/isa.h | 1 + > hw/isa_mmio.c | 17 +++++- > hw/lsi53c895a.c | 60 ++++++-------------- > hw/macio.c | 107 +++++++++++------------------------- > hw/ne2000.c | 66 +++++++++++++++------- > hw/openpic.c | 36 ++---------- > hw/pci.c | 158 ++++++++++++++++++++++++++++++++-------------------- > hw/pci.h | 18 +++++- > hw/pcnet.c | 62 ++++++++++----------- > hw/ppc_mac.h | 5 +- > hw/ppc_newworld.c | 2 +- > hw/ppc_oldworld.c | 4 +- > hw/rtl8139.c | 42 +++++--------- > hw/sun4u.c | 29 +++------ > hw/usb-ohci.c | 10 +--- > hw/usb-uhci.c | 31 +++++----- > hw/vga-pci.c | 22 +------ > hw/virtio-pci.c | 39 ++++++------- > hw/vmware_vga.c | 107 ++++++++++++++++++------------------ > hw/wdt_i6300esb.c | 38 +++++-------- > ioport.c | 119 ++++++++++++++++++++++++++++++++++++---- > ioport.h | 6 ++ > 30 files changed, 778 insertions(+), 737 deletions(-) > > diff --git a/hw/ac97.c b/hw/ac97.c > index 4319bc8..28d0c19 100644 > --- a/hw/ac97.c > +++ b/hw/ac97.c > @@ -1234,31 +1234,29 @@ static const VMStateDescription vmstate_ac97 = { > } > }; > > -static void ac97_map (PCIDevice *pci_dev, int region_num, > - pcibus_t addr, pcibus_t size, int type) > -{ > - AC97LinkState *s = DO_UPCAST (AC97LinkState, dev, pci_dev); > - PCIDevice *d =&s->dev; > - > - if (!region_num) { > - s->base[0] = addr; > - register_ioport_read (addr, 256 * 1, 1, nam_readb, d); > - register_ioport_read (addr, 256 * 2, 2, nam_readw, d); > - register_ioport_read (addr, 256 * 4, 4, nam_readl, d); > - register_ioport_write (addr, 256 * 1, 1, nam_writeb, d); > - register_ioport_write (addr, 256 * 2, 2, nam_writew, d); > - register_ioport_write (addr, 256 * 4, 4, nam_writel, d); > - } > - else { > - s->base[1] = addr; > - register_ioport_read (addr, 64 * 1, 1, nabm_readb, d); > - register_ioport_read (addr, 64 * 2, 2, nabm_readw, d); > - register_ioport_read (addr, 64 * 4, 4, nabm_readl, d); > - register_ioport_write (addr, 64 * 1, 1, nabm_writeb, d); > - register_ioport_write (addr, 64 * 2, 2, nabm_writew, d); > - register_ioport_write (addr, 64 * 4, 4, nabm_writel, d); > - } > -} > +static IOPortWriteFunc * const nam_writes[] = { > + nam_writeb, > + nam_writew, > + nam_writel, > +}; > + > +static IOPortReadFunc * const nam_reads[] = { > + nam_readb, > + nam_readw, > + nam_readl, > +}; > + > +static IOPortWriteFunc * const nabm_writes[] = { > + nabm_writeb, > + nabm_writew, > + nabm_writel, > +}; > + > +static IOPortReadFunc * const nabm_reads[] = { > + nabm_readb, > + nabm_readw, > + nabm_readl, > +}; > > static void ac97_on_reset (void *opaque) > { > @@ -1280,6 +1278,7 @@ static int ac97_initfn (PCIDevice *dev) > { > AC97LinkState *s = DO_UPCAST (AC97LinkState, dev, dev); > uint8_t *c = s->dev.config; > + int io_index; > > pci_config_set_vendor_id (c, PCI_VENDOR_ID_INTEL); /* ro */ > pci_config_set_device_id (c, PCI_DEVICE_ID_INTEL_82801AA_5); /* ro */ > @@ -1321,9 +1320,14 @@ static int ac97_initfn (PCIDevice *dev) > /* TODO: RST# value should be 0. */ > c[PCI_INTERRUPT_PIN] = 0x01; /* intr_pn interrupt pin ro */ > > - pci_register_bar (&s->dev, 0, 256 * 4, PCI_BASE_ADDRESS_SPACE_IO, > - ac97_map); > - pci_register_bar (&s->dev, 1, 64 * 4, PCI_BASE_ADDRESS_SPACE_IO, ac97_map); > + pci_register_bar(&s->dev, 0, 256 * 4, PCI_BASE_ADDRESS_SPACE_IO); > + io_index = cpu_register_io(nam_reads, nam_writes, 256 * 4, s); > + pci_bar_map(&s->dev, 0, 0, 0, 256 * 4, io_index); > + > + pci_register_bar(&s->dev, 1, 64 * 4, PCI_BASE_ADDRESS_SPACE_IO); > + io_index = cpu_register_io(nabm_reads, nabm_writes, 64 * 4, s); > + pci_bar_map(&s->dev, 1, 0, 0, 64 * 4, io_index); > Any reason to keep this a three step process? I see no reason not to unify the io and mem function pointers into a single type. These callbacks should be working off of pci bus addresses and should not be tied directly to CPU memory/pio callbacks. Regards, Anthony Liguori > + > qemu_register_reset (ac97_on_reset, s); > AUD_register_card ("ac97",&s->card); > ac97_on_reset (s); > diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c > index bbd4b08..829d837 100644 > --- a/hw/cirrus_vga.c > +++ b/hw/cirrus_vga.c > @@ -3139,36 +3139,6 @@ void isa_cirrus_vga_init(void) > * > ***************************************/ > > -static void cirrus_pci_lfb_map(PCIDevice *d, int region_num, > - pcibus_t addr, pcibus_t size, int type) > -{ > - CirrusVGAState *s =&DO_UPCAST(PCICirrusVGAState, dev, d)->cirrus_vga; > - > - /* XXX: add byte swapping apertures */ > - cpu_register_physical_memory(addr, s->vga.vram_size, > - s->cirrus_linear_io_addr); > - cpu_register_physical_memory(addr + 0x1000000, 0x400000, > - s->cirrus_linear_bitblt_io_addr); > - > - s->vga.map_addr = s->vga.map_end = 0; > - s->vga.lfb_addr = addr& TARGET_PAGE_MASK; > - s->vga.lfb_end = ((addr + VGA_RAM_SIZE) + TARGET_PAGE_SIZE - 1)& > TARGET_PAGE_MASK; > - /* account for overflow */ > - if (s->vga.lfb_end< addr + VGA_RAM_SIZE) > - s->vga.lfb_end = addr + VGA_RAM_SIZE; > - > - vga_dirty_log_start(&s->vga); > -} > - > -static void cirrus_pci_mmio_map(PCIDevice *d, int region_num, > - pcibus_t addr, pcibus_t size, int type) > -{ > - CirrusVGAState *s =&DO_UPCAST(PCICirrusVGAState, dev, d)->cirrus_vga; > - > - cpu_register_physical_memory(addr, CIRRUS_PNPMMIO_SIZE, > - s->cirrus_mmio_io_addr); > -} > - > static void pci_cirrus_write_config(PCIDevice *d, > uint32_t address, uint32_t val, int len) > { > @@ -3205,10 +3175,16 @@ static int pci_cirrus_vga_initfn(PCIDevice *dev) > /* memory #1 memory-mapped I/O */ > /* XXX: s->vga.vram_size must be a power of two */ > pci_register_bar((PCIDevice *)d, 0, 0x2000000, > - PCI_BASE_ADDRESS_MEM_PREFETCH, cirrus_pci_lfb_map); > + PCI_BASE_ADDRESS_MEM_PREFETCH); > + pci_bar_map((PCIDevice *)d, 0, 0, 0, s->vga.vram_size, > + s->cirrus_linear_io_addr); > + pci_bar_map((PCIDevice *)d, 0, 1, 0x1000000, 0x400000, > + s->cirrus_linear_bitblt_io_addr); > if (device_id == CIRRUS_ID_CLGD5446) { > pci_register_bar((PCIDevice *)d, 1, CIRRUS_PNPMMIO_SIZE, > - PCI_BASE_ADDRESS_SPACE_MEMORY, cirrus_pci_mmio_map); > + PCI_BASE_ADDRESS_SPACE_MEMORY); > + pci_bar_map((PCIDevice *)d, 1, 0, 0, CIRRUS_PNPMMIO_SIZE, > + s->cirrus_mmio_io_addr); > } > return 0; > } > diff --git a/hw/e1000.c b/hw/e1000.c > index 0da65f9..b5e9143 100644 > --- a/hw/e1000.c > +++ b/hw/e1000.c > @@ -149,14 +149,6 @@ static const char phy_regcap[0x20] = { > }; > > static void > -ioport_map(PCIDevice *pci_dev, int region_num, pcibus_t addr, > - pcibus_t size, int type) > -{ > - DBGOUT(IO, "e1000_ioport_map addr=0x%04"FMT_PCIBUS > - " size=0x%08"FMT_PCIBUS"\n", addr, size); > -} > - > -static void > set_interrupt_cause(E1000State *s, int index, uint32_t val) > { > if (val) > @@ -1018,30 +1010,6 @@ static CPUReadMemoryFunc * const e1000_mmio_read[] = { > }; > > static void > -e1000_mmio_map(PCIDevice *pci_dev, int region_num, > - pcibus_t addr, pcibus_t size, int type) > -{ > - E1000State *d = DO_UPCAST(E1000State, dev, pci_dev); > - int i; > - const uint32_t excluded_regs[] = { > - E1000_MDIC, E1000_ICR, E1000_ICS, E1000_IMS, > - E1000_IMC, E1000_TCTL, E1000_TDT, PNPMMIO_SIZE > - }; > - > - > - DBGOUT(MMIO, "e1000_mmio_map addr=0x%08"FMT_PCIBUS" 0x%08"FMT_PCIBUS"\n", > - addr, size); > - > - cpu_register_physical_memory(addr, PNPMMIO_SIZE, d->mmio_index); > - qemu_register_coalesced_mmio(addr, excluded_regs[0]); > - > - for (i = 0; excluded_regs[i] != PNPMMIO_SIZE; i++) > - qemu_register_coalesced_mmio(addr + excluded_regs[i] + 4, > - excluded_regs[i + 1] - > - excluded_regs[i] - 4); > -} > - > -static void > e1000_cleanup(VLANClientState *nc) > { > E1000State *s = DO_UPCAST(NICState, nc, nc)->opaque; > @@ -1106,10 +1074,11 @@ static int pci_e1000_init(PCIDevice *pci_dev) > e1000_mmio_write, d); > > pci_register_bar((PCIDevice *)d, 0, PNPMMIO_SIZE, > - PCI_BASE_ADDRESS_SPACE_MEMORY, e1000_mmio_map); > + PCI_BASE_ADDRESS_SPACE_MEMORY); > + pci_bar_map((PCIDevice *)d, 0, 0, 0, PNPMMIO_SIZE, d->mmio_index); > > pci_register_bar((PCIDevice *)d, 1, IOPORT_SIZE, > - PCI_BASE_ADDRESS_SPACE_IO, ioport_map); > + PCI_BASE_ADDRESS_SPACE_IO); > > memmove(d->eeprom_data, e1000_eeprom_template, > sizeof e1000_eeprom_template); > diff --git a/hw/eepro100.c b/hw/eepro100.c > index 2b75c8f..da41476 100644 > --- a/hw/eepro100.c > +++ b/hw/eepro100.c > @@ -226,7 +226,7 @@ typedef struct { > uint8_t scb_stat; /* SCB stat/ack byte */ > uint8_t int_stat; /* PCI interrupt status */ > /* region must not be saved by nic_save. */ > - uint32_t region[3]; /* PCI region addresses */ > + uint32_t region; /* PCI region addresses */ > uint16_t mdimem[32]; > eeprom_t *eeprom; > uint32_t device; /* device variant */ > @@ -1479,19 +1479,19 @@ static uint32_t ioport_read1(void *opaque, > uint32_t addr) > #if 0 > logout("addr=%s\n", regname(addr)); > #endif > - return eepro100_read1(s, addr - s->region[1]); > + return eepro100_read1(s, addr - s->region); > } > > static uint32_t ioport_read2(void *opaque, uint32_t addr) > { > EEPRO100State *s = opaque; > - return eepro100_read2(s, addr - s->region[1]); > + return eepro100_read2(s, addr - s->region); > } > > static uint32_t ioport_read4(void *opaque, uint32_t addr) > { > EEPRO100State *s = opaque; > - return eepro100_read4(s, addr - s->region[1]); > + return eepro100_read4(s, addr - s->region); > } > > static void ioport_write1(void *opaque, uint32_t addr, uint32_t val) > @@ -1500,43 +1500,35 @@ static void ioport_write1(void *opaque, > uint32_t addr, uint32_t val) > #if 0 > logout("addr=%s val=0x%02x\n", regname(addr), val); > #endif > - eepro100_write1(s, addr - s->region[1], val); > + eepro100_write1(s, addr - s->region, val); > } > > static void ioport_write2(void *opaque, uint32_t addr, uint32_t val) > { > EEPRO100State *s = opaque; > - eepro100_write2(s, addr - s->region[1], val); > + eepro100_write2(s, addr - s->region, val); > } > > static void ioport_write4(void *opaque, uint32_t addr, uint32_t val) > { > EEPRO100State *s = opaque; > - eepro100_write4(s, addr - s->region[1], val); > + eepro100_write4(s, addr - s->region, val); > } > > /***********************************************************/ > /* PCI EEPRO100 definitions */ > > -static void pci_map(PCIDevice * pci_dev, int region_num, > - pcibus_t addr, pcibus_t size, int type) > -{ > - EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev); > - > - TRACE(OTHER, logout("region %d, addr=0x%08"FMT_PCIBUS", " > - "size=0x%08"FMT_PCIBUS", type=%d\n", > - region_num, addr, size, type)); > - > - assert(region_num == 1); > - register_ioport_write(addr, size, 1, ioport_write1, s); > - register_ioport_read(addr, size, 1, ioport_read1, s); > - register_ioport_write(addr, size, 2, ioport_write2, s); > - register_ioport_read(addr, size, 2, ioport_read2, s); > - register_ioport_write(addr, size, 4, ioport_write4, s); > - register_ioport_read(addr, size, 4, ioport_read4, s); > +static IOPortWriteFunc * const io_writes[] = { > + ioport_write1, > + ioport_write2, > + ioport_write4, > +}; > > - s->region[region_num] = addr; > -} > +static IOPortReadFunc * const io_reads[] = { > + ioport_read1, > + ioport_read2, > + ioport_read4, > +}; > > /***************************************************************************** > * > @@ -1610,22 +1602,6 @@ static CPUReadMemoryFunc * const pci_mmio_read[] = { > pci_mmio_readl > }; > > -static void pci_mmio_map(PCIDevice * pci_dev, int region_num, > - pcibus_t addr, pcibus_t size, int type) > -{ > - EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev); > - > - TRACE(OTHER, logout("region %d, addr=0x%08"FMT_PCIBUS", " > - "size=0x%08"FMT_PCIBUS", type=%d\n", > - region_num, addr, size, type)); > - > - assert(region_num == 0 || region_num == 2); > - > - /* Map control / status registers and flash. */ > - cpu_register_physical_memory(addr, size, s->mmio_index); > - s->region[region_num] = addr; > -} > - > static int nic_can_receive(VLANClientState *nc) > { > EEPRO100State *s = DO_UPCAST(NICState, nc, nc)->opaque; > @@ -1853,6 +1829,7 @@ static int e100_nic_init(PCIDevice *pci_dev) > EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev); > E100PCIDeviceInfo *e100_device = DO_UPCAST(E100PCIDeviceInfo, pci.qdev, > pci_dev->qdev.info); > + int io_index; > > TRACE(OTHER, logout("\n")); > > @@ -1868,17 +1845,23 @@ static int e100_nic_init(PCIDevice *pci_dev) > s->mmio_index = > cpu_register_io_memory(pci_mmio_read, pci_mmio_write, s); > > + /* Map control / status registers. */ > pci_register_bar(&s->dev, 0, PCI_MEM_SIZE, > PCI_BASE_ADDRESS_SPACE_MEMORY | > - PCI_BASE_ADDRESS_MEM_PREFETCH, pci_mmio_map); > - pci_register_bar(&s->dev, 1, PCI_IO_SIZE, PCI_BASE_ADDRESS_SPACE_IO, > - pci_map); > - pci_register_bar(&s->dev, 2, PCI_FLASH_SIZE, PCI_BASE_ADDRESS_SPACE_MEMORY, > - pci_mmio_map); > + PCI_BASE_ADDRESS_MEM_PREFETCH); > + pci_bar_map(&s->dev, 0, 0, 0, PCI_IO_SIZE, s->mmio_index); > + > + io_index = cpu_register_io(io_reads, io_writes, PCI_IO_SIZE, s); > + pci_register_bar(&s->dev, 1, PCI_IO_SIZE, PCI_BASE_ADDRESS_SPACE_IO); > + pci_bar_map(&s->dev, 1, 0, 0, PCI_IO_SIZE, io_index); > + > + /* Map flash. */ > + pci_register_bar(&s->dev, 2, PCI_FLASH_SIZE, > + PCI_BASE_ADDRESS_SPACE_MEMORY); > + pci_bar_map(&s->dev, 2, 0, 0, PCI_FLASH_SIZE, s->mmio_index); > > qemu_macaddr_default_if_unset(&s->conf.macaddr); > logout("macaddr: %s\n", nic_dump(&s->conf.macaddr.a[0], 6)); > - assert(s->region[1] == 0); > > nic_reset(s); > > diff --git a/hw/es1370.c b/hw/es1370.c > index 40cb48c..652f0d4 100644 > --- a/hw/es1370.c > +++ b/hw/es1370.c > @@ -906,23 +906,17 @@ static void es1370_adc_callback (void *opaque, int avail) > es1370_run_channel (s, ADC_CHANNEL, avail); > } > > -static void es1370_map (PCIDevice *pci_dev, int region_num, > - pcibus_t addr, pcibus_t size, int type) > -{ > - ES1370State *s = DO_UPCAST (ES1370State, dev, pci_dev); > - > - (void) region_num; > - (void) size; > - (void) type; > - > - register_ioport_write (addr, 0x40 * 4, 1, es1370_writeb, s); > - register_ioport_write (addr, 0x40 * 2, 2, es1370_writew, s); > - register_ioport_write (addr, 0x40, 4, es1370_writel, s); > +static IOPortWriteFunc * const es1370_writes[] = { > + es1370_writeb, > + es1370_writew, > + es1370_writel, > +}; > > - register_ioport_read (addr, 0x40 * 4, 1, es1370_readb, s); > - register_ioport_read (addr, 0x40 * 2, 2, es1370_readw, s); > - register_ioport_read (addr, 0x40, 4, es1370_readl, s); > -} > +static IOPortReadFunc * const es1370_reads[] = { > + es1370_readb, > + es1370_readw, > + es1370_readl, > +}; > > static const VMStateDescription vmstate_es1370_channel = { > .name = "es1370_channel", > @@ -997,6 +991,7 @@ static int es1370_initfn (PCIDevice *dev) > { > ES1370State *s = DO_UPCAST (ES1370State, dev, dev); > uint8_t *c = s->dev.config; > + int io_index; > > pci_config_set_vendor_id (c, PCI_VENDOR_ID_ENSONIQ); > pci_config_set_device_id (c, PCI_DEVICE_ID_ENSONIQ_ES1370); > @@ -1023,7 +1018,10 @@ static int es1370_initfn (PCIDevice *dev) > c[PCI_MIN_GNT] = 0x0c; > c[PCI_MAX_LAT] = 0x80; > > - pci_register_bar (&s->dev, 0, 256, PCI_BASE_ADDRESS_SPACE_IO, es1370_map); > + pci_register_bar (&s->dev, 0, 256, PCI_BASE_ADDRESS_SPACE_IO); > + io_index = cpu_register_io(es1370_reads, es1370_writes, 256, s); > + pci_bar_map(&s->dev, 0, 0, 0, 256, io_index); > + > qemu_register_reset (es1370_on_reset, s); > > AUD_register_card ("es1370",&s->card); > diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c > index 8b71a13..b30e279 100644 > --- a/hw/ide/cmd646.c > +++ b/hw/ide/cmd646.c > @@ -44,29 +44,29 @@ > > static void cmd646_update_irq(PCIIDEState *d); > > -static void ide_map(PCIDevice *pci_dev, int region_num, > - pcibus_t addr, pcibus_t size, int type) > -{ > - PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, pci_dev); > - IDEBus *bus; > - > - if (region_num<= 3) { > - bus =&d->bus[(region_num>> 1)]; > - if (region_num& 1) { > - register_ioport_read(addr + 2, 1, 1, ide_status_read, bus); > - register_ioport_write(addr + 2, 1, 1, ide_cmd_write, bus); > - } else { > - register_ioport_write(addr, 8, 1, ide_ioport_write, bus); > - register_ioport_read(addr, 8, 1, ide_ioport_read, bus); > - > - /* data ports */ > - register_ioport_write(addr, 2, 2, ide_data_writew, bus); > - register_ioport_read(addr, 2, 2, ide_data_readw, bus); > - register_ioport_write(addr, 4, 4, ide_data_writel, bus); > - register_ioport_read(addr, 4, 4, ide_data_readl, bus); > - } > - } > -} > +static IOPortWriteFunc * const ide_cmd_writes[] = { > + ide_cmd_write, > + NULL, > + NULL, > +}; > + > +static IOPortReadFunc * const ide_status_reads[] = { > + ide_status_read, > + NULL, > + NULL, > +}; > + > +static IOPortWriteFunc * const ide_ioport_writes[] = { > + ide_ioport_write, > + ide_data_writew, > + ide_data_writel, > +}; > + > +static IOPortReadFunc * const ide_ioport_reads[] = { > + ide_ioport_read, > + ide_data_readw, > + ide_data_readl, > +}; > > static uint32_t bmdma_readb_common(PCIIDEState *pci_dev, BMDMAState *bm, > uint32_t addr) > @@ -159,35 +159,41 @@ static void bmdma_writeb_1(void *opaque, > uint32_t addr, uint32_t val) > bmdma_writeb_common(pci_dev, bm, addr, val); > } > > -static void bmdma_map(PCIDevice *pci_dev, int region_num, > - pcibus_t addr, pcibus_t size, int type) > -{ > - PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, pci_dev); > - int i; > +static IOPortWriteFunc * const bmdma_io_writes_0[] = { > + bmdma_writeb_0, > + NULL, > + NULL, > +}; > > - for(i = 0;i< 2; i++) { > - BMDMAState *bm =&d->bmdma[i]; > - d->bus[i].bmdma = bm; > - bm->bus = d->bus+i; > - qemu_add_vm_change_state_handler(ide_dma_restart_cb, bm); > +static IOPortReadFunc * const bmdma_io_reads_0[] = { > + bmdma_readb_0, > + NULL, > + NULL, > +}; > > - if (i == 0) { > - register_ioport_write(addr, 4, 1, bmdma_writeb_0, d); > - register_ioport_read(addr, 4, 1, bmdma_readb_0, d); > - } else { > - register_ioport_write(addr, 4, 1, bmdma_writeb_1, d); > - register_ioport_read(addr, 4, 1, bmdma_readb_1, d); > - } > +static IOPortWriteFunc * const bmdma_io_writes_1[] = { > + bmdma_writeb_1, > + NULL, > + NULL, > +}; > > - register_ioport_write(addr + 4, 4, 1, bmdma_addr_writeb, bm); > - register_ioport_read(addr + 4, 4, 1, bmdma_addr_readb, bm); > - register_ioport_write(addr + 4, 4, 2, bmdma_addr_writew, bm); > - register_ioport_read(addr + 4, 4, 2, bmdma_addr_readw, bm); > - register_ioport_write(addr + 4, 4, 4, bmdma_addr_writel, bm); > - register_ioport_read(addr + 4, 4, 4, bmdma_addr_readl, bm); > - addr += 8; > - } > -} > +static IOPortReadFunc * const bmdma_io_reads_1[] = { > + bmdma_readb_1, > + NULL, > + NULL, > +}; > + > +static IOPortWriteFunc * const bmdma_addr_writes[] = { > + bmdma_addr_writeb, > + bmdma_addr_writew, > + bmdma_addr_writel, > +}; > + > +static IOPortReadFunc * const bmdma_addr_reads[] = { > + bmdma_addr_readb, > + bmdma_addr_readw, > + bmdma_addr_readl, > +}; > > /* XXX: call it also when the MRDMODE is changed from the PCI config > registers */ > @@ -232,6 +238,8 @@ static int pci_cmd646_ide_initfn(PCIDevice *dev) > PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev); > uint8_t *pci_conf = d->dev.config; > qemu_irq *irq; > + unsigned int i; > + int io_index; > > pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_CMD); > pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_CMD_646); > @@ -248,11 +256,38 @@ static int pci_cmd646_ide_initfn(PCIDevice *dev) > pci_conf[0x51] |= 0x08; /* enable IDE1 */ > } > > - pci_register_bar(dev, 0, 0x8, PCI_BASE_ADDRESS_SPACE_IO, ide_map); > - pci_register_bar(dev, 1, 0x4, PCI_BASE_ADDRESS_SPACE_IO, ide_map); > - pci_register_bar(dev, 2, 0x8, PCI_BASE_ADDRESS_SPACE_IO, ide_map); > - pci_register_bar(dev, 3, 0x4, PCI_BASE_ADDRESS_SPACE_IO, ide_map); > - pci_register_bar(dev, 4, 0x10, PCI_BASE_ADDRESS_SPACE_IO, bmdma_map); > + pci_register_bar(dev, 0, 0x8, PCI_BASE_ADDRESS_SPACE_IO); > + io_index = cpu_register_io(ide_ioport_reads, ide_ioport_writes, > 8,&d->bus[0]); > + pci_bar_map(&d->dev, 0, 0, 8, 8, io_index); > + pci_register_bar(dev, 1, 0x4, PCI_BASE_ADDRESS_SPACE_IO); > + io_index = cpu_register_io(ide_status_reads, ide_cmd_writes, 1, > &d->bus[0]); > + pci_bar_map(&d->dev, 1, 0, 1, 1, io_index); > + pci_register_bar(dev, 2, 0x8, PCI_BASE_ADDRESS_SPACE_IO); > + io_index = cpu_register_io(ide_ioport_reads, ide_ioport_writes, > 8,&d->bus[1]); > + pci_bar_map(&d->dev, 2, 0, 8, 8, io_index); > + pci_register_bar(dev, 3, 0x4, PCI_BASE_ADDRESS_SPACE_IO); > + io_index = cpu_register_io(ide_status_reads, ide_cmd_writes, 1, > &d->bus[1]); > + pci_bar_map(&d->dev, 3, 0, 1, 1, io_index); > + pci_register_bar(dev, 4, 0x10, PCI_BASE_ADDRESS_SPACE_IO); > + for (i = 0; i< 2; i++) { > + BMDMAState *bm =&d->bmdma[i]; > + > + d->bus[i].bmdma = bm; > + bm->bus = d->bus+i; > + qemu_add_vm_change_state_handler(ide_dma_restart_cb, bm); > + > + if (i == 0) { > + io_index = cpu_register_io(bmdma_io_reads_0, bmdma_io_writes_0, > + 1, d); > + } else { > + io_index = cpu_register_io(bmdma_io_reads_1, bmdma_io_writes_1, > + 1, d); > + } > + pci_bar_map(&d->dev, 4, i * 4 + 0, 0, 1, io_index); > + > + io_index = cpu_register_io(bmdma_addr_reads, bmdma_addr_writes, 4, bm); > + pci_bar_map(&d->dev, 4, i * 4 + 4, 4, 4, io_index); > + } > > /* TODO: RST# value should be 0 */ > pci_conf[PCI_INTERRUPT_PIN] = 0x01; // interrupt on pin 1 > diff --git a/hw/ide/piix.c b/hw/ide/piix.c > index 9223834..0506990 100644 > --- a/hw/ide/piix.c > +++ b/hw/ide/piix.c > @@ -68,32 +68,35 @@ static void bmdma_writeb(void *opaque, uint32_t > addr, uint32_t val) > } > } > > -static void bmdma_map(PCIDevice *pci_dev, int region_num, > - pcibus_t addr, pcibus_t size, int type) > -{ > - PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, pci_dev); > - int i; > +static IOPortWriteFunc * const bmdma_cmd_io_writes[] = { > + bmdma_cmd_writeb, > + NULL, > + NULL, > +}; > > - for(i = 0;i< 2; i++) { > - BMDMAState *bm =&d->bmdma[i]; > - d->bus[i].bmdma = bm; > - bm->bus = d->bus+i; > - qemu_add_vm_change_state_handler(ide_dma_restart_cb, bm); > +static IOPortWriteFunc * const bmdma_io_writes[] = { > + bmdma_writeb, > + NULL, > + NULL, > +}; > > - register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm); > +static IOPortReadFunc * const bmdma_io_reads[] = { > + bmdma_readb, > + NULL, > + NULL, > +}; > > - register_ioport_write(addr + 1, 3, 1, bmdma_writeb, bm); > - register_ioport_read(addr, 4, 1, bmdma_readb, bm); > +static IOPortWriteFunc * const bmdma_addr_writes[] = { > + bmdma_addr_writeb, > + bmdma_addr_writew, > + bmdma_addr_writel, > +}; > > - register_ioport_write(addr + 4, 4, 1, bmdma_addr_writeb, bm); > - register_ioport_read(addr + 4, 4, 1, bmdma_addr_readb, bm); > - register_ioport_write(addr + 4, 4, 2, bmdma_addr_writew, bm); > - register_ioport_read(addr + 4, 4, 2, bmdma_addr_readw, bm); > - register_ioport_write(addr + 4, 4, 4, bmdma_addr_writel, bm); > - register_ioport_read(addr + 4, 4, 4, bmdma_addr_readl, bm); > - addr += 8; > - } > -} > +static IOPortReadFunc * const bmdma_addr_reads[] = { > + bmdma_addr_readb, > + bmdma_addr_readw, > + bmdma_addr_readl, > +}; > > static void piix3_reset(void *opaque) > { > @@ -119,6 +122,8 @@ static void piix3_reset(void *opaque) > static int pci_piix_ide_initfn(PCIIDEState *d) > { > uint8_t *pci_conf = d->dev.config; > + unsigned int i; > + int io_index; > > pci_conf[PCI_CLASS_PROG] = 0x80; // legacy ATA mode > pci_config_set_class(pci_conf, PCI_CLASS_STORAGE_IDE); > @@ -126,7 +131,22 @@ static int pci_piix_ide_initfn(PCIIDEState *d) > > qemu_register_reset(piix3_reset, d); > > - pci_register_bar(&d->dev, 4, 0x10, PCI_BASE_ADDRESS_SPACE_IO, bmdma_map); > + pci_register_bar(&d->dev, 4, 0x10, PCI_BASE_ADDRESS_SPACE_IO); > + for (i = 0; i< 2; i++) { > + BMDMAState *bm =&d->bmdma[i]; > + > + d->bus[i].bmdma = bm; > + bm->bus = d->bus + i; > + qemu_add_vm_change_state_handler(ide_dma_restart_cb, bm); > + io_index = cpu_register_io(NULL, bmdma_cmd_io_writes, 1, bm); > + pci_bar_map(&d->dev, 0, i * 4 + 0, 0, 1, io_index); > + io_index = cpu_register_io(NULL, bmdma_io_writes, 3, bm); > + pci_bar_map(&d->dev, 0, i * 4 + 1, 1, 3, io_index); > + io_index = cpu_register_io(bmdma_io_reads, NULL, 4, bm); > + pci_bar_map(&d->dev, 0, i * 4 + 2, 0, 4, io_index); > + io_index = cpu_register_io(bmdma_addr_reads, bmdma_addr_writes, 4, bm); > + pci_bar_map(&d->dev, 0, i * 4 + 3, 4, 4, io_index); > + } > > vmstate_register(&d->dev.qdev, 0,&vmstate_ide_pci, d); > > diff --git a/hw/ide/via.c b/hw/ide/via.c > index a403e8c..d2f5d00 100644 > --- a/hw/ide/via.c > +++ b/hw/ide/via.c > @@ -70,32 +70,35 @@ static void bmdma_writeb(void *opaque, uint32_t > addr, uint32_t val) > } > } > > -static void bmdma_map(PCIDevice *pci_dev, int region_num, > - pcibus_t addr, pcibus_t size, int type) > -{ > - PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, pci_dev); > - int i; > +static IOPortWriteFunc * const bmdma_cmd_io_writes[] = { > + bmdma_cmd_writeb, > + NULL, > + NULL, > +}; > > - for(i = 0;i< 2; i++) { > - BMDMAState *bm =&d->bmdma[i]; > - d->bus[i].bmdma = bm; > - bm->bus = d->bus+i; > - qemu_add_vm_change_state_handler(ide_dma_restart_cb, bm); > +static IOPortWriteFunc * const bmdma_io_writes[] = { > + bmdma_writeb, > + NULL, > + NULL, > +}; > > - register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm); > +static IOPortReadFunc * const bmdma_io_reads[] = { > + bmdma_readb, > + NULL, > + NULL, > +}; > > - register_ioport_write(addr + 1, 3, 1, bmdma_writeb, bm); > - register_ioport_read(addr, 4, 1, bmdma_readb, bm); > +static IOPortWriteFunc * const bmdma_addr_writes[] = { > + bmdma_addr_writeb, > + bmdma_addr_writew, > + bmdma_addr_writel, > +}; > > - register_ioport_write(addr + 4, 4, 1, bmdma_addr_writeb, bm); > - register_ioport_read(addr + 4, 4, 1, bmdma_addr_readb, bm); > - register_ioport_write(addr + 4, 4, 2, bmdma_addr_writew, bm); > - register_ioport_read(addr + 4, 4, 2, bmdma_addr_readw, bm); > - register_ioport_write(addr + 4, 4, 4, bmdma_addr_writel, bm); > - register_ioport_read(addr + 4, 4, 4, bmdma_addr_readl, bm); > - addr += 8; > - } > -} > +static IOPortReadFunc * const bmdma_addr_reads[] = { > + bmdma_addr_readb, > + bmdma_addr_readw, > + bmdma_addr_readl, > +}; > > static void via_reset(void *opaque) > { > @@ -144,6 +147,8 @@ static int vt82c686b_ide_initfn(PCIDevice *dev) > { > PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev);; > uint8_t *pci_conf = d->dev.config; > + unsigned int i; > + int io_index; > > pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_VIA); > pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_VIA_IDE); > @@ -154,8 +159,22 @@ static int vt82c686b_ide_initfn(PCIDevice *dev) > pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x000000c0); > > qemu_register_reset(via_reset, d); > - pci_register_bar((PCIDevice *)d, 4, 0x10, > - PCI_BASE_ADDRESS_SPACE_IO, bmdma_map); > + pci_register_bar((PCIDevice *)d, 4, 0x10, PCI_BASE_ADDRESS_SPACE_IO); > + for (i = 0; i< 2; i++) { > + BMDMAState *bm =&d->bmdma[i]; > + > + d->bus[i].bmdma = bm; > + bm->bus = d->bus + i; > + qemu_add_vm_change_state_handler(ide_dma_restart_cb, bm); > + io_index = cpu_register_io(NULL, bmdma_cmd_io_writes, 1, bm); > + pci_bar_map(&d->dev, 0, i * 4 + 0, 0, 1, io_index); > + io_index = cpu_register_io(NULL, bmdma_io_writes, 3, bm); > + pci_bar_map(&d->dev, 0, i * 4 + 1, 1, 3, io_index); > + io_index = cpu_register_io(bmdma_io_reads, NULL, 4, bm); > + pci_bar_map(&d->dev, 0, i * 4 + 2, 0, 4, io_index); > + io_index = cpu_register_io(bmdma_addr_reads, bmdma_addr_writes, 4, bm); > + pci_bar_map(&d->dev, 0, i * 4 + 3, 4, 4, io_index); > + } > > vmstate_register(&dev->qdev, 0,&vmstate_ide_pci, d); > > diff --git a/hw/isa.h b/hw/isa.h > index aaf0272..6fba4ac 100644 > --- a/hw/isa.h > +++ b/hw/isa.h > @@ -33,6 +33,7 @@ ISADevice *isa_create_simple(const char *name); > extern target_phys_addr_t isa_mem_base; > > void isa_mmio_init(target_phys_addr_t base, target_phys_addr_t size, int be); > +int pci_isa_mmio_init(int be); > > /* dma.c */ > int DMA_get_channel_mode (int nchan); > diff --git a/hw/isa_mmio.c b/hw/isa_mmio.c > index 66bdd2c..3b2de4a 100644 > --- a/hw/isa_mmio.c > +++ b/hw/isa_mmio.c > @@ -125,7 +125,7 @@ static CPUReadMemoryFunc * const isa_mmio_read_le[] = { > > static int isa_mmio_iomemtype = 0; > > -void isa_mmio_init(target_phys_addr_t base, target_phys_addr_t size, int be) > +static int isa_mmio_memtype(int be) > { > if (!isa_mmio_iomemtype) { > if (be) { > @@ -138,5 +138,18 @@ void isa_mmio_init(target_phys_addr_t base, > target_phys_addr_t size, int be) > NULL); > } > } > - cpu_register_physical_memory(base, size, isa_mmio_iomemtype); > + return isa_mmio_iomemtype; > +} > + > +void isa_mmio_init(target_phys_addr_t base, target_phys_addr_t size, int be) > +{ > + int isa; > + > + isa = isa_mmio_memtype(be); > + cpu_register_physical_memory(base, size, isa); > +} > + > +int pci_isa_mmio_init(int be) > +{ > + return isa_mmio_memtype(be); > } > diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c > index bd7b661..32de5d1 100644 > --- a/hw/lsi53c895a.c > +++ b/hw/lsi53c895a.c > @@ -186,7 +186,6 @@ typedef struct { > PCIDevice dev; > int mmio_io_addr; > int ram_io_addr; > - uint32_t script_ram_base; > > int carry; /* ??? Should this be an a visible register somewhere? */ > int sense; > @@ -390,10 +389,6 @@ static inline uint32_t read_dword(LSIState *s, > uint32_t addr) > { > uint32_t buf; > > - /* Optimize reading from SCRIPTS RAM. */ > - if ((addr& 0xffffe000) == s->script_ram_base) { > - return s->script_ram[(addr& 0x1fff)>> 2]; > - } > cpu_physical_memory_read(addr, (uint8_t *)&buf, 4); > return cpu_to_le32(buf); > } > @@ -2004,39 +1999,17 @@ static void lsi_io_writel(void *opaque, > uint32_t addr, uint32_t val) > lsi_reg_writeb(s, addr + 3, (val>> 24)& 0xff); > } > > -static void lsi_io_mapfunc(PCIDevice *pci_dev, int region_num, > - pcibus_t addr, pcibus_t size, int type) > -{ > - LSIState *s = DO_UPCAST(LSIState, dev, pci_dev); > - > - DPRINTF("Mapping IO at %08"FMT_PCIBUS"\n", addr); > - > - register_ioport_write(addr, 256, 1, lsi_io_writeb, s); > - register_ioport_read(addr, 256, 1, lsi_io_readb, s); > - register_ioport_write(addr, 256, 2, lsi_io_writew, s); > - register_ioport_read(addr, 256, 2, lsi_io_readw, s); > - register_ioport_write(addr, 256, 4, lsi_io_writel, s); > - register_ioport_read(addr, 256, 4, lsi_io_readl, s); > -} > - > -static void lsi_ram_mapfunc(PCIDevice *pci_dev, int region_num, > - pcibus_t addr, pcibus_t size, int type) > -{ > - LSIState *s = DO_UPCAST(LSIState, dev, pci_dev); > - > - DPRINTF("Mapping ram at %08"FMT_PCIBUS"\n", addr); > - s->script_ram_base = addr; > - cpu_register_physical_memory(addr + 0, 0x2000, s->ram_io_addr); > -} > - > -static void lsi_mmio_mapfunc(PCIDevice *pci_dev, int region_num, > - pcibus_t addr, pcibus_t size, int type) > -{ > - LSIState *s = DO_UPCAST(LSIState, dev, pci_dev); > +static IOPortWriteFunc * const lsi_io_writes[] = { > + lsi_io_writeb, > + lsi_io_writew, > + lsi_io_writel, > +}; > > - DPRINTF("Mapping registers at %08"FMT_PCIBUS"\n", addr); > - cpu_register_physical_memory(addr + 0, 0x400, s->mmio_io_addr); > -} > +static IOPortReadFunc * const lsi_io_reads[] = { > + lsi_io_readb, > + lsi_io_readw, > + lsi_io_readl, > +}; > > static void lsi_scsi_reset(DeviceState *dev) > { > @@ -2153,6 +2126,7 @@ static int lsi_scsi_init(PCIDevice *dev) > { > LSIState *s = DO_UPCAST(LSIState, dev, dev); > uint8_t *pci_conf; > + int io_index; > > pci_conf = s->dev.config; > > @@ -2177,12 +2151,16 @@ static int lsi_scsi_init(PCIDevice *dev) > lsi_ram_writefn, s); > > /* TODO: use dev and get rid of cast below */ > - pci_register_bar((struct PCIDevice *)s, 0, 256, > - PCI_BASE_ADDRESS_SPACE_IO, lsi_io_mapfunc); > + pci_register_bar((struct PCIDevice *)s, 0, 256, PCI_BASE_ADDRESS_SPACE_IO); > + io_index = cpu_register_io(lsi_io_reads, lsi_io_writes, 256, s); > + pci_bar_map((struct PCIDevice *)s, 0, 0, 0, 256, io_index); > + > pci_register_bar((struct PCIDevice *)s, 1, 0x400, > - PCI_BASE_ADDRESS_SPACE_MEMORY, lsi_mmio_mapfunc); > + PCI_BASE_ADDRESS_SPACE_MEMORY); > + pci_bar_map((struct PCIDevice *)s, 1, 0, 0, 0x400, s->mmio_io_addr); > pci_register_bar((struct PCIDevice *)s, 2, 0x2000, > - PCI_BASE_ADDRESS_SPACE_MEMORY, lsi_ram_mapfunc); > + PCI_BASE_ADDRESS_SPACE_MEMORY); > + pci_bar_map((struct PCIDevice *)s, 2, 0, 0, 0x2000, s->ram_io_addr); > QTAILQ_INIT(&s->queue); > > scsi_bus_new(&s->bus,&dev->qdev, 1, LSI_MAX_DEVS, lsi_command_complete); > diff --git a/hw/macio.c b/hw/macio.c > index e92e82a..653b4df 100644 > --- a/hw/macio.c > +++ b/hw/macio.c > @@ -27,83 +27,16 @@ > #include "pci.h" > #include "escc.h" > > -typedef struct macio_state_t macio_state_t; > -struct macio_state_t { > - int is_oldworld; > - int pic_mem_index; > - int dbdma_mem_index; > - int cuda_mem_index; > - int escc_mem_index; > - void *nvram; > - int nb_ide; > - int ide_mem_index[4]; > -}; > - > -static void macio_map (PCIDevice *pci_dev, int region_num, > - pcibus_t addr, pcibus_t size, int type) > -{ > - macio_state_t *macio_state; > - int i; > - > - macio_state = (macio_state_t *)(pci_dev + 1); > - if (macio_state->pic_mem_index>= 0) { > - if (macio_state->is_oldworld) { > - /* Heathrow PIC */ > - cpu_register_physical_memory(addr + 0x00000, 0x1000, > - macio_state->pic_mem_index); > - } else { > - /* OpenPIC */ > - cpu_register_physical_memory(addr + 0x40000, 0x40000, > - macio_state->pic_mem_index); > - } > - } > - if (macio_state->dbdma_mem_index>= 0) { > - cpu_register_physical_memory(addr + 0x08000, 0x1000, > - macio_state->dbdma_mem_index); > - } > - if (macio_state->escc_mem_index>= 0) { > - cpu_register_physical_memory(addr + 0x13000, ESCC_SIZE<< 4, > - macio_state->escc_mem_index); > - } > - if (macio_state->cuda_mem_index>= 0) { > - cpu_register_physical_memory(addr + 0x16000, 0x2000, > - macio_state->cuda_mem_index); > - } > - for (i = 0; i< macio_state->nb_ide; i++) { > - if (macio_state->ide_mem_index[i]>= 0) { > - cpu_register_physical_memory(addr + 0x1f000 + (i * 0x1000), 0x1000, > - macio_state->ide_mem_index[i]); > - } > - } > - if (macio_state->nvram != NULL) > - macio_nvram_map(macio_state->nvram, addr + 0x60000); > -} > - > void macio_init (PCIBus *bus, int device_id, int is_oldworld, int > pic_mem_index, > - int dbdma_mem_index, int cuda_mem_index, void *nvram, > - int nb_ide, int *ide_mem_index, int escc_mem_index) > + int dbdma_mem_index, int cuda_mem_index, int nvram_size, > + int nvram_mem_index, int nb_ide, int *ide_mem_index, > + int escc_mem_index) > { > PCIDevice *d; > - macio_state_t *macio_state; > int i; > > - d = pci_register_device(bus, "macio", > - sizeof(PCIDevice) + sizeof(macio_state_t), > - -1, NULL, NULL); > - macio_state = (macio_state_t *)(d + 1); > - macio_state->is_oldworld = is_oldworld; > - macio_state->pic_mem_index = pic_mem_index; > - macio_state->dbdma_mem_index = dbdma_mem_index; > - macio_state->cuda_mem_index = cuda_mem_index; > - macio_state->escc_mem_index = escc_mem_index; > - macio_state->nvram = nvram; > - if (nb_ide> 4) > - nb_ide = 4; > - macio_state->nb_ide = nb_ide; > - for (i = 0; i< nb_ide; i++) > - macio_state->ide_mem_index[i] = ide_mem_index[i]; > - for (; i< 4; i++) > - macio_state->ide_mem_index[i] = -1; > + d = pci_register_device(bus, "macio", sizeof(PCIDevice), -1, NULL, NULL); > + > /* Note: this code is strongly inspirated from the corresponding code > in PearPC */ > > @@ -114,6 +47,32 @@ void macio_init (PCIBus *bus, int device_id, int > is_oldworld, int pic_mem_index, > > d->config[0x3d] = 0x01; // interrupt on pin 1 > > - pci_register_bar(d, 0, 0x80000, > - PCI_BASE_ADDRESS_SPACE_MEMORY, macio_map); > + pci_register_bar(d, 0, 0x80000, PCI_BASE_ADDRESS_SPACE_MEMORY); > + if (pic_mem_index>= 0) { > + if (is_oldworld) { > + /* Heathrow PIC */ > + pci_bar_map(d, 0, 0, 0x1000, 0, pic_mem_index); > + } else { > + /* OpenPIC */ > + pci_bar_map(d, 0, 0, 0x40000, 0x40000, pic_mem_index); > + } > + } > + if (dbdma_mem_index>= 0) { > + pci_bar_map(d, 0, 1, 0x8000, 0x1000, dbdma_mem_index); > + } > + if (escc_mem_index>= 0) { > + pci_bar_map(d, 0, 2, 0x13000, ESCC_SIZE<< 4, escc_mem_index); > + } > + if (cuda_mem_index>= 0) { > + pci_bar_map(d, 0, 3, 0x16000, 0x2000, cuda_mem_index); > + } > + for (i = 0; i< nb_ide; i++) { > + if (ide_mem_index[i]>= 0) { > + pci_bar_map(d, 0, 4 + i, 0x1f000 + (i * 0x1000), 0x1000, > + ide_mem_index[i]); > + } > + } > + if (nvram_mem_index>= 0) { > + pci_bar_map(d, 0, 4 + nb_ide, 0x60000, nvram_size, nvram_mem_index); > + } > } > diff --git a/hw/ne2000.c b/hw/ne2000.c > index 78fe14f..7598e76 100644 > --- a/hw/ne2000.c > +++ b/hw/ne2000.c > @@ -464,6 +464,18 @@ uint32_t ne2000_ioport_read(void *opaque, uint32_t addr) > return ret; > } > > +static IOPortWriteFunc * const ne2000_io_writes[] = { > + ne2000_ioport_write, > + NULL, > + NULL, > +}; > + > +static IOPortReadFunc * const ne2000_io_reads[] = { > + ne2000_ioport_read, > + NULL, > + NULL, > +}; > + > static inline void ne2000_mem_writeb(NE2000State *s, uint32_t addr, > uint32_t val) > { > @@ -611,6 +623,18 @@ static uint32_t ne2000_asic_ioport_readl(void > *opaque, uint32_t addr) > return ret; > } > > +static IOPortWriteFunc * const ne2000_asic_io_writes[] = { > + ne2000_asic_ioport_write, > + ne2000_asic_ioport_write, > + ne2000_asic_ioport_writel, > +}; > + > +static IOPortReadFunc * const ne2000_asic_io_reads[] = { > + ne2000_asic_ioport_read, > + ne2000_asic_ioport_read, > + ne2000_asic_ioport_readl, > +}; > + > void ne2000_reset_ioport_write(void *opaque, uint32_t addr, uint32_t val) > { > /* nothing to do (end of reset pulse) */ > @@ -623,6 +647,18 @@ uint32_t ne2000_reset_ioport_read(void *opaque, > uint32_t addr) > return 0; > } > > +static IOPortWriteFunc * const ne2000_reset_io_writes[] = { > + ne2000_reset_ioport_write, > + NULL, > + NULL, > +}; > + > +static IOPortReadFunc * const ne2000_reset_io_reads[] = { > + ne2000_reset_ioport_read, > + NULL, > + NULL, > +}; > + > static int ne2000_post_load(void* opaque, int version_id) > { > NE2000State* s = opaque; > @@ -678,26 +714,6 @@ static const VMStateDescription vmstate_pci_ne2000 = { > /***********************************************************/ > /* PCI NE2000 definitions */ > > -static void ne2000_map(PCIDevice *pci_dev, int region_num, > - pcibus_t addr, pcibus_t size, int type) > -{ > - PCINE2000State *d = DO_UPCAST(PCINE2000State, dev, pci_dev); > - NE2000State *s =&d->ne2000; > - > - register_ioport_write(addr, 16, 1, ne2000_ioport_write, s); > - register_ioport_read(addr, 16, 1, ne2000_ioport_read, s); > - > - register_ioport_write(addr + 0x10, 1, 1, ne2000_asic_ioport_write, s); > - register_ioport_read(addr + 0x10, 1, 1, ne2000_asic_ioport_read, s); > - register_ioport_write(addr + 0x10, 2, 2, ne2000_asic_ioport_write, s); > - register_ioport_read(addr + 0x10, 2, 2, ne2000_asic_ioport_read, s); > - register_ioport_write(addr + 0x10, 4, 4, ne2000_asic_ioport_writel, s); > - register_ioport_read(addr + 0x10, 4, 4, ne2000_asic_ioport_readl, s); > - > - register_ioport_write(addr + 0x1f, 1, 1, ne2000_reset_ioport_write, s); > - register_ioport_read(addr + 0x1f, 1, 1, ne2000_reset_ioport_read, s); > -} > - > static void ne2000_cleanup(VLANClientState *nc) > { > NE2000State *s = DO_UPCAST(NICState, nc, nc)->opaque; > @@ -718,6 +734,7 @@ static int pci_ne2000_init(PCIDevice *pci_dev) > PCINE2000State *d = DO_UPCAST(PCINE2000State, dev, pci_dev); > NE2000State *s; > uint8_t *pci_conf; > + int io_index; > > pci_conf = d->dev.config; > pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_REALTEK); > @@ -727,9 +744,14 @@ static int pci_ne2000_init(PCIDevice *pci_dev) > /* TODO: RST# value should be 0. PCI spec 6.2.4 */ > pci_conf[PCI_INTERRUPT_PIN] = 1; // interrupt pin 0 > > - pci_register_bar(&d->dev, 0, 0x100, > - PCI_BASE_ADDRESS_SPACE_IO, ne2000_map); > s =&d->ne2000; > + pci_register_bar(&d->dev, 0, 0x100, PCI_BASE_ADDRESS_SPACE_IO); > + io_index = cpu_register_io(ne2000_io_reads, ne2000_io_writes, 16, s); > + pci_bar_map(&d->dev, 0, 0, 0, 16, io_index); > + io_index = cpu_register_io(ne2000_asic_io_reads, > ne2000_asic_io_writes, 4, s); > + pci_bar_map(&d->dev, 0, 1, 0x10, 4, io_index); > + io_index = cpu_register_io(ne2000_reset_io_reads, > ne2000_reset_io_writes, 1, s); > + pci_bar_map(&d->dev, 0, 2, 0x1f, 1, io_index); > s->irq = d->dev.irq[0]; > > qemu_macaddr_default_if_unset(&s->c.macaddr); > diff --git a/hw/openpic.c b/hw/openpic.c > index 2b4cb00..ed1903d 100644 > --- a/hw/openpic.c > +++ b/hw/openpic.c > @@ -1013,34 +1013,6 @@ static CPUReadMemoryFunc * const openpic_read[] = { > &openpic_readl, > }; > > -static void openpic_map(PCIDevice *pci_dev, int region_num, > - pcibus_t addr, pcibus_t size, int type) > -{ > - openpic_t *opp; > - > - DPRINTF("Map OpenPIC\n"); > - opp = (openpic_t *)pci_dev; > - /* Global registers */ > - DPRINTF("Register OPENPIC gbl %08x => %08x\n", > - addr + 0x1000, addr + 0x1000 + 0x100); > - /* Timer registers */ > - DPRINTF("Register OPENPIC timer %08x => %08x\n", > - addr + 0x1100, addr + 0x1100 + 0x40 * MAX_TMR); > - /* Interrupt source registers */ > - DPRINTF("Register OPENPIC src %08x => %08x\n", > - addr + 0x10000, addr + 0x10000 + 0x20 * (OPENPIC_EXT_IRQ + 2)); > - /* Per CPU registers */ > - DPRINTF("Register OPENPIC dst %08x => %08x\n", > - addr + 0x20000, addr + 0x20000 + 0x1000 * MAX_CPU); > - cpu_register_physical_memory(addr, 0x40000, opp->mem_index); > -#if 0 // Don't implement ISU for now > - opp_io_memory = cpu_register_io_memory(openpic_src_read, > - openpic_src_write); > - cpu_register_physical_memory(isu_base, 0x20 * (EXT_IRQ + 2), > - opp_io_memory); > -#endif > -} > - > static void openpic_save_IRQ_queue(QEMUFile* f, IRQ_queue_t *q) > { > unsigned int i; > @@ -1199,12 +1171,14 @@ qemu_irq *openpic_init (PCIBus *bus, int > *pmem_index, int nb_cpus, > > /* Register I/O spaces */ > pci_register_bar((PCIDevice *)opp, 0, 0x40000, > - PCI_BASE_ADDRESS_SPACE_MEMORY,&openpic_map); > + PCI_BASE_ADDRESS_SPACE_MEMORY); > } else { > opp = qemu_mallocz(sizeof(openpic_t)); > } > - opp->mem_index = cpu_register_io_memory(openpic_read, > - openpic_write, opp); > + opp->mem_index = cpu_register_io_memory(openpic_read, openpic_write, opp); > + if (bus) { > + pci_bar_map((PCIDevice *)opp, 0, 0, 0x40000, 0, opp->mem_index); > + } > > // isu_base&= 0xFFFC0000; > opp->nb_cpus = nb_cpus; > diff --git a/hw/pci.c b/hw/pci.c > index a7ff566..fd4b1bb 100644 > --- a/hw/pci.c > +++ b/hw/pci.c > @@ -681,19 +681,28 @@ static target_phys_addr_t pci_to_cpu_addr(PCIBus *bus, > static void pci_unregister_io_regions(PCIDevice *pci_dev) > { > PCIIORegion *r; > - int i; > + PCIIOSubRegion *s; > + int i, j; > > for(i = 0; i< PCI_NUM_REGIONS; i++) { > r =&pci_dev->io_regions[i]; > if (!r->size || r->addr == PCI_BAR_UNMAPPED) > continue; > - if (r->type == PCI_BASE_ADDRESS_SPACE_IO) { > - isa_unassign_ioport(r->addr, r->filtered_size); > - } else { > - cpu_register_physical_memory(pci_to_cpu_addr(pci_dev->bus, > - r->addr), > - r->filtered_size, > - IO_MEM_UNASSIGNED); > + > + for (j = 0; j< PCI_NUM_SUBREGIONS; j++) { > + s =&r->subregions[j]; > + > + if (!s->size) { > + continue; > + } > + if (r->type == PCI_BASE_ADDRESS_SPACE_IO) { > + isa_unassign_ioport(r->addr + s->offset, s->filtered_size); > + } else { > + cpu_register_physical_memory(pci_to_cpu_addr(pci_dev->bus, > + r->addr + s->offset), > + s->filtered_size, > + IO_MEM_UNASSIGNED); > + } > } > } > } > @@ -716,8 +725,7 @@ static int pci_unregister_device(DeviceState *dev) > } > > void pci_register_bar(PCIDevice *pci_dev, int region_num, > - pcibus_t size, int type, > - PCIMapIORegionFunc *map_func) > + pcibus_t size, int type) > { > PCIIORegion *r; > uint32_t addr; > @@ -735,9 +743,7 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num, > r =&pci_dev->io_regions[region_num]; > r->addr = PCI_BAR_UNMAPPED; > r->size = size; > - r->filtered_size = size; > r->type = type; > - r->map_func = map_func; > > wmask = ~(size - 1); > addr = pci_bar(pci_dev, region_num); > @@ -756,6 +762,23 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num, > } > } > > +void pci_bar_map(PCIDevice *pci_dev, int region_num, int subregion_num, > + pcibus_t offset, pcibus_t size, int ix) > +{ > + PCIIOSubRegion *s; > + > + if ((unsigned int)region_num>= PCI_NUM_REGIONS || > + (unsigned int)subregion_num>= PCI_NUM_SUBREGIONS) { > + return; > + } > + > + s =&pci_dev->io_regions[region_num].subregions[subregion_num]; > + > + s->offset = offset; > + s->size = size; > + s->ix = ix; > +} > + > static uint32_t pci_config_get_io_base(PCIDevice *d, > uint32_t base, uint32_t base_upper16) > { > @@ -928,8 +951,9 @@ static pcibus_t pci_bar_address(PCIDevice *d, > static void pci_update_mappings(PCIDevice *d) > { > PCIIORegion *r; > - int i; > - pcibus_t new_addr, filtered_size; > + PCIIOSubRegion *s; > + int i, j; > + pcibus_t bar_addr, new_addr, filtered_size; > > for(i = 0; i< PCI_NUM_REGIONS; i++) { > r =&d->io_regions[i]; > @@ -938,54 +962,71 @@ static void pci_update_mappings(PCIDevice *d) > if (!r->size) > continue; > > - new_addr = pci_bar_address(d, i, r->type, r->size); > + bar_addr = pci_bar_address(d, i, r->type, r->size); > > - /* bridge filtering */ > - filtered_size = r->size; > - if (new_addr != PCI_BAR_UNMAPPED) { > - pci_bridge_filter(d,&new_addr,&filtered_size, r->type); > - } > + for (j = 0; j< PCI_NUM_SUBREGIONS; j++) { > + s =&r->subregions[j]; > > - /* This bar isn't changed */ > - if (new_addr == r->addr&& filtered_size == r->filtered_size) > - continue; > + /* this region isn't registered */ > + if (!s->size) { > + continue; > + } > > - /* now do the real mapping */ > - if (r->addr != PCI_BAR_UNMAPPED) { > - if (r->type& PCI_BASE_ADDRESS_SPACE_IO) { > - int class; > - /* NOTE: specific hack for IDE in PC case: > - only one byte must be mapped. */ > - class = pci_get_word(d->config + PCI_CLASS_DEVICE); > - if (class == 0x0101&& r->size == 4) { > - isa_unassign_ioport(r->addr + 2, 1); > + new_addr = bar_addr + s->offset; > + /* bridge filtering */ > + filtered_size = s->size; > + if (bar_addr != PCI_BAR_UNMAPPED) { > + pci_bridge_filter(d,&new_addr,&filtered_size, r->type); > + } > + > + /* This bar isn't changed */ > + if (new_addr == r->addr + s->offset&& > + filtered_size == s->filtered_size) > + continue; > + > + /* now do the real mapping */ > + if (r->addr != PCI_BAR_UNMAPPED) { > + if (r->type& PCI_BASE_ADDRESS_SPACE_IO) { > + int class; > + /* NOTE: specific hack for IDE in PC case: > + only one byte must be mapped. */ > + class = pci_get_word(d->config + PCI_CLASS_DEVICE); > + if (class == 0x0101&& r->size == 4) { > + isa_unassign_ioport(r->addr + s->offset + 2, 1); > + } else { > + isa_unassign_ioport(r->addr + s->offset, > + s->filtered_size); > + } > } else { > - isa_unassign_ioport(r->addr, r->filtered_size); > + cpu_register_physical_memory(pci_to_cpu_addr(d->bus, > + r->addr + > + s->offset), > + s->filtered_size, > + IO_MEM_UNASSIGNED); > + qemu_unregister_coalesced_mmio(r->addr + s->offset, > + s->filtered_size); > } > - } else { > - cpu_register_physical_memory(pci_to_cpu_addr(d->bus, r->addr), > - r->filtered_size, > - IO_MEM_UNASSIGNED); > - qemu_unregister_coalesced_mmio(r->addr, r->filtered_size); > } > - } > - r->addr = new_addr; > - r->filtered_size = filtered_size; > - if (r->addr != PCI_BAR_UNMAPPED) { > - /* > - * TODO: currently almost all the map funcions assumes > - * filtered_size == size and addr& ~(size - 1) == addr. > - * However with bridge filtering, they aren't always true. > - * Teach them such cases, such that filtered_size< size and > - * addr& (size - 1) != 0. > - */ > - if (r->type& PCI_BASE_ADDRESS_SPACE_IO) { > - r->map_func(d, i, r->addr, r->filtered_size, r->type); > - } else { > - r->map_func(d, i, pci_to_cpu_addr(d->bus, r->addr), > - r->filtered_size, r->type); > + s->filtered_size = filtered_size; > + if (new_addr != PCI_BAR_UNMAPPED) { > + /* > + * TODO: currently almost all the map funcions assumes > + * filtered_size == size and addr& ~(size - 1) == addr. > + * However with bridge filtering, they aren't always true. > + * Teach them such cases, such that filtered_size< size and > + * addr& (size - 1) != 0. > + */ > + if (r->type& PCI_BASE_ADDRESS_SPACE_IO) { > + cpu_map_io(new_addr, s->ix); > + } else { > + cpu_register_physical_memory(pci_to_cpu_addr(d->bus, > + new_addr), > + s->filtered_size, > + s->ix); > + } > } > } > + r->addr = bar_addr; > } > } > > @@ -1704,11 +1745,6 @@ static uint8_t > pci_find_capability_list(PCIDevice *pdev, uint8_t cap_id, > return next; > } > > -static void pci_map_option_rom(PCIDevice *pdev, int region_num, > pcibus_t addr, pcibus_t size, int type) > -{ > - cpu_register_physical_memory(addr, size, pdev->rom_offset); > -} > - > /* Add an option rom for the device */ > static int pci_add_option_rom(PCIDevice *pdev) > { > @@ -1761,8 +1797,8 @@ static int pci_add_option_rom(PCIDevice *pdev) > load_image(path, ptr); > qemu_free(path); > > - pci_register_bar(pdev, PCI_ROM_SLOT, size, > - 0, pci_map_option_rom); > + pci_register_bar(pdev, PCI_ROM_SLOT, size, 0); > + pci_bar_map(pdev, PCI_ROM_SLOT, 0, 0, size, pdev->rom_offset); > > return 0; > } > diff --git a/hw/pci.h b/hw/pci.h > index 3a15bd4..3648105 100644 > --- a/hw/pci.h > +++ b/hw/pci.h > @@ -80,13 +80,21 @@ typedef void PCIMapIORegionFunc(PCIDevice > *pci_dev, int region_num, > pcibus_t addr, pcibus_t size, int type); > typedef int PCIUnregisterFunc(PCIDevice *pci_dev); > > +typedef struct PCIIOSubRegion { > + pcibus_t offset; /* offset to BAR start. -1 means not mapped */ > + pcibus_t size; > + pcibus_t filtered_size; > + int ix; > +} PCIIOSubRegion; > + > +#define PCI_NUM_SUBREGIONS 8 > + > typedef struct PCIIORegion { > pcibus_t addr; /* current PCI mapping address. -1 means not mapped */ > #define PCI_BAR_UNMAPPED (~(pcibus_t)0) > pcibus_t size; > - pcibus_t filtered_size; > uint8_t type; > - PCIMapIORegionFunc *map_func; > + PCIIOSubRegion subregions[PCI_NUM_SUBREGIONS]; > } PCIIORegion; > > #define PCI_ROM_SLOT 6 > @@ -175,8 +183,10 @@ PCIDevice *pci_register_device(PCIBus *bus, const > char *name, > PCIConfigWriteFunc *config_write); > > void pci_register_bar(PCIDevice *pci_dev, int region_num, > - pcibus_t size, int type, > - PCIMapIORegionFunc *map_func); > + pcibus_t size, int type); > + > +void pci_bar_map(PCIDevice *pci_dev, int region_num, int subregion_num, > + pcibus_t offset, pcibus_t size, int ix); > > int pci_add_capability(PCIDevice *pci_dev, uint8_t cap_id, uint8_t cap_size); > int pci_add_capability_at_offset(PCIDevice *pci_dev, uint8_t cap_id, > diff --git a/hw/pcnet.c b/hw/pcnet.c > index 5e63eb5..4782717 100644 > --- a/hw/pcnet.c > +++ b/hw/pcnet.c > @@ -1615,6 +1615,18 @@ static uint32_t pcnet_aprom_readb(void *opaque, > uint32_t addr) > return val; > } > > +static IOPortWriteFunc * const pcnet_aprom_writes[] = { > + pcnet_aprom_writeb, > + NULL, > + NULL, > +}; > + > +static IOPortReadFunc * const pcnet_aprom_reads[] = { > + pcnet_aprom_readb, > + NULL, > + NULL, > +}; > + > void pcnet_ioport_writew(void *opaque, uint32_t addr, uint32_t val) > { > PCNetState *s = opaque; > @@ -1726,24 +1738,17 @@ static uint32_t pcnet_ioport_readl(void > *opaque, uint32_t addr) > return val; > } > > -static void pcnet_ioport_map(PCIDevice *pci_dev, int region_num, > - pcibus_t addr, pcibus_t size, int type) > -{ > - PCNetState *d =&DO_UPCAST(PCIPCNetState, pci_dev, pci_dev)->state; > - > -#ifdef PCNET_DEBUG_IO > - printf("pcnet_ioport_map addr=0x%04"FMT_PCIBUS" size=0x%04"FMT_PCIBUS"\n", > - addr, size); > -#endif > - > - register_ioport_write(addr, 16, 1, pcnet_aprom_writeb, d); > - register_ioport_read(addr, 16, 1, pcnet_aprom_readb, d); > +static IOPortWriteFunc * const pcnet_ioport_writes[] = { > + NULL, > + pcnet_ioport_writew, > + pcnet_ioport_writel, > +}; > > - register_ioport_write(addr + 0x10, 0x10, 2, pcnet_ioport_writew, d); > - register_ioport_read(addr + 0x10, 0x10, 2, pcnet_ioport_readw, d); > - register_ioport_write(addr + 0x10, 0x10, 4, pcnet_ioport_writel, d); > - register_ioport_read(addr + 0x10, 0x10, 4, pcnet_ioport_readl, d); > -} > +static IOPortReadFunc * const pcnet_ioport_reads[] = { > + NULL, > + pcnet_ioport_readw, > + pcnet_ioport_readl, > +}; > > static void pcnet_mmio_writeb(void *opaque, target_phys_addr_t addr, > uint32_t val) > { > @@ -1915,19 +1920,6 @@ static CPUReadMemoryFunc * const pcnet_mmio_read[] = { > &pcnet_mmio_readl > }; > > -static void pcnet_mmio_map(PCIDevice *pci_dev, int region_num, > - pcibus_t addr, pcibus_t size, int type) > -{ > - PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev, pci_dev); > - > -#ifdef PCNET_DEBUG_IO > - printf("pcnet_mmio_map addr=0x%08"FMT_PCIBUS" 0x%08"FMT_PCIBUS"\n", > - addr, size); > -#endif > - > - cpu_register_physical_memory(addr, PCNET_PNPMMIO_SIZE, > d->state.mmio_index); > -} > - > static void pci_physical_memory_write(void *dma_opaque, > target_phys_addr_t addr, > uint8_t *buf, int len, int do_bswap) > { > @@ -1971,6 +1963,7 @@ static int pci_pcnet_init(PCIDevice *pci_dev) > PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev, pci_dev); > PCNetState *s =&d->state; > uint8_t *pci_conf; > + int io_index; > > #if 0 > printf("sizeof(RMD)=%d, sizeof(TMD)=%d\n", > @@ -2011,10 +2004,15 @@ static int pci_pcnet_init(PCIDevice *pci_dev) > > /* TODO: use pci_dev, avoid cast below. */ > pci_register_bar((PCIDevice *)d, 0, PCNET_IOPORT_SIZE, > - PCI_BASE_ADDRESS_SPACE_IO, pcnet_ioport_map); > + PCI_BASE_ADDRESS_SPACE_IO); > + io_index = cpu_register_io(pcnet_aprom_reads, pcnet_aprom_writes, 16, s); > + pci_bar_map((PCIDevice *)d, 0, 0, 0, 16, io_index); > + io_index = cpu_register_io(pcnet_ioport_reads, pcnet_ioport_writes, 16, s); > + pci_bar_map((PCIDevice *)d, 0, 1, 0x10, 16, io_index); > > pci_register_bar((PCIDevice *)d, 1, PCNET_PNPMMIO_SIZE, > - PCI_BASE_ADDRESS_SPACE_MEMORY, pcnet_mmio_map); > + PCI_BASE_ADDRESS_SPACE_MEMORY); > + pci_bar_map((PCIDevice *)d, 1, 0, 0, PCNET_PNPMMIO_SIZE, s->mmio_index); > > s->irq = pci_dev->irq[0]; > s->phys_mem_read = pci_physical_memory_read; > diff --git a/hw/ppc_mac.h b/hw/ppc_mac.h > index 89f96bb..6b3e27f 100644 > --- a/hw/ppc_mac.h > +++ b/hw/ppc_mac.h > @@ -46,8 +46,9 @@ void cuda_init (int *cuda_mem_index, qemu_irq irq); > > /* MacIO */ > void macio_init (PCIBus *bus, int device_id, int is_oldworld, int > pic_mem_index, > - int dbdma_mem_index, int cuda_mem_index, void *nvram, > - int nb_ide, int *ide_mem_index, int escc_mem_index); > + int dbdma_mem_index, int cuda_mem_index, int nvram_size, > + int nvram_mem_index, int nb_ide, int *ide_mem_index, > + int escc_mem_index); > > /* Heathrow PIC */ > qemu_irq *heathrow_pic_init(int *pmem_index, > diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c > index fbba9b6..75fef3c 100644 > --- a/hw/ppc_newworld.c > +++ b/hw/ppc_newworld.c > @@ -383,7 +383,7 @@ static void ppc_core99_init (ram_addr_t ram_size, > adb_mouse_init(&adb_bus); > > macio_init(pci_bus, PCI_DEVICE_ID_APPLE_UNI_N_KEYL, 0, pic_mem_index, > - dbdma_mem_index, cuda_mem_index, NULL, 3, ide_mem_index, > + dbdma_mem_index, cuda_mem_index, -1, 0, 3, ide_mem_index, > escc_mem_index); > > if (usb_enabled) { > diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c > index 6b3ab89..220dca7 100644 > --- a/hw/ppc_oldworld.c > +++ b/hw/ppc_oldworld.c > @@ -366,8 +366,8 @@ static void ppc_heathrow_init (ram_addr_t ram_size, > pmac_format_nvram_partition(nvr, 0x2000); > > macio_init(pci_bus, PCI_DEVICE_ID_APPLE_343S1201, 1, pic_mem_index, > - dbdma_mem_index, cuda_mem_index, nvr, 2, ide_mem_index, > - escc_mem_index); > + dbdma_mem_index, cuda_mem_index, nvram_mem_index, 0x2000, > + 2, ide_mem_index, escc_mem_index); > > if (usb_enabled) { > usb_ohci_init_pci(pci_bus, -1); > diff --git a/hw/rtl8139.c b/hw/rtl8139.c > index 72e2242..d87f3ae 100644 > --- a/hw/rtl8139.c > +++ b/hw/rtl8139.c > @@ -3269,28 +3269,17 @@ static const VMStateDescription vmstate_rtl8139 = { > /***********************************************************/ > /* PCI RTL8139 definitions */ > > -static void rtl8139_mmio_map(PCIDevice *pci_dev, int region_num, > - pcibus_t addr, pcibus_t size, int type) > -{ > - RTL8139State *s = DO_UPCAST(RTL8139State, dev, pci_dev); > - > - cpu_register_physical_memory(addr + 0, 0x100, s->rtl8139_mmio_io_addr); > -} > - > -static void rtl8139_ioport_map(PCIDevice *pci_dev, int region_num, > - pcibus_t addr, pcibus_t size, int type) > -{ > - RTL8139State *s = DO_UPCAST(RTL8139State, dev, pci_dev); > - > - register_ioport_write(addr, 0x100, 1, rtl8139_ioport_writeb, s); > - register_ioport_read( addr, 0x100, 1, rtl8139_ioport_readb, s); > - > - register_ioport_write(addr, 0x100, 2, rtl8139_ioport_writew, s); > - register_ioport_read( addr, 0x100, 2, rtl8139_ioport_readw, s); > +static IOPortWriteFunc * const rtl8139_io_writes[] = { > + rtl8139_ioport_writeb, > + rtl8139_ioport_writew, > + rtl8139_ioport_writel, > +}; > > - register_ioport_write(addr, 0x100, 4, rtl8139_ioport_writel, s); > - register_ioport_read( addr, 0x100, 4, rtl8139_ioport_readl, s); > -} > +static IOPortReadFunc * const rtl8139_io_reads[] = { > + rtl8139_ioport_readb, > + rtl8139_ioport_readw, > + rtl8139_ioport_readl, > +}; > > static CPUReadMemoryFunc * const rtl8139_mmio_read[3] = { > rtl8139_mmio_readb, > @@ -3353,6 +3342,7 @@ static int pci_rtl8139_init(PCIDevice *dev) > { > RTL8139State * s = DO_UPCAST(RTL8139State, dev, dev); > uint8_t *pci_conf; > + int io_index; > > pci_conf = s->dev.config; > pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_REALTEK); > @@ -3372,11 +3362,11 @@ static int pci_rtl8139_init(PCIDevice *dev) > s->rtl8139_mmio_io_addr = > cpu_register_io_memory(rtl8139_mmio_read, rtl8139_mmio_write, s); > > - pci_register_bar(&s->dev, 0, 0x100, > - PCI_BASE_ADDRESS_SPACE_IO, rtl8139_ioport_map); > - > - pci_register_bar(&s->dev, 1, 0x100, > - PCI_BASE_ADDRESS_SPACE_MEMORY, rtl8139_mmio_map); > + pci_register_bar(&s->dev, 0, 0x100, PCI_BASE_ADDRESS_SPACE_IO); > + io_index = cpu_register_io(rtl8139_io_reads, rtl8139_io_writes, 0x100, s); > + pci_bar_map(&s->dev, 0, 0, 0, 0x100, io_index); > + pci_register_bar(&s->dev, 1, 0x100, PCI_BASE_ADDRESS_SPACE_MEMORY); > + pci_bar_map(&s->dev, 1, 0, 0, 0x100, s->rtl8139_mmio_io_addr); > > qemu_macaddr_default_if_unset(&s->conf.macaddr); > > diff --git a/hw/sun4u.c b/hw/sun4u.c > index 2234b4e..48d89d3 100644 > --- a/hw/sun4u.c > +++ b/hw/sun4u.c > @@ -517,21 +517,6 @@ void cpu_tick_set_limit(CPUTimer *timer, uint64_t limit) > } > } > > -static void ebus_mmio_mapfunc(PCIDevice *pci_dev, int region_num, > - pcibus_t addr, pcibus_t size, int type) > -{ > - EBUS_DPRINTF("Mapping region %d registers at %" FMT_PCIBUS "\n", > - region_num, addr); > - switch (region_num) { > - case 0: > - isa_mmio_init(addr, 0x1000000, 1); > - break; > - case 1: > - isa_mmio_init(addr, 0x800000, 1); > - break; > - } > -} > - > static void dummy_isa_irq_handler(void *opaque, int n, int level) > { > } > @@ -550,6 +535,8 @@ pci_ebus_init(PCIBus *bus, int devfn) > static int > pci_ebus_init1(PCIDevice *s) > { > + int io_index; > + > isa_bus_new(&s->qdev); > > pci_config_set_vendor_id(s->config, PCI_VENDOR_ID_SUN); > @@ -564,10 +551,14 @@ pci_ebus_init1(PCIDevice *s) > s->config[0x0D] = 0x0a; // latency_timer > s->config[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type > > - pci_register_bar(s, 0, 0x1000000, PCI_BASE_ADDRESS_SPACE_MEMORY, > - ebus_mmio_mapfunc); > - pci_register_bar(s, 1, 0x800000, PCI_BASE_ADDRESS_SPACE_MEMORY, > - ebus_mmio_mapfunc); > + pci_register_bar(s, 0, 0x1000000, PCI_BASE_ADDRESS_SPACE_MEMORY); > + io_index = pci_isa_mmio_init(1); > + pci_bar_map(s, 0, 0, 0, 0x1000000, io_index); > + > + pci_register_bar(s, 1, 0x800000, PCI_BASE_ADDRESS_SPACE_MEMORY); > + io_index = pci_isa_mmio_init(1); > + pci_bar_map(s, 1, 0, 0, 0x800000, io_index); > + > return 0; > } > > diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c > index c60fd8d..343603f 100644 > --- a/hw/usb-ohci.c > +++ b/hw/usb-ohci.c > @@ -1717,13 +1717,6 @@ typedef struct { > OHCIState state; > } OHCIPCIState; > > -static void ohci_mapfunc(PCIDevice *pci_dev, int i, > - pcibus_t addr, pcibus_t size, int type) > -{ > - OHCIPCIState *ohci = DO_UPCAST(OHCIPCIState, pci_dev, pci_dev); > - cpu_register_physical_memory(addr, size, ohci->state.mem); > -} > - > static int usb_ohci_initfn_pci(struct PCIDevice *dev) > { > OHCIPCIState *ohci = DO_UPCAST(OHCIPCIState, pci_dev, dev); > @@ -1742,7 +1735,8 @@ static int usb_ohci_initfn_pci(struct PCIDevice *dev) > > /* TODO: avoid cast below by using dev */ > pci_register_bar((struct PCIDevice *)ohci, 0, 256, > - PCI_BASE_ADDRESS_SPACE_MEMORY, ohci_mapfunc); > + PCI_BASE_ADDRESS_SPACE_MEMORY); > + pci_bar_map((struct PCIDevice *)ohci, 0, 0, 256, 0, ohci->state.mem); > return 0; > } > > diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c > index 4cdb55e..b182eb5 100644 > --- a/hw/usb-uhci.c > +++ b/hw/usb-uhci.c > @@ -1088,23 +1088,22 @@ static void uhci_frame_timer(void *opaque) > qemu_mod_timer(s->frame_timer, s->expire_time); > } > > -static void uhci_map(PCIDevice *pci_dev, int region_num, > - pcibus_t addr, pcibus_t size, int type) > -{ > - UHCIState *s = (UHCIState *)pci_dev; > - > - register_ioport_write(addr, 32, 2, uhci_ioport_writew, s); > - register_ioport_read(addr, 32, 2, uhci_ioport_readw, s); > - register_ioport_write(addr, 32, 4, uhci_ioport_writel, s); > - register_ioport_read(addr, 32, 4, uhci_ioport_readl, s); > - register_ioport_write(addr, 32, 1, uhci_ioport_writeb, s); > - register_ioport_read(addr, 32, 1, uhci_ioport_readb, s); > -} > +static IOPortWriteFunc * const uhci_io_writes[] = { > + uhci_ioport_writeb, > + uhci_ioport_writew, > + uhci_ioport_writel, > +}; > + > +static IOPortReadFunc * const uhci_io_reads[] = { > + uhci_ioport_readb, > + uhci_ioport_readw, > + uhci_ioport_readl, > +}; > > static int usb_uhci_common_initfn(UHCIState *s) > { > uint8_t *pci_conf = s->dev.config; > - int i; > + int i, io_index; > > pci_conf[PCI_REVISION_ID] = 0x01; // revision number > pci_conf[PCI_CLASS_PROG] = 0x00; > @@ -1127,9 +1126,9 @@ static int usb_uhci_common_initfn(UHCIState *s) > > /* Use region 4 for consistency with real hardware. BSD guests seem > to rely on this. */ > - pci_register_bar(&s->dev, 4, 0x20, > - PCI_BASE_ADDRESS_SPACE_IO, uhci_map); > - > + pci_register_bar(&s->dev, 4, 0x20, PCI_BASE_ADDRESS_SPACE_IO); > + io_index = cpu_register_io(uhci_io_reads, uhci_io_writes, 32, s); > + pci_bar_map(&s->dev, 4, 0, 0, 0x20, io_index); > return 0; > } > > diff --git a/hw/vga-pci.c b/hw/vga-pci.c > index eef78ed..818e77f 100644 > --- a/hw/vga-pci.c > +++ b/hw/vga-pci.c > @@ -47,21 +47,6 @@ static const VMStateDescription vmstate_vga_pci = { > } > }; > > -static void vga_map(PCIDevice *pci_dev, int region_num, > - pcibus_t addr, pcibus_t size, int type) > -{ > - PCIVGAState *d = (PCIVGAState *)pci_dev; > - VGACommonState *s =&d->vga; > - if (region_num == PCI_ROM_SLOT) { > - cpu_register_physical_memory(addr, s->bios_size, s->bios_offset); > - } else { > - cpu_register_physical_memory(addr, s->vram_size, s->vram_offset); > - s->map_addr = addr; > - s->map_end = addr + s->vram_size; > - vga_dirty_log_start(s); > - } > -} > - > static void pci_vga_write_config(PCIDevice *d, > uint32_t address, uint32_t val, int len) > { > @@ -93,8 +78,8 @@ static int pci_vga_initfn(PCIDevice *dev) > pci_conf[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type > > /* XXX: VGA_RAM_SIZE must be a power of two */ > - pci_register_bar(&d->dev, 0, VGA_RAM_SIZE, > - PCI_BASE_ADDRESS_MEM_PREFETCH, vga_map); > + pci_register_bar(&d->dev, 0, VGA_RAM_SIZE, PCI_BASE_ADDRESS_MEM_PREFETCH); > + pci_bar_map(&d->dev, 0, 0, 0, s->vram_size, s->vram_offset); > > if (s->bios_size) { > unsigned int bios_total_size; > @@ -103,7 +88,8 @@ static int pci_vga_initfn(PCIDevice *dev) > while (bios_total_size< s->bios_size) > bios_total_size<<= 1; > pci_register_bar(&d->dev, PCI_ROM_SLOT, bios_total_size, > - PCI_BASE_ADDRESS_MEM_PREFETCH, vga_map); > + PCI_BASE_ADDRESS_MEM_PREFETCH); > + pci_bar_map(&d->dev, PCI_ROM_SLOT, 0, 0, s->bios_size, s->bios_offset); > } > > vga_init_vbe(s); > diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c > index c6ef825..415acfc 100644 > --- a/hw/virtio-pci.c > +++ b/hw/virtio-pci.c > @@ -374,25 +374,17 @@ static void virtio_pci_config_writel(void > *opaque, uint32_t addr, uint32_t val) > virtio_config_writel(proxy->vdev, addr, val); > } > > -static void virtio_map(PCIDevice *pci_dev, int region_num, > - pcibus_t addr, pcibus_t size, int type) > -{ > - VirtIOPCIProxy *proxy = container_of(pci_dev, VirtIOPCIProxy, pci_dev); > - VirtIODevice *vdev = proxy->vdev; > - unsigned config_len = VIRTIO_PCI_REGION_SIZE(pci_dev) + vdev->config_len; > - > - proxy->addr = addr; > - > - register_ioport_write(addr, config_len, 1, > virtio_pci_config_writeb, proxy); > - register_ioport_write(addr, config_len, 2, > virtio_pci_config_writew, proxy); > - register_ioport_write(addr, config_len, 4, > virtio_pci_config_writel, proxy); > - register_ioport_read(addr, config_len, 1, virtio_pci_config_readb, proxy); > - register_ioport_read(addr, config_len, 2, virtio_pci_config_readw, proxy); > - register_ioport_read(addr, config_len, 4, virtio_pci_config_readl, proxy); > +static IOPortWriteFunc * const virtio_pci_config_io_writes[] = { > + virtio_pci_config_writeb, > + virtio_pci_config_writew, > + virtio_pci_config_writel, > +}; > > - if (vdev->config_len) > - vdev->get_config(vdev, vdev->config); > -} > +static IOPortReadFunc * const virtio_pci_config_io_reads[] = { > + virtio_pci_config_readb, > + virtio_pci_config_readw, > + virtio_pci_config_readl, > +}; > > static void virtio_write_config(PCIDevice *pci_dev, uint32_t address, > uint32_t val, int len) > @@ -495,6 +487,7 @@ static void virtio_init_pci(VirtIOPCIProxy *proxy, > VirtIODevice *vdev, > { > uint8_t *config; > uint32_t size; > + int io_index; > > proxy->vdev = vdev; > > @@ -518,8 +511,7 @@ static void virtio_init_pci(VirtIOPCIProxy *proxy, > VirtIODevice *vdev, > if (vdev->nvectors&& !msix_init(&proxy->pci_dev, vdev->nvectors, 1, 0)) { > pci_register_bar(&proxy->pci_dev, 1, > msix_bar_size(&proxy->pci_dev), > - PCI_BASE_ADDRESS_SPACE_MEMORY, > - msix_mmio_map); > + PCI_BASE_ADDRESS_SPACE_MEMORY); > } else > vdev->nvectors = 0; > > @@ -529,8 +521,11 @@ static void virtio_init_pci(VirtIOPCIProxy > *proxy, VirtIODevice *vdev, > if (size& (size-1)) > size = 1<< qemu_fls(size); > > - pci_register_bar(&proxy->pci_dev, 0, size, PCI_BASE_ADDRESS_SPACE_IO, > - virtio_map); > + pci_register_bar(&proxy->pci_dev, 0, size, PCI_BASE_ADDRESS_SPACE_IO); > + io_index = cpu_register_io(virtio_pci_config_io_reads, > + virtio_pci_config_io_writes, > + size,&proxy->pci_dev); > + pci_bar_map(&proxy->pci_dev, 0, 0, 0, size, io_index); > > virtio_bind_device(vdev,&virtio_pci_bindings, proxy); > proxy->host_features |= 0x1<< VIRTIO_F_NOTIFY_ON_EMPTY; > diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c > index 9e72d2e..bf5f075 100644 > --- a/hw/vmware_vga.c > +++ b/hw/vmware_vga.c > @@ -1178,65 +1178,47 @@ static void vmsvga_init(struct vmsvga_state_s > *s, int vga_ram_size) > vmsvga_reset(s); > } > > -static void pci_vmsvga_map_ioport(PCIDevice *pci_dev, int region_num, > - pcibus_t addr, pcibus_t size, int type) > -{ > - struct pci_vmsvga_state_s *d = (struct pci_vmsvga_state_s *) pci_dev; > - struct vmsvga_state_s *s =&d->chip; > - > - register_ioport_read(addr + SVGA_IO_MUL * SVGA_INDEX_PORT, > - 1, 4, vmsvga_index_read, s); > - register_ioport_write(addr + SVGA_IO_MUL * SVGA_INDEX_PORT, > - 1, 4, vmsvga_index_write, s); > - register_ioport_read(addr + SVGA_IO_MUL * SVGA_VALUE_PORT, > - 1, 4, vmsvga_value_read, s); > - register_ioport_write(addr + SVGA_IO_MUL * SVGA_VALUE_PORT, > - 1, 4, vmsvga_value_write, s); > - register_ioport_read(addr + SVGA_IO_MUL * SVGA_BIOS_PORT, > - 1, 4, vmsvga_bios_read, s); > - register_ioport_write(addr + SVGA_IO_MUL * SVGA_BIOS_PORT, > - 1, 4, vmsvga_bios_write, s); > -} > +static IOPortWriteFunc * const vmsvga_index_io_writes[] = { > + NULL, > + NULL, > + vmsvga_index_write, > +}; > > -static void pci_vmsvga_map_mem(PCIDevice *pci_dev, int region_num, > - pcibus_t addr, pcibus_t size, int type) > -{ > - struct pci_vmsvga_state_s *d = (struct pci_vmsvga_state_s *) pci_dev; > - struct vmsvga_state_s *s =&d->chip; > - ram_addr_t iomemtype; > +static IOPortReadFunc * const vmsvga_index_io_reads[] = { > + NULL, > + NULL, > + vmsvga_index_read, > +}; > > - s->vram_base = addr; > -#ifdef DIRECT_VRAM > - iomemtype = cpu_register_io_memory(vmsvga_vram_read, > - vmsvga_vram_write, s); > -#else > - iomemtype = s->vga.vram_offset | IO_MEM_RAM; > -#endif > - cpu_register_physical_memory(s->vram_base, s->vga.vram_size, > - iomemtype); > +static IOPortWriteFunc * const vmsvga_value_io_writes[] = { > + NULL, > + NULL, > + vmsvga_value_write, > +}; > > - s->vga.map_addr = addr; > - s->vga.map_end = addr + s->vga.vram_size; > - vga_dirty_log_restart(&s->vga); > -} > +static IOPortReadFunc * const vmsvga_value_io_reads[] = { > + NULL, > + NULL, > + vmsvga_value_read, > +}; > > -static void pci_vmsvga_map_fifo(PCIDevice *pci_dev, int region_num, > - pcibus_t addr, pcibus_t size, int type) > -{ > - struct pci_vmsvga_state_s *d = (struct pci_vmsvga_state_s *) pci_dev; > - struct vmsvga_state_s *s =&d->chip; > - ram_addr_t iomemtype; > +static IOPortWriteFunc * const vmsvga_bios_io_writes[] = { > + NULL, > + NULL, > + vmsvga_bios_write, > +}; > > - s->fifo_base = addr; > - iomemtype = s->fifo_offset | IO_MEM_RAM; > - cpu_register_physical_memory(s->fifo_base, s->fifo_size, > - iomemtype); > -} > +static IOPortReadFunc * const vmsvga_bios_io_reads[] = { > + NULL, > + NULL, > + vmsvga_bios_read, > +}; > > static int pci_vmsvga_initfn(PCIDevice *dev) > { > struct pci_vmsvga_state_s *s = > DO_UPCAST(struct pci_vmsvga_state_s, card, dev); > + ram_addr_t iomemtype; > > pci_config_set_vendor_id(s->card.config, PCI_VENDOR_ID_VMWARE); > pci_config_set_device_id(s->card.config, SVGA_PCI_DEVICE_ID); > @@ -1253,16 +1235,33 @@ static int pci_vmsvga_initfn(PCIDevice *dev) > s->card.config[PCI_SUBSYSTEM_ID + 1] = SVGA_PCI_DEVICE_ID>> 8; > s->card.config[PCI_INTERRUPT_LINE] = 0xff; /* End */ > > - pci_register_bar(&s->card, 0, 0x10, > - PCI_BASE_ADDRESS_SPACE_IO, pci_vmsvga_map_ioport); > + pci_register_bar(&s->card, 0, 0x10, PCI_BASE_ADDRESS_SPACE_IO); > + iomemtype = cpu_register_io(vmsvga_index_io_reads, vmsvga_index_io_writes, > + 4,&s->card); > + pci_bar_map(&s->card, 0, 0, SVGA_IO_MUL * SVGA_INDEX_PORT, 4, iomemtype); > + iomemtype = cpu_register_io(vmsvga_value_io_reads, vmsvga_value_io_writes, > + 4,&s->card); > + pci_bar_map(&s->card, 0, 0, SVGA_IO_MUL * SVGA_VALUE_PORT, 4, iomemtype); > + iomemtype = cpu_register_io(vmsvga_bios_io_reads, vmsvga_bios_io_writes, > + 4,&s->card); > + pci_bar_map(&s->card, 0, 0, SVGA_IO_MUL * SVGA_BIOS_PORT, 4, iomemtype); > pci_register_bar(&s->card, 1, VGA_RAM_SIZE, > - PCI_BASE_ADDRESS_MEM_PREFETCH, pci_vmsvga_map_mem); > - > + PCI_BASE_ADDRESS_MEM_PREFETCH); > pci_register_bar(&s->card, 2, SVGA_FIFO_SIZE, > - PCI_BASE_ADDRESS_MEM_PREFETCH, pci_vmsvga_map_fifo); > + PCI_BASE_ADDRESS_MEM_PREFETCH); > > vmsvga_init(&s->chip, VGA_RAM_SIZE); > > +#ifdef DIRECT_VRAM > + iomemtype = cpu_register_io_memory(vmsvga_vram_read, > + vmsvga_vram_write, s); > +#else > + iomemtype = s->chip.vga.vram_offset | IO_MEM_RAM; > +#endif > + pci_bar_map(&s->card, 1, 0, 0, s->chip.vga.vram_size, iomemtype); > + iomemtype = s->chip.fifo_offset | IO_MEM_RAM; > + pci_bar_map(&s->card, 2, 0, 0, s->chip.fifo_size, iomemtype); > + > return 0; > } > > diff --git a/hw/wdt_i6300esb.c b/hw/wdt_i6300esb.c > index be0e89e..4c5bb32 100644 > --- a/hw/wdt_i6300esb.c > +++ b/hw/wdt_i6300esb.c > @@ -342,29 +342,17 @@ static void i6300esb_mem_writel(void *vp, > target_phys_addr_t addr, uint32_t val) > } > } > > -static void i6300esb_map(PCIDevice *dev, int region_num, > - pcibus_t addr, pcibus_t size, int type) > -{ > - static CPUReadMemoryFunc * const mem_read[3] = { > - i6300esb_mem_readb, > - i6300esb_mem_readw, > - i6300esb_mem_readl, > - }; > - static CPUWriteMemoryFunc * const mem_write[3] = { > - i6300esb_mem_writeb, > - i6300esb_mem_writew, > - i6300esb_mem_writel, > - }; > - I6300State *d = DO_UPCAST(I6300State, dev, dev); > - int io_mem; > - > - i6300esb_debug("addr = %"FMT_PCIBUS", size = %"FMT_PCIBUS", type = %d\n", > - addr, size, type); > +static CPUReadMemoryFunc * const mem_read[3] = { > + i6300esb_mem_readb, > + i6300esb_mem_readw, > + i6300esb_mem_readl, > +}; > > - io_mem = cpu_register_io_memory(mem_read, mem_write, d); > - cpu_register_physical_memory (addr, 0x10, io_mem); > - /* qemu_register_coalesced_mmio (addr, 0x10); ? */ > -} > +static CPUWriteMemoryFunc * const mem_write[3] = { > + i6300esb_mem_writeb, > + i6300esb_mem_writew, > + i6300esb_mem_writel, > +}; > > static const VMStateDescription vmstate_i6300esb = { > .name = "i6300esb_wdt", > @@ -393,6 +381,7 @@ static int i6300esb_init(PCIDevice *dev) > { > I6300State *d = DO_UPCAST(I6300State, dev, dev); > uint8_t *pci_conf; > + int io_mem; > > d->reboot_enabled = 1; > d->clock_scale = CLOCK_SCALE_1KHZ; > @@ -413,8 +402,9 @@ static int i6300esb_init(PCIDevice *dev) > pci_config_set_class(pci_conf, PCI_CLASS_SYSTEM_OTHER); > pci_conf[PCI_HEADER_TYPE] = 0x00; > > - pci_register_bar(&d->dev, 0, 0x10, > - PCI_BASE_ADDRESS_SPACE_MEMORY, i6300esb_map); > + pci_register_bar(&d->dev, 0, 0x10, PCI_BASE_ADDRESS_SPACE_MEMORY); > + io_mem = cpu_register_io_memory(mem_read, mem_write, d); > + pci_bar_map(&d->dev, 0, 0, 0, 0x10, io_mem); > > return 0; > } > diff --git a/ioport.c b/ioport.c > index 53dd87a..90fec90 100644 > --- a/ioport.c > +++ b/ioport.c > @@ -54,29 +54,39 @@ static IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS]; > static IOPortReadFunc default_ioport_readb, default_ioport_readw, > default_ioport_readl; > static IOPortWriteFunc default_ioport_writeb, default_ioport_writew, > default_ioport_writel; > > +#define IO_NB_ENTRIES 256 > + > +static IOPortWriteFunc *io_writes[IO_NB_ENTRIES][3]; > +static IOPortReadFunc *io_reads[IO_NB_ENTRIES][3]; > +static void *io_opaques[IO_NB_ENTRIES]; > +static int io_sizes[IO_NB_ENTRIES]; > +static char io_used[IO_NB_ENTRIES]; > + > +static IOPortReadFunc * const default_read_func[3] = { > + default_ioport_readb, > + default_ioport_readw, > + default_ioport_readl > +}; > + > static uint32_t ioport_read(int index, uint32_t address) > { > - static IOPortReadFunc * const default_func[3] = { > - default_ioport_readb, > - default_ioport_readw, > - default_ioport_readl > - }; > IOPortReadFunc *func = ioport_read_table[index][address]; > if (!func) > - func = default_func[index]; > + func = default_read_func[index]; > return func(ioport_opaque[address], address); > } > > +static IOPortWriteFunc * const default_write_func[3] = { > + default_ioport_writeb, > + default_ioport_writew, > + default_ioport_writel > +}; > + > static void ioport_write(int index, uint32_t address, uint32_t data) > { > - static IOPortWriteFunc * const default_func[3] = { > - default_ioport_writeb, > - default_ioport_writew, > - default_ioport_writel > - }; > IOPortWriteFunc *func = ioport_write_table[index][address]; > if (!func) > - func = default_func[index]; > + func = default_write_func[index]; > func(ioport_opaque[address], address, data); > } > > @@ -173,6 +183,86 @@ int register_ioport_write(pio_addr_t start, int > length, int size, > return 0; > } > > +static int get_free_io_mem_idx(void) > +{ > + int i; > + > + for (i = 0; i< IO_NB_ENTRIES; i++) { > + if (!io_used[i]) { > + io_used[i] = 1; > + return i; > + } > + } > + fprintf(stderr, "RAN out out io_mem_idx, max %d !\n", IO_NB_ENTRIES); > + return -1; > +} > + > +/* io_read and io_write are arrays of functions containing the > + function to access byte (index 0), word (index 1) and dword (index > + 2). Functions can be omitted with a NULL function pointer. (-1) is > + returned if error. */ > +int cpu_register_io(IOPortReadFunc * const *io_read, > + IOPortWriteFunc * const *io_write, > + int size, void *opaque) > +{ > + unsigned int i; > + int io_index; > + > + io_index = get_free_io_mem_idx(); > + if (io_index == -1) { > + return io_index; > + } > + > + if (io_read) { > + for (i = 0; i< 3; ++i) { > + io_reads[io_index][i] = io_read[i]; > + } > + } > + if (io_write) { > + for (i = 0; i< 3; ++i) { > + io_writes[io_index][i] = io_write[i]; > + } > + } > + io_opaques[io_index] = opaque; > + io_sizes[io_index] = size; > + > + return io_index; > +} > + > +void cpu_unregister_io(int io_index) > +{ > + unsigned int i; > + > + for (i = 0; i< 3; i++) { > + io_reads[io_index][i] = NULL; > + io_writes[io_index][i] = NULL; > + } > + io_opaques[io_index] = NULL; > + io_sizes[io_index] = 0; > + io_used[io_index] = 0; > +} > + > +void cpu_map_io(pio_addr_t start, int io_index) > +{ > + unsigned int i, j; > + > + assert(io_index>= 0); > + for (i = start; i< start + io_sizes[io_index]; i++) { > + for (j = 0; j< 3; j++) { > + if (io_reads[io_index][j]) { > + register_ioport_read(i, io_sizes[io_index], 1<< j, > + io_reads[io_index][j], > + io_opaques[io_index]); > + } > + if (io_writes[io_index][j]) { > + register_ioport_write(i, io_sizes[io_index], 1<< j, > + io_writes[io_index][j], > + io_opaques[io_index]); > + } > + } > + } > +} > + > void isa_unassign_ioport(pio_addr_t start, int length) > { > int i; > @@ -190,6 +280,11 @@ void isa_unassign_ioport(pio_addr_t start, int length) > } > } > > +void cpu_unmap_io(pio_addr_t start, int io_index) > +{ > + isa_unassign_ioport(start, io_sizes[io_index]); > +} > + > /***********************************************************/ > > void cpu_outb(pio_addr_t addr, uint8_t val) > diff --git a/ioport.h b/ioport.h > index 3d3c8a3..4ba78ed 100644 > --- a/ioport.h > +++ b/ioport.h > @@ -40,6 +40,12 @@ int register_ioport_read(pio_addr_t start, int > length, int size, > IOPortReadFunc *func, void *opaque); > int register_ioport_write(pio_addr_t start, int length, int size, > IOPortWriteFunc *func, void *opaque); > +int cpu_register_io(IOPortReadFunc * const *io_read, > + IOPortWriteFunc * const *io_write, > + int size, void *opaque); > +void cpu_unregister_io(int io_index); > +void cpu_map_io(pio_addr_t start, int io_index); > +void cpu_unmap_io(pio_addr_t start, int io_index); > void isa_unassign_ioport(pio_addr_t start, int length); > > >
On Wed, Jul 7, 2010 at 6:15 PM, malc <av1474@comtv.ru> wrote: > On Wed, 7 Jul 2010, Blue Swirl wrote: > >> Add I/O port registration functions which separate registration >> from the mapping stage. > > Why? So that the device code can specify all other parameters except for the I/O port, which will be handled by PCI BAR mappings.
On Wed, Jul 7, 2010 at 7:02 PM, Anthony Liguori <anthony@codemonkey.ws> wrote: > On 07/07/2010 12:53 PM, Blue Swirl wrote: >> >> Add I/O port registration functions which separate registration >> from the mapping stage. >> >> Move IOIO and MMIO BAR mapping to pci.c. >> >> TODO: fix dirty logging, coalesced MMIO and base address comparisons >> (eepro100 etc). Bridge filtering may be broken. Broke virtio-pci and MSIX. >> >> Signed-off-by: Blue Swirl<blauwirbel@gmail.com> >> --- >> i386 boots but resets. PPC and Sparc64 can't even start. >> >> Patch also available at >> git://repo.or.cz/qemu/blueswirl.git >> >> It may be worthwhile to break this into some kind of smaller steps. >> >>  hw/ac97.c     |  60 +++++++++++--------- >>  hw/cirrus_vga.c  |  40 +++----------- >>  hw/e1000.c     |  37 +----------- >>  hw/eepro100.c   |  77 ++++++++++---------------- >>  hw/es1370.c    |  32 +++++------ >>  hw/ide/cmd646.c  |  149 >> +++++++++++++++++++++++++++++++------------------- >>  hw/ide/piix.c   |  74 ++++++++++++++++--------- >>  hw/ide/via.c    |  67 ++++++++++++++-------- >>  hw/isa.h      |   1 + >>  hw/isa_mmio.c   |  17 +++++- >>  hw/lsi53c895a.c  |  60 ++++++-------------- >>  hw/macio.c     |  107 +++++++++++------------------------- >>  hw/ne2000.c    |  66 +++++++++++++++------- >>  hw/openpic.c    |  36 ++---------- >>  hw/pci.c      |  158 >> ++++++++++++++++++++++++++++++++-------------------- >>  hw/pci.h      |  18 +++++- >>  hw/pcnet.c     |  62 ++++++++++----------- >>  hw/ppc_mac.h    |   5 +- >>  hw/ppc_newworld.c |   2 +- >>  hw/ppc_oldworld.c |   4 +- >>  hw/rtl8139.c    |  42 +++++--------- >>  hw/sun4u.c     |  29 +++------ >>  hw/usb-ohci.c   |  10 +--- >>  hw/usb-uhci.c   |  31 +++++----- >>  hw/vga-pci.c    |  22 +------ >>  hw/virtio-pci.c  |  39 ++++++------- >>  hw/vmware_vga.c  |  107 ++++++++++++++++++------------------ >>  hw/wdt_i6300esb.c |  38 +++++-------- >>  ioport.c      |  119 ++++++++++++++++++++++++++++++++++++---- >>  ioport.h      |   6 ++ >>  30 files changed, 778 insertions(+), 737 deletions(-) >> >> diff --git a/hw/ac97.c b/hw/ac97.c >> index 4319bc8..28d0c19 100644 >> --- a/hw/ac97.c >> +++ b/hw/ac97.c >> @@ -1234,31 +1234,29 @@ static const VMStateDescription vmstate_ac97 = { >>    } >>  }; >> >> -static void ac97_map (PCIDevice *pci_dev, int region_num, >> -            pcibus_t addr, pcibus_t size, int type) >> -{ >> -   AC97LinkState *s = DO_UPCAST (AC97LinkState, dev, pci_dev); >> -   PCIDevice *d =&s->dev; >> - >> -   if (!region_num) { >> -     s->base[0] = addr; >> -     register_ioport_read (addr, 256 * 1, 1, nam_readb, d); >> -     register_ioport_read (addr, 256 * 2, 2, nam_readw, d); >> -     register_ioport_read (addr, 256 * 4, 4, nam_readl, d); >> -     register_ioport_write (addr, 256 * 1, 1, nam_writeb, d); >> -     register_ioport_write (addr, 256 * 2, 2, nam_writew, d); >> -     register_ioport_write (addr, 256 * 4, 4, nam_writel, d); >> -   } >> -   else { >> -     s->base[1] = addr; >> -     register_ioport_read (addr, 64 * 1, 1, nabm_readb, d); >> -     register_ioport_read (addr, 64 * 2, 2, nabm_readw, d); >> -     register_ioport_read (addr, 64 * 4, 4, nabm_readl, d); >> -     register_ioport_write (addr, 64 * 1, 1, nabm_writeb, d); >> -     register_ioport_write (addr, 64 * 2, 2, nabm_writew, d); >> -     register_ioport_write (addr, 64 * 4, 4, nabm_writel, d); >> -   } >> -} >> +static IOPortWriteFunc * const nam_writes[] = { >> +   nam_writeb, >> +   nam_writew, >> +   nam_writel, >> +}; >> + >> +static IOPortReadFunc * const nam_reads[] = { >> +   nam_readb, >> +   nam_readw, >> +   nam_readl, >> +}; >> + >> +static IOPortWriteFunc * const nabm_writes[] = { >> +   nabm_writeb, >> +   nabm_writew, >> +   nabm_writel, >> +}; >> + >> +static IOPortReadFunc * const nabm_reads[] = { >> +   nabm_readb, >> +   nabm_readw, >> +   nabm_readl, >> +}; >> >>  static void ac97_on_reset (void *opaque) >>  { >> @@ -1280,6 +1278,7 @@ static int ac97_initfn (PCIDevice *dev) >>  { >>    AC97LinkState *s = DO_UPCAST (AC97LinkState, dev, dev); >>    uint8_t *c = s->dev.config; >> +   int io_index; >> >>    pci_config_set_vendor_id (c, PCI_VENDOR_ID_INTEL); /* ro */ >>    pci_config_set_device_id (c, PCI_DEVICE_ID_INTEL_82801AA_5); /* ro */ >> @@ -1321,9 +1320,14 @@ static int ac97_initfn (PCIDevice *dev) >>    /* TODO: RST# value should be 0. */ >>    c[PCI_INTERRUPT_PIN] = 0x01;    /* intr_pn interrupt pin ro */ >> >> -   pci_register_bar (&s->dev, 0, 256 * 4, PCI_BASE_ADDRESS_SPACE_IO, >> -            ac97_map); >> -   pci_register_bar (&s->dev, 1, 64 * 4, PCI_BASE_ADDRESS_SPACE_IO, >> ac97_map); >> +   pci_register_bar(&s->dev, 0, 256 * 4, PCI_BASE_ADDRESS_SPACE_IO); >> +   io_index = cpu_register_io(nam_reads, nam_writes, 256 * 4, s); >> +   pci_bar_map(&s->dev, 0, 0, 0, 256 * 4, io_index); >> + >> +   pci_register_bar(&s->dev, 1, 64 * 4, PCI_BASE_ADDRESS_SPACE_IO); >> +   io_index = cpu_register_io(nabm_reads, nabm_writes, 64 * 4, s); >> +   pci_bar_map(&s->dev, 1, 0, 0, 64 * 4, io_index); >> > > Any reason to keep this a three step process?  I see no reason not to unify > the io and mem function pointers into a single type. I was also considering this, but the function signatures don't match now. With a lot more effort (or smaller steps) it could be doable. > These callbacks should > be working off of pci bus addresses and should not be tied directly to CPU > memory/pio callbacks. The CPU callbacks may be useful outside of PCI code, like ISA.
diff --git a/hw/ac97.c b/hw/ac97.c index 4319bc8..28d0c19 100644 --- a/hw/ac97.c +++ b/hw/ac97.c @@ -1234,31 +1234,29 @@ static const VMStateDescription vmstate_ac97 = { } }; -static void ac97_map (PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - AC97LinkState *s = DO_UPCAST (AC97LinkState, dev, pci_dev); - PCIDevice *d = &s->dev; - - if (!region_num) { - s->base[0] = addr; - register_ioport_read (addr, 256 * 1, 1, nam_readb, d); - register_ioport_read (addr, 256 * 2, 2, nam_readw, d); - register_ioport_read (addr, 256 * 4, 4, nam_readl, d); - register_ioport_write (addr, 256 * 1, 1, nam_writeb, d); - register_ioport_write (addr, 256 * 2, 2, nam_writew, d); - register_ioport_write (addr, 256 * 4, 4, nam_writel, d); - } - else { - s->base[1] = addr; - register_ioport_read (addr, 64 * 1, 1, nabm_readb, d); - register_ioport_read (addr, 64 * 2, 2, nabm_readw, d); - register_ioport_read (addr, 64 * 4, 4, nabm_readl, d); - register_ioport_write (addr, 64 * 1, 1, nabm_writeb, d); - register_ioport_write (addr, 64 * 2, 2, nabm_writew, d); - register_ioport_write (addr, 64 * 4, 4, nabm_writel, d); - } -} +static IOPortWriteFunc * const nam_writes[] = { + nam_writeb, + nam_writew, + nam_writel, +}; + +static IOPortReadFunc * const nam_reads[] = { + nam_readb, + nam_readw, + nam_readl, +}; + +static IOPortWriteFunc * const nabm_writes[] = { + nabm_writeb, + nabm_writew, + nabm_writel, +}; + +static IOPortReadFunc * const nabm_reads[] = { + nabm_readb, + nabm_readw, + nabm_readl, +}; static void ac97_on_reset (void *opaque) { @@ -1280,6 +1278,7 @@ static int ac97_initfn (PCIDevice *dev) { AC97LinkState *s = DO_UPCAST (AC97LinkState, dev, dev); uint8_t *c = s->dev.config; + int io_index; pci_config_set_vendor_id (c, PCI_VENDOR_ID_INTEL); /* ro */ pci_config_set_device_id (c, PCI_DEVICE_ID_INTEL_82801AA_5); /* ro */ @@ -1321,9 +1320,14 @@ static int ac97_initfn (PCIDevice *dev) /* TODO: RST# value should be 0. */ c[PCI_INTERRUPT_PIN] = 0x01; /* intr_pn interrupt pin ro */ - pci_register_bar (&s->dev, 0, 256 * 4, PCI_BASE_ADDRESS_SPACE_IO, - ac97_map); - pci_register_bar (&s->dev, 1, 64 * 4, PCI_BASE_ADDRESS_SPACE_IO, ac97_map); + pci_register_bar(&s->dev, 0, 256 * 4, PCI_BASE_ADDRESS_SPACE_IO); + io_index = cpu_register_io(nam_reads, nam_writes, 256 * 4, s); + pci_bar_map(&s->dev, 0, 0, 0, 256 * 4, io_index); + + pci_register_bar(&s->dev, 1, 64 * 4, PCI_BASE_ADDRESS_SPACE_IO); + io_index = cpu_register_io(nabm_reads, nabm_writes, 64 * 4, s); + pci_bar_map(&s->dev, 1, 0, 0, 64 * 4, io_index); + qemu_register_reset (ac97_on_reset, s); AUD_register_card ("ac97", &s->card); ac97_on_reset (s); diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c index bbd4b08..829d837 100644 --- a/hw/cirrus_vga.c +++ b/hw/cirrus_vga.c @@ -3139,36 +3139,6 @@ void isa_cirrus_vga_init(void) * ***************************************/ -static void cirrus_pci_lfb_map(PCIDevice *d, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - CirrusVGAState *s = &DO_UPCAST(PCICirrusVGAState, dev, d)->cirrus_vga; - - /* XXX: add byte swapping apertures */ - cpu_register_physical_memory(addr, s->vga.vram_size, - s->cirrus_linear_io_addr); - cpu_register_physical_memory(addr + 0x1000000, 0x400000, - s->cirrus_linear_bitblt_io_addr); - - s->vga.map_addr = s->vga.map_end = 0; - s->vga.lfb_addr = addr & TARGET_PAGE_MASK; - s->vga.lfb_end = ((addr + VGA_RAM_SIZE) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK; - /* account for overflow */ - if (s->vga.lfb_end < addr + VGA_RAM_SIZE) - s->vga.lfb_end = addr + VGA_RAM_SIZE; - - vga_dirty_log_start(&s->vga); -} - -static void cirrus_pci_mmio_map(PCIDevice *d, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - CirrusVGAState *s = &DO_UPCAST(PCICirrusVGAState, dev, d)->cirrus_vga; - - cpu_register_physical_memory(addr, CIRRUS_PNPMMIO_SIZE, - s->cirrus_mmio_io_addr); -} - static void pci_cirrus_write_config(PCIDevice *d, uint32_t address, uint32_t val, int len) { @@ -3205,10 +3175,16 @@ static int pci_cirrus_vga_initfn(PCIDevice *dev) /* memory #1 memory-mapped I/O */ /* XXX: s->vga.vram_size must be a power of two */ pci_register_bar((PCIDevice *)d, 0, 0x2000000, - PCI_BASE_ADDRESS_MEM_PREFETCH, cirrus_pci_lfb_map); + PCI_BASE_ADDRESS_MEM_PREFETCH); + pci_bar_map((PCIDevice *)d, 0, 0, 0, s->vga.vram_size, + s->cirrus_linear_io_addr); + pci_bar_map((PCIDevice *)d, 0, 1, 0x1000000, 0x400000, + s->cirrus_linear_bitblt_io_addr); if (device_id == CIRRUS_ID_CLGD5446) { pci_register_bar((PCIDevice *)d, 1, CIRRUS_PNPMMIO_SIZE, - PCI_BASE_ADDRESS_SPACE_MEMORY, cirrus_pci_mmio_map); + PCI_BASE_ADDRESS_SPACE_MEMORY); + pci_bar_map((PCIDevice *)d, 1, 0, 0, CIRRUS_PNPMMIO_SIZE, + s->cirrus_mmio_io_addr); } return 0; } diff --git a/hw/e1000.c b/hw/e1000.c index 0da65f9..b5e9143 100644 --- a/hw/e1000.c +++ b/hw/e1000.c @@ -149,14 +149,6 @@ static const char phy_regcap[0x20] = { }; static void -ioport_map(PCIDevice *pci_dev, int region_num, pcibus_t addr, - pcibus_t size, int type) -{ - DBGOUT(IO, "e1000_ioport_map addr=0x%04"FMT_PCIBUS - " size=0x%08"FMT_PCIBUS"\n", addr, size); -} - -static void set_interrupt_cause(E1000State *s, int index, uint32_t val) { if (val) @@ -1018,30 +1010,6 @@ static CPUReadMemoryFunc * const e1000_mmio_read[] = { }; static void -e1000_mmio_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - E1000State *d = DO_UPCAST(E1000State, dev, pci_dev); - int i; - const uint32_t excluded_regs[] = { - E1000_MDIC, E1000_ICR, E1000_ICS, E1000_IMS, - E1000_IMC, E1000_TCTL, E1000_TDT, PNPMMIO_SIZE - }; - - - DBGOUT(MMIO, "e1000_mmio_map addr=0x%08"FMT_PCIBUS" 0x%08"FMT_PCIBUS"\n", - addr, size); - - cpu_register_physical_memory(addr, PNPMMIO_SIZE, d->mmio_index); - qemu_register_coalesced_mmio(addr, excluded_regs[0]); - - for (i = 0; excluded_regs[i] != PNPMMIO_SIZE; i++) - qemu_register_coalesced_mmio(addr + excluded_regs[i] + 4, - excluded_regs[i + 1] - - excluded_regs[i] - 4); -} - -static void e1000_cleanup(VLANClientState *nc) { E1000State *s = DO_UPCAST(NICState, nc, nc)->opaque; @@ -1106,10 +1074,11 @@ static int pci_e1000_init(PCIDevice *pci_dev) e1000_mmio_write, d); pci_register_bar((PCIDevice *)d, 0, PNPMMIO_SIZE, - PCI_BASE_ADDRESS_SPACE_MEMORY, e1000_mmio_map); + PCI_BASE_ADDRESS_SPACE_MEMORY); + pci_bar_map((PCIDevice *)d, 0, 0, 0, PNPMMIO_SIZE, d->mmio_index); pci_register_bar((PCIDevice *)d, 1, IOPORT_SIZE, - PCI_BASE_ADDRESS_SPACE_IO, ioport_map); + PCI_BASE_ADDRESS_SPACE_IO); memmove(d->eeprom_data, e1000_eeprom_template, sizeof e1000_eeprom_template); diff --git a/hw/eepro100.c b/hw/eepro100.c index 2b75c8f..da41476 100644 --- a/hw/eepro100.c +++ b/hw/eepro100.c @@ -226,7 +226,7 @@ typedef struct { uint8_t scb_stat; /* SCB stat/ack byte */ uint8_t int_stat; /* PCI interrupt status */ /* region must not be saved by nic_save. */ - uint32_t region[3]; /* PCI region addresses */ + uint32_t region; /* PCI region addresses */ uint16_t mdimem[32]; eeprom_t *eeprom; uint32_t device; /* device variant */ @@ -1479,19 +1479,19 @@ static uint32_t ioport_read1(void *opaque, uint32_t addr) #if 0 logout("addr=%s\n", regname(addr)); #endif - return eepro100_read1(s, addr - s->region[1]); + return eepro100_read1(s, addr - s->region); } static uint32_t ioport_read2(void *opaque, uint32_t addr) { EEPRO100State *s = opaque; - return eepro100_read2(s, addr - s->region[1]); + return eepro100_read2(s, addr - s->region); } static uint32_t ioport_read4(void *opaque, uint32_t addr) { EEPRO100State *s = opaque; - return eepro100_read4(s, addr - s->region[1]); + return eepro100_read4(s, addr - s->region); } static void ioport_write1(void *opaque, uint32_t addr, uint32_t val) @@ -1500,43 +1500,35 @@ static void ioport_write1(void *opaque, uint32_t addr, uint32_t val) #if 0 logout("addr=%s val=0x%02x\n", regname(addr), val); #endif - eepro100_write1(s, addr - s->region[1], val); + eepro100_write1(s, addr - s->region, val); } static void ioport_write2(void *opaque, uint32_t addr, uint32_t val) { EEPRO100State *s = opaque; - eepro100_write2(s, addr - s->region[1], val); + eepro100_write2(s, addr - s->region, val); } static void ioport_write4(void *opaque, uint32_t addr, uint32_t val) { EEPRO100State *s = opaque; - eepro100_write4(s, addr - s->region[1], val); + eepro100_write4(s, addr - s->region, val); } /***********************************************************/ /* PCI EEPRO100 definitions */ -static void pci_map(PCIDevice * pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev); - - TRACE(OTHER, logout("region %d, addr=0x%08"FMT_PCIBUS", " - "size=0x%08"FMT_PCIBUS", type=%d\n", - region_num, addr, size, type)); - - assert(region_num == 1); - register_ioport_write(addr, size, 1, ioport_write1, s); - register_ioport_read(addr, size, 1, ioport_read1, s); - register_ioport_write(addr, size, 2, ioport_write2, s); - register_ioport_read(addr, size, 2, ioport_read2, s); - register_ioport_write(addr, size, 4, ioport_write4, s); - register_ioport_read(addr, size, 4, ioport_read4, s); +static IOPortWriteFunc * const io_writes[] = { + ioport_write1, + ioport_write2, + ioport_write4, +}; - s->region[region_num] = addr; -} +static IOPortReadFunc * const io_reads[] = { + ioport_read1, + ioport_read2, + ioport_read4, +}; /***************************************************************************** * @@ -1610,22 +1602,6 @@ static CPUReadMemoryFunc * const pci_mmio_read[] = { pci_mmio_readl }; -static void pci_mmio_map(PCIDevice * pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev); - - TRACE(OTHER, logout("region %d, addr=0x%08"FMT_PCIBUS", " - "size=0x%08"FMT_PCIBUS", type=%d\n", - region_num, addr, size, type)); - - assert(region_num == 0 || region_num == 2); - - /* Map control / status registers and flash. */ - cpu_register_physical_memory(addr, size, s->mmio_index); - s->region[region_num] = addr; -} - static int nic_can_receive(VLANClientState *nc) { EEPRO100State *s = DO_UPCAST(NICState, nc, nc)->opaque; @@ -1853,6 +1829,7 @@ static int e100_nic_init(PCIDevice *pci_dev) EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev); E100PCIDeviceInfo *e100_device = DO_UPCAST(E100PCIDeviceInfo, pci.qdev, pci_dev->qdev.info); + int io_index; TRACE(OTHER, logout("\n")); @@ -1868,17 +1845,23 @@ static int e100_nic_init(PCIDevice *pci_dev) s->mmio_index = cpu_register_io_memory(pci_mmio_read, pci_mmio_write, s); + /* Map control / status registers. */ pci_register_bar(&s->dev, 0, PCI_MEM_SIZE, PCI_BASE_ADDRESS_SPACE_MEMORY | - PCI_BASE_ADDRESS_MEM_PREFETCH, pci_mmio_map); - pci_register_bar(&s->dev, 1, PCI_IO_SIZE, PCI_BASE_ADDRESS_SPACE_IO, - pci_map); - pci_register_bar(&s->dev, 2, PCI_FLASH_SIZE, PCI_BASE_ADDRESS_SPACE_MEMORY, - pci_mmio_map); + PCI_BASE_ADDRESS_MEM_PREFETCH); + pci_bar_map(&s->dev, 0, 0, 0, PCI_IO_SIZE, s->mmio_index); + + io_index = cpu_register_io(io_reads, io_writes, PCI_IO_SIZE, s); + pci_register_bar(&s->dev, 1, PCI_IO_SIZE, PCI_BASE_ADDRESS_SPACE_IO); + pci_bar_map(&s->dev, 1, 0, 0, PCI_IO_SIZE, io_index); + + /* Map flash. */ + pci_register_bar(&s->dev, 2, PCI_FLASH_SIZE, + PCI_BASE_ADDRESS_SPACE_MEMORY); + pci_bar_map(&s->dev, 2, 0, 0, PCI_FLASH_SIZE, s->mmio_index); qemu_macaddr_default_if_unset(&s->conf.macaddr); logout("macaddr: %s\n", nic_dump(&s->conf.macaddr.a[0], 6)); - assert(s->region[1] == 0); nic_reset(s); diff --git a/hw/es1370.c b/hw/es1370.c index 40cb48c..652f0d4 100644 --- a/hw/es1370.c +++ b/hw/es1370.c @@ -906,23 +906,17 @@ static void es1370_adc_callback (void *opaque, int avail) es1370_run_channel (s, ADC_CHANNEL, avail); } -static void es1370_map (PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - ES1370State *s = DO_UPCAST (ES1370State, dev, pci_dev); - - (void) region_num; - (void) size; - (void) type; - - register_ioport_write (addr, 0x40 * 4, 1, es1370_writeb, s); - register_ioport_write (addr, 0x40 * 2, 2, es1370_writew, s); - register_ioport_write (addr, 0x40, 4, es1370_writel, s); +static IOPortWriteFunc * const es1370_writes[] = { + es1370_writeb, + es1370_writew, + es1370_writel, +}; - register_ioport_read (addr, 0x40 * 4, 1, es1370_readb, s); - register_ioport_read (addr, 0x40 * 2, 2, es1370_readw, s); - register_ioport_read (addr, 0x40, 4, es1370_readl, s); -} +static IOPortReadFunc * const es1370_reads[] = { + es1370_readb, + es1370_readw, + es1370_readl, +}; static const VMStateDescription vmstate_es1370_channel = { .name = "es1370_channel", @@ -997,6 +991,7 @@ static int es1370_initfn (PCIDevice *dev) { ES1370State *s = DO_UPCAST (ES1370State, dev, dev); uint8_t *c = s->dev.config; + int io_index; pci_config_set_vendor_id (c, PCI_VENDOR_ID_ENSONIQ); pci_config_set_device_id (c, PCI_DEVICE_ID_ENSONIQ_ES1370); @@ -1023,7 +1018,10 @@ static int es1370_initfn (PCIDevice *dev) c[PCI_MIN_GNT] = 0x0c; c[PCI_MAX_LAT] = 0x80; - pci_register_bar (&s->dev, 0, 256, PCI_BASE_ADDRESS_SPACE_IO, es1370_map); + pci_register_bar (&s->dev, 0, 256, PCI_BASE_ADDRESS_SPACE_IO); + io_index = cpu_register_io(es1370_reads, es1370_writes, 256, s); + pci_bar_map(&s->dev, 0, 0, 0, 256, io_index); + qemu_register_reset (es1370_on_reset, s); AUD_register_card ("es1370", &s->card); diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c index 8b71a13..b30e279 100644 --- a/hw/ide/cmd646.c +++ b/hw/ide/cmd646.c @@ -44,29 +44,29 @@ static void cmd646_update_irq(PCIIDEState *d); -static void ide_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, pci_dev); - IDEBus *bus; - - if (region_num <= 3) { - bus = &d->bus[(region_num >> 1)]; - if (region_num & 1) { - register_ioport_read(addr + 2, 1, 1, ide_status_read, bus); - register_ioport_write(addr + 2, 1, 1, ide_cmd_write, bus); - } else { - register_ioport_write(addr, 8, 1, ide_ioport_write, bus); - register_ioport_read(addr, 8, 1, ide_ioport_read, bus); - - /* data ports */ - register_ioport_write(addr, 2, 2, ide_data_writew, bus); - register_ioport_read(addr, 2, 2, ide_data_readw, bus); - register_ioport_write(addr, 4, 4, ide_data_writel, bus); - register_ioport_read(addr, 4, 4, ide_data_readl, bus); - } - } -} +static IOPortWriteFunc * const ide_cmd_writes[] = { + ide_cmd_write, + NULL, + NULL, +}; + +static IOPortReadFunc * const ide_status_reads[] = { + ide_status_read, + NULL, + NULL, +}; + +static IOPortWriteFunc * const ide_ioport_writes[] = { + ide_ioport_write, + ide_data_writew, + ide_data_writel, +}; + +static IOPortReadFunc * const ide_ioport_reads[] = { + ide_ioport_read, + ide_data_readw, + ide_data_readl, +}; static uint32_t bmdma_readb_common(PCIIDEState *pci_dev, BMDMAState *bm, uint32_t addr) @@ -159,35 +159,41 @@ static void bmdma_writeb_1(void *opaque, uint32_t addr, uint32_t val) bmdma_writeb_common(pci_dev, bm, addr, val); } -static void bmdma_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, pci_dev); - int i; +static IOPortWriteFunc * const bmdma_io_writes_0[] = { + bmdma_writeb_0, + NULL, + NULL, +}; - for(i = 0;i < 2; i++) { - BMDMAState *bm = &d->bmdma[i]; - d->bus[i].bmdma = bm; - bm->bus = d->bus+i; - qemu_add_vm_change_state_handler(ide_dma_restart_cb, bm); +static IOPortReadFunc * const bmdma_io_reads_0[] = { + bmdma_readb_0, + NULL, + NULL, +}; - if (i == 0) { - register_ioport_write(addr, 4, 1, bmdma_writeb_0, d); - register_ioport_read(addr, 4, 1, bmdma_readb_0, d); - } else { - register_ioport_write(addr, 4, 1, bmdma_writeb_1, d); - register_ioport_read(addr, 4, 1, bmdma_readb_1, d); - } +static IOPortWriteFunc * const bmdma_io_writes_1[] = { + bmdma_writeb_1, + NULL, + NULL, +}; - register_ioport_write(addr + 4, 4, 1, bmdma_addr_writeb, bm); - register_ioport_read(addr + 4, 4, 1, bmdma_addr_readb, bm); - register_ioport_write(addr + 4, 4, 2, bmdma_addr_writew, bm); - register_ioport_read(addr + 4, 4, 2, bmdma_addr_readw, bm); - register_ioport_write(addr + 4, 4, 4, bmdma_addr_writel, bm); - register_ioport_read(addr + 4, 4, 4, bmdma_addr_readl, bm); - addr += 8; - } -} +static IOPortReadFunc * const bmdma_io_reads_1[] = { + bmdma_readb_1, + NULL, + NULL, +}; + +static IOPortWriteFunc * const bmdma_addr_writes[] = { + bmdma_addr_writeb, + bmdma_addr_writew, + bmdma_addr_writel, +}; + +static IOPortReadFunc * const bmdma_addr_reads[] = { + bmdma_addr_readb, + bmdma_addr_readw, + bmdma_addr_readl, +}; /* XXX: call it also when the MRDMODE is changed from the PCI config registers */ @@ -232,6 +238,8 @@ static int pci_cmd646_ide_initfn(PCIDevice *dev) PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev); uint8_t *pci_conf = d->dev.config; qemu_irq *irq; + unsigned int i; + int io_index; pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_CMD); pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_CMD_646); @@ -248,11 +256,38 @@ static int pci_cmd646_ide_initfn(PCIDevice *dev) pci_conf[0x51] |= 0x08; /* enable IDE1 */ } - pci_register_bar(dev, 0, 0x8, PCI_BASE_ADDRESS_SPACE_IO, ide_map); - pci_register_bar(dev, 1, 0x4, PCI_BASE_ADDRESS_SPACE_IO, ide_map); - pci_register_bar(dev, 2, 0x8, PCI_BASE_ADDRESS_SPACE_IO, ide_map); - pci_register_bar(dev, 3, 0x4, PCI_BASE_ADDRESS_SPACE_IO, ide_map); - pci_register_bar(dev, 4, 0x10, PCI_BASE_ADDRESS_SPACE_IO, bmdma_map); + pci_register_bar(dev, 0, 0x8, PCI_BASE_ADDRESS_SPACE_IO); + io_index = cpu_register_io(ide_ioport_reads, ide_ioport_writes, 8, &d->bus[0]); + pci_bar_map(&d->dev, 0, 0, 8, 8, io_index); + pci_register_bar(dev, 1, 0x4, PCI_BASE_ADDRESS_SPACE_IO); + io_index = cpu_register_io(ide_status_reads, ide_cmd_writes, 1, &d->bus[0]); + pci_bar_map(&d->dev, 1, 0, 1, 1, io_index); + pci_register_bar(dev, 2, 0x8, PCI_BASE_ADDRESS_SPACE_IO); + io_index = cpu_register_io(ide_ioport_reads, ide_ioport_writes, 8, &d->bus[1]); + pci_bar_map(&d->dev, 2, 0, 8, 8, io_index); + pci_register_bar(dev, 3, 0x4, PCI_BASE_ADDRESS_SPACE_IO); + io_index = cpu_register_io(ide_status_reads, ide_cmd_writes, 1, &d->bus[1]); + pci_bar_map(&d->dev, 3, 0, 1, 1, io_index); + pci_register_bar(dev, 4, 0x10, PCI_BASE_ADDRESS_SPACE_IO); + for (i = 0; i < 2; i++) { + BMDMAState *bm = &d->bmdma[i]; + + d->bus[i].bmdma = bm; + bm->bus = d->bus+i; + qemu_add_vm_change_state_handler(ide_dma_restart_cb, bm); + + if (i == 0) { + io_index = cpu_register_io(bmdma_io_reads_0, bmdma_io_writes_0, + 1, d); + } else { + io_index = cpu_register_io(bmdma_io_reads_1, bmdma_io_writes_1, + 1, d); + } + pci_bar_map(&d->dev, 4, i * 4 + 0, 0, 1, io_index); + + io_index = cpu_register_io(bmdma_addr_reads, bmdma_addr_writes, 4, bm); + pci_bar_map(&d->dev, 4, i * 4 + 4, 4, 4, io_index); + } /* TODO: RST# value should be 0 */ pci_conf[PCI_INTERRUPT_PIN] = 0x01; // interrupt on pin 1 diff --git a/hw/ide/piix.c b/hw/ide/piix.c index 9223834..0506990 100644 --- a/hw/ide/piix.c +++ b/hw/ide/piix.c @@ -68,32 +68,35 @@ static void bmdma_writeb(void *opaque, uint32_t addr, uint32_t val) } } -static void bmdma_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, pci_dev); - int i; +static IOPortWriteFunc * const bmdma_cmd_io_writes[] = { + bmdma_cmd_writeb, + NULL, + NULL, +}; - for(i = 0;i < 2; i++) { - BMDMAState *bm = &d->bmdma[i]; - d->bus[i].bmdma = bm; - bm->bus = d->bus+i; - qemu_add_vm_change_state_handler(ide_dma_restart_cb, bm); +static IOPortWriteFunc * const bmdma_io_writes[] = { + bmdma_writeb, + NULL, + NULL, +}; - register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm); +static IOPortReadFunc * const bmdma_io_reads[] = { + bmdma_readb, + NULL, + NULL, +}; - register_ioport_write(addr + 1, 3, 1, bmdma_writeb, bm); - register_ioport_read(addr, 4, 1, bmdma_readb, bm); +static IOPortWriteFunc * const bmdma_addr_writes[] = { + bmdma_addr_writeb, + bmdma_addr_writew, + bmdma_addr_writel, +}; - register_ioport_write(addr + 4, 4, 1, bmdma_addr_writeb, bm); - register_ioport_read(addr + 4, 4, 1, bmdma_addr_readb, bm); - register_ioport_write(addr + 4, 4, 2, bmdma_addr_writew, bm); - register_ioport_read(addr + 4, 4, 2, bmdma_addr_readw, bm); - register_ioport_write(addr + 4, 4, 4, bmdma_addr_writel, bm); - register_ioport_read(addr + 4, 4, 4, bmdma_addr_readl, bm); - addr += 8; - } -} +static IOPortReadFunc * const bmdma_addr_reads[] = { + bmdma_addr_readb, + bmdma_addr_readw, + bmdma_addr_readl, +}; static void piix3_reset(void *opaque) { @@ -119,6 +122,8 @@ static void piix3_reset(void *opaque) static int pci_piix_ide_initfn(PCIIDEState *d) { uint8_t *pci_conf = d->dev.config; + unsigned int i; + int io_index; pci_conf[PCI_CLASS_PROG] = 0x80; // legacy ATA mode pci_config_set_class(pci_conf, PCI_CLASS_STORAGE_IDE); @@ -126,7 +131,22 @@ static int pci_piix_ide_initfn(PCIIDEState *d) qemu_register_reset(piix3_reset, d); - pci_register_bar(&d->dev, 4, 0x10, PCI_BASE_ADDRESS_SPACE_IO, bmdma_map); + pci_register_bar(&d->dev, 4, 0x10, PCI_BASE_ADDRESS_SPACE_IO); + for (i = 0; i < 2; i++) { + BMDMAState *bm = &d->bmdma[i]; + + d->bus[i].bmdma = bm; + bm->bus = d->bus + i; + qemu_add_vm_change_state_handler(ide_dma_restart_cb, bm); + io_index = cpu_register_io(NULL, bmdma_cmd_io_writes, 1, bm); + pci_bar_map(&d->dev, 0, i * 4 + 0, 0, 1, io_index); + io_index = cpu_register_io(NULL, bmdma_io_writes, 3, bm); + pci_bar_map(&d->dev, 0, i * 4 + 1, 1, 3, io_index); + io_index = cpu_register_io(bmdma_io_reads, NULL, 4, bm); + pci_bar_map(&d->dev, 0, i * 4 + 2, 0, 4, io_index); + io_index = cpu_register_io(bmdma_addr_reads, bmdma_addr_writes, 4, bm); + pci_bar_map(&d->dev, 0, i * 4 + 3, 4, 4, io_index); + } vmstate_register(&d->dev.qdev, 0, &vmstate_ide_pci, d); diff --git a/hw/ide/via.c b/hw/ide/via.c index a403e8c..d2f5d00 100644 --- a/hw/ide/via.c +++ b/hw/ide/via.c @@ -70,32 +70,35 @@ static void bmdma_writeb(void *opaque, uint32_t addr, uint32_t val) } } -static void bmdma_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, pci_dev); - int i; +static IOPortWriteFunc * const bmdma_cmd_io_writes[] = { + bmdma_cmd_writeb, + NULL, + NULL, +}; - for(i = 0;i < 2; i++) { - BMDMAState *bm = &d->bmdma[i]; - d->bus[i].bmdma = bm; - bm->bus = d->bus+i; - qemu_add_vm_change_state_handler(ide_dma_restart_cb, bm); +static IOPortWriteFunc * const bmdma_io_writes[] = { + bmdma_writeb, + NULL, + NULL, +}; - register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm); +static IOPortReadFunc * const bmdma_io_reads[] = { + bmdma_readb, + NULL, + NULL, +}; - register_ioport_write(addr + 1, 3, 1, bmdma_writeb, bm); - register_ioport_read(addr, 4, 1, bmdma_readb, bm); +static IOPortWriteFunc * const bmdma_addr_writes[] = { + bmdma_addr_writeb, + bmdma_addr_writew, + bmdma_addr_writel, +}; - register_ioport_write(addr + 4, 4, 1, bmdma_addr_writeb, bm); - register_ioport_read(addr + 4, 4, 1, bmdma_addr_readb, bm); - register_ioport_write(addr + 4, 4, 2, bmdma_addr_writew, bm); - register_ioport_read(addr + 4, 4, 2, bmdma_addr_readw, bm); - register_ioport_write(addr + 4, 4, 4, bmdma_addr_writel, bm); - register_ioport_read(addr + 4, 4, 4, bmdma_addr_readl, bm); - addr += 8; - } -} +static IOPortReadFunc * const bmdma_addr_reads[] = { + bmdma_addr_readb, + bmdma_addr_readw, + bmdma_addr_readl, +}; static void via_reset(void *opaque) { @@ -144,6 +147,8 @@ static int vt82c686b_ide_initfn(PCIDevice *dev) { PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev);; uint8_t *pci_conf = d->dev.config; + unsigned int i; + int io_index; pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_VIA); pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_VIA_IDE); @@ -154,8 +159,22 @@ static int vt82c686b_ide_initfn(PCIDevice *dev) pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x000000c0); qemu_register_reset(via_reset, d); - pci_register_bar((PCIDevice *)d, 4, 0x10, - PCI_BASE_ADDRESS_SPACE_IO, bmdma_map); + pci_register_bar((PCIDevice *)d, 4, 0x10, PCI_BASE_ADDRESS_SPACE_IO); + for (i = 0; i < 2; i++) { + BMDMAState *bm = &d->bmdma[i]; + + d->bus[i].bmdma = bm; + bm->bus = d->bus + i; + qemu_add_vm_change_state_handler(ide_dma_restart_cb, bm); + io_index = cpu_register_io(NULL, bmdma_cmd_io_writes, 1, bm); + pci_bar_map(&d->dev, 0, i * 4 + 0, 0, 1, io_index); + io_index = cpu_register_io(NULL, bmdma_io_writes, 3, bm); + pci_bar_map(&d->dev, 0, i * 4 + 1, 1, 3, io_index); + io_index = cpu_register_io(bmdma_io_reads, NULL, 4, bm); + pci_bar_map(&d->dev, 0, i * 4 + 2, 0, 4, io_index); + io_index = cpu_register_io(bmdma_addr_reads, bmdma_addr_writes, 4, bm); + pci_bar_map(&d->dev, 0, i * 4 + 3, 4, 4, io_index); + } vmstate_register(&dev->qdev, 0, &vmstate_ide_pci, d); diff --git a/hw/isa.h b/hw/isa.h index aaf0272..6fba4ac 100644 --- a/hw/isa.h +++ b/hw/isa.h @@ -33,6 +33,7 @@ ISADevice *isa_create_simple(const char *name); extern target_phys_addr_t isa_mem_base; void isa_mmio_init(target_phys_addr_t base, target_phys_addr_t size, int be); +int pci_isa_mmio_init(int be); /* dma.c */ int DMA_get_channel_mode (int nchan); diff --git a/hw/isa_mmio.c b/hw/isa_mmio.c index 66bdd2c..3b2de4a 100644 --- a/hw/isa_mmio.c +++ b/hw/isa_mmio.c @@ -125,7 +125,7 @@ static CPUReadMemoryFunc * const isa_mmio_read_le[] = { static int isa_mmio_iomemtype = 0; -void isa_mmio_init(target_phys_addr_t base, target_phys_addr_t size, int be) +static int isa_mmio_memtype(int be) { if (!isa_mmio_iomemtype) { if (be) { @@ -138,5 +138,18 @@ void isa_mmio_init(target_phys_addr_t base, target_phys_addr_t size, int be) NULL); } } - cpu_register_physical_memory(base, size, isa_mmio_iomemtype); + return isa_mmio_iomemtype; +} + +void isa_mmio_init(target_phys_addr_t base, target_phys_addr_t size, int be) +{ + int isa; + + isa = isa_mmio_memtype(be); + cpu_register_physical_memory(base, size, isa); +} + +int pci_isa_mmio_init(int be) +{ + return isa_mmio_memtype(be); } diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c index bd7b661..32de5d1 100644 --- a/hw/lsi53c895a.c +++ b/hw/lsi53c895a.c @@ -186,7 +186,6 @@ typedef struct { PCIDevice dev; int mmio_io_addr; int ram_io_addr; - uint32_t script_ram_base; int carry; /* ??? Should this be an a visible register somewhere? */ int sense; @@ -390,10 +389,6 @@ static inline uint32_t read_dword(LSIState *s, uint32_t addr) { uint32_t buf; - /* Optimize reading from SCRIPTS RAM. */ - if ((addr & 0xffffe000) == s->script_ram_base) { - return s->script_ram[(addr & 0x1fff) >> 2]; - } cpu_physical_memory_read(addr, (uint8_t *)&buf, 4); return cpu_to_le32(buf); } @@ -2004,39 +1999,17 @@ static void lsi_io_writel(void *opaque, uint32_t addr, uint32_t val) lsi_reg_writeb(s, addr + 3, (val >> 24) & 0xff); } -static void lsi_io_mapfunc(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - LSIState *s = DO_UPCAST(LSIState, dev, pci_dev); - - DPRINTF("Mapping IO at %08"FMT_PCIBUS"\n", addr); - - register_ioport_write(addr, 256, 1, lsi_io_writeb, s); - register_ioport_read(addr, 256, 1, lsi_io_readb, s); - register_ioport_write(addr, 256, 2, lsi_io_writew, s); - register_ioport_read(addr, 256, 2, lsi_io_readw, s); - register_ioport_write(addr, 256, 4, lsi_io_writel, s); - register_ioport_read(addr, 256, 4, lsi_io_readl, s); -} - -static void lsi_ram_mapfunc(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - LSIState *s = DO_UPCAST(LSIState, dev, pci_dev); - - DPRINTF("Mapping ram at %08"FMT_PCIBUS"\n", addr); - s->script_ram_base = addr; - cpu_register_physical_memory(addr + 0, 0x2000, s->ram_io_addr); -} - -static void lsi_mmio_mapfunc(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - LSIState *s = DO_UPCAST(LSIState, dev, pci_dev); +static IOPortWriteFunc * const lsi_io_writes[] = { + lsi_io_writeb, + lsi_io_writew, + lsi_io_writel, +}; - DPRINTF("Mapping registers at %08"FMT_PCIBUS"\n", addr); - cpu_register_physical_memory(addr + 0, 0x400, s->mmio_io_addr); -} +static IOPortReadFunc * const lsi_io_reads[] = { + lsi_io_readb, + lsi_io_readw, + lsi_io_readl, +}; static void lsi_scsi_reset(DeviceState *dev) { @@ -2153,6 +2126,7 @@ static int lsi_scsi_init(PCIDevice *dev) { LSIState *s = DO_UPCAST(LSIState, dev, dev); uint8_t *pci_conf; + int io_index; pci_conf = s->dev.config; @@ -2177,12 +2151,16 @@ static int lsi_scsi_init(PCIDevice *dev) lsi_ram_writefn, s); /* TODO: use dev and get rid of cast below */ - pci_register_bar((struct PCIDevice *)s, 0, 256, - PCI_BASE_ADDRESS_SPACE_IO, lsi_io_mapfunc); + pci_register_bar((struct PCIDevice *)s, 0, 256, PCI_BASE_ADDRESS_SPACE_IO); + io_index = cpu_register_io(lsi_io_reads, lsi_io_writes, 256, s); + pci_bar_map((struct PCIDevice *)s, 0, 0, 0, 256, io_index); + pci_register_bar((struct PCIDevice *)s, 1, 0x400, - PCI_BASE_ADDRESS_SPACE_MEMORY, lsi_mmio_mapfunc); + PCI_BASE_ADDRESS_SPACE_MEMORY); + pci_bar_map((struct PCIDevice *)s, 1, 0, 0, 0x400, s->mmio_io_addr); pci_register_bar((struct PCIDevice *)s, 2, 0x2000, - PCI_BASE_ADDRESS_SPACE_MEMORY, lsi_ram_mapfunc); + PCI_BASE_ADDRESS_SPACE_MEMORY); + pci_bar_map((struct PCIDevice *)s, 2, 0, 0, 0x2000, s->ram_io_addr); QTAILQ_INIT(&s->queue); scsi_bus_new(&s->bus, &dev->qdev, 1, LSI_MAX_DEVS, lsi_command_complete); diff --git a/hw/macio.c b/hw/macio.c index e92e82a..653b4df 100644 --- a/hw/macio.c +++ b/hw/macio.c @@ -27,83 +27,16 @@ #include "pci.h" #include "escc.h" -typedef struct macio_state_t macio_state_t; -struct macio_state_t { - int is_oldworld; - int pic_mem_index; - int dbdma_mem_index; - int cuda_mem_index; - int escc_mem_index; - void *nvram; - int nb_ide; - int ide_mem_index[4]; -}; - -static void macio_map (PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - macio_state_t *macio_state; - int i; - - macio_state = (macio_state_t *)(pci_dev + 1); - if (macio_state->pic_mem_index >= 0) { - if (macio_state->is_oldworld) { - /* Heathrow PIC */ - cpu_register_physical_memory(addr + 0x00000, 0x1000, - macio_state->pic_mem_index); - } else { - /* OpenPIC */ - cpu_register_physical_memory(addr + 0x40000, 0x40000, - macio_state->pic_mem_index); - } - } - if (macio_state->dbdma_mem_index >= 0) { - cpu_register_physical_memory(addr + 0x08000, 0x1000, - macio_state->dbdma_mem_index); - } - if (macio_state->escc_mem_index >= 0) { - cpu_register_physical_memory(addr + 0x13000, ESCC_SIZE << 4, - macio_state->escc_mem_index); - } - if (macio_state->cuda_mem_index >= 0) { - cpu_register_physical_memory(addr + 0x16000, 0x2000, - macio_state->cuda_mem_index); - } - for (i = 0; i < macio_state->nb_ide; i++) { - if (macio_state->ide_mem_index[i] >= 0) { - cpu_register_physical_memory(addr + 0x1f000 + (i * 0x1000), 0x1000, - macio_state->ide_mem_index[i]); - } - } - if (macio_state->nvram != NULL) - macio_nvram_map(macio_state->nvram, addr + 0x60000); -} - void macio_init (PCIBus *bus, int device_id, int is_oldworld, int pic_mem_index, - int dbdma_mem_index, int cuda_mem_index, void *nvram, - int nb_ide, int *ide_mem_index, int escc_mem_index) + int dbdma_mem_index, int cuda_mem_index, int nvram_size, + int nvram_mem_index, int nb_ide, int *ide_mem_index, + int escc_mem_index) { PCIDevice *d; - macio_state_t *macio_state; int i; - d = pci_register_device(bus, "macio", - sizeof(PCIDevice) + sizeof(macio_state_t), - -1, NULL, NULL); - macio_state = (macio_state_t *)(d + 1); - macio_state->is_oldworld = is_oldworld; - macio_state->pic_mem_index = pic_mem_index; - macio_state->dbdma_mem_index = dbdma_mem_index; - macio_state->cuda_mem_index = cuda_mem_index; - macio_state->escc_mem_index = escc_mem_index; - macio_state->nvram = nvram; - if (nb_ide > 4) - nb_ide = 4; - macio_state->nb_ide = nb_ide; - for (i = 0; i < nb_ide; i++) - macio_state->ide_mem_index[i] = ide_mem_index[i]; - for (; i < 4; i++) - macio_state->ide_mem_index[i] = -1; + d = pci_register_device(bus, "macio", sizeof(PCIDevice), -1, NULL, NULL); + /* Note: this code is strongly inspirated from the corresponding code in PearPC */ @@ -114,6 +47,32 @@ void macio_init (PCIBus *bus, int device_id, int is_oldworld, int pic_mem_index, d->config[0x3d] = 0x01; // interrupt on pin 1 - pci_register_bar(d, 0, 0x80000, - PCI_BASE_ADDRESS_SPACE_MEMORY, macio_map); + pci_register_bar(d, 0, 0x80000, PCI_BASE_ADDRESS_SPACE_MEMORY); + if (pic_mem_index >= 0) { + if (is_oldworld) { + /* Heathrow PIC */ + pci_bar_map(d, 0, 0, 0x1000, 0, pic_mem_index); + } else { + /* OpenPIC */ + pci_bar_map(d, 0, 0, 0x40000, 0x40000, pic_mem_index); + } + } + if (dbdma_mem_index >= 0) { + pci_bar_map(d, 0, 1, 0x8000, 0x1000, dbdma_mem_index); + } + if (escc_mem_index >= 0) { + pci_bar_map(d, 0, 2, 0x13000, ESCC_SIZE << 4, escc_mem_index); + } + if (cuda_mem_index >= 0) { + pci_bar_map(d, 0, 3, 0x16000, 0x2000, cuda_mem_index); + } + for (i = 0; i < nb_ide; i++) { + if (ide_mem_index[i] >= 0) { + pci_bar_map(d, 0, 4 + i, 0x1f000 + (i * 0x1000), 0x1000, + ide_mem_index[i]); + } + } + if (nvram_mem_index >= 0) { + pci_bar_map(d, 0, 4 + nb_ide, 0x60000, nvram_size, nvram_mem_index); + } } diff --git a/hw/ne2000.c b/hw/ne2000.c index 78fe14f..7598e76 100644 --- a/hw/ne2000.c +++ b/hw/ne2000.c @@ -464,6 +464,18 @@ uint32_t ne2000_ioport_read(void *opaque, uint32_t addr) return ret; } +static IOPortWriteFunc * const ne2000_io_writes[] = { + ne2000_ioport_write, + NULL, + NULL, +}; + +static IOPortReadFunc * const ne2000_io_reads[] = { + ne2000_ioport_read, + NULL, + NULL, +}; + static inline void ne2000_mem_writeb(NE2000State *s, uint32_t addr, uint32_t val) { @@ -611,6 +623,18 @@ static uint32_t ne2000_asic_ioport_readl(void *opaque, uint32_t addr) return ret; } +static IOPortWriteFunc * const ne2000_asic_io_writes[] = { + ne2000_asic_ioport_write, + ne2000_asic_ioport_write, + ne2000_asic_ioport_writel, +}; + +static IOPortReadFunc * const ne2000_asic_io_reads[] = { + ne2000_asic_ioport_read, + ne2000_asic_ioport_read, + ne2000_asic_ioport_readl, +}; + void ne2000_reset_ioport_write(void *opaque, uint32_t addr, uint32_t val) { /* nothing to do (end of reset pulse) */ @@ -623,6 +647,18 @@ uint32_t ne2000_reset_ioport_read(void *opaque, uint32_t addr) return 0; } +static IOPortWriteFunc * const ne2000_reset_io_writes[] = { + ne2000_reset_ioport_write, + NULL, + NULL, +}; + +static IOPortReadFunc * const ne2000_reset_io_reads[] = { + ne2000_reset_ioport_read, + NULL, + NULL, +}; + static int ne2000_post_load(void* opaque, int version_id) { NE2000State* s = opaque; @@ -678,26 +714,6 @@ static const VMStateDescription vmstate_pci_ne2000 = { /***********************************************************/ /* PCI NE2000 definitions */ -static void ne2000_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - PCINE2000State *d = DO_UPCAST(PCINE2000State, dev, pci_dev); - NE2000State *s = &d->ne2000; - - register_ioport_write(addr, 16, 1, ne2000_ioport_write, s); - register_ioport_read(addr, 16, 1, ne2000_ioport_read, s); - - register_ioport_write(addr + 0x10, 1, 1, ne2000_asic_ioport_write, s); - register_ioport_read(addr + 0x10, 1, 1, ne2000_asic_ioport_read, s); - register_ioport_write(addr + 0x10, 2, 2, ne2000_asic_ioport_write, s); - register_ioport_read(addr + 0x10, 2, 2, ne2000_asic_ioport_read, s); - register_ioport_write(addr + 0x10, 4, 4, ne2000_asic_ioport_writel, s); - register_ioport_read(addr + 0x10, 4, 4, ne2000_asic_ioport_readl, s); - - register_ioport_write(addr + 0x1f, 1, 1, ne2000_reset_ioport_write, s); - register_ioport_read(addr + 0x1f, 1, 1, ne2000_reset_ioport_read, s); -} - static void ne2000_cleanup(VLANClientState *nc) { NE2000State *s = DO_UPCAST(NICState, nc, nc)->opaque; @@ -718,6 +734,7 @@ static int pci_ne2000_init(PCIDevice *pci_dev) PCINE2000State *d = DO_UPCAST(PCINE2000State, dev, pci_dev); NE2000State *s; uint8_t *pci_conf; + int io_index; pci_conf = d->dev.config; pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_REALTEK); @@ -727,9 +744,14 @@ static int pci_ne2000_init(PCIDevice *pci_dev) /* TODO: RST# value should be 0. PCI spec 6.2.4 */ pci_conf[PCI_INTERRUPT_PIN] = 1; // interrupt pin 0 - pci_register_bar(&d->dev, 0, 0x100, - PCI_BASE_ADDRESS_SPACE_IO, ne2000_map); s = &d->ne2000; + pci_register_bar(&d->dev, 0, 0x100, PCI_BASE_ADDRESS_SPACE_IO); + io_index = cpu_register_io(ne2000_io_reads, ne2000_io_writes, 16, s); + pci_bar_map(&d->dev, 0, 0, 0, 16, io_index); + io_index = cpu_register_io(ne2000_asic_io_reads, ne2000_asic_io_writes, 4, s); + pci_bar_map(&d->dev, 0, 1, 0x10, 4, io_index); + io_index = cpu_register_io(ne2000_reset_io_reads, ne2000_reset_io_writes, 1, s); + pci_bar_map(&d->dev, 0, 2, 0x1f, 1, io_index); s->irq = d->dev.irq[0]; qemu_macaddr_default_if_unset(&s->c.macaddr); diff --git a/hw/openpic.c b/hw/openpic.c index 2b4cb00..ed1903d 100644 --- a/hw/openpic.c +++ b/hw/openpic.c @@ -1013,34 +1013,6 @@ static CPUReadMemoryFunc * const openpic_read[] = { &openpic_readl, }; -static void openpic_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - openpic_t *opp; - - DPRINTF("Map OpenPIC\n"); - opp = (openpic_t *)pci_dev; - /* Global registers */ - DPRINTF("Register OPENPIC gbl %08x => %08x\n", - addr + 0x1000, addr + 0x1000 + 0x100); - /* Timer registers */ - DPRINTF("Register OPENPIC timer %08x => %08x\n", - addr + 0x1100, addr + 0x1100 + 0x40 * MAX_TMR); - /* Interrupt source registers */ - DPRINTF("Register OPENPIC src %08x => %08x\n", - addr + 0x10000, addr + 0x10000 + 0x20 * (OPENPIC_EXT_IRQ + 2)); - /* Per CPU registers */ - DPRINTF("Register OPENPIC dst %08x => %08x\n", - addr + 0x20000, addr + 0x20000 + 0x1000 * MAX_CPU); - cpu_register_physical_memory(addr, 0x40000, opp->mem_index); -#if 0 // Don't implement ISU for now - opp_io_memory = cpu_register_io_memory(openpic_src_read, - openpic_src_write); - cpu_register_physical_memory(isu_base, 0x20 * (EXT_IRQ + 2), - opp_io_memory); -#endif -} - static void openpic_save_IRQ_queue(QEMUFile* f, IRQ_queue_t *q) { unsigned int i; @@ -1199,12 +1171,14 @@ qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus, /* Register I/O spaces */ pci_register_bar((PCIDevice *)opp, 0, 0x40000, - PCI_BASE_ADDRESS_SPACE_MEMORY, &openpic_map); + PCI_BASE_ADDRESS_SPACE_MEMORY); } else { opp = qemu_mallocz(sizeof(openpic_t)); } - opp->mem_index = cpu_register_io_memory(openpic_read, - openpic_write, opp); + opp->mem_index = cpu_register_io_memory(openpic_read, openpic_write, opp); + if (bus) { + pci_bar_map((PCIDevice *)opp, 0, 0, 0x40000, 0, opp->mem_index); + } // isu_base &= 0xFFFC0000; opp->nb_cpus = nb_cpus; diff --git a/hw/pci.c b/hw/pci.c index a7ff566..fd4b1bb 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -681,19 +681,28 @@ static target_phys_addr_t pci_to_cpu_addr(PCIBus *bus, static void pci_unregister_io_regions(PCIDevice *pci_dev) { PCIIORegion *r; - int i; + PCIIOSubRegion *s; + int i, j; for(i = 0; i < PCI_NUM_REGIONS; i++) { r = &pci_dev->io_regions[i]; if (!r->size || r->addr == PCI_BAR_UNMAPPED) continue; - if (r->type == PCI_BASE_ADDRESS_SPACE_IO) { - isa_unassign_ioport(r->addr, r->filtered_size); - } else { - cpu_register_physical_memory(pci_to_cpu_addr(pci_dev->bus, - r->addr), - r->filtered_size, - IO_MEM_UNASSIGNED); + + for (j = 0; j < PCI_NUM_SUBREGIONS; j++) { + s = &r->subregions[j]; + + if (!s->size) { + continue; + } + if (r->type == PCI_BASE_ADDRESS_SPACE_IO) { + isa_unassign_ioport(r->addr + s->offset, s->filtered_size); + } else { + cpu_register_physical_memory(pci_to_cpu_addr(pci_dev->bus, + r->addr + s->offset), + s->filtered_size, + IO_MEM_UNASSIGNED); + } } } } @@ -716,8 +725,7 @@ static int pci_unregister_device(DeviceState *dev) } void pci_register_bar(PCIDevice *pci_dev, int region_num, - pcibus_t size, int type, - PCIMapIORegionFunc *map_func) + pcibus_t size, int type) { PCIIORegion *r; uint32_t addr; @@ -735,9 +743,7 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num, r = &pci_dev->io_regions[region_num]; r->addr = PCI_BAR_UNMAPPED; r->size = size; - r->filtered_size = size; r->type = type; - r->map_func = map_func; wmask = ~(size - 1); addr = pci_bar(pci_dev, region_num); @@ -756,6 +762,23 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num, } } +void pci_bar_map(PCIDevice *pci_dev, int region_num, int subregion_num, + pcibus_t offset, pcibus_t size, int ix) +{ + PCIIOSubRegion *s; + + if ((unsigned int)region_num >= PCI_NUM_REGIONS || + (unsigned int)subregion_num >= PCI_NUM_SUBREGIONS) { + return; + } + + s = &pci_dev->io_regions[region_num].subregions[subregion_num]; + + s->offset = offset; + s->size = size; + s->ix = ix; +} + static uint32_t pci_config_get_io_base(PCIDevice *d, uint32_t base, uint32_t base_upper16) { @@ -928,8 +951,9 @@ static pcibus_t pci_bar_address(PCIDevice *d, static void pci_update_mappings(PCIDevice *d) { PCIIORegion *r; - int i; - pcibus_t new_addr, filtered_size; + PCIIOSubRegion *s; + int i, j; + pcibus_t bar_addr, new_addr, filtered_size; for(i = 0; i < PCI_NUM_REGIONS; i++) { r = &d->io_regions[i]; @@ -938,54 +962,71 @@ static void pci_update_mappings(PCIDevice *d) if (!r->size) continue; - new_addr = pci_bar_address(d, i, r->type, r->size); + bar_addr = pci_bar_address(d, i, r->type, r->size); - /* bridge filtering */ - filtered_size = r->size; - if (new_addr != PCI_BAR_UNMAPPED) { - pci_bridge_filter(d, &new_addr, &filtered_size, r->type); - } + for (j = 0; j < PCI_NUM_SUBREGIONS; j++) { + s = &r->subregions[j]; - /* This bar isn't changed */ - if (new_addr == r->addr && filtered_size == r->filtered_size) - continue; + /* this region isn't registered */ + if (!s->size) { + continue; + } - /* now do the real mapping */ - if (r->addr != PCI_BAR_UNMAPPED) { - if (r->type & PCI_BASE_ADDRESS_SPACE_IO) { - int class; - /* NOTE: specific hack for IDE in PC case: - only one byte must be mapped. */ - class = pci_get_word(d->config + PCI_CLASS_DEVICE); - if (class == 0x0101 && r->size == 4) { - isa_unassign_ioport(r->addr + 2, 1); + new_addr = bar_addr + s->offset; + /* bridge filtering */ + filtered_size = s->size; + if (bar_addr != PCI_BAR_UNMAPPED) { + pci_bridge_filter(d, &new_addr, &filtered_size, r->type); + } + + /* This bar isn't changed */ + if (new_addr == r->addr + s->offset && + filtered_size == s->filtered_size) + continue; + + /* now do the real mapping */ + if (r->addr != PCI_BAR_UNMAPPED) { + if (r->type & PCI_BASE_ADDRESS_SPACE_IO) { + int class; + /* NOTE: specific hack for IDE in PC case: + only one byte must be mapped. */ + class = pci_get_word(d->config + PCI_CLASS_DEVICE); + if (class == 0x0101 && r->size == 4) { + isa_unassign_ioport(r->addr + s->offset + 2, 1); + } else { + isa_unassign_ioport(r->addr + s->offset, + s->filtered_size); + } } else { - isa_unassign_ioport(r->addr, r->filtered_size); + cpu_register_physical_memory(pci_to_cpu_addr(d->bus, + r->addr + + s->offset), + s->filtered_size, + IO_MEM_UNASSIGNED); + qemu_unregister_coalesced_mmio(r->addr + s->offset, + s->filtered_size); } - } else { - cpu_register_physical_memory(pci_to_cpu_addr(d->bus, r->addr), - r->filtered_size, - IO_MEM_UNASSIGNED); - qemu_unregister_coalesced_mmio(r->addr, r->filtered_size); } - } - r->addr = new_addr; - r->filtered_size = filtered_size; - if (r->addr != PCI_BAR_UNMAPPED) { - /* - * TODO: currently almost all the map funcions assumes - * filtered_size == size and addr & ~(size - 1) == addr. - * However with bridge filtering, they aren't always true. - * Teach them such cases, such that filtered_size < size and - * addr & (size - 1) != 0. - */ - if (r->type & PCI_BASE_ADDRESS_SPACE_IO) { - r->map_func(d, i, r->addr, r->filtered_size, r->type); - } else { - r->map_func(d, i, pci_to_cpu_addr(d->bus, r->addr), - r->filtered_size, r->type); + s->filtered_size = filtered_size; + if (new_addr != PCI_BAR_UNMAPPED) { + /* + * TODO: currently almost all the map funcions assumes + * filtered_size == size and addr & ~(size - 1) == addr. + * However with bridge filtering, they aren't always true. + * Teach them such cases, such that filtered_size < size and + * addr & (size - 1) != 0. + */ + if (r->type & PCI_BASE_ADDRESS_SPACE_IO) { + cpu_map_io(new_addr, s->ix); + } else { + cpu_register_physical_memory(pci_to_cpu_addr(d->bus, + new_addr), + s->filtered_size, + s->ix); + } } } + r->addr = bar_addr; } } @@ -1704,11 +1745,6 @@ static uint8_t pci_find_capability_list(PCIDevice *pdev, uint8_t cap_id, return next; } -static void pci_map_option_rom(PCIDevice *pdev, int region_num, pcibus_t addr, pcibus_t size, int type) -{ - cpu_register_physical_memory(addr, size, pdev->rom_offset); -} - /* Add an option rom for the device */ static int pci_add_option_rom(PCIDevice *pdev) { @@ -1761,8 +1797,8 @@ static int pci_add_option_rom(PCIDevice *pdev) load_image(path, ptr); qemu_free(path); - pci_register_bar(pdev, PCI_ROM_SLOT, size, - 0, pci_map_option_rom); + pci_register_bar(pdev, PCI_ROM_SLOT, size, 0); + pci_bar_map(pdev, PCI_ROM_SLOT, 0, 0, size, pdev->rom_offset); return 0; } diff --git a/hw/pci.h b/hw/pci.h index 3a15bd4..3648105 100644 --- a/hw/pci.h +++ b/hw/pci.h @@ -80,13 +80,21 @@ typedef void PCIMapIORegionFunc(PCIDevice *pci_dev, int region_num, pcibus_t addr, pcibus_t size, int type); typedef int PCIUnregisterFunc(PCIDevice *pci_dev); +typedef struct PCIIOSubRegion { + pcibus_t offset; /* offset to BAR start. -1 means not mapped */ + pcibus_t size; + pcibus_t filtered_size; + int ix; +} PCIIOSubRegion; + +#define PCI_NUM_SUBREGIONS 8 + typedef struct PCIIORegion { pcibus_t addr; /* current PCI mapping address. -1 means not mapped */ #define PCI_BAR_UNMAPPED (~(pcibus_t)0) pcibus_t size; - pcibus_t filtered_size; uint8_t type; - PCIMapIORegionFunc *map_func; + PCIIOSubRegion subregions[PCI_NUM_SUBREGIONS]; } PCIIORegion; #define PCI_ROM_SLOT 6 @@ -175,8 +183,10 @@ PCIDevice *pci_register_device(PCIBus *bus, const char *name, PCIConfigWriteFunc *config_write); void pci_register_bar(PCIDevice *pci_dev, int region_num, - pcibus_t size, int type, - PCIMapIORegionFunc *map_func); + pcibus_t size, int type); + +void pci_bar_map(PCIDevice *pci_dev, int region_num, int subregion_num, + pcibus_t offset, pcibus_t size, int ix); int pci_add_capability(PCIDevice *pci_dev, uint8_t cap_id, uint8_t cap_size); int pci_add_capability_at_offset(PCIDevice *pci_dev, uint8_t cap_id, diff --git a/hw/pcnet.c b/hw/pcnet.c index 5e63eb5..4782717 100644 --- a/hw/pcnet.c +++ b/hw/pcnet.c @@ -1615,6 +1615,18 @@ static uint32_t pcnet_aprom_readb(void *opaque, uint32_t addr) return val; } +static IOPortWriteFunc * const pcnet_aprom_writes[] = { + pcnet_aprom_writeb, + NULL, + NULL, +}; + +static IOPortReadFunc * const pcnet_aprom_reads[] = { + pcnet_aprom_readb, + NULL, + NULL, +}; + void pcnet_ioport_writew(void *opaque, uint32_t addr, uint32_t val) { PCNetState *s = opaque; @@ -1726,24 +1738,17 @@ static uint32_t pcnet_ioport_readl(void *opaque, uint32_t addr) return val; } -static void pcnet_ioport_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - PCNetState *d = &DO_UPCAST(PCIPCNetState, pci_dev, pci_dev)->state; - -#ifdef PCNET_DEBUG_IO - printf("pcnet_ioport_map addr=0x%04"FMT_PCIBUS" size=0x%04"FMT_PCIBUS"\n", - addr, size); -#endif - - register_ioport_write(addr, 16, 1, pcnet_aprom_writeb, d); - register_ioport_read(addr, 16, 1, pcnet_aprom_readb, d); +static IOPortWriteFunc * const pcnet_ioport_writes[] = { + NULL, + pcnet_ioport_writew, + pcnet_ioport_writel, +}; - register_ioport_write(addr + 0x10, 0x10, 2, pcnet_ioport_writew, d); - register_ioport_read(addr + 0x10, 0x10, 2, pcnet_ioport_readw, d); - register_ioport_write(addr + 0x10, 0x10, 4, pcnet_ioport_writel, d); - register_ioport_read(addr + 0x10, 0x10, 4, pcnet_ioport_readl, d); -} +static IOPortReadFunc * const pcnet_ioport_reads[] = { + NULL, + pcnet_ioport_readw, + pcnet_ioport_readl, +}; static void pcnet_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) { @@ -1915,19 +1920,6 @@ static CPUReadMemoryFunc * const pcnet_mmio_read[] = { &pcnet_mmio_readl }; -static void pcnet_mmio_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev, pci_dev); - -#ifdef PCNET_DEBUG_IO - printf("pcnet_mmio_map addr=0x%08"FMT_PCIBUS" 0x%08"FMT_PCIBUS"\n", - addr, size); -#endif - - cpu_register_physical_memory(addr, PCNET_PNPMMIO_SIZE, d->state.mmio_index); -} - static void pci_physical_memory_write(void *dma_opaque, target_phys_addr_t addr, uint8_t *buf, int len, int do_bswap) { @@ -1971,6 +1963,7 @@ static int pci_pcnet_init(PCIDevice *pci_dev) PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev, pci_dev); PCNetState *s = &d->state; uint8_t *pci_conf; + int io_index; #if 0 printf("sizeof(RMD)=%d, sizeof(TMD)=%d\n", @@ -2011,10 +2004,15 @@ static int pci_pcnet_init(PCIDevice *pci_dev) /* TODO: use pci_dev, avoid cast below. */ pci_register_bar((PCIDevice *)d, 0, PCNET_IOPORT_SIZE, - PCI_BASE_ADDRESS_SPACE_IO, pcnet_ioport_map); + PCI_BASE_ADDRESS_SPACE_IO); + io_index = cpu_register_io(pcnet_aprom_reads, pcnet_aprom_writes, 16, s); + pci_bar_map((PCIDevice *)d, 0, 0, 0, 16, io_index); + io_index = cpu_register_io(pcnet_ioport_reads, pcnet_ioport_writes, 16, s); + pci_bar_map((PCIDevice *)d, 0, 1, 0x10, 16, io_index); pci_register_bar((PCIDevice *)d, 1, PCNET_PNPMMIO_SIZE, - PCI_BASE_ADDRESS_SPACE_MEMORY, pcnet_mmio_map); + PCI_BASE_ADDRESS_SPACE_MEMORY); + pci_bar_map((PCIDevice *)d, 1, 0, 0, PCNET_PNPMMIO_SIZE, s->mmio_index); s->irq = pci_dev->irq[0]; s->phys_mem_read = pci_physical_memory_read; diff --git a/hw/ppc_mac.h b/hw/ppc_mac.h index 89f96bb..6b3e27f 100644 --- a/hw/ppc_mac.h +++ b/hw/ppc_mac.h @@ -46,8 +46,9 @@ void cuda_init (int *cuda_mem_index, qemu_irq irq); /* MacIO */ void macio_init (PCIBus *bus, int device_id, int is_oldworld, int pic_mem_index, - int dbdma_mem_index, int cuda_mem_index, void *nvram, - int nb_ide, int *ide_mem_index, int escc_mem_index); + int dbdma_mem_index, int cuda_mem_index, int nvram_size, + int nvram_mem_index, int nb_ide, int *ide_mem_index, + int escc_mem_index); /* Heathrow PIC */ qemu_irq *heathrow_pic_init(int *pmem_index, diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c index fbba9b6..75fef3c 100644 --- a/hw/ppc_newworld.c +++ b/hw/ppc_newworld.c @@ -383,7 +383,7 @@ static void ppc_core99_init (ram_addr_t ram_size, adb_mouse_init(&adb_bus); macio_init(pci_bus, PCI_DEVICE_ID_APPLE_UNI_N_KEYL, 0, pic_mem_index, - dbdma_mem_index, cuda_mem_index, NULL, 3, ide_mem_index, + dbdma_mem_index, cuda_mem_index, -1, 0, 3, ide_mem_index, escc_mem_index); if (usb_enabled) { diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c index 6b3ab89..220dca7 100644 --- a/hw/ppc_oldworld.c +++ b/hw/ppc_oldworld.c @@ -366,8 +366,8 @@ static void ppc_heathrow_init (ram_addr_t ram_size, pmac_format_nvram_partition(nvr, 0x2000); macio_init(pci_bus, PCI_DEVICE_ID_APPLE_343S1201, 1, pic_mem_index, - dbdma_mem_index, cuda_mem_index, nvr, 2, ide_mem_index, - escc_mem_index); + dbdma_mem_index, cuda_mem_index, nvram_mem_index, 0x2000, + 2, ide_mem_index, escc_mem_index); if (usb_enabled) { usb_ohci_init_pci(pci_bus, -1); diff --git a/hw/rtl8139.c b/hw/rtl8139.c index 72e2242..d87f3ae 100644 --- a/hw/rtl8139.c +++ b/hw/rtl8139.c @@ -3269,28 +3269,17 @@ static const VMStateDescription vmstate_rtl8139 = { /***********************************************************/ /* PCI RTL8139 definitions */ -static void rtl8139_mmio_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - RTL8139State *s = DO_UPCAST(RTL8139State, dev, pci_dev); - - cpu_register_physical_memory(addr + 0, 0x100, s->rtl8139_mmio_io_addr); -} - -static void rtl8139_ioport_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - RTL8139State *s = DO_UPCAST(RTL8139State, dev, pci_dev); - - register_ioport_write(addr, 0x100, 1, rtl8139_ioport_writeb, s); - register_ioport_read( addr, 0x100, 1, rtl8139_ioport_readb, s); - - register_ioport_write(addr, 0x100, 2, rtl8139_ioport_writew, s); - register_ioport_read( addr, 0x100, 2, rtl8139_ioport_readw, s); +static IOPortWriteFunc * const rtl8139_io_writes[] = { + rtl8139_ioport_writeb, + rtl8139_ioport_writew, + rtl8139_ioport_writel, +}; - register_ioport_write(addr, 0x100, 4, rtl8139_ioport_writel, s); - register_ioport_read( addr, 0x100, 4, rtl8139_ioport_readl, s); -} +static IOPortReadFunc * const rtl8139_io_reads[] = { + rtl8139_ioport_readb, + rtl8139_ioport_readw, + rtl8139_ioport_readl, +}; static CPUReadMemoryFunc * const rtl8139_mmio_read[3] = { rtl8139_mmio_readb, @@ -3353,6 +3342,7 @@ static int pci_rtl8139_init(PCIDevice *dev) { RTL8139State * s = DO_UPCAST(RTL8139State, dev, dev); uint8_t *pci_conf; + int io_index; pci_conf = s->dev.config; pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_REALTEK); @@ -3372,11 +3362,11 @@ static int pci_rtl8139_init(PCIDevice *dev) s->rtl8139_mmio_io_addr = cpu_register_io_memory(rtl8139_mmio_read, rtl8139_mmio_write, s); - pci_register_bar(&s->dev, 0, 0x100, - PCI_BASE_ADDRESS_SPACE_IO, rtl8139_ioport_map); - - pci_register_bar(&s->dev, 1, 0x100, - PCI_BASE_ADDRESS_SPACE_MEMORY, rtl8139_mmio_map); + pci_register_bar(&s->dev, 0, 0x100, PCI_BASE_ADDRESS_SPACE_IO); + io_index = cpu_register_io(rtl8139_io_reads, rtl8139_io_writes, 0x100, s); + pci_bar_map(&s->dev, 0, 0, 0, 0x100, io_index); + pci_register_bar(&s->dev, 1, 0x100, PCI_BASE_ADDRESS_SPACE_MEMORY); + pci_bar_map(&s->dev, 1, 0, 0, 0x100, s->rtl8139_mmio_io_addr); qemu_macaddr_default_if_unset(&s->conf.macaddr); diff --git a/hw/sun4u.c b/hw/sun4u.c index 2234b4e..48d89d3 100644 --- a/hw/sun4u.c +++ b/hw/sun4u.c @@ -517,21 +517,6 @@ void cpu_tick_set_limit(CPUTimer *timer, uint64_t limit) } } -static void ebus_mmio_mapfunc(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - EBUS_DPRINTF("Mapping region %d registers at %" FMT_PCIBUS "\n", - region_num, addr); - switch (region_num) { - case 0: - isa_mmio_init(addr, 0x1000000, 1); - break; - case 1: - isa_mmio_init(addr, 0x800000, 1); - break; - } -} - static void dummy_isa_irq_handler(void *opaque, int n, int level) { } @@ -550,6 +535,8 @@ pci_ebus_init(PCIBus *bus, int devfn) static int pci_ebus_init1(PCIDevice *s) { + int io_index; + isa_bus_new(&s->qdev); pci_config_set_vendor_id(s->config, PCI_VENDOR_ID_SUN); @@ -564,10 +551,14 @@ pci_ebus_init1(PCIDevice *s) s->config[0x0D] = 0x0a; // latency_timer s->config[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type - pci_register_bar(s, 0, 0x1000000, PCI_BASE_ADDRESS_SPACE_MEMORY, - ebus_mmio_mapfunc); - pci_register_bar(s, 1, 0x800000, PCI_BASE_ADDRESS_SPACE_MEMORY, - ebus_mmio_mapfunc); + pci_register_bar(s, 0, 0x1000000, PCI_BASE_ADDRESS_SPACE_MEMORY); + io_index = pci_isa_mmio_init(1); + pci_bar_map(s, 0, 0, 0, 0x1000000, io_index); + + pci_register_bar(s, 1, 0x800000, PCI_BASE_ADDRESS_SPACE_MEMORY); + io_index = pci_isa_mmio_init(1); + pci_bar_map(s, 1, 0, 0, 0x800000, io_index); + return 0; } diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c index c60fd8d..343603f 100644 --- a/hw/usb-ohci.c +++ b/hw/usb-ohci.c @@ -1717,13 +1717,6 @@ typedef struct { OHCIState state; } OHCIPCIState; -static void ohci_mapfunc(PCIDevice *pci_dev, int i, - pcibus_t addr, pcibus_t size, int type) -{ - OHCIPCIState *ohci = DO_UPCAST(OHCIPCIState, pci_dev, pci_dev); - cpu_register_physical_memory(addr, size, ohci->state.mem); -} - static int usb_ohci_initfn_pci(struct PCIDevice *dev) { OHCIPCIState *ohci = DO_UPCAST(OHCIPCIState, pci_dev, dev); @@ -1742,7 +1735,8 @@ static int usb_ohci_initfn_pci(struct PCIDevice *dev) /* TODO: avoid cast below by using dev */ pci_register_bar((struct PCIDevice *)ohci, 0, 256, - PCI_BASE_ADDRESS_SPACE_MEMORY, ohci_mapfunc); + PCI_BASE_ADDRESS_SPACE_MEMORY); + pci_bar_map((struct PCIDevice *)ohci, 0, 0, 256, 0, ohci->state.mem); return 0; } diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c index 4cdb55e..b182eb5 100644 --- a/hw/usb-uhci.c +++ b/hw/usb-uhci.c @@ -1088,23 +1088,22 @@ static void uhci_frame_timer(void *opaque) qemu_mod_timer(s->frame_timer, s->expire_time); } -static void uhci_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - UHCIState *s = (UHCIState *)pci_dev; - - register_ioport_write(addr, 32, 2, uhci_ioport_writew, s); - register_ioport_read(addr, 32, 2, uhci_ioport_readw, s); - register_ioport_write(addr, 32, 4, uhci_ioport_writel, s); - register_ioport_read(addr, 32, 4, uhci_ioport_readl, s); - register_ioport_write(addr, 32, 1, uhci_ioport_writeb, s); - register_ioport_read(addr, 32, 1, uhci_ioport_readb, s); -} +static IOPortWriteFunc * const uhci_io_writes[] = { + uhci_ioport_writeb, + uhci_ioport_writew, + uhci_ioport_writel, +}; + +static IOPortReadFunc * const uhci_io_reads[] = { + uhci_ioport_readb, + uhci_ioport_readw, + uhci_ioport_readl, +}; static int usb_uhci_common_initfn(UHCIState *s) { uint8_t *pci_conf = s->dev.config; - int i; + int i, io_index; pci_conf[PCI_REVISION_ID] = 0x01; // revision number pci_conf[PCI_CLASS_PROG] = 0x00; @@ -1127,9 +1126,9 @@ static int usb_uhci_common_initfn(UHCIState *s) /* Use region 4 for consistency with real hardware. BSD guests seem to rely on this. */ - pci_register_bar(&s->dev, 4, 0x20, - PCI_BASE_ADDRESS_SPACE_IO, uhci_map); - + pci_register_bar(&s->dev, 4, 0x20, PCI_BASE_ADDRESS_SPACE_IO); + io_index = cpu_register_io(uhci_io_reads, uhci_io_writes, 32, s); + pci_bar_map(&s->dev, 4, 0, 0, 0x20, io_index); return 0; } diff --git a/hw/vga-pci.c b/hw/vga-pci.c index eef78ed..818e77f 100644 --- a/hw/vga-pci.c +++ b/hw/vga-pci.c @@ -47,21 +47,6 @@ static const VMStateDescription vmstate_vga_pci = { } }; -static void vga_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - PCIVGAState *d = (PCIVGAState *)pci_dev; - VGACommonState *s = &d->vga; - if (region_num == PCI_ROM_SLOT) { - cpu_register_physical_memory(addr, s->bios_size, s->bios_offset); - } else { - cpu_register_physical_memory(addr, s->vram_size, s->vram_offset); - s->map_addr = addr; - s->map_end = addr + s->vram_size; - vga_dirty_log_start(s); - } -} - static void pci_vga_write_config(PCIDevice *d, uint32_t address, uint32_t val, int len) { @@ -93,8 +78,8 @@ static int pci_vga_initfn(PCIDevice *dev) pci_conf[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type /* XXX: VGA_RAM_SIZE must be a power of two */ - pci_register_bar(&d->dev, 0, VGA_RAM_SIZE, - PCI_BASE_ADDRESS_MEM_PREFETCH, vga_map); + pci_register_bar(&d->dev, 0, VGA_RAM_SIZE, PCI_BASE_ADDRESS_MEM_PREFETCH); + pci_bar_map(&d->dev, 0, 0, 0, s->vram_size, s->vram_offset); if (s->bios_size) { unsigned int bios_total_size; @@ -103,7 +88,8 @@ static int pci_vga_initfn(PCIDevice *dev) while (bios_total_size < s->bios_size) bios_total_size <<= 1; pci_register_bar(&d->dev, PCI_ROM_SLOT, bios_total_size, - PCI_BASE_ADDRESS_MEM_PREFETCH, vga_map); + PCI_BASE_ADDRESS_MEM_PREFETCH); + pci_bar_map(&d->dev, PCI_ROM_SLOT, 0, 0, s->bios_size, s->bios_offset); } vga_init_vbe(s); diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index c6ef825..415acfc 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -374,25 +374,17 @@ static void virtio_pci_config_writel(void *opaque, uint32_t addr, uint32_t val) virtio_config_writel(proxy->vdev, addr, val); } -static void virtio_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - VirtIOPCIProxy *proxy = container_of(pci_dev, VirtIOPCIProxy, pci_dev); - VirtIODevice *vdev = proxy->vdev; - unsigned config_len = VIRTIO_PCI_REGION_SIZE(pci_dev) + vdev->config_len; - - proxy->addr = addr; - - register_ioport_write(addr, config_len, 1, virtio_pci_config_writeb, proxy); - register_ioport_write(addr, config_len, 2, virtio_pci_config_writew, proxy); - register_ioport_write(addr, config_len, 4, virtio_pci_config_writel, proxy); - register_ioport_read(addr, config_len, 1, virtio_pci_config_readb, proxy); - register_ioport_read(addr, config_len, 2, virtio_pci_config_readw, proxy); - register_ioport_read(addr, config_len, 4, virtio_pci_config_readl, proxy); +static IOPortWriteFunc * const virtio_pci_config_io_writes[] = { + virtio_pci_config_writeb, + virtio_pci_config_writew, + virtio_pci_config_writel, +}; - if (vdev->config_len) - vdev->get_config(vdev, vdev->config); -} +static IOPortReadFunc * const virtio_pci_config_io_reads[] = { + virtio_pci_config_readb, + virtio_pci_config_readw, + virtio_pci_config_readl, +}; static void virtio_write_config(PCIDevice *pci_dev, uint32_t address, uint32_t val, int len) @@ -495,6 +487,7 @@ static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev, { uint8_t *config; uint32_t size; + int io_index; proxy->vdev = vdev; @@ -518,8 +511,7 @@ static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev, if (vdev->nvectors && !msix_init(&proxy->pci_dev, vdev->nvectors, 1, 0)) { pci_register_bar(&proxy->pci_dev, 1, msix_bar_size(&proxy->pci_dev), - PCI_BASE_ADDRESS_SPACE_MEMORY, - msix_mmio_map); + PCI_BASE_ADDRESS_SPACE_MEMORY); } else vdev->nvectors = 0; @@ -529,8 +521,11 @@ static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev, if (size & (size-1)) size = 1 << qemu_fls(size); - pci_register_bar(&proxy->pci_dev, 0, size, PCI_BASE_ADDRESS_SPACE_IO, - virtio_map); + pci_register_bar(&proxy->pci_dev, 0, size, PCI_BASE_ADDRESS_SPACE_IO); + io_index = cpu_register_io(virtio_pci_config_io_reads, + virtio_pci_config_io_writes, + size, &proxy->pci_dev); + pci_bar_map(&proxy->pci_dev, 0, 0, 0, size, io_index); virtio_bind_device(vdev, &virtio_pci_bindings, proxy); proxy->host_features |= 0x1 << VIRTIO_F_NOTIFY_ON_EMPTY; diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c index 9e72d2e..bf5f075 100644 --- a/hw/vmware_vga.c +++ b/hw/vmware_vga.c @@ -1178,65 +1178,47 @@ static void vmsvga_init(struct vmsvga_state_s *s, int vga_ram_size) vmsvga_reset(s); } -static void pci_vmsvga_map_ioport(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - struct pci_vmsvga_state_s *d = (struct pci_vmsvga_state_s *) pci_dev; - struct vmsvga_state_s *s = &d->chip; - - register_ioport_read(addr + SVGA_IO_MUL * SVGA_INDEX_PORT, - 1, 4, vmsvga_index_read, s); - register_ioport_write(addr + SVGA_IO_MUL * SVGA_INDEX_PORT, - 1, 4, vmsvga_index_write, s); - register_ioport_read(addr + SVGA_IO_MUL * SVGA_VALUE_PORT, - 1, 4, vmsvga_value_read, s); - register_ioport_write(addr + SVGA_IO_MUL * SVGA_VALUE_PORT, - 1, 4, vmsvga_value_write, s); - register_ioport_read(addr + SVGA_IO_MUL * SVGA_BIOS_PORT, - 1, 4, vmsvga_bios_read, s); - register_ioport_write(addr + SVGA_IO_MUL * SVGA_BIOS_PORT, - 1, 4, vmsvga_bios_write, s); -} +static IOPortWriteFunc * const vmsvga_index_io_writes[] = { + NULL, + NULL, + vmsvga_index_write, +}; -static void pci_vmsvga_map_mem(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - struct pci_vmsvga_state_s *d = (struct pci_vmsvga_state_s *) pci_dev; - struct vmsvga_state_s *s = &d->chip; - ram_addr_t iomemtype; +static IOPortReadFunc * const vmsvga_index_io_reads[] = { + NULL, + NULL, + vmsvga_index_read, +}; - s->vram_base = addr; -#ifdef DIRECT_VRAM - iomemtype = cpu_register_io_memory(vmsvga_vram_read, - vmsvga_vram_write, s); -#else - iomemtype = s->vga.vram_offset | IO_MEM_RAM; -#endif - cpu_register_physical_memory(s->vram_base, s->vga.vram_size, - iomemtype); +static IOPortWriteFunc * const vmsvga_value_io_writes[] = { + NULL, + NULL, + vmsvga_value_write, +}; - s->vga.map_addr = addr; - s->vga.map_end = addr + s->vga.vram_size; - vga_dirty_log_restart(&s->vga); -} +static IOPortReadFunc * const vmsvga_value_io_reads[] = { + NULL, + NULL, + vmsvga_value_read, +}; -static void pci_vmsvga_map_fifo(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - struct pci_vmsvga_state_s *d = (struct pci_vmsvga_state_s *) pci_dev; - struct vmsvga_state_s *s = &d->chip; - ram_addr_t iomemtype; +static IOPortWriteFunc * const vmsvga_bios_io_writes[] = { + NULL, + NULL, + vmsvga_bios_write, +}; - s->fifo_base = addr; - iomemtype = s->fifo_offset | IO_MEM_RAM; - cpu_register_physical_memory(s->fifo_base, s->fifo_size, - iomemtype); -} +static IOPortReadFunc * const vmsvga_bios_io_reads[] = { + NULL, + NULL, + vmsvga_bios_read, +}; static int pci_vmsvga_initfn(PCIDevice *dev) { struct pci_vmsvga_state_s *s = DO_UPCAST(struct pci_vmsvga_state_s, card, dev); + ram_addr_t iomemtype; pci_config_set_vendor_id(s->card.config, PCI_VENDOR_ID_VMWARE); pci_config_set_device_id(s->card.config, SVGA_PCI_DEVICE_ID); @@ -1253,16 +1235,33 @@ static int pci_vmsvga_initfn(PCIDevice *dev) s->card.config[PCI_SUBSYSTEM_ID + 1] = SVGA_PCI_DEVICE_ID >> 8; s->card.config[PCI_INTERRUPT_LINE] = 0xff; /* End */ - pci_register_bar(&s->card, 0, 0x10, - PCI_BASE_ADDRESS_SPACE_IO, pci_vmsvga_map_ioport); + pci_register_bar(&s->card, 0, 0x10, PCI_BASE_ADDRESS_SPACE_IO); + iomemtype = cpu_register_io(vmsvga_index_io_reads, vmsvga_index_io_writes, + 4, &s->card); + pci_bar_map(&s->card, 0, 0, SVGA_IO_MUL * SVGA_INDEX_PORT, 4, iomemtype); + iomemtype = cpu_register_io(vmsvga_value_io_reads, vmsvga_value_io_writes, + 4, &s->card); + pci_bar_map(&s->card, 0, 0, SVGA_IO_MUL * SVGA_VALUE_PORT, 4, iomemtype); + iomemtype = cpu_register_io(vmsvga_bios_io_reads, vmsvga_bios_io_writes, + 4, &s->card); + pci_bar_map(&s->card, 0, 0, SVGA_IO_MUL * SVGA_BIOS_PORT, 4, iomemtype); pci_register_bar(&s->card, 1, VGA_RAM_SIZE, - PCI_BASE_ADDRESS_MEM_PREFETCH, pci_vmsvga_map_mem); - + PCI_BASE_ADDRESS_MEM_PREFETCH); pci_register_bar(&s->card, 2, SVGA_FIFO_SIZE, - PCI_BASE_ADDRESS_MEM_PREFETCH, pci_vmsvga_map_fifo); + PCI_BASE_ADDRESS_MEM_PREFETCH); vmsvga_init(&s->chip, VGA_RAM_SIZE); +#ifdef DIRECT_VRAM + iomemtype = cpu_register_io_memory(vmsvga_vram_read, + vmsvga_vram_write, s); +#else + iomemtype = s->chip.vga.vram_offset | IO_MEM_RAM; +#endif + pci_bar_map(&s->card, 1, 0, 0, s->chip.vga.vram_size, iomemtype); + iomemtype = s->chip.fifo_offset | IO_MEM_RAM; + pci_bar_map(&s->card, 2, 0, 0, s->chip.fifo_size, iomemtype); + return 0; } diff --git a/hw/wdt_i6300esb.c b/hw/wdt_i6300esb.c index be0e89e..4c5bb32 100644 --- a/hw/wdt_i6300esb.c +++ b/hw/wdt_i6300esb.c @@ -342,29 +342,17 @@ static void i6300esb_mem_writel(void *vp, target_phys_addr_t addr, uint32_t val) } } -static void i6300esb_map(PCIDevice *dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - static CPUReadMemoryFunc * const mem_read[3] = { - i6300esb_mem_readb, - i6300esb_mem_readw, - i6300esb_mem_readl, - }; - static CPUWriteMemoryFunc * const mem_write[3] = { - i6300esb_mem_writeb, - i6300esb_mem_writew, - i6300esb_mem_writel, - }; - I6300State *d = DO_UPCAST(I6300State, dev, dev); - int io_mem; - - i6300esb_debug("addr = %"FMT_PCIBUS", size = %"FMT_PCIBUS", type = %d\n", - addr, size, type); +static CPUReadMemoryFunc * const mem_read[3] = { + i6300esb_mem_readb, + i6300esb_mem_readw, + i6300esb_mem_readl, +}; - io_mem = cpu_register_io_memory(mem_read, mem_write, d); - cpu_register_physical_memory (addr, 0x10, io_mem); - /* qemu_register_coalesced_mmio (addr, 0x10); ? */ -} +static CPUWriteMemoryFunc * const mem_write[3] = { + i6300esb_mem_writeb, + i6300esb_mem_writew, + i6300esb_mem_writel, +}; static const VMStateDescription vmstate_i6300esb = { .name = "i6300esb_wdt", @@ -393,6 +381,7 @@ static int i6300esb_init(PCIDevice *dev) { I6300State *d = DO_UPCAST(I6300State, dev, dev); uint8_t *pci_conf; + int io_mem; d->reboot_enabled = 1; d->clock_scale = CLOCK_SCALE_1KHZ; @@ -413,8 +402,9 @@ static int i6300esb_init(PCIDevice *dev) pci_config_set_class(pci_conf, PCI_CLASS_SYSTEM_OTHER); pci_conf[PCI_HEADER_TYPE] = 0x00; - pci_register_bar(&d->dev, 0, 0x10, - PCI_BASE_ADDRESS_SPACE_MEMORY, i6300esb_map); + pci_register_bar(&d->dev, 0, 0x10, PCI_BASE_ADDRESS_SPACE_MEMORY); + io_mem = cpu_register_io_memory(mem_read, mem_write, d); + pci_bar_map(&d->dev, 0, 0, 0, 0x10, io_mem); return 0; } diff --git a/ioport.c b/ioport.c index 53dd87a..90fec90 100644 --- a/ioport.c +++ b/ioport.c @@ -54,29 +54,39 @@ static IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS]; static IOPortReadFunc default_ioport_readb, default_ioport_readw, default_ioport_readl; static IOPortWriteFunc default_ioport_writeb, default_ioport_writew, default_ioport_writel; +#define IO_NB_ENTRIES 256 + +static IOPortWriteFunc *io_writes[IO_NB_ENTRIES][3]; +static IOPortReadFunc *io_reads[IO_NB_ENTRIES][3]; +static void *io_opaques[IO_NB_ENTRIES]; +static int io_sizes[IO_NB_ENTRIES]; +static char io_used[IO_NB_ENTRIES]; + +static IOPortReadFunc * const default_read_func[3] = { + default_ioport_readb, + default_ioport_readw, + default_ioport_readl +}; + static uint32_t ioport_read(int index, uint32_t address) { - static IOPortReadFunc * const default_func[3] = { - default_ioport_readb, - default_ioport_readw, - default_ioport_readl - }; IOPortReadFunc *func = ioport_read_table[index][address]; if (!func) - func = default_func[index]; + func = default_read_func[index]; return func(ioport_opaque[address], address); } +static IOPortWriteFunc * const default_write_func[3] = { + default_ioport_writeb, + default_ioport_writew, + default_ioport_writel +}; + static void ioport_write(int index, uint32_t address, uint32_t data) { - static IOPortWriteFunc * const default_func[3] = { - default_ioport_writeb, - default_ioport_writew, - default_ioport_writel - }; IOPortWriteFunc *func = ioport_write_table[index][address]; if (!func) - func = default_func[index]; + func = default_write_func[index]; func(ioport_opaque[address], address, data); } @@ -173,6 +183,86 @@ int register_ioport_write(pio_addr_t start, int length, int size, return 0; } +static int get_free_io_mem_idx(void) +{ + int i; + + for (i = 0; i < IO_NB_ENTRIES; i++) { + if (!io_used[i]) { + io_used[i] = 1; + return i; + } + } + fprintf(stderr, "RAN out out io_mem_idx, max %d !\n", IO_NB_ENTRIES); + return -1; +} + +/* io_read and io_write are arrays of functions containing the + function to access byte (index 0), word (index 1) and dword (index + 2). Functions can be omitted with a NULL function pointer. (-1) is + returned if error. */ +int cpu_register_io(IOPortReadFunc * const *io_read, + IOPortWriteFunc * const *io_write, + int size, void *opaque) +{ + unsigned int i; + int io_index; + + io_index = get_free_io_mem_idx(); + if (io_index == -1) { + return io_index; + } + + if (io_read) { + for (i = 0; i < 3; ++i) { + io_reads[io_index][i] = io_read[i]; + } + } + if (io_write) { + for (i = 0; i < 3; ++i) { + io_writes[io_index][i] = io_write[i]; + } + } + io_opaques[io_index] = opaque; + io_sizes[io_index] = size; + + return io_index; +} + +void cpu_unregister_io(int io_index) +{ + unsigned int i; + + for (i = 0; i < 3; i++) { + io_reads[io_index][i] = NULL; + io_writes[io_index][i] = NULL; + } + io_opaques[io_index] = NULL; + io_sizes[io_index] = 0; + io_used[io_index] = 0; +} + +void cpu_map_io(pio_addr_t start, int io_index) +{ + unsigned int i, j; + + assert(io_index >= 0); + for (i = start; i < start + io_sizes[io_index]; i++) { + for (j = 0; j < 3; j++) { + if (io_reads[io_index][j]) { + register_ioport_read(i, io_sizes[io_index], 1 << j, + io_reads[io_index][j], + io_opaques[io_index]); + } + if (io_writes[io_index][j]) { + register_ioport_write(i, io_sizes[io_index], 1 << j, + io_writes[io_index][j], + io_opaques[io_index]); + } + } + } +} + void isa_unassign_ioport(pio_addr_t start, int length) { int i; @@ -190,6 +280,11 @@ void isa_unassign_ioport(pio_addr_t start, int length) } } +void cpu_unmap_io(pio_addr_t start, int io_index) +{ + isa_unassign_ioport(start, io_sizes[io_index]); +} + /***********************************************************/ void cpu_outb(pio_addr_t addr, uint8_t val) diff --git a/ioport.h b/ioport.h index 3d3c8a3..4ba78ed 100644 --- a/ioport.h +++ b/ioport.h @@ -40,6 +40,12 @@ int register_ioport_read(pio_addr_t start, int length, int size, IOPortReadFunc *func, void *opaque); int register_ioport_write(pio_addr_t start, int length, int size, IOPortWriteFunc *func, void *opaque); +int cpu_register_io(IOPortReadFunc * const *io_read, + IOPortWriteFunc * const *io_write, + int size, void *opaque); +void cpu_unregister_io(int io_index); +void cpu_map_io(pio_addr_t start, int io_index); +void cpu_unmap_io(pio_addr_t start, int io_index); void isa_unassign_ioport(pio_addr_t start, int length);
Add I/O port registration functions which separate registration from the mapping stage. Move IOIO and MMIO BAR mapping to pci.c. TODO: fix dirty logging, coalesced MMIO and base address comparisons (eepro100 etc). Bridge filtering may be broken. Broke virtio-pci and MSIX. Signed-off-by: Blue Swirl <blauwirbel@gmail.com> --- i386 boots but resets. PPC and Sparc64 can't even start. Patch also available at git://repo.or.cz/qemu/blueswirl.git It may be worthwhile to break this into some kind of smaller steps. hw/ac97.c | 60 +++++++++++--------- hw/cirrus_vga.c | 40 +++----------- hw/e1000.c | 37 +----------- hw/eepro100.c | 77 ++++++++++---------------- hw/es1370.c | 32 +++++------ hw/ide/cmd646.c | 149 +++++++++++++++++++++++++++++++------------------- hw/ide/piix.c | 74 ++++++++++++++++--------- hw/ide/via.c | 67 ++++++++++++++-------- hw/isa.h | 1 + hw/isa_mmio.c | 17 +++++- hw/lsi53c895a.c | 60 ++++++-------------- hw/macio.c | 107 +++++++++++------------------------- hw/ne2000.c | 66 +++++++++++++++------- hw/openpic.c | 36 ++---------- hw/pci.c | 158 ++++++++++++++++++++++++++++++++-------------------- hw/pci.h | 18 +++++- hw/pcnet.c | 62 ++++++++++----------- hw/ppc_mac.h | 5 +- hw/ppc_newworld.c | 2 +- hw/ppc_oldworld.c | 4 +- hw/rtl8139.c | 42 +++++--------- hw/sun4u.c | 29 +++------ hw/usb-ohci.c | 10 +--- hw/usb-uhci.c | 31 +++++----- hw/vga-pci.c | 22 +------ hw/virtio-pci.c | 39 ++++++------- hw/vmware_vga.c | 107 ++++++++++++++++++------------------ hw/wdt_i6300esb.c | 38 +++++-------- ioport.c | 119 ++++++++++++++++++++++++++++++++++++---- ioport.h | 6 ++ 30 files changed, 778 insertions(+), 737 deletions(-)