diff --git a/hw/integratorcp.c b/hw/integratorcp.c index 7f27d075c2..3327b5ea8e 100644 --- a/hw/integratorcp.c +++ b/hw/integratorcp.c @@ -482,8 +482,8 @@ static void integratorcp_init(ram_addr_t ram_size, icp_pic_init(0xca000000, pic[26], NULL); icp_pit_init(0x13000000, pic, 5); pl031_init(0x15000000, pic[8]); - pl011_init(0x16000000, pic[1], serial_hds[0], PL011_ARM); - pl011_init(0x17000000, pic[2], serial_hds[1], PL011_ARM); + sysbus_create_simple("pl011", 0x16000000, pic[1]); + sysbus_create_simple("pl011", 0x17000000, pic[2]); icp_control_init(0xcb000000); pl050_init(0x18000000, pic[3], 0); pl050_init(0x19000000, pic[4], 1); diff --git a/hw/pl011.c b/hw/pl011.c index 3a4e149d48..3a1a4cbd9e 100644 --- a/hw/pl011.c +++ b/hw/pl011.c @@ -7,11 +7,11 @@ * This code is licenced under the GPL. */ -#include "hw.h" +#include "sysbus.h" #include "qemu-char.h" -#include "primecell.h" typedef struct { + SysBusDevice busdev; uint32_t readbuff; uint32_t flags; uint32_t lcr; @@ -29,7 +29,7 @@ typedef struct { int read_trigger; CharDriverState *chr; qemu_irq irq; - enum pl011_type type; + const unsigned char *id; } pl011_state; #define PL011_INT_TX 0x20 @@ -40,10 +40,10 @@ typedef struct { #define PL011_FLAG_TXFF 0x20 #define PL011_FLAG_RXFE 0x10 -static const unsigned char pl011_id[2][8] = { - { 0x11, 0x10, 0x14, 0x00, 0x0d, 0xf0, 0x05, 0xb1 }, /* PL011_ARM */ - { 0x11, 0x00, 0x18, 0x01, 0x0d, 0xf0, 0x05, 0xb1 }, /* PL011_LUMINARY */ -}; +static const unsigned char pl011_id_arm[8] = + { 0x11, 0x10, 0x14, 0x00, 0x0d, 0xf0, 0x05, 0xb1 }; +static const unsigned char pl011_id_luminary[8] = + { 0x11, 0x00, 0x18, 0x01, 0x0d, 0xf0, 0x05, 0xb1 }; static void pl011_update(pl011_state *s) { @@ -59,7 +59,7 @@ static uint32_t pl011_read(void *opaque, target_phys_addr_t offset) uint32_t c; if (offset >= 0xfe0 && offset < 0x1000) { - return pl011_id[s->type][(offset - 0xfe0) >> 2]; + return s->id[(offset - 0xfe0) >> 2]; } switch (offset >> 2) { case 0: /* UARTDR */ @@ -286,26 +286,45 @@ static int pl011_load(QEMUFile *f, void *opaque, int version_id) return 0; } -void pl011_init(uint32_t base, qemu_irq irq, - CharDriverState *chr, enum pl011_type type) +static void pl011_init(SysBusDevice *dev, const unsigned char *id) { int iomemtype; - pl011_state *s; + pl011_state *s = FROM_SYSBUS(pl011_state, dev); - s = (pl011_state *)qemu_mallocz(sizeof(pl011_state)); iomemtype = cpu_register_io_memory(0, pl011_readfn, pl011_writefn, s); - cpu_register_physical_memory(base, 0x00001000, iomemtype); - s->irq = irq; - s->type = type; - s->chr = chr; + sysbus_init_mmio(dev, 0x1000,iomemtype); + sysbus_init_irq(dev, &s->irq); + s->id = id; + s->chr = qdev_init_chardev(&dev->qdev); + s->read_trigger = 1; s->ifl = 0x12; s->cr = 0x300; s->flags = 0x90; - if (chr){ - qemu_chr_add_handlers(chr, pl011_can_receive, pl011_receive, + if (s->chr) { + qemu_chr_add_handlers(s->chr, pl011_can_receive, pl011_receive, pl011_event, s); } register_savevm("pl011_uart", -1, 1, pl011_save, pl011_load, s); } + +static void pl011_init_arm(SysBusDevice *dev) +{ + pl011_init(dev, pl011_id_arm); +} + +static void pl011_init_luminary(SysBusDevice *dev) +{ + pl011_init(dev, pl011_id_luminary); +} + +static void pl011_register_devices(void) +{ + sysbus_register_dev("pl011", sizeof(pl011_state), + pl011_init_arm); + sysbus_register_dev("pl011_luminary", sizeof(pl011_state), + pl011_init_luminary); +} + +device_init(pl011_register_devices) diff --git a/hw/primecell.h b/hw/primecell.h index 5d270ffe98..714fc785ed 100644 --- a/hw/primecell.h +++ b/hw/primecell.h @@ -8,15 +8,6 @@ /* pl031.c */ void pl031_init(uint32_t base, qemu_irq irq); -/* pl011.c */ -enum pl011_type { - PL011_ARM, - PL011_LUMINARY -}; - -void pl011_init(uint32_t base, qemu_irq irq, CharDriverState *chr, - enum pl011_type type); - /* pl022.c */ typedef int (*ssi_xfer_cb)(void *, int); void pl022_init(uint32_t base, qemu_irq irq, ssi_xfer_cb xfer_cb, diff --git a/hw/realview.c b/hw/realview.c index 4c24ac25d4..bbfa56b1c8 100644 --- a/hw/realview.c +++ b/hw/realview.c @@ -85,10 +85,10 @@ static void realview_init(ram_addr_t ram_size, pl050_init(0x10006000, pic[20], 0); pl050_init(0x10007000, pic[21], 1); - pl011_init(0x10009000, pic[12], serial_hds[0], PL011_ARM); - pl011_init(0x1000a000, pic[13], serial_hds[1], PL011_ARM); - pl011_init(0x1000b000, pic[14], serial_hds[2], PL011_ARM); - pl011_init(0x1000c000, pic[15], serial_hds[3], PL011_ARM); + sysbus_create_simple("pl011", 0x10009000, pic[12]); + sysbus_create_simple("pl011", 0x1000a000, pic[13]); + sysbus_create_simple("pl011", 0x1000b000, pic[14]); + sysbus_create_simple("pl011", 0x1000c000, pic[15]); /* DMA controller is optional, apparently. */ pl080_init(0x10030000, pic[24], 2); diff --git a/hw/stellaris.c b/hw/stellaris.c index cfd1de9600..31206c34f2 100644 --- a/hw/stellaris.c +++ b/hw/stellaris.c @@ -7,7 +7,7 @@ * This code is licenced under the GPL. */ -#include "hw.h" +#include "sysbus.h" #include "arm-misc.h" #include "primecell.h" #include "devices.h" @@ -1330,8 +1330,8 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, for (i = 0; i < 4; i++) { if (board->dc2 & (1 << i)) { - pl011_init(0x4000c000 + i * 0x1000, pic[uart_irq[i]], - serial_hds[i], PL011_LUMINARY); + sysbus_create_simple("pl011_luminary", 0x4000c000 + i * 0x1000, + pic[uart_irq[i]]); } } if (board->dc2 & (1 << 4)) { diff --git a/hw/versatilepb.c b/hw/versatilepb.c index f00ebf95c3..bde07bf4ca 100644 --- a/hw/versatilepb.c +++ b/hw/versatilepb.c @@ -217,10 +217,10 @@ static void versatile_init(ram_addr_t ram_size, lsi_scsi_attach(scsi_hba, drives_table[index].bdrv, n); } - pl011_init(0x101f1000, pic[12], serial_hds[0], PL011_ARM); - pl011_init(0x101f2000, pic[13], serial_hds[1], PL011_ARM); - pl011_init(0x101f3000, pic[14], serial_hds[2], PL011_ARM); - pl011_init(0x10009000, sic[6], serial_hds[3], PL011_ARM); + sysbus_create_simple("pl011", 0x101f1000, pic[12]); + sysbus_create_simple("pl011", 0x101f2000, pic[13]); + sysbus_create_simple("pl011", 0x101f3000, pic[14]); + sysbus_create_simple("pl011", 0x10009000, sic[6]); pl080_init(0x10130000, pic[17], 8); sp804_init(0x101e2000, pic[4]);