diff options
Diffstat (limited to 'hw/sun4c_intctl.c')
-rw-r--r-- | hw/sun4c_intctl.c | 63 |
1 files changed, 48 insertions, 15 deletions
diff --git a/hw/sun4c_intctl.c b/hw/sun4c_intctl.c index 1273213b42..c9867da454 100644 --- a/hw/sun4c_intctl.c +++ b/hw/sun4c_intctl.c @@ -21,9 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + #include "hw.h" #include "sun4m.h" #include "monitor.h" +#include "sysbus.h" + //#define DEBUG_IRQ_COUNT //#define DEBUG_IRQ @@ -42,10 +45,11 @@ #define MAX_PILS 16 typedef struct Sun4c_INTCTLState { + SysBusDevice busdev; #ifdef DEBUG_IRQ_COUNT uint64_t irq_count; #endif - qemu_irq *cpu_irqs; + qemu_irq cpu_irqs[MAX_PILS]; const uint32_t *intbit_to_level; uint32_t pil_out; uint8_t reg; @@ -194,25 +198,54 @@ static void sun4c_intctl_reset(void *opaque) s->pending = 0; } -void *sun4c_intctl_init(target_phys_addr_t addr, qemu_irq **irq, - qemu_irq *parent_irq) +DeviceState *sun4c_intctl_init(target_phys_addr_t addr, qemu_irq *parent_irq) { - int sun4c_intctl_io_memory; - Sun4c_INTCTLState *s; + DeviceState *dev; + SysBusDevice *s; + unsigned int i; - s = qemu_mallocz(sizeof(Sun4c_INTCTLState)); + dev = qdev_create(NULL, "sun4c_intctl"); + qdev_init(dev); - sun4c_intctl_io_memory = cpu_register_io_memory(sun4c_intctl_mem_read, - sun4c_intctl_mem_write, s); - cpu_register_physical_memory(addr, INTCTL_SIZE, sun4c_intctl_io_memory); - s->cpu_irqs = parent_irq; + s = sysbus_from_qdev(dev); - register_savevm("sun4c_intctl", addr, 1, sun4c_intctl_save, - sun4c_intctl_load, s); + for (i = 0; i < MAX_PILS; i++) { + sysbus_connect_irq(s, i, parent_irq[i]); + } + sysbus_mmio_map(s, 0, addr); - qemu_register_reset(sun4c_intctl_reset, s); - *irq = qemu_allocate_irqs(sun4c_set_irq, s, 8); + return dev; +} + +static void sun4c_intctl_init1(SysBusDevice *dev) +{ + Sun4c_INTCTLState *s = FROM_SYSBUS(Sun4c_INTCTLState, dev); + int io_memory; + unsigned int i; + io_memory = cpu_register_io_memory(sun4c_intctl_mem_read, + sun4c_intctl_mem_write, s); + sysbus_init_mmio(dev, INTCTL_SIZE, io_memory); + qdev_init_gpio_in(&dev->qdev, sun4c_set_irq, 8); + + for (i = 0; i < MAX_PILS; i++) { + sysbus_init_irq(dev, &s->cpu_irqs[i]); + } + register_savevm("sun4c_intctl", -1, 1, sun4c_intctl_save, + sun4c_intctl_load, s); + qemu_register_reset(sun4c_intctl_reset, s); sun4c_intctl_reset(s); - return s; } + +static SysBusDeviceInfo sun4c_intctl_info = { + .init = sun4c_intctl_init1, + .qdev.name = "sun4c_intctl", + .qdev.size = sizeof(Sun4c_INTCTLState), +}; + +static void sun4c_intctl_register_devices(void) +{ + sysbus_register_withprop(&sun4c_intctl_info); +} + +device_init(sun4c_intctl_register_devices) |