diff --git a/hw/sun4c_intctl.c b/hw/sun4c_intctl.c index 1273213b4219b29a9ab044b961a44387a3e5025e..c9867da4540dd9f6199fc16df1e208005b8e6084 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) diff --git a/hw/sun4m.c b/hw/sun4m.c index 1e240179bb7207c5b013783144dba1cb2c396678..1e668fca1f48e41ea4d52e87fe24540fd066ed13 100644 --- a/hw/sun4m.c +++ b/hw/sun4m.c @@ -1502,13 +1502,15 @@ static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size, { CPUState *env; void *iommu, *espdma, *ledma, *nvram; - qemu_irq *cpu_irqs, *slavio_irq, espdma_irq, ledma_irq; + qemu_irq *cpu_irqs, slavio_irq[8], espdma_irq, ledma_irq; qemu_irq *esp_reset, *le_reset; qemu_irq fdc_tc; unsigned long kernel_size; BlockDriverState *fd[MAX_FD]; int drive_index; void *fw_cfg; + DeviceState *dev; + unsigned int i; /* init CPU */ if (!cpu_model) @@ -1521,8 +1523,11 @@ static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size, prom_init(hwdef->slavio_base, bios_name); - slavio_intctl = sun4c_intctl_init(hwdef->intctl_base, - &slavio_irq, cpu_irqs); + dev = sun4c_intctl_init(hwdef->intctl_base, cpu_irqs); + + for (i = 0; i < 8; i++) { + slavio_irq[i] = qdev_get_gpio_in(dev, i); + } iommu = iommu_init(hwdef->iommu_base, hwdef->iommu_version, slavio_irq[hwdef->me_irq]); diff --git a/hw/sun4m.h b/hw/sun4m.h index db4acb4aa80ce38147337f5656202f17df7acb7f..33d5010daf5ae851b1eb7a684be191352bfa22b8 100644 --- a/hw/sun4m.h +++ b/hw/sun4m.h @@ -39,8 +39,7 @@ void slavio_irq_info(Monitor *mon, void *opaque); DeviceState *sbi_init(target_phys_addr_t addr, qemu_irq **parent_irq); /* sun4c_intctl.c */ -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); void sun4c_pic_info(Monitor *mon, void *opaque); void sun4c_irq_info(Monitor *mon, void *opaque);