diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2022-07-19 09:57:13 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2022-07-19 09:57:13 +0100 |
commit | f9d9fff72eed03acde97ea2d66104748dc474b2e (patch) | |
tree | da84931a6e68fdd730d25b5d066350ca551362d0 /hw | |
parent | b8bb9bbf4695b89bbdca702a054db0a7a2c8ff2b (diff) | |
parent | b704d63d094cc757c20c186ff40d692deb5e30de (diff) |
Merge tag 'qemu-sparc-20220718' of https://github.com/mcayland/qemu into staging
qemu-sparc queue
# gpg: Signature made Mon 18 Jul 2022 19:29:32 BST
# gpg: using RSA key CC621AB98E82200D915CC9C45BC2C56FAE0F321F
# gpg: issuer "mark.cave-ayland@ilande.co.uk"
# gpg: Good signature from "Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>" [full]
# Primary key fingerprint: CC62 1AB9 8E82 200D 915C C9C4 5BC2 C56F AE0F 321F
* tag 'qemu-sparc-20220718' of https://github.com/mcayland/qemu: (40 commits)
pckbd: remove legacy i8042_mm_init() function
ps2: remove unused legacy ps2_mouse_init() function
pckbd: don't use legacy ps2_mouse_init() function
ps2: remove unused legacy ps2_kbd_init() function
pckbd: don't use legacy ps2_kbd_init() function
pckbd: introduce new vmstate_kbd_mmio VMStateDescription for the I8042_MMIO device
lasips2: update VMStateDescription for LASIPS2 device
lasips2: don't use legacy ps2_mouse_init() function
lasips2: don't use legacy ps2_kbd_init() function
lasips2: switch register memory region to DEVICE_BIG_ENDIAN
lasips2: standardise on lp name for LASIPS2Port variables
lasips2: rename LASIPS2Port parent pointer to lasips2
lasips2: switch to using port-based IRQs
lasips2: add named input gpio to handle incoming port IRQs
lasips2: add named input gpio to port for downstream PS2 device IRQ
lasips2: introduce LASIPS2PortDeviceClass for the LASIPS2_PORT device
lasips2: introduce port IRQ and new lasips2_port_init() function
lasips2: rename LASIPS2Port irq field to birq
lasips2: introduce lasips2_mouse_port_class_init() and lasips2_mouse_port_realize()
lasips2: introduce lasips2_kbd_port_class_init() and lasips2_kbd_port_realize()
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/hppa/machine.c | 7 | ||||
-rw-r--r-- | hw/input/lasips2.c | 320 | ||||
-rw-r--r-- | hw/input/pckbd.c | 82 | ||||
-rw-r--r-- | hw/input/pl050.c | 112 | ||||
-rw-r--r-- | hw/input/ps2.c | 26 | ||||
-rw-r--r-- | hw/input/trace-events | 2 | ||||
-rw-r--r-- | hw/mips/jazz.c | 13 |
7 files changed, 362 insertions, 200 deletions
diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c index 44ecd446c3..e53d5f0fa7 100644 --- a/hw/hppa/machine.c +++ b/hw/hppa/machine.c @@ -280,9 +280,10 @@ static void machine_hppa_init(MachineState *machine) } /* PS/2 Keyboard/Mouse */ - dev = DEVICE(lasips2_initfn(LASI_PS2KBD_HPA, - qdev_get_gpio_in(lasi_dev, - LASI_IRQ_PS2KBD_HPA))); + dev = qdev_new(TYPE_LASIPS2); + sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); + sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, + qdev_get_gpio_in(lasi_dev, LASI_IRQ_PS2KBD_HPA)); memory_region_add_subregion(addr_space, LASI_PS2KBD_HPA, sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0)); diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c index 9223cb0af4..ea7c07a2ba 100644 --- a/hw/input/lasips2.c +++ b/hw/input/lasips2.c @@ -35,17 +35,28 @@ #include "qapi/error.h" +static const VMStateDescription vmstate_lasips2_port = { + .name = "lasips2-port", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT8(control, LASIPS2Port), + VMSTATE_UINT8(buf, LASIPS2Port), + VMSTATE_BOOL(loopback_rbne, LASIPS2Port), + VMSTATE_END_OF_LIST() + } +}; + static const VMStateDescription vmstate_lasips2 = { .name = "lasips2", - .version_id = 0, - .minimum_version_id = 0, + .version_id = 1, + .minimum_version_id = 1, .fields = (VMStateField[]) { - VMSTATE_UINT8(kbd.control, LASIPS2State), - VMSTATE_UINT8(kbd.id, LASIPS2State), - VMSTATE_BOOL(kbd.irq, LASIPS2State), - VMSTATE_UINT8(mouse.control, LASIPS2State), - VMSTATE_UINT8(mouse.id, LASIPS2State), - VMSTATE_BOOL(mouse.irq, LASIPS2State), + VMSTATE_UINT8(int_status, LASIPS2State), + VMSTATE_STRUCT(kbd_port.parent_obj, LASIPS2State, 1, + vmstate_lasips2_port, LASIPS2Port), + VMSTATE_STRUCT(mouse_port.parent_obj, LASIPS2State, 1, + vmstate_lasips2_port, LASIPS2Port), VMSTATE_END_OF_LIST() } }; @@ -119,36 +130,50 @@ static const char *lasips2_write_reg_name(uint64_t addr) static void lasips2_update_irq(LASIPS2State *s) { - trace_lasips2_intr(s->kbd.irq | s->mouse.irq); - qemu_set_irq(s->irq, s->kbd.irq | s->mouse.irq); + int level = s->int_status ? 1 : 0; + + trace_lasips2_intr(level); + qemu_set_irq(s->irq, level); +} + +static void lasips2_set_irq(void *opaque, int n, int level) +{ + LASIPS2State *s = LASIPS2(opaque); + + if (level) { + s->int_status |= BIT(n); + } else { + s->int_status &= ~BIT(n); + } + + lasips2_update_irq(s); } static void lasips2_reg_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { - LASIPS2Port *port = opaque; + LASIPS2Port *lp = LASIPS2_PORT(opaque); - trace_lasips2_reg_write(size, port->id, addr, + trace_lasips2_reg_write(size, lp->id, addr, lasips2_write_reg_name(addr), val); switch (addr & 0xc) { case REG_PS2_CONTROL: - port->control = val; + lp->control = val; break; case REG_PS2_XMTDATA: - if (port->control & LASIPS2_CONTROL_LOOPBACK) { - port->buf = val; - port->irq = true; - port->loopback_rbne = true; - lasips2_update_irq(port->parent); + if (lp->control & LASIPS2_CONTROL_LOOPBACK) { + lp->buf = val; + lp->loopback_rbne = true; + qemu_set_irq(lp->irq, 1); break; } - if (port->id) { - ps2_write_mouse(port->dev, val); + if (lp->id) { + ps2_write_mouse(PS2_MOUSE_DEVICE(lp->ps2dev), val); } else { - ps2_write_keyboard(port->dev, val); + ps2_write_keyboard(PS2_KBD_DEVICE(lp->ps2dev), val); } break; @@ -164,54 +189,53 @@ static void lasips2_reg_write(void *opaque, hwaddr addr, uint64_t val, static uint64_t lasips2_reg_read(void *opaque, hwaddr addr, unsigned size) { - LASIPS2Port *port = opaque; + LASIPS2Port *lp = LASIPS2_PORT(opaque); uint64_t ret = 0; switch (addr & 0xc) { case REG_PS2_ID: - ret = port->id; + ret = lp->id; break; case REG_PS2_RCVDATA: - if (port->control & LASIPS2_CONTROL_LOOPBACK) { - port->irq = false; - port->loopback_rbne = false; - lasips2_update_irq(port->parent); - ret = port->buf; + if (lp->control & LASIPS2_CONTROL_LOOPBACK) { + lp->loopback_rbne = false; + qemu_set_irq(lp->irq, 0); + ret = lp->buf; break; } - ret = ps2_read_data(port->dev); + ret = ps2_read_data(lp->ps2dev); break; case REG_PS2_CONTROL: - ret = port->control; + ret = lp->control; break; case REG_PS2_STATUS: ret = LASIPS2_STATUS_DATSHD | LASIPS2_STATUS_CLKSHD; - if (port->control & LASIPS2_CONTROL_DIAG) { - if (!(port->control & LASIPS2_CONTROL_DATDIR)) { + if (lp->control & LASIPS2_CONTROL_DIAG) { + if (!(lp->control & LASIPS2_CONTROL_DATDIR)) { ret &= ~LASIPS2_STATUS_DATSHD; } - if (!(port->control & LASIPS2_CONTROL_CLKDIR)) { + if (!(lp->control & LASIPS2_CONTROL_CLKDIR)) { ret &= ~LASIPS2_STATUS_CLKSHD; } } - if (port->control & LASIPS2_CONTROL_LOOPBACK) { - if (port->loopback_rbne) { + if (lp->control & LASIPS2_CONTROL_LOOPBACK) { + if (lp->loopback_rbne) { ret |= LASIPS2_STATUS_RBNE; } } else { - if (!ps2_queue_empty(port->dev)) { + if (!ps2_queue_empty(lp->ps2dev)) { ret |= LASIPS2_STATUS_RBNE; } } - if (port->parent->kbd.irq || port->parent->mouse.irq) { + if (lp->lasips2->int_status) { ret |= LASIPS2_STATUS_CMPINTR; } break; @@ -222,7 +246,7 @@ static uint64_t lasips2_reg_read(void *opaque, hwaddr addr, unsigned size) break; } - trace_lasips2_reg_read(size, port->id, addr, + trace_lasips2_reg_read(size, lp->id, addr, lasips2_read_reg_name(addr), ret); return ret; } @@ -234,106 +258,208 @@ static const MemoryRegionOps lasips2_reg_ops = { .min_access_size = 1, .max_access_size = 4, }, - .endianness = DEVICE_NATIVE_ENDIAN, + .endianness = DEVICE_BIG_ENDIAN, }; -static void lasips2_set_kbd_irq(void *opaque, int n, int level) +static void lasips2_realize(DeviceState *dev, Error **errp) { - LASIPS2State *s = LASIPS2(opaque); - LASIPS2Port *port = &s->kbd; + LASIPS2State *s = LASIPS2(dev); + LASIPS2Port *lp; - port->irq = level; - lasips2_update_irq(port->parent); + lp = LASIPS2_PORT(&s->kbd_port); + if (!(qdev_realize(DEVICE(lp), NULL, errp))) { + return; + } + + qdev_connect_gpio_out(DEVICE(lp), 0, + qdev_get_gpio_in_named(dev, "lasips2-port-input-irq", + lp->id)); + + lp = LASIPS2_PORT(&s->mouse_port); + if (!(qdev_realize(DEVICE(lp), NULL, errp))) { + return; + } + + qdev_connect_gpio_out(DEVICE(lp), 0, + qdev_get_gpio_in_named(dev, "lasips2-port-input-irq", + lp->id)); } -static void lasips2_set_mouse_irq(void *opaque, int n, int level) +static void lasips2_init(Object *obj) { - LASIPS2State *s = LASIPS2(opaque); - LASIPS2Port *port = &s->mouse; + LASIPS2State *s = LASIPS2(obj); + LASIPS2Port *lp; + + object_initialize_child(obj, "lasips2-kbd-port", &s->kbd_port, + TYPE_LASIPS2_KBD_PORT); + object_initialize_child(obj, "lasips2-mouse-port", &s->mouse_port, + TYPE_LASIPS2_MOUSE_PORT); + + lp = LASIPS2_PORT(&s->kbd_port); + sysbus_init_mmio(SYS_BUS_DEVICE(obj), &lp->reg); + lp = LASIPS2_PORT(&s->mouse_port); + sysbus_init_mmio(SYS_BUS_DEVICE(obj), &lp->reg); + + sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq); - port->irq = level; - lasips2_update_irq(port->parent); + qdev_init_gpio_in_named(DEVICE(obj), lasips2_set_irq, + "lasips2-port-input-irq", 2); } -LASIPS2State *lasips2_initfn(hwaddr base, qemu_irq irq) +static void lasips2_class_init(ObjectClass *klass, void *data) { - DeviceState *dev; + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->realize = lasips2_realize; + dc->vmsd = &vmstate_lasips2; + set_bit(DEVICE_CATEGORY_INPUT, dc->categories); +} - dev = qdev_new(TYPE_LASIPS2); - qdev_prop_set_uint64(dev, "base", base); - sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); +static const TypeInfo lasips2_info = { + .name = TYPE_LASIPS2, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_init = lasips2_init, + .instance_size = sizeof(LASIPS2State), + .class_init = lasips2_class_init, +}; - sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq); +static void lasips2_port_set_irq(void *opaque, int n, int level) +{ + LASIPS2Port *s = LASIPS2_PORT(opaque); - return LASIPS2(dev); + qemu_set_irq(s->irq, level); } -static void lasips2_realize(DeviceState *dev, Error **errp) +static void lasips2_port_realize(DeviceState *dev, Error **errp) { - LASIPS2State *s = LASIPS2(dev); + LASIPS2Port *s = LASIPS2_PORT(dev); - vmstate_register(NULL, s->base, &vmstate_lasips2, s); + qdev_connect_gpio_out(DEVICE(s->ps2dev), PS2_DEVICE_IRQ, + qdev_get_gpio_in_named(dev, "ps2-input-irq", 0)); +} + +static void lasips2_port_init(Object *obj) +{ + LASIPS2Port *s = LASIPS2_PORT(obj); - s->kbd.dev = ps2_kbd_init(); - qdev_connect_gpio_out(DEVICE(s->kbd.dev), PS2_DEVICE_IRQ, - qdev_get_gpio_in_named(dev, "ps2-kbd-input-irq", - 0)); - s->mouse.dev = ps2_mouse_init(); - qdev_connect_gpio_out(DEVICE(s->mouse.dev), PS2_DEVICE_IRQ, - qdev_get_gpio_in_named(dev, "ps2-mouse-input-irq", - 0)); + qdev_init_gpio_out(DEVICE(obj), &s->irq, 1); + qdev_init_gpio_in_named(DEVICE(obj), lasips2_port_set_irq, + "ps2-input-irq", 1); } -static void lasips2_init(Object *obj) +static void lasips2_port_class_init(ObjectClass *klass, void *data) { - LASIPS2State *s = LASIPS2(obj); + DeviceClass *dc = DEVICE_CLASS(klass); - s->kbd.id = 0; - s->mouse.id = 1; - s->kbd.parent = s; - s->mouse.parent = s; + dc->realize = lasips2_port_realize; +} - memory_region_init_io(&s->kbd.reg, obj, &lasips2_reg_ops, &s->kbd, - "lasips2-kbd", 0x100); - memory_region_init_io(&s->mouse.reg, obj, &lasips2_reg_ops, &s->mouse, - "lasips2-mouse", 0x100); +static const TypeInfo lasips2_port_info = { + .name = TYPE_LASIPS2_PORT, + .parent = TYPE_DEVICE, + .instance_init = lasips2_port_init, + .instance_size = sizeof(LASIPS2Port), + .class_init = lasips2_port_class_init, + .class_size = sizeof(LASIPS2PortDeviceClass), + .abstract = true, +}; - sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->kbd.reg); - sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mouse.reg); +static void lasips2_kbd_port_realize(DeviceState *dev, Error **errp) +{ + LASIPS2KbdPort *s = LASIPS2_KBD_PORT(dev); + LASIPS2Port *lp = LASIPS2_PORT(dev); + LASIPS2PortDeviceClass *lpdc = LASIPS2_PORT_GET_CLASS(lp); - sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq); + if (!sysbus_realize(SYS_BUS_DEVICE(&s->kbd), errp)) { + return; + } + + lp->ps2dev = PS2_DEVICE(&s->kbd); + lpdc->parent_realize(dev, errp); +} + +static void lasips2_kbd_port_init(Object *obj) +{ + LASIPS2KbdPort *s = LASIPS2_KBD_PORT(obj); + LASIPS2Port *lp = LASIPS2_PORT(obj); + + memory_region_init_io(&lp->reg, obj, &lasips2_reg_ops, lp, "lasips2-kbd", + 0x100); + + object_initialize_child(obj, "kbd", &s->kbd, TYPE_PS2_KBD_DEVICE); + + lp->id = 0; + lp->lasips2 = container_of(s, LASIPS2State, kbd_port); +} + +static void lasips2_kbd_port_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + LASIPS2PortDeviceClass *lpdc = LASIPS2_PORT_CLASS(klass); - qdev_init_gpio_in_named(DEVICE(obj), lasips2_set_kbd_irq, - "ps2-kbd-input-irq", 1); - qdev_init_gpio_in_named(DEVICE(obj), lasips2_set_mouse_irq, - "ps2-mouse-input-irq", 1); + device_class_set_parent_realize(dc, lasips2_kbd_port_realize, + &lpdc->parent_realize); } -static Property lasips2_properties[] = { - DEFINE_PROP_UINT64("base", LASIPS2State, base, UINT64_MAX), - DEFINE_PROP_END_OF_LIST(), +static const TypeInfo lasips2_kbd_port_info = { + .name = TYPE_LASIPS2_KBD_PORT, + .parent = TYPE_LASIPS2_PORT, + .instance_size = sizeof(LASIPS2KbdPort), + .instance_init = lasips2_kbd_port_init, + .class_init = lasips2_kbd_port_class_init, }; -static void lasips2_class_init(ObjectClass *klass, void *data) +static void lasips2_mouse_port_realize(DeviceState *dev, Error **errp) +{ + LASIPS2MousePort *s = LASIPS2_MOUSE_PORT(dev); + LASIPS2Port *lp = LASIPS2_PORT(dev); + LASIPS2PortDeviceClass *lpdc = LASIPS2_PORT_GET_CLASS(lp); + + if (!sysbus_realize(SYS_BUS_DEVICE(&s->mouse), errp)) { + return; + } + + lp->ps2dev = PS2_DEVICE(&s->mouse); + lpdc->parent_realize(dev, errp); +} + +static void lasips2_mouse_port_init(Object *obj) +{ + LASIPS2MousePort *s = LASIPS2_MOUSE_PORT(obj); + LASIPS2Port *lp = LASIPS2_PORT(obj); + + memory_region_init_io(&lp->reg, obj, &lasips2_reg_ops, lp, "lasips2-mouse", + 0x100); + + object_initialize_child(obj, "mouse", &s->mouse, TYPE_PS2_MOUSE_DEVICE); + + lp->id = 1; + lp->lasips2 = container_of(s, LASIPS2State, mouse_port); +} + +static void lasips2_mouse_port_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + LASIPS2PortDeviceClass *lpdc = LASIPS2_PORT_CLASS(klass); - dc->realize = lasips2_realize; - device_class_set_props(dc, lasips2_properties); - set_bit(DEVICE_CATEGORY_INPUT, dc->categories); + device_class_set_parent_realize(dc, lasips2_mouse_port_realize, + &lpdc->parent_realize); } -static const TypeInfo lasips2_info = { - .name = TYPE_LASIPS2, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_init = lasips2_init, - .instance_size = sizeof(LASIPS2State), - .class_init = lasips2_class_init, +static const TypeInfo lasips2_mouse_port_info = { + .name = TYPE_LASIPS2_MOUSE_PORT, + .parent = TYPE_LASIPS2_PORT, + .instance_size = sizeof(LASIPS2MousePort), + .instance_init = lasips2_mouse_port_init, + .class_init = lasips2_mouse_port_class_init, }; static void lasips2_register_types(void) { type_register_static(&lasips2_info); + type_register_static(&lasips2_port_info); + type_register_static(&lasips2_kbd_port_info); + type_register_static(&lasips2_mouse_port_info); } type_init(lasips2_register_types) diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c index 9184411c3e..b92b63bedc 100644 --- a/hw/input/pckbd.c +++ b/hw/input/pckbd.c @@ -286,7 +286,7 @@ static void kbd_queue(KBDState *s, int b, int aux) s->pending |= aux ? KBD_PENDING_CTRL_AUX : KBD_PENDING_CTRL_KBD; kbd_safe_update_irq(s); } else { - ps2_queue(aux ? s->mouse : s->kbd, b); + ps2_queue(aux ? PS2_DEVICE(&s->ps2mouse) : PS2_DEVICE(&s->ps2kbd), b); } } @@ -408,9 +408,9 @@ static uint64_t kbd_read_data(void *opaque, hwaddr addr, timer_mod(s->throttle_timer, qemu_clock_get_us(QEMU_CLOCK_VIRTUAL) + 1000); } - s->obdata = ps2_read_data(s->kbd); + s->obdata = ps2_read_data(PS2_DEVICE(&s->ps2kbd)); } else if (s->obsrc & KBD_OBSRC_MOUSE) { - s->obdata = ps2_read_data(s->mouse); + s->obdata = ps2_read_data(PS2_DEVICE(&s->ps2mouse)); } else if (s->obsrc & KBD_OBSRC_CTRL) { s->obdata = kbd_dequeue(s); } @@ -429,14 +429,15 @@ static void kbd_write_data(void *opaque, hwaddr addr, switch (s->write_cmd) { case 0: - ps2_write_keyboard(s->kbd, val); + ps2_write_keyboard(&s->ps2kbd, val); /* sending data to the keyboard reenables PS/2 communication */ s->mode &= ~KBD_MODE_DISABLE_KBD; kbd_safe_update_irq(s); break; case KBD_CCMD_WRITE_MODE: s->mode = val; - ps2_keyboard_set_translation(s->kbd, (s->mode & KBD_MODE_KCC) != 0); + ps2_keyboard_set_translation(&s->ps2kbd, + (s->mode & KBD_MODE_KCC) != 0); /* * a write to the mode byte interrupt enable flags directly updates * the irq lines @@ -458,7 +459,7 @@ static void kbd_write_data(void *opaque, hwaddr addr, outport_write(s, val); break; case KBD_CCMD_WRITE_MOUSE: - ps2_write_mouse(s->mouse, val); + ps2_write_mouse(&s->ps2mouse, val); /* sending data to the mouse reenables PS/2 communication */ s->mode &= ~KBD_MODE_DISABLE_MOUSE; kbd_safe_update_irq(s); @@ -699,15 +700,19 @@ static void i8042_mmio_realize(DeviceState *dev, Error **errp) sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->region); - /* Note we can't use dc->vmsd without breaking migration compatibility */ - vmstate_register(NULL, 0, &vmstate_kbd, ks); + if (!sysbus_realize(SYS_BUS_DEVICE(&ks->ps2kbd), errp)) { + return; + } + + if (!sysbus_realize(SYS_BUS_DEVICE(&ks->ps2mouse), errp)) { + return; + } - ks->kbd = ps2_kbd_init(); - qdev_connect_gpio_out(DEVICE(ks->kbd), PS2_DEVICE_IRQ, + qdev_connect_gpio_out(DEVICE(&ks->ps2kbd), PS2_DEVICE_IRQ, qdev_get_gpio_in_named(dev, "ps2-kbd-input-irq", 0)); - ks->mouse = ps2_mouse_init(); - qdev_connect_gpio_out(DEVICE(ks->mouse), PS2_DEVICE_IRQ, + + qdev_connect_gpio_out(DEVICE(&ks->ps2mouse), PS2_DEVICE_IRQ, qdev_get_gpio_in_named(dev, "ps2-mouse-input-irq", 0)); } @@ -719,6 +724,10 @@ static void i8042_mmio_init(Object *obj) ks->extended_state = true; + object_initialize_child(obj, "ps2kbd", &ks->ps2kbd, TYPE_PS2_KBD_DEVICE); + object_initialize_child(obj, "ps2mouse", &ks->ps2mouse, + TYPE_PS2_MOUSE_DEVICE); + qdev_init_gpio_out(DEVICE(obj), ks->irqs, 2); qdev_init_gpio_in_named(DEVICE(obj), i8042_mmio_set_kbd_irq, "ps2-kbd-input-irq", 1); @@ -732,32 +741,27 @@ static Property i8042_mmio_properties[] = { DEFINE_PROP_END_OF_LIST(), }; +static const VMStateDescription vmstate_kbd_mmio = { + .name = "pckbd-mmio", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_STRUCT(kbd, MMIOKBDState, 0, vmstate_kbd, KBDState), + VMSTATE_END_OF_LIST() + } +}; + static void i8042_mmio_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); dc->realize = i8042_mmio_realize; dc->reset = i8042_mmio_reset; + dc->vmsd = &vmstate_kbd_mmio; device_class_set_props(dc, i8042_mmio_properties); set_bit(DEVICE_CATEGORY_INPUT, dc->categories); } -MMIOKBDState *i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq, - ram_addr_t size, hwaddr mask) -{ - DeviceState *dev; - - dev = qdev_new(TYPE_I8042_MMIO); - qdev_prop_set_uint64(dev, "mask", mask); - qdev_prop_set_uint32(dev, "size", size); - sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); - - qdev_connect_gpio_out(dev, I8042_KBD_IRQ, kbd_irq); - qdev_connect_gpio_out(dev, I8042_MOUSE_IRQ, mouse_irq); - - return I8042_MMIO(dev); -} - static const TypeInfo i8042_mmio_info = { .name = TYPE_I8042_MMIO, .parent = TYPE_SYS_BUS_DEVICE, @@ -770,7 +774,7 @@ void i8042_isa_mouse_fake_event(ISAKBDState *isa) { KBDState *s = &isa->kbd; - ps2_mouse_fake_event(s->mouse); + ps2_mouse_fake_event(&s->ps2mouse); } void i8042_setup_a20_line(ISADevice *dev, qemu_irq a20_out) @@ -843,6 +847,10 @@ static void i8042_initfn(Object *obj) memory_region_init_io(isa_s->io + 1, obj, &i8042_cmd_ops, s, "i8042-cmd", 1); + object_initialize_child(obj, "ps2kbd", &s->ps2kbd, TYPE_PS2_KBD_DEVICE); + object_initialize_child(obj, "ps2mouse", &s->ps2mouse, + TYPE_PS2_MOUSE_DEVICE); + qdev_init_gpio_out_named(DEVICE(obj), &s->a20_out, I8042_A20_LINE, 1); qdev_init_gpio_out(DEVICE(obj), s->irqs, 2); @@ -876,14 +884,22 @@ static void i8042_realizefn(DeviceState *dev, Error **errp) isa_register_ioport(isadev, isa_s->io + 0, 0x60); isa_register_ioport(isadev, isa_s->io + 1, 0x64); - s->kbd = ps2_kbd_init(); - qdev_connect_gpio_out(DEVICE(s->kbd), PS2_DEVICE_IRQ, + if (!sysbus_realize(SYS_BUS_DEVICE(&s->ps2kbd), errp)) { + return; + } + + qdev_connect_gpio_out(DEVICE(&s->ps2kbd), PS2_DEVICE_IRQ, qdev_get_gpio_in_named(dev, "ps2-kbd-input-irq", 0)); - s->mouse = ps2_mouse_init(); - qdev_connect_gpio_out(DEVICE(s->mouse), PS2_DEVICE_IRQ, + + if (!sysbus_realize(SYS_BUS_DEVICE(&s->ps2mouse), errp)) { + return; + } + + qdev_connect_gpio_out(DEVICE(&s->ps2mouse), PS2_DEVICE_IRQ, qdev_get_gpio_in_named(dev, "ps2-mouse-input-irq", 0)); + if (isa_s->kbd_throttle && !isa_s->kbd.extended_state) { warn_report(TYPE_I8042 ": can't enable kbd-throttle without" " extended-state, disabling kbd-throttle"); diff --git a/hw/input/pl050.c b/hw/input/pl050.c index 209cc001cf..ec5e19285e 100644 --- a/hw/input/pl050.c +++ b/hw/input/pl050.c @@ -19,26 +19,12 @@ #include "hw/sysbus.h" #include "migration/vmstate.h" #include "hw/input/ps2.h" +#include "hw/input/pl050.h" #include "hw/irq.h" #include "qemu/log.h" #include "qemu/module.h" #include "qom/object.h" -#define TYPE_PL050 "pl050" -OBJECT_DECLARE_SIMPLE_TYPE(PL050State, PL050) - -struct PL050State { - SysBusDevice parent_obj; - - MemoryRegion iomem; - void *dev; - uint32_t cr; - uint32_t clk; - uint32_t last; - int pending; - qemu_irq irq; - bool is_mouse; -}; static const VMStateDescription vmstate_pl050 = { .name = "pl050", @@ -115,7 +101,7 @@ static uint64_t pl050_read(void *opaque, hwaddr offset, } case 2: /* KMIDATA */ if (s->pending) { - s->last = ps2_read_data(s->dev); + s->last = ps2_read_data(s->ps2dev); } return s->last; case 3: /* KMICLKDIV */ @@ -144,9 +130,9 @@ static void pl050_write(void *opaque, hwaddr offset, /* ??? This should toggle the TX interrupt line. */ /* ??? This means kbd/mouse can block each other. */ if (s->is_mouse) { - ps2_write_mouse(s->dev, value); + ps2_write_mouse(PS2_MOUSE_DEVICE(s->ps2dev), value); } else { - ps2_write_keyboard(s->dev, value); + ps2_write_keyboard(PS2_KBD_DEVICE(s->ps2dev), value); } break; case 3: /* KMICLKDIV */ @@ -166,48 +152,100 @@ static const MemoryRegionOps pl050_ops = { static void pl050_realize(DeviceState *dev, Error **errp) { PL050State *s = PL050(dev); - SysBusDevice *sbd = SYS_BUS_DEVICE(dev); - memory_region_init_io(&s->iomem, OBJECT(s), &pl050_ops, s, "pl050", 0x1000); - sysbus_init_mmio(sbd, &s->iomem); - sysbus_init_irq(sbd, &s->irq); - if (s->is_mouse) { - s->dev = ps2_mouse_init(); - } else { - s->dev = ps2_kbd_init(); - } - qdev_connect_gpio_out(DEVICE(s->dev), PS2_DEVICE_IRQ, + qdev_connect_gpio_out(DEVICE(s->ps2dev), PS2_DEVICE_IRQ, qdev_get_gpio_in_named(dev, "ps2-input-irq", 0)); } -static void pl050_keyboard_init(Object *obj) +static void pl050_kbd_realize(DeviceState *dev, Error **errp) { - PL050State *s = PL050(obj); + PL050DeviceClass *pdc = PL050_GET_CLASS(dev); + PL050KbdState *s = PL050_KBD_DEVICE(dev); + PL050State *ps = PL050(dev); + + if (!sysbus_realize(SYS_BUS_DEVICE(&s->kbd), errp)) { + return; + } + + ps->ps2dev = PS2_DEVICE(&s->kbd); + pdc->parent_realize(dev, errp); +} + +static void pl050_kbd_init(Object *obj) +{ + PL050KbdState *s = PL050_KBD_DEVICE(obj); + PL050State *ps = PL050(obj); + + ps->is_mouse = false; + object_initialize_child(obj, "kbd", &s->kbd, TYPE_PS2_KBD_DEVICE); +} + +static void pl050_mouse_realize(DeviceState *dev, Error **errp) +{ + PL050DeviceClass *pdc = PL050_GET_CLASS(dev); + PL050MouseState *s = PL050_MOUSE_DEVICE(dev); + PL050State *ps = PL050(dev); + + if (!sysbus_realize(SYS_BUS_DEVICE(&s->mouse), errp)) { + return; + } - s->is_mouse = false; + ps->ps2dev = PS2_DEVICE(&s->mouse); + pdc->parent_realize(dev, errp); } static void pl050_mouse_init(Object *obj) { - PL050State *s = PL050(obj); + PL050MouseState *s = PL050_MOUSE_DEVICE(obj); + PL050State *ps = PL050(obj); + + ps->is_mouse = true; + object_initialize_child(obj, "mouse", &s->mouse, TYPE_PS2_MOUSE_DEVICE); +} - s->is_mouse = true; +static void pl050_kbd_class_init(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PL050DeviceClass *pdc = PL050_CLASS(oc); + + device_class_set_parent_realize(dc, pl050_kbd_realize, + &pdc->parent_realize); } static const TypeInfo pl050_kbd_info = { - .name = "pl050_keyboard", + .name = TYPE_PL050_KBD_DEVICE, .parent = TYPE_PL050, - .instance_init = pl050_keyboard_init, + .instance_init = pl050_kbd_init, + .instance_size = sizeof(PL050KbdState), + .class_init = pl050_kbd_class_init, }; +static void pl050_mouse_class_init(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PL050DeviceClass *pdc = PL050_CLASS(oc); + + device_class_set_parent_realize(dc, pl050_mouse_realize, + &pdc->parent_realize); +} + static const TypeInfo pl050_mouse_info = { - .name = "pl050_mouse", + .name = TYPE_PL050_MOUSE_DEVICE, .parent = TYPE_PL050, .instance_init = pl050_mouse_init, + .instance_size = sizeof(PL050MouseState), + .class_init = pl050_mouse_class_init, }; static void pl050_init(Object *obj) { + PL050State *s = PL050(obj); + SysBusDevice *sbd = SYS_BUS_DEVICE(obj); + + memory_region_init_io(&s->iomem, obj, &pl050_ops, s, "pl050", 0x1000); + sysbus_init_mmio(sbd, &s->iomem); + sysbus_init_irq(sbd, &s->irq); + qdev_init_gpio_in_named(DEVICE(obj), pl050_set_irq, "ps2-input-irq", 1); } @@ -224,6 +262,8 @@ static const TypeInfo pl050_type_info = { .parent = TYPE_SYS_BUS_DEVICE, .instance_init = pl050_init, .instance_size = sizeof(PL050State), + .class_init = pl050_class_init, + .class_size = sizeof(PL050DeviceClass), .abstract = true, .class_init = pl050_class_init, }; diff --git a/hw/input/ps2.c b/hw/input/ps2.c index 59bac28ac8..05cf7111e3 100644 --- a/hw/input/ps2.c +++ b/hw/input/ps2.c @@ -1224,19 +1224,6 @@ static void ps2_kbd_realize(DeviceState *dev, Error **errp) qemu_input_handler_register(dev, &ps2_keyboard_handler); } -void *ps2_kbd_init(void) -{ - DeviceState *dev; - PS2KbdState *s; - - dev = qdev_new(TYPE_PS2_KBD_DEVICE); - sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); - s = PS2_KBD_DEVICE(dev); - - trace_ps2_kbd_init(s); - return s; -} - static QemuInputHandler ps2_mouse_handler = { .name = "QEMU PS/2 Mouse", .mask = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL, @@ -1249,19 +1236,6 @@ static void ps2_mouse_realize(DeviceState *dev, Error **errp) qemu_input_handler_register(dev, &ps2_mouse_handler); } -void *ps2_mouse_init(void) -{ - DeviceState *dev; - PS2MouseState *s; - - dev = qdev_new(TYPE_PS2_MOUSE_DEVICE); - sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); - s = PS2_MOUSE_DEVICE(dev); - - trace_ps2_mouse_init(s); - return s; -} - static void ps2_kbd_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/input/trace-events b/hw/input/trace-events index e0bfe7f3ee..29001a827d 100644 --- a/hw/input/trace-events +++ b/hw/input/trace-events @@ -41,8 +41,6 @@ ps2_mouse_fake_event(void *opaque) "%p" ps2_write_mouse(void *opaque, int val) "%p val %d" ps2_kbd_reset(void *opaque) "%p" ps2_mouse_reset(void *opaque) "%p" -ps2_kbd_init(void *s) "%p" -ps2_mouse_init(void *s) "%p" # hid.c hid_kbd_queue_full(void) "queue full" diff --git a/hw/mips/jazz.c b/hw/mips/jazz.c index 1eb8bd5018..6aefe9a61b 100644 --- a/hw/mips/jazz.c +++ b/hw/mips/jazz.c @@ -361,9 +361,16 @@ static void mips_jazz_init(MachineState *machine, memory_region_add_subregion(address_space, 0x80004000, rtc); /* Keyboard (i8042) */ - i8042 = i8042_mm_init(qdev_get_gpio_in(rc4030, 6), - qdev_get_gpio_in(rc4030, 7), - 0x1000, 0x1); + i8042 = I8042_MMIO(qdev_new(TYPE_I8042_MMIO)); + qdev_prop_set_uint64(DEVICE(i8042), "mask", 1); + qdev_prop_set_uint32(DEVICE(i8042), "size", 0x1000); + sysbus_realize_and_unref(SYS_BUS_DEVICE(i8042), &error_fatal); + + qdev_connect_gpio_out(DEVICE(i8042), I8042_KBD_IRQ, + qdev_get_gpio_in(rc4030, 6)); + qdev_connect_gpio_out(DEVICE(i8042), I8042_MOUSE_IRQ, + qdev_get_gpio_in(rc4030, 7)); + memory_region_add_subregion(address_space, 0x80005000, sysbus_mmio_get_region(SYS_BUS_DEVICE(i8042), 0)); |