After playing around with this a bit, it might even be easier to register your IO port routines with the ISAPNP manager. The ISAPNP manager could then add/remove them from the global IO port list as necessary: isapnp_register_ioport_write(c, 0, 16, 1, ne2000_ioport_write, s); isapnp_register_ioport_read(c, 0, 16, 1, ne2000_ioport_read, s); Note that c is the ISAPNP context from below and 0 is the first bank of IO port registers. Matt. Matthew Mastracci wrote: >I was looking at how much work it would take to switch to using ISA-PNP >for resource management. I believe that it might simplify some of the >QEMU internals, as well as make things like having multiple >network/other devices much easier. It may make moving to PCI (or having >an option to boot with either ISAPNP or PCI on the fly) much easier. > >For anyone interested, the ISAPNP spec page is at: > > http://osdev.neopages.net/docs/PNP-ISA-v1.0a.pdf?the_id=54 > >I believe the best way to implement ISA-PNP would be for each device to >register an ISA-PNP context, then add specific resource requirements to >the context as necessary. The ISAPNP manager would then interact with >the operating system and call the isapnp_configure method whenever the >OS changes the setup. > >Perhaps something like this. I would imagine that the ISAPNP resource >manager would clear the IO port range back to the default IO port >manager before calling the *_isapnp_configure routine: > >static void ne2000_isapnp_configure(void* opaque, ISAPNPContext *c) >{ > /* Get the first IO port as the base IO address */ > int base = isapnp_get_ioport(c, 0); > > register_ioport_write(base, 16, 1, ne2000_ioport_write, s); > register_ioport_read(base, 16, 1, ne2000_ioport_read, s); > > register_ioport_write(base + 0x10, 1, 1, ne2000_asic_ioport_write, >s); > register_ioport_read(base + 0x10, 1, 1, ne2000_asic_ioport_read, s); > register_ioport_write(base + 0x10, 2, 2, ne2000_asic_ioport_write, >s); > register_ioport_read(base + 0x10, 2, 2, ne2000_asic_ioport_read, s); > > register_ioport_write(base + 0x1f, 1, 1, ne2000_reset_ioport_write, >s); > register_ioport_read(base + 0x1f, 1, 1, ne2000_reset_ioport_read, >s); > > s->irq = isapnp_get_irq(c, 0); > > /* Perhaps this would happen below... (?) */ > ne2000_reset(); >} > >void ne2000_init(int base, int irq, NetDriverState *nd) >{ > ISAPNPContext *c; > /* KTC2000 is an ISAPNP vendor ID for an NE2000 compatible card */ > /* No serial number specified here, ISAPNP manager can autogenerate >it */ > c = isapnp_create_context("KTC", 2000, ne2000_isapnp_configure, s); > > /* Need an edge-triggered IRQ, default is irq */ > isapnp_register_irq(IRQ_MODE_EDGE, irq); > > /* Need a block of 32 IO ports, default is base */ > isapnp_register_ioport(32, base); >} > >