diff options
Diffstat (limited to 'hw/pl011.c')
-rw-r--r-- | hw/pl011.c | 55 |
1 files changed, 37 insertions, 18 deletions
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) |