diff --git a/hw/sbi.c b/hw/sbi.c index 32c8fa9446154e6f050835c6edef627310fc5462..101fba5ae6edf631c3e5e90b29cc5b4aac0d9fec 100644 --- a/hw/sbi.c +++ b/hw/sbi.c @@ -21,9 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + #include "hw.h" #include "sun4m.h" #include "console.h" +#include "sysbus.h" //#define DEBUG_IRQ @@ -39,9 +41,10 @@ #define SBI_NREGS 16 typedef struct SBIState { + SysBusDevice busdev; uint32_t regs[SBI_NREGS]; uint32_t intreg_pending[MAX_CPUS]; - qemu_irq *cpu_irqs[MAX_CPUS]; + qemu_irq cpu_irqs[MAX_CPUS]; uint32_t pil_out[MAX_CPUS]; } SBIState; @@ -51,10 +54,6 @@ static void sbi_set_irq(void *opaque, int irq, int level) { } -static void sbi_set_timer_irq_cpu(void *opaque, int cpu, int level) -{ -} - static uint32_t sbi_mem_readl(void *opaque, target_phys_addr_t addr) { SBIState *s = opaque; @@ -132,27 +131,54 @@ static void sbi_reset(void *opaque) } } -void *sbi_init(target_phys_addr_t addr, qemu_irq **irq, qemu_irq **cpu_irq, - qemu_irq **parent_irq) +DeviceState *sbi_init(target_phys_addr_t addr, qemu_irq **parent_irq) { + DeviceState *dev; + SysBusDevice *s; unsigned int i; - int sbi_io_memory; - SBIState *s; - s = qemu_mallocz(sizeof(SBIState)); + dev = qdev_create(NULL, "sbi"); + qdev_init(dev); + + s = sysbus_from_qdev(dev); for (i = 0; i < MAX_CPUS; i++) { - s->cpu_irqs[i] = parent_irq[i]; + sysbus_connect_irq(s, i, *parent_irq[i]); + } + + sysbus_mmio_map(s, 0, addr); + + return dev; +} + +static void sbi_init1(SysBusDevice *dev) +{ + SBIState *s = FROM_SYSBUS(SBIState, dev); + int sbi_io_memory; + unsigned int i; + + qdev_init_gpio_in(&dev->qdev, sbi_set_irq, 32 + MAX_CPUS); + for (i = 0; i < MAX_CPUS; i++) { + sysbus_init_irq(dev, &s->cpu_irqs[i]); } sbi_io_memory = cpu_register_io_memory(sbi_mem_read, sbi_mem_write, s); - cpu_register_physical_memory(addr, SBI_SIZE, sbi_io_memory); + sysbus_init_mmio(dev, SBI_SIZE, sbi_io_memory); - register_savevm("sbi", addr, 1, sbi_save, sbi_load, s); + register_savevm("sbi", -1, 1, sbi_save, sbi_load, s); qemu_register_reset(sbi_reset, s); - *irq = qemu_allocate_irqs(sbi_set_irq, s, 32); - *cpu_irq = qemu_allocate_irqs(sbi_set_timer_irq_cpu, s, MAX_CPUS); sbi_reset(s); +} + +static SysBusDeviceInfo sbi_info = { + .init = sbi_init1, + .qdev.name = "sbi", + .qdev.size = sizeof(SBIState), +}; - return s; +static void sbi_register_devices(void) +{ + sysbus_register_withprop(&sbi_info); } + +device_init(sbi_register_devices) diff --git a/hw/sun4m.c b/hw/sun4m.c index 9e4bfac9fefb903effab5ab4defc79ac790c02f0..1e240179bb7207c5b013783144dba1cb2c396678 100644 --- a/hw/sun4m.c +++ b/hw/sun4m.c @@ -1322,12 +1322,13 @@ static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, ram_addr_t RAM_size, { CPUState *envs[MAX_CPUS]; unsigned int i; - void *iounits[MAX_IOUNITS], *espdma, *ledma, *nvram, *sbi; - qemu_irq *cpu_irqs[MAX_CPUS], *sbi_irq, *sbi_cpu_irq, + void *iounits[MAX_IOUNITS], *espdma, *ledma, *nvram; + qemu_irq *cpu_irqs[MAX_CPUS], sbi_irq[32], sbi_cpu_irq[MAX_CPUS], espdma_irq, ledma_irq; qemu_irq *esp_reset, *le_reset; unsigned long kernel_size; void *fw_cfg; + DeviceState *dev; /* init CPUs */ if (!cpu_model) @@ -1345,7 +1346,14 @@ static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, ram_addr_t RAM_size, prom_init(hwdef->slavio_base, bios_name); - sbi = sbi_init(hwdef->sbi_base, &sbi_irq, &sbi_cpu_irq, cpu_irqs); + dev = sbi_init(hwdef->sbi_base, cpu_irqs); + + for (i = 0; i < 32; i++) { + sbi_irq[i] = qdev_get_gpio_in(dev, i); + } + for (i = 0; i < MAX_CPUS; i++) { + sbi_cpu_irq[i] = qdev_get_gpio_in(dev, 32 + i); + } for (i = 0; i < MAX_IOUNITS; i++) if (hwdef->iounit_bases[i] != (target_phys_addr_t)-1) diff --git a/hw/sun4m.h b/hw/sun4m.h index d818fb1840e93f574c4f715c22e931ecb0a041fc..db4acb4aa80ce38147337f5656202f17df7acb7f 100644 --- a/hw/sun4m.h +++ b/hw/sun4m.h @@ -36,8 +36,7 @@ void slavio_pic_info(Monitor *mon, void *opaque); void slavio_irq_info(Monitor *mon, void *opaque); /* sbi.c */ -void *sbi_init(target_phys_addr_t addr, qemu_irq **irq, qemu_irq **cpu_irq, - qemu_irq **parent_irq); +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,