From 545e5cf817c0e635479f202cbb2e0973aa6431d0 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:16 +0100 Subject: [PATCH 01/55] ps2: checkpatch fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Acked-by: Helge Deller Message-Id: <20220624134109.881989-2-mark.cave-ayland@ilande.co.uk> --- hw/input/ps2.c | 154 +++++++++++++++++++++++++++---------------------- 1 file changed, 86 insertions(+), 68 deletions(-) diff --git a/hw/input/ps2.c b/hw/input/ps2.c index c16df1de7a..67dd2eca84 100644 --- a/hw/input/ps2.c +++ b/hw/input/ps2.c @@ -34,41 +34,41 @@ #include "trace.h" /* Keyboard Commands */ -#define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */ -#define KBD_CMD_ECHO 0xEE -#define KBD_CMD_SCANCODE 0xF0 /* Get/set scancode set */ -#define KBD_CMD_GET_ID 0xF2 /* get keyboard ID */ -#define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */ -#define KBD_CMD_ENABLE 0xF4 /* Enable scanning */ -#define KBD_CMD_RESET_DISABLE 0xF5 /* reset and disable scanning */ -#define KBD_CMD_RESET_ENABLE 0xF6 /* reset and enable scanning */ -#define KBD_CMD_RESET 0xFF /* Reset */ +#define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */ +#define KBD_CMD_ECHO 0xEE +#define KBD_CMD_SCANCODE 0xF0 /* Get/set scancode set */ +#define KBD_CMD_GET_ID 0xF2 /* get keyboard ID */ +#define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */ +#define KBD_CMD_ENABLE 0xF4 /* Enable scanning */ +#define KBD_CMD_RESET_DISABLE 0xF5 /* reset and disable scanning */ +#define KBD_CMD_RESET_ENABLE 0xF6 /* reset and enable scanning */ +#define KBD_CMD_RESET 0xFF /* Reset */ #define KBD_CMD_SET_MAKE_BREAK 0xFC /* Set Make and Break mode */ #define KBD_CMD_SET_TYPEMATIC 0xFA /* Set Typematic Make and Break mode */ /* Keyboard Replies */ -#define KBD_REPLY_POR 0xAA /* Power on reset */ -#define KBD_REPLY_ID 0xAB /* Keyboard ID */ -#define KBD_REPLY_ACK 0xFA /* Command ACK */ -#define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */ +#define KBD_REPLY_POR 0xAA /* Power on reset */ +#define KBD_REPLY_ID 0xAB /* Keyboard ID */ +#define KBD_REPLY_ACK 0xFA /* Command ACK */ +#define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */ /* Mouse Commands */ -#define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */ -#define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */ -#define AUX_SET_RES 0xE8 /* Set resolution */ -#define AUX_GET_SCALE 0xE9 /* Get scaling factor */ -#define AUX_SET_STREAM 0xEA /* Set stream mode */ -#define AUX_POLL 0xEB /* Poll */ -#define AUX_RESET_WRAP 0xEC /* Reset wrap mode */ -#define AUX_SET_WRAP 0xEE /* Set wrap mode */ -#define AUX_SET_REMOTE 0xF0 /* Set remote mode */ -#define AUX_GET_TYPE 0xF2 /* Get type */ -#define AUX_SET_SAMPLE 0xF3 /* Set sample rate */ -#define AUX_ENABLE_DEV 0xF4 /* Enable aux device */ -#define AUX_DISABLE_DEV 0xF5 /* Disable aux device */ -#define AUX_SET_DEFAULT 0xF6 -#define AUX_RESET 0xFF /* Reset aux device */ -#define AUX_ACK 0xFA /* Command byte ACK. */ +#define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */ +#define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */ +#define AUX_SET_RES 0xE8 /* Set resolution */ +#define AUX_GET_SCALE 0xE9 /* Get scaling factor */ +#define AUX_SET_STREAM 0xEA /* Set stream mode */ +#define AUX_POLL 0xEB /* Poll */ +#define AUX_RESET_WRAP 0xEC /* Reset wrap mode */ +#define AUX_SET_WRAP 0xEE /* Set wrap mode */ +#define AUX_SET_REMOTE 0xF0 /* Set remote mode */ +#define AUX_GET_TYPE 0xF2 /* Get type */ +#define AUX_SET_SAMPLE 0xF3 /* Set sample rate */ +#define AUX_ENABLE_DEV 0xF4 /* Enable aux device */ +#define AUX_DISABLE_DEV 0xF5 /* Disable aux device */ +#define AUX_SET_DEFAULT 0xF6 +#define AUX_RESET 0xFF /* Reset aux device */ +#define AUX_ACK 0xFA /* Command byte ACK. */ #define MOUSE_STATUS_REMOTE 0x40 #define MOUSE_STATUS_ENABLED 0x20 @@ -436,8 +436,9 @@ static void ps2_keyboard_event(DeviceState *dev, QemuConsole *src, } } } else { - if (qcode < qemu_input_map_qcode_to_atset1_len) + if (qcode < qemu_input_map_qcode_to_atset1_len) { keycode = qemu_input_map_qcode_to_atset1[qcode]; + } if (keycode) { if (keycode & 0xff00) { ps2_put_keycode(s, keycode >> 8); @@ -530,8 +531,9 @@ static void ps2_keyboard_event(DeviceState *dev, QemuConsole *src, } } } else { - if (qcode < qemu_input_map_qcode_to_atset2_len) + if (qcode < qemu_input_map_qcode_to_atset2_len) { keycode = qemu_input_map_qcode_to_atset2[qcode]; + } if (keycode) { if (keycode & 0xff00) { ps2_put_keycode(s, keycode >> 8); @@ -546,8 +548,9 @@ static void ps2_keyboard_event(DeviceState *dev, QemuConsole *src, } } } else if (s->scancode_set == 3) { - if (qcode < qemu_input_map_qcode_to_atset3_len) + if (qcode < qemu_input_map_qcode_to_atset3_len) { keycode = qemu_input_map_qcode_to_atset3[qcode]; + } if (keycode) { /* FIXME: break code should be configured on a key by key basis */ if (!key->down) { @@ -569,8 +572,10 @@ uint32_t ps2_read_data(PS2State *s) trace_ps2_read_data(s); q = &s->queue; if (q->count == 0) { - /* NOTE: if no data left, we return the last keyboard one - (needed for EMM386) */ + /* + * NOTE: if no data left, we return the last keyboard one + * (needed for EMM386) + */ /* XXX: need a timer to do things correctly */ index = q->rptr - 1; if (index < 0) { @@ -619,10 +624,10 @@ void ps2_write_keyboard(void *opaque, int val) trace_ps2_write_keyboard(opaque, val); ps2_cqueue_reset(&s->common); - switch(s->common.write_cmd) { + switch (s->common.write_cmd) { default: case -1: - switch(val) { + switch (val) { case 0x00: ps2_cqueue_1(&s->common, KBD_REPLY_ACK); break; @@ -632,7 +637,7 @@ void ps2_write_keyboard(void *opaque, int val) case KBD_CMD_GET_ID: /* We emulate a MF2 AT keyboard here */ ps2_cqueue_3(&s->common, KBD_REPLY_ACK, KBD_REPLY_ID, - s->translate ? 0x41 : 0x83); + s->translate ? 0x41 : 0x83); break; case KBD_CMD_ECHO: ps2_cqueue_1(&s->common, KBD_CMD_ECHO); @@ -661,8 +666,8 @@ void ps2_write_keyboard(void *opaque, int val) case KBD_CMD_RESET: ps2_reset_keyboard(s); ps2_cqueue_2(&s->common, - KBD_REPLY_ACK, - KBD_REPLY_POR); + KBD_REPLY_ACK, + KBD_REPLY_POR); break; case KBD_CMD_SET_TYPEMATIC: ps2_cqueue_1(&s->common, KBD_REPLY_ACK); @@ -700,9 +705,11 @@ void ps2_write_keyboard(void *opaque, int val) } } -/* Set the scancode translation mode. - 0 = raw scancodes. - 1 = translated scancodes (used by qemu internally). */ +/* + * Set the scancode translation mode. + * 0 = raw scancodes. + * 1 = translated scancodes (used by qemu internally). + */ void ps2_keyboard_set_translation(void *opaque, int mode) { @@ -727,30 +734,33 @@ static int ps2_mouse_send_packet(PS2MouseState *s) dz1 = s->mouse_dz; dw1 = s->mouse_dw; /* XXX: increase range to 8 bits ? */ - if (dx1 > 127) + if (dx1 > 127) { dx1 = 127; - else if (dx1 < -127) + } else if (dx1 < -127) { dx1 = -127; - if (dy1 > 127) + } + if (dy1 > 127) { dy1 = 127; - else if (dy1 < -127) + } else if (dy1 < -127) { dy1 = -127; + } b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07); ps2_queue_noirq(&s->common, b); ps2_queue_noirq(&s->common, dx1 & 0xff); ps2_queue_noirq(&s->common, dy1 & 0xff); /* extra byte for IMPS/2 or IMEX */ - switch(s->mouse_type) { + switch (s->mouse_type) { default: /* Just ignore the wheels if not supported */ s->mouse_dz = 0; s->mouse_dw = 0; break; case 3: - if (dz1 > 127) + if (dz1 > 127) { dz1 = 127; - else if (dz1 < -127) - dz1 = -127; + } else if (dz1 < -127) { + dz1 = -127; + } ps2_queue_noirq(&s->common, dz1 & 0xff); s->mouse_dz -= dz1; s->mouse_dw = 0; @@ -816,8 +826,9 @@ static void ps2_mouse_event(DeviceState *dev, QemuConsole *src, InputBtnEvent *btn; /* check if deltas are recorded when disabled */ - if (!(s->mouse_status & MOUSE_STATUS_ENABLED)) + if (!(s->mouse_status & MOUSE_STATUS_ENABLED)) { return; + } switch (evt->type) { case INPUT_EVENT_KIND_REL: @@ -868,8 +879,10 @@ static void ps2_mouse_sync(DeviceState *dev) qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, NULL); } if (!(s->mouse_status & MOUSE_STATUS_REMOTE)) { - /* if not remote, send event. Multiple events are sent if - too big deltas */ + /* + * if not remote, send event. Multiple events are sent if + * too big deltas + */ while (ps2_mouse_send_packet(s)) { if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0 && s->mouse_dw == 0) { @@ -892,7 +905,7 @@ void ps2_write_mouse(void *opaque, int val) PS2MouseState *s = (PS2MouseState *)opaque; trace_ps2_write_mouse(opaque, val); - switch(s->common.write_cmd) { + switch (s->common.write_cmd) { default: case -1: /* mouse command */ @@ -906,7 +919,7 @@ void ps2_write_mouse(void *opaque, int val) return; } } - switch(val) { + switch (val) { case AUX_SET_SCALE11: s->mouse_status &= ~MOUSE_STATUS_SCALE21; ps2_queue(&s->common, AUX_ACK); @@ -980,28 +993,32 @@ void ps2_write_mouse(void *opaque, int val) case AUX_SET_SAMPLE: s->mouse_sample_rate = val; /* detect IMPS/2 or IMEX */ - switch(s->mouse_detect_state) { + switch (s->mouse_detect_state) { default: case 0: - if (val == 200) + if (val == 200) { s->mouse_detect_state = 1; + } break; case 1: - if (val == 100) + if (val == 100) { s->mouse_detect_state = 2; - else if (val == 200) + } else if (val == 200) { s->mouse_detect_state = 3; - else + } else { s->mouse_detect_state = 0; + } break; case 2: - if (val == 80) + if (val == 80) { s->mouse_type = 3; /* IMPS/2 */ + } s->mouse_detect_state = 0; break; case 3: - if (val == 80) + if (val == 80) { s->mouse_type = 4; /* IMEX */ + } s->mouse_detect_state = 0; break; } @@ -1154,13 +1171,14 @@ static const VMStateDescription vmstate_ps2_keyboard_cqueue = { } }; -static int ps2_kbd_post_load(void* opaque, int version_id) +static int ps2_kbd_post_load(void *opaque, int version_id) { - PS2KbdState *s = (PS2KbdState*)opaque; + PS2KbdState *s = (PS2KbdState *)opaque; PS2State *ps2 = &s->common; - if (version_id == 2) - s->scancode_set=2; + if (version_id == 2) { + s->scancode_set = 2; + } ps2_common_post_load(ps2); @@ -1176,10 +1194,10 @@ static const VMStateDescription vmstate_ps2_keyboard = { VMSTATE_STRUCT(common, PS2KbdState, 0, vmstate_ps2_common, PS2State), VMSTATE_INT32(scan_enabled, PS2KbdState), VMSTATE_INT32(translate, PS2KbdState), - VMSTATE_INT32_V(scancode_set, PS2KbdState,3), + VMSTATE_INT32_V(scancode_set, PS2KbdState, 3), VMSTATE_END_OF_LIST() }, - .subsections = (const VMStateDescription*[]) { + .subsections = (const VMStateDescription * []) { &vmstate_ps2_keyboard_ledstate, &vmstate_ps2_keyboard_need_high_bit, &vmstate_ps2_keyboard_cqueue, From 64bbdd138a1e40b71d54c71d25653361329d69fe Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:17 +0100 Subject: [PATCH 02/55] ps2: QOMify PS2State MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make PS2State a new abstract PS2_DEVICE QOM type to represent the common functionality shared between PS2 keyboard and mouse devices. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Acked-by: Helge Deller Message-Id: <20220624134109.881989-3-mark.cave-ayland@ilande.co.uk> --- hw/input/ps2.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/hw/input/ps2.c b/hw/input/ps2.c index 67dd2eca84..514e55cbb6 100644 --- a/hw/input/ps2.c +++ b/hw/input/ps2.c @@ -24,6 +24,7 @@ #include "qemu/osdep.h" #include "qemu/log.h" +#include "hw/sysbus.h" #include "hw/input/ps2.h" #include "migration/vmstate.h" #include "ui/console.h" @@ -96,12 +97,17 @@ typedef struct { } PS2Queue; struct PS2State { + SysBusDevice parent_obj; + PS2Queue queue; int32_t write_cmd; void (*update_irq)(void *, int); void *update_arg; }; +#define TYPE_PS2_DEVICE "ps2-device" +OBJECT_DECLARE_SIMPLE_TYPE(PS2State, PS2_DEVICE) + typedef struct { PS2State common; int scan_enabled; @@ -1277,3 +1283,25 @@ void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg) qemu_register_reset(ps2_mouse_reset, s); return s; } + +static void ps2_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + set_bit(DEVICE_CATEGORY_INPUT, dc->categories); +} + +static const TypeInfo ps2_info = { + .name = TYPE_PS2_DEVICE, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(PS2State), + .class_init = ps2_class_init, + .abstract = true +}; + +static void ps2_register_types(void) +{ + type_register_static(&ps2_info); +} + +type_init(ps2_register_types) From 8f84e53cd0067a1d4be4f6b2deb7d24bd5f469c6 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:18 +0100 Subject: [PATCH 03/55] ps2: QOMify PS2KbdState MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make PS2KbdState into a new PS2_KBD_DEVICE QOM type which inherits from the abstract PS2_DEVICE type. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Acked-by: Helge Deller Message-Id: <20220624134109.881989-4-mark.cave-ayland@ilande.co.uk> --- hw/input/ps2.c | 104 ++++++++++++++++++++++++++++++------------------- 1 file changed, 65 insertions(+), 39 deletions(-) diff --git a/hw/input/ps2.c b/hw/input/ps2.c index 514e55cbb6..14eb777c3f 100644 --- a/hw/input/ps2.c +++ b/hw/input/ps2.c @@ -31,6 +31,7 @@ #include "ui/input.h" #include "sysemu/reset.h" #include "sysemu/runstate.h" +#include "qapi/error.h" #include "trace.h" @@ -108,15 +109,19 @@ struct PS2State { #define TYPE_PS2_DEVICE "ps2-device" OBJECT_DECLARE_SIMPLE_TYPE(PS2State, PS2_DEVICE) -typedef struct { - PS2State common; +struct PS2KbdState { + PS2State parent_obj; + int scan_enabled; int translate; int scancode_set; /* 1=XT, 2=AT, 3=PS/2 */ int ledstate; bool need_high_bit; unsigned int modifiers; /* bitmask of MOD_* constants above */ -} PS2KbdState; +}; + +#define TYPE_PS2_KBD_DEVICE "ps2-kbd" +OBJECT_DECLARE_SIMPLE_TYPE(PS2KbdState, PS2_KBD_DEVICE) typedef struct { PS2State common; @@ -330,6 +335,7 @@ static void ps2_cqueue_reset(PS2State *s) static void ps2_put_keycode(void *opaque, int keycode) { PS2KbdState *s = opaque; + PS2State *ps = PS2_DEVICE(s); trace_ps2_put_keycode(opaque, keycode); qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, NULL); @@ -338,13 +344,13 @@ static void ps2_put_keycode(void *opaque, int keycode) if (keycode == 0xf0) { s->need_high_bit = true; } else if (s->need_high_bit) { - ps2_queue(&s->common, translate_table[keycode] | 0x80); + ps2_queue(ps, translate_table[keycode] | 0x80); s->need_high_bit = false; } else { - ps2_queue(&s->common, translate_table[keycode]); + ps2_queue(ps, translate_table[keycode]); } } else { - ps2_queue(&s->common, keycode); + ps2_queue(ps, keycode); } } @@ -617,96 +623,99 @@ static void ps2_set_ledstate(PS2KbdState *s, int ledstate) static void ps2_reset_keyboard(PS2KbdState *s) { + PS2State *ps2 = PS2_DEVICE(s); + trace_ps2_reset_keyboard(s); s->scan_enabled = 1; s->scancode_set = 2; - ps2_reset_queue(&s->common); + ps2_reset_queue(ps2); ps2_set_ledstate(s, 0); } void ps2_write_keyboard(void *opaque, int val) { PS2KbdState *s = (PS2KbdState *)opaque; + PS2State *ps2 = PS2_DEVICE(s); trace_ps2_write_keyboard(opaque, val); - ps2_cqueue_reset(&s->common); - switch (s->common.write_cmd) { + ps2_cqueue_reset(ps2); + switch (ps2->write_cmd) { default: case -1: switch (val) { case 0x00: - ps2_cqueue_1(&s->common, KBD_REPLY_ACK); + ps2_cqueue_1(ps2, KBD_REPLY_ACK); break; case 0x05: - ps2_cqueue_1(&s->common, KBD_REPLY_RESEND); + ps2_cqueue_1(ps2, KBD_REPLY_RESEND); break; case KBD_CMD_GET_ID: /* We emulate a MF2 AT keyboard here */ - ps2_cqueue_3(&s->common, KBD_REPLY_ACK, KBD_REPLY_ID, + ps2_cqueue_3(ps2, KBD_REPLY_ACK, KBD_REPLY_ID, s->translate ? 0x41 : 0x83); break; case KBD_CMD_ECHO: - ps2_cqueue_1(&s->common, KBD_CMD_ECHO); + ps2_cqueue_1(ps2, KBD_CMD_ECHO); break; case KBD_CMD_ENABLE: s->scan_enabled = 1; - ps2_cqueue_1(&s->common, KBD_REPLY_ACK); + ps2_cqueue_1(ps2, KBD_REPLY_ACK); break; case KBD_CMD_SCANCODE: case KBD_CMD_SET_LEDS: case KBD_CMD_SET_RATE: case KBD_CMD_SET_MAKE_BREAK: - s->common.write_cmd = val; - ps2_cqueue_1(&s->common, KBD_REPLY_ACK); + ps2->write_cmd = val; + ps2_cqueue_1(ps2, KBD_REPLY_ACK); break; case KBD_CMD_RESET_DISABLE: ps2_reset_keyboard(s); s->scan_enabled = 0; - ps2_cqueue_1(&s->common, KBD_REPLY_ACK); + ps2_cqueue_1(ps2, KBD_REPLY_ACK); break; case KBD_CMD_RESET_ENABLE: ps2_reset_keyboard(s); s->scan_enabled = 1; - ps2_cqueue_1(&s->common, KBD_REPLY_ACK); + ps2_cqueue_1(ps2, KBD_REPLY_ACK); break; case KBD_CMD_RESET: ps2_reset_keyboard(s); - ps2_cqueue_2(&s->common, + ps2_cqueue_2(ps2, KBD_REPLY_ACK, KBD_REPLY_POR); break; case KBD_CMD_SET_TYPEMATIC: - ps2_cqueue_1(&s->common, KBD_REPLY_ACK); + ps2_cqueue_1(ps2, KBD_REPLY_ACK); break; default: - ps2_cqueue_1(&s->common, KBD_REPLY_RESEND); + ps2_cqueue_1(ps2, KBD_REPLY_RESEND); break; } break; case KBD_CMD_SET_MAKE_BREAK: - ps2_cqueue_1(&s->common, KBD_REPLY_ACK); - s->common.write_cmd = -1; + ps2_cqueue_1(ps2, KBD_REPLY_ACK); + ps2->write_cmd = -1; break; case KBD_CMD_SCANCODE: if (val == 0) { - ps2_cqueue_2(&s->common, KBD_REPLY_ACK, s->translate ? + ps2_cqueue_2(ps2, KBD_REPLY_ACK, s->translate ? translate_table[s->scancode_set] : s->scancode_set); } else if (val >= 1 && val <= 3) { s->scancode_set = val; - ps2_cqueue_1(&s->common, KBD_REPLY_ACK); + ps2_cqueue_1(ps2, KBD_REPLY_ACK); } else { - ps2_cqueue_1(&s->common, KBD_REPLY_RESEND); + ps2_cqueue_1(ps2, KBD_REPLY_RESEND); } - s->common.write_cmd = -1; + ps2->write_cmd = -1; break; case KBD_CMD_SET_LEDS: ps2_set_ledstate(s, val); - ps2_cqueue_1(&s->common, KBD_REPLY_ACK); - s->common.write_cmd = -1; + ps2_cqueue_1(ps2, KBD_REPLY_ACK); + ps2->write_cmd = -1; break; case KBD_CMD_SET_RATE: - ps2_cqueue_1(&s->common, KBD_REPLY_ACK); - s->common.write_cmd = -1; + ps2_cqueue_1(ps2, KBD_REPLY_ACK); + ps2->write_cmd = -1; break; } } @@ -1075,9 +1084,10 @@ static void ps2_common_post_load(PS2State *s) static void ps2_kbd_reset(void *opaque) { PS2KbdState *s = (PS2KbdState *) opaque; + PS2State *ps2 = PS2_DEVICE(s); trace_ps2_kbd_reset(opaque); - ps2_common_reset(&s->common); + ps2_common_reset(ps2); s->scan_enabled = 1; s->translate = 0; s->scancode_set = 2; @@ -1164,15 +1174,16 @@ static const VMStateDescription vmstate_ps2_keyboard_need_high_bit = { static bool ps2_keyboard_cqueue_needed(void *opaque) { PS2KbdState *s = opaque; + PS2State *ps2 = PS2_DEVICE(s); - return s->common.queue.cwptr != -1; /* the queue is mostly empty */ + return ps2->queue.cwptr != -1; /* the queue is mostly empty */ } static const VMStateDescription vmstate_ps2_keyboard_cqueue = { .name = "ps2kbd/command_reply_queue", .needed = ps2_keyboard_cqueue_needed, .fields = (VMStateField[]) { - VMSTATE_INT32(common.queue.cwptr, PS2KbdState), + VMSTATE_INT32(parent_obj.queue.cwptr, PS2KbdState), VMSTATE_END_OF_LIST() } }; @@ -1180,7 +1191,7 @@ static const VMStateDescription vmstate_ps2_keyboard_cqueue = { static int ps2_kbd_post_load(void *opaque, int version_id) { PS2KbdState *s = (PS2KbdState *)opaque; - PS2State *ps2 = &s->common; + PS2State *ps2 = PS2_DEVICE(s); if (version_id == 2) { s->scancode_set = 2; @@ -1197,7 +1208,8 @@ static const VMStateDescription vmstate_ps2_keyboard = { .minimum_version_id = 2, .post_load = ps2_kbd_post_load, .fields = (VMStateField[]) { - VMSTATE_STRUCT(common, PS2KbdState, 0, vmstate_ps2_common, PS2State), + VMSTATE_STRUCT(parent_obj, PS2KbdState, 0, vmstate_ps2_common, + PS2State), VMSTATE_INT32(scan_enabled, PS2KbdState), VMSTATE_INT32(translate, PS2KbdState), VMSTATE_INT32_V(scancode_set, PS2KbdState, 3), @@ -1250,11 +1262,18 @@ static QemuInputHandler ps2_keyboard_handler = { void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg) { - PS2KbdState *s = g_new0(PS2KbdState, 1); + DeviceState *dev; + PS2KbdState *s; + PS2State *ps2; + + dev = qdev_new(TYPE_PS2_KBD_DEVICE); + sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); + s = PS2_KBD_DEVICE(dev); + ps2 = PS2_DEVICE(s); trace_ps2_kbd_init(s); - s->common.update_irq = update_irq; - s->common.update_arg = update_arg; + ps2->update_irq = update_irq; + ps2->update_arg = update_arg; s->scancode_set = 2; vmstate_register(NULL, 0, &vmstate_ps2_keyboard, s); qemu_input_handler_register((DeviceState *)s, @@ -1284,6 +1303,12 @@ void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg) return s; } +static const TypeInfo ps2_kbd_info = { + .name = TYPE_PS2_KBD_DEVICE, + .parent = TYPE_PS2_DEVICE, + .instance_size = sizeof(PS2KbdState), +}; + static void ps2_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -1302,6 +1327,7 @@ static const TypeInfo ps2_info = { static void ps2_register_types(void) { type_register_static(&ps2_info); + type_register_static(&ps2_kbd_info); } type_init(ps2_register_types) From 2d135409e642bb31cff032dc533bf7ce6b0d0051 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:19 +0100 Subject: [PATCH 04/55] ps2: QOMify PS2MouseState MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make PS2MouseState into a new PS2_MOUSE_DEVICE QOM type which inherits from the abstract PS2_DEVICE type. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Acked-by: Helge Deller Message-Id: <20220624134109.881989-5-mark.cave-ayland@ilande.co.uk> --- hw/input/ps2.c | 98 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 60 insertions(+), 38 deletions(-) diff --git a/hw/input/ps2.c b/hw/input/ps2.c index 14eb777c3f..ee7c36d4f2 100644 --- a/hw/input/ps2.c +++ b/hw/input/ps2.c @@ -123,8 +123,9 @@ struct PS2KbdState { #define TYPE_PS2_KBD_DEVICE "ps2-kbd" OBJECT_DECLARE_SIMPLE_TYPE(PS2KbdState, PS2_KBD_DEVICE) -typedef struct { - PS2State common; +struct PS2MouseState { + PS2State parent_obj; + uint8_t mouse_status; uint8_t mouse_resolution; uint8_t mouse_sample_rate; @@ -136,7 +137,10 @@ typedef struct { int mouse_dz; int mouse_dw; uint8_t mouse_buttons; -} PS2MouseState; +}; + +#define TYPE_PS2_MOUSE_DEVICE "ps2-mouse" +OBJECT_DECLARE_SIMPLE_TYPE(PS2MouseState, PS2_MOUSE_DEVICE) static uint8_t translate_table[256] = { 0xff, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x3c, 0x58, @@ -735,12 +739,13 @@ void ps2_keyboard_set_translation(void *opaque, int mode) static int ps2_mouse_send_packet(PS2MouseState *s) { + PS2State *ps2 = PS2_DEVICE(s); /* IMPS/2 and IMEX send 4 bytes, PS2 sends 3 bytes */ const int needed = s->mouse_type ? 4 : 3; unsigned int b; int dx1, dy1, dz1, dw1; - if (PS2_QUEUE_SIZE - s->common.queue.count < needed) { + if (PS2_QUEUE_SIZE - ps2->queue.count < needed) { return 0; } @@ -760,9 +765,9 @@ static int ps2_mouse_send_packet(PS2MouseState *s) dy1 = -127; } b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07); - ps2_queue_noirq(&s->common, b); - ps2_queue_noirq(&s->common, dx1 & 0xff); - ps2_queue_noirq(&s->common, dy1 & 0xff); + ps2_queue_noirq(ps2, b); + ps2_queue_noirq(ps2, dx1 & 0xff); + ps2_queue_noirq(ps2, dy1 & 0xff); /* extra byte for IMPS/2 or IMEX */ switch (s->mouse_type) { default: @@ -776,7 +781,7 @@ static int ps2_mouse_send_packet(PS2MouseState *s) } else if (dz1 < -127) { dz1 = -127; } - ps2_queue_noirq(&s->common, dz1 & 0xff); + ps2_queue_noirq(ps2, dz1 & 0xff); s->mouse_dz -= dz1; s->mouse_dw = 0; break; @@ -812,11 +817,11 @@ static int ps2_mouse_send_packet(PS2MouseState *s) b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1); s->mouse_dz -= dz1; } - ps2_queue_noirq(&s->common, b); + ps2_queue_noirq(ps2, b); break; } - ps2_raise_irq(&s->common); + ps2_raise_irq(ps2); trace_ps2_mouse_send_packet(s, dx1, dy1, dz1, b); /* update deltas */ @@ -918,85 +923,86 @@ void ps2_mouse_fake_event(void *opaque) void ps2_write_mouse(void *opaque, int val) { PS2MouseState *s = (PS2MouseState *)opaque; + PS2State *ps2 = PS2_DEVICE(s); trace_ps2_write_mouse(opaque, val); - switch (s->common.write_cmd) { + switch (ps2->write_cmd) { default: case -1: /* mouse command */ if (s->mouse_wrap) { if (val == AUX_RESET_WRAP) { s->mouse_wrap = 0; - ps2_queue(&s->common, AUX_ACK); + ps2_queue(ps2, AUX_ACK); return; } else if (val != AUX_RESET) { - ps2_queue(&s->common, val); + ps2_queue(ps2, val); return; } } switch (val) { case AUX_SET_SCALE11: s->mouse_status &= ~MOUSE_STATUS_SCALE21; - ps2_queue(&s->common, AUX_ACK); + ps2_queue(ps2, AUX_ACK); break; case AUX_SET_SCALE21: s->mouse_status |= MOUSE_STATUS_SCALE21; - ps2_queue(&s->common, AUX_ACK); + ps2_queue(ps2, AUX_ACK); break; case AUX_SET_STREAM: s->mouse_status &= ~MOUSE_STATUS_REMOTE; - ps2_queue(&s->common, AUX_ACK); + ps2_queue(ps2, AUX_ACK); break; case AUX_SET_WRAP: s->mouse_wrap = 1; - ps2_queue(&s->common, AUX_ACK); + ps2_queue(ps2, AUX_ACK); break; case AUX_SET_REMOTE: s->mouse_status |= MOUSE_STATUS_REMOTE; - ps2_queue(&s->common, AUX_ACK); + ps2_queue(ps2, AUX_ACK); break; case AUX_GET_TYPE: - ps2_queue_2(&s->common, + ps2_queue_2(ps2, AUX_ACK, s->mouse_type); break; case AUX_SET_RES: case AUX_SET_SAMPLE: - s->common.write_cmd = val; - ps2_queue(&s->common, AUX_ACK); + ps2->write_cmd = val; + ps2_queue(ps2, AUX_ACK); break; case AUX_GET_SCALE: - ps2_queue_4(&s->common, + ps2_queue_4(ps2, AUX_ACK, s->mouse_status, s->mouse_resolution, s->mouse_sample_rate); break; case AUX_POLL: - ps2_queue(&s->common, AUX_ACK); + ps2_queue(ps2, AUX_ACK); ps2_mouse_send_packet(s); break; case AUX_ENABLE_DEV: s->mouse_status |= MOUSE_STATUS_ENABLED; - ps2_queue(&s->common, AUX_ACK); + ps2_queue(ps2, AUX_ACK); break; case AUX_DISABLE_DEV: s->mouse_status &= ~MOUSE_STATUS_ENABLED; - ps2_queue(&s->common, AUX_ACK); + ps2_queue(ps2, AUX_ACK); break; case AUX_SET_DEFAULT: s->mouse_sample_rate = 100; s->mouse_resolution = 2; s->mouse_status = 0; - ps2_queue(&s->common, AUX_ACK); + ps2_queue(ps2, AUX_ACK); break; case AUX_RESET: s->mouse_sample_rate = 100; s->mouse_resolution = 2; s->mouse_status = 0; s->mouse_type = 0; - ps2_reset_queue(&s->common); - ps2_queue_3(&s->common, + ps2_reset_queue(ps2); + ps2_queue_3(ps2, AUX_ACK, 0xaa, s->mouse_type); @@ -1037,13 +1043,13 @@ void ps2_write_mouse(void *opaque, int val) s->mouse_detect_state = 0; break; } - ps2_queue(&s->common, AUX_ACK); - s->common.write_cmd = -1; + ps2_queue(ps2, AUX_ACK); + ps2->write_cmd = -1; break; case AUX_SET_RES: s->mouse_resolution = val; - ps2_queue(&s->common, AUX_ACK); - s->common.write_cmd = -1; + ps2_queue(ps2, AUX_ACK); + ps2->write_cmd = -1; break; } } @@ -1097,9 +1103,10 @@ static void ps2_kbd_reset(void *opaque) static void ps2_mouse_reset(void *opaque) { PS2MouseState *s = (PS2MouseState *) opaque; + PS2State *ps2 = PS2_DEVICE(s); trace_ps2_mouse_reset(opaque); - ps2_common_reset(&s->common); + ps2_common_reset(ps2); s->mouse_status = 0; s->mouse_resolution = 0; s->mouse_sample_rate = 0; @@ -1226,7 +1233,7 @@ static const VMStateDescription vmstate_ps2_keyboard = { static int ps2_mouse_post_load(void *opaque, int version_id) { PS2MouseState *s = (PS2MouseState *)opaque; - PS2State *ps2 = &s->common; + PS2State *ps2 = PS2_DEVICE(s); ps2_common_post_load(ps2); @@ -1239,7 +1246,8 @@ static const VMStateDescription vmstate_ps2_mouse = { .minimum_version_id = 2, .post_load = ps2_mouse_post_load, .fields = (VMStateField[]) { - VMSTATE_STRUCT(common, PS2MouseState, 0, vmstate_ps2_common, PS2State), + VMSTATE_STRUCT(parent_obj, PS2MouseState, 0, vmstate_ps2_common, + PS2State), VMSTATE_UINT8(mouse_status, PS2MouseState), VMSTATE_UINT8(mouse_resolution, PS2MouseState), VMSTATE_UINT8(mouse_sample_rate, PS2MouseState), @@ -1291,11 +1299,18 @@ static QemuInputHandler ps2_mouse_handler = { void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg) { - PS2MouseState *s = g_new0(PS2MouseState, 1); + DeviceState *dev; + PS2MouseState *s; + PS2State *ps2; + + dev = qdev_new(TYPE_PS2_MOUSE_DEVICE); + sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); + s = PS2_MOUSE_DEVICE(dev); + ps2 = PS2_DEVICE(s); trace_ps2_mouse_init(s); - s->common.update_irq = update_irq; - s->common.update_arg = update_arg; + ps2->update_irq = update_irq; + ps2->update_arg = update_arg; vmstate_register(NULL, 0, &vmstate_ps2_mouse, s); qemu_input_handler_register((DeviceState *)s, &ps2_mouse_handler); @@ -1309,6 +1324,12 @@ static const TypeInfo ps2_kbd_info = { .instance_size = sizeof(PS2KbdState), }; +static const TypeInfo ps2_mouse_info = { + .name = TYPE_PS2_MOUSE_DEVICE, + .parent = TYPE_PS2_DEVICE, + .instance_size = sizeof(PS2MouseState), +}; + static void ps2_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -1328,6 +1349,7 @@ static void ps2_register_types(void) { type_register_static(&ps2_info); type_register_static(&ps2_kbd_info); + type_register_static(&ps2_mouse_info); } type_init(ps2_register_types) From 0c235e38893c9376c7f235f7ecaf83c091436187 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:20 +0100 Subject: [PATCH 05/55] ps2: move QOM type definitions from ps2.c to ps2.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the QOM type definitions into the ps2.h header file to allow the new QOM types to be used by other devices. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Acked-by: Helge Deller Message-Id: <20220624134109.881989-6-mark.cave-ayland@ilande.co.uk> --- hw/input/ps2.c | 55 --------------------------------------- include/hw/input/ps2.h | 58 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 57 insertions(+), 56 deletions(-) diff --git a/hw/input/ps2.c b/hw/input/ps2.c index ee7c36d4f2..f4bad9876a 100644 --- a/hw/input/ps2.c +++ b/hw/input/ps2.c @@ -76,11 +76,6 @@ #define MOUSE_STATUS_ENABLED 0x20 #define MOUSE_STATUS_SCALE21 0x10 -/* - * PS/2 buffer size. Keep 256 bytes for compatibility with - * older QEMU versions. - */ -#define PS2_BUFFER_SIZE 256 #define PS2_QUEUE_SIZE 16 /* Queue size required by PS/2 protocol */ #define PS2_QUEUE_HEADROOM 8 /* Queue size for keyboard command replies */ @@ -92,56 +87,6 @@ #define MOD_SHIFT_R (1 << 4) #define MOD_ALT_R (1 << 5) -typedef struct { - uint8_t data[PS2_BUFFER_SIZE]; - int rptr, wptr, cwptr, count; -} PS2Queue; - -struct PS2State { - SysBusDevice parent_obj; - - PS2Queue queue; - int32_t write_cmd; - void (*update_irq)(void *, int); - void *update_arg; -}; - -#define TYPE_PS2_DEVICE "ps2-device" -OBJECT_DECLARE_SIMPLE_TYPE(PS2State, PS2_DEVICE) - -struct PS2KbdState { - PS2State parent_obj; - - int scan_enabled; - int translate; - int scancode_set; /* 1=XT, 2=AT, 3=PS/2 */ - int ledstate; - bool need_high_bit; - unsigned int modifiers; /* bitmask of MOD_* constants above */ -}; - -#define TYPE_PS2_KBD_DEVICE "ps2-kbd" -OBJECT_DECLARE_SIMPLE_TYPE(PS2KbdState, PS2_KBD_DEVICE) - -struct PS2MouseState { - PS2State parent_obj; - - uint8_t mouse_status; - uint8_t mouse_resolution; - uint8_t mouse_sample_rate; - uint8_t mouse_wrap; - uint8_t mouse_type; /* 0 = PS2, 3 = IMPS/2, 4 = IMEX */ - uint8_t mouse_detect_state; - int mouse_dx; /* current values, needed for 'poll' mode */ - int mouse_dy; - int mouse_dz; - int mouse_dw; - uint8_t mouse_buttons; -}; - -#define TYPE_PS2_MOUSE_DEVICE "ps2-mouse" -OBJECT_DECLARE_SIMPLE_TYPE(PS2MouseState, PS2_MOUSE_DEVICE) - static uint8_t translate_table[256] = { 0xff, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x3c, 0x58, 0x64, 0x44, 0x42, 0x40, 0x3e, 0x0f, 0x29, 0x59, diff --git a/include/hw/input/ps2.h b/include/hw/input/ps2.h index 35d983897a..7f2c3f6090 100644 --- a/include/hw/input/ps2.h +++ b/include/hw/input/ps2.h @@ -25,13 +25,69 @@ #ifndef HW_PS2_H #define HW_PS2_H +#include "hw/sysbus.h" + #define PS2_MOUSE_BUTTON_LEFT 0x01 #define PS2_MOUSE_BUTTON_RIGHT 0x02 #define PS2_MOUSE_BUTTON_MIDDLE 0x04 #define PS2_MOUSE_BUTTON_SIDE 0x08 #define PS2_MOUSE_BUTTON_EXTRA 0x10 -typedef struct PS2State PS2State; +/* + * PS/2 buffer size. Keep 256 bytes for compatibility with + * older QEMU versions. + */ +#define PS2_BUFFER_SIZE 256 + +typedef struct { + uint8_t data[PS2_BUFFER_SIZE]; + int rptr, wptr, cwptr, count; +} PS2Queue; + +struct PS2State { + SysBusDevice parent_obj; + + PS2Queue queue; + int32_t write_cmd; + void (*update_irq)(void *, int); + void *update_arg; +}; + +#define TYPE_PS2_DEVICE "ps2-device" +OBJECT_DECLARE_SIMPLE_TYPE(PS2State, PS2_DEVICE) + +struct PS2KbdState { + PS2State parent_obj; + + int scan_enabled; + int translate; + int scancode_set; /* 1=XT, 2=AT, 3=PS/2 */ + int ledstate; + bool need_high_bit; + unsigned int modifiers; /* bitmask of MOD_* constants above */ +}; + +#define TYPE_PS2_KBD_DEVICE "ps2-kbd" +OBJECT_DECLARE_SIMPLE_TYPE(PS2KbdState, PS2_KBD_DEVICE) + +struct PS2MouseState { + PS2State parent_obj; + + uint8_t mouse_status; + uint8_t mouse_resolution; + uint8_t mouse_sample_rate; + uint8_t mouse_wrap; + uint8_t mouse_type; /* 0 = PS2, 3 = IMPS/2, 4 = IMEX */ + uint8_t mouse_detect_state; + int mouse_dx; /* current values, needed for 'poll' mode */ + int mouse_dy; + int mouse_dz; + int mouse_dw; + uint8_t mouse_buttons; +}; + +#define TYPE_PS2_MOUSE_DEVICE "ps2-mouse" +OBJECT_DECLARE_SIMPLE_TYPE(PS2MouseState, PS2_MOUSE_DEVICE) /* ps2.c */ void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg); From 54334e7387c9da6015cf8b79b58dbf06286f822f Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:21 +0100 Subject: [PATCH 06/55] ps2: improve function prototypes in ps2.c and ps2.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the latest changes it is now possible to improve some of the function prototypes in ps2.c and ps.h to use the appropriate PS2KbdState or PS2MouseState type instead of being a void opaque. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Acked-by: Helge Deller Message-Id: <20220624134109.881989-7-mark.cave-ayland@ilande.co.uk> --- hw/input/ps2.c | 22 +++++++++------------- include/hw/input/ps2.h | 8 ++++---- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/hw/input/ps2.c b/hw/input/ps2.c index f4bad9876a..3a770f3b78 100644 --- a/hw/input/ps2.c +++ b/hw/input/ps2.c @@ -581,12 +581,11 @@ static void ps2_reset_keyboard(PS2KbdState *s) ps2_set_ledstate(s, 0); } -void ps2_write_keyboard(void *opaque, int val) +void ps2_write_keyboard(PS2KbdState *s, int val) { - PS2KbdState *s = (PS2KbdState *)opaque; PS2State *ps2 = PS2_DEVICE(s); - trace_ps2_write_keyboard(opaque, val); + trace_ps2_write_keyboard(s, val); ps2_cqueue_reset(ps2); switch (ps2->write_cmd) { default: @@ -675,10 +674,9 @@ void ps2_write_keyboard(void *opaque, int val) * 1 = translated scancodes (used by qemu internally). */ -void ps2_keyboard_set_translation(void *opaque, int mode) +void ps2_keyboard_set_translation(PS2KbdState *s, int mode) { - PS2KbdState *s = (PS2KbdState *)opaque; - trace_ps2_keyboard_set_translation(opaque, mode); + trace_ps2_keyboard_set_translation(s, mode); s->translate = mode; } @@ -857,20 +855,18 @@ static void ps2_mouse_sync(DeviceState *dev) } } -void ps2_mouse_fake_event(void *opaque) +void ps2_mouse_fake_event(PS2MouseState *s) { - PS2MouseState *s = opaque; - trace_ps2_mouse_fake_event(opaque); + trace_ps2_mouse_fake_event(s); s->mouse_dx++; - ps2_mouse_sync(opaque); + ps2_mouse_sync(DEVICE(s)); } -void ps2_write_mouse(void *opaque, int val) +void ps2_write_mouse(PS2MouseState *s, int val) { - PS2MouseState *s = (PS2MouseState *)opaque; PS2State *ps2 = PS2_DEVICE(s); - trace_ps2_write_mouse(opaque, val); + trace_ps2_write_mouse(s, val); switch (ps2->write_cmd) { default: case -1: diff --git a/include/hw/input/ps2.h b/include/hw/input/ps2.h index 7f2c3f6090..1a3321d77e 100644 --- a/include/hw/input/ps2.h +++ b/include/hw/input/ps2.h @@ -92,8 +92,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(PS2MouseState, PS2_MOUSE_DEVICE) /* ps2.c */ void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg); void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg); -void ps2_write_mouse(void *, int val); -void ps2_write_keyboard(void *, int val); +void ps2_write_mouse(PS2MouseState *s, int val); +void ps2_write_keyboard(PS2KbdState *s, int val); uint32_t ps2_read_data(PS2State *s); void ps2_queue_noirq(PS2State *s, int b); void ps2_raise_irq(PS2State *s); @@ -101,8 +101,8 @@ void ps2_queue(PS2State *s, int b); void ps2_queue_2(PS2State *s, int b1, int b2); void ps2_queue_3(PS2State *s, int b1, int b2, int b3); void ps2_queue_4(PS2State *s, int b1, int b2, int b3, int b4); -void ps2_keyboard_set_translation(void *opaque, int mode); -void ps2_mouse_fake_event(void *opaque); +void ps2_keyboard_set_translation(PS2KbdState *s, int mode); +void ps2_mouse_fake_event(PS2MouseState *s); int ps2_queue_empty(PS2State *s); #endif /* HW_PS2_H */ From 494145b28644dee66c1125c33ba55a02d5585db7 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:22 +0100 Subject: [PATCH 07/55] ps2: introduce PS2DeviceClass MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is in preparation for allowing the new PS2_KBD_DEVICE and PS2_MOUSE_DEVICE QOM types to reference the parent PS2_DEVICE device reset() function. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Acked-by: Helge Deller Message-Id: <20220624134109.881989-8-mark.cave-ayland@ilande.co.uk> --- hw/input/ps2.c | 1 + include/hw/input/ps2.h | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/hw/input/ps2.c b/hw/input/ps2.c index 3a770f3b78..fd5236690a 100644 --- a/hw/input/ps2.c +++ b/hw/input/ps2.c @@ -1283,6 +1283,7 @@ static const TypeInfo ps2_info = { .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(PS2State), .class_init = ps2_class_init, + .class_size = sizeof(PS2DeviceClass), .abstract = true }; diff --git a/include/hw/input/ps2.h b/include/hw/input/ps2.h index 1a3321d77e..aef892b5e6 100644 --- a/include/hw/input/ps2.h +++ b/include/hw/input/ps2.h @@ -33,6 +33,10 @@ #define PS2_MOUSE_BUTTON_SIDE 0x08 #define PS2_MOUSE_BUTTON_EXTRA 0x10 +struct PS2DeviceClass { + SysBusDeviceClass parent_class; +}; + /* * PS/2 buffer size. Keep 256 bytes for compatibility with * older QEMU versions. @@ -54,7 +58,7 @@ struct PS2State { }; #define TYPE_PS2_DEVICE "ps2-device" -OBJECT_DECLARE_SIMPLE_TYPE(PS2State, PS2_DEVICE) +OBJECT_DECLARE_TYPE(PS2State, PS2DeviceClass, PS2_DEVICE) struct PS2KbdState { PS2State parent_obj; From 108cb22e4837a36bc22959a612f8bb50471139f6 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:23 +0100 Subject: [PATCH 08/55] ps2: implement ps2_reset() for the PS2_DEVICE QOM type based upon ps2_common_reset() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The functionality of ps2_common_reset() can be moved into a new ps2_reset() function for the PS2_DEVICE QOM type. Update PS2DeviceClass to hold a reference to the parent reset function and update the PS2_KBD_DEVICE and PS2_MOUSE_DEVICE types to use device_class_set_parent_reset() accordingly. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Acked-by: Helge Deller Message-Id: <20220624134109.881989-9-mark.cave-ayland@ilande.co.uk> --- hw/input/ps2.c | 48 ++++++++++++++++++++++++++++++------------ include/hw/input/ps2.h | 2 ++ 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/hw/input/ps2.c b/hw/input/ps2.c index fd5236690a..f6f5514f0b 100644 --- a/hw/input/ps2.c +++ b/hw/input/ps2.c @@ -995,8 +995,10 @@ void ps2_write_mouse(PS2MouseState *s, int val) } } -static void ps2_common_reset(PS2State *s) +static void ps2_reset(DeviceState *dev) { + PS2State *s = PS2_DEVICE(dev); + s->write_cmd = -1; ps2_reset_queue(s); s->update_irq(s->update_arg, 0); @@ -1028,26 +1030,28 @@ static void ps2_common_post_load(PS2State *s) q->cwptr = ccount ? (q->rptr + ccount) & (PS2_BUFFER_SIZE - 1) : -1; } -static void ps2_kbd_reset(void *opaque) +static void ps2_kbd_reset(DeviceState *dev) { - PS2KbdState *s = (PS2KbdState *) opaque; - PS2State *ps2 = PS2_DEVICE(s); + PS2DeviceClass *ps2dc = PS2_DEVICE_GET_CLASS(dev); + PS2KbdState *s = PS2_KBD_DEVICE(dev); + + trace_ps2_kbd_reset(s); + ps2dc->parent_reset(dev); - trace_ps2_kbd_reset(opaque); - ps2_common_reset(ps2); s->scan_enabled = 1; s->translate = 0; s->scancode_set = 2; s->modifiers = 0; } -static void ps2_mouse_reset(void *opaque) +static void ps2_mouse_reset(DeviceState *dev) { - PS2MouseState *s = (PS2MouseState *) opaque; - PS2State *ps2 = PS2_DEVICE(s); + PS2DeviceClass *ps2dc = PS2_DEVICE_GET_CLASS(dev); + PS2MouseState *s = PS2_MOUSE_DEVICE(dev); + + trace_ps2_mouse_reset(s); + ps2dc->parent_reset(dev); - trace_ps2_mouse_reset(opaque); - ps2_common_reset(ps2); s->mouse_status = 0; s->mouse_resolution = 0; s->mouse_sample_rate = 0; @@ -1227,7 +1231,6 @@ void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg) vmstate_register(NULL, 0, &vmstate_ps2_keyboard, s); qemu_input_handler_register((DeviceState *)s, &ps2_keyboard_handler); - qemu_register_reset(ps2_kbd_reset, s); return s; } @@ -1255,26 +1258,45 @@ void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg) vmstate_register(NULL, 0, &vmstate_ps2_mouse, s); qemu_input_handler_register((DeviceState *)s, &ps2_mouse_handler); - qemu_register_reset(ps2_mouse_reset, s); return s; } +static void ps2_kbd_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + PS2DeviceClass *ps2dc = PS2_DEVICE_CLASS(klass); + + device_class_set_parent_reset(dc, ps2_kbd_reset, &ps2dc->parent_reset); +} + static const TypeInfo ps2_kbd_info = { .name = TYPE_PS2_KBD_DEVICE, .parent = TYPE_PS2_DEVICE, .instance_size = sizeof(PS2KbdState), + .class_init = ps2_kbd_class_init }; +static void ps2_mouse_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + PS2DeviceClass *ps2dc = PS2_DEVICE_CLASS(klass); + + device_class_set_parent_reset(dc, ps2_mouse_reset, + &ps2dc->parent_reset); +} + static const TypeInfo ps2_mouse_info = { .name = TYPE_PS2_MOUSE_DEVICE, .parent = TYPE_PS2_DEVICE, .instance_size = sizeof(PS2MouseState), + .class_init = ps2_mouse_class_init }; static void ps2_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + dc->reset = ps2_reset; set_bit(DEVICE_CATEGORY_INPUT, dc->categories); } diff --git a/include/hw/input/ps2.h b/include/hw/input/ps2.h index aef892b5e6..4be27de316 100644 --- a/include/hw/input/ps2.h +++ b/include/hw/input/ps2.h @@ -35,6 +35,8 @@ struct PS2DeviceClass { SysBusDeviceClass parent_class; + + DeviceReset parent_reset; }; /* From a243ecf8c09efd25a09f28e41eca0fea4f3444a0 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:24 +0100 Subject: [PATCH 09/55] ps2: remove duplicate setting of scancode_set in ps2_kbd_init() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The default value for scancode_set is already set in ps2_kbd_reset() so there is no need to duplicate this in ps2_kbd_init(). Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Acked-by: Helge Deller Message-Id: <20220624134109.881989-10-mark.cave-ayland@ilande.co.uk> --- hw/input/ps2.c | 1 - 1 file changed, 1 deletion(-) diff --git a/hw/input/ps2.c b/hw/input/ps2.c index f6f5514f0b..8018e39b17 100644 --- a/hw/input/ps2.c +++ b/hw/input/ps2.c @@ -1227,7 +1227,6 @@ void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg) trace_ps2_kbd_init(s); ps2->update_irq = update_irq; ps2->update_arg = update_arg; - s->scancode_set = 2; vmstate_register(NULL, 0, &vmstate_ps2_keyboard, s); qemu_input_handler_register((DeviceState *)s, &ps2_keyboard_handler); From ea247a0f3696a0ccdbc7ab818c1c15e5b53e4c31 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:25 +0100 Subject: [PATCH 10/55] ps2: implement ps2_kbd_realize() and use it to register ps2_keyboard_handler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the registration of ps2_keyboard_handler from ps2_kbd_init() to a new ps2_kbd_realize() function. Since the abstract PS2_DEVICE parent class doesn't have a realize() function then it is not necessary to store the reference to it in PS2DeviceClass and use device_class_set_parent_realize(). Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Acked-by: Helge Deller Message-Id: <20220624134109.881989-11-mark.cave-ayland@ilande.co.uk> --- hw/input/ps2.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/hw/input/ps2.c b/hw/input/ps2.c index 8018e39b17..62ea4c228b 100644 --- a/hw/input/ps2.c +++ b/hw/input/ps2.c @@ -1213,6 +1213,11 @@ static QemuInputHandler ps2_keyboard_handler = { .event = ps2_keyboard_event, }; +static void ps2_kbd_realize(DeviceState *dev, Error **errp) +{ + qemu_input_handler_register(dev, &ps2_keyboard_handler); +} + void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg) { DeviceState *dev; @@ -1228,8 +1233,7 @@ void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg) ps2->update_irq = update_irq; ps2->update_arg = update_arg; vmstate_register(NULL, 0, &vmstate_ps2_keyboard, s); - qemu_input_handler_register((DeviceState *)s, - &ps2_keyboard_handler); + return s; } @@ -1265,6 +1269,7 @@ static void ps2_kbd_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); PS2DeviceClass *ps2dc = PS2_DEVICE_CLASS(klass); + dc->realize = ps2_kbd_realize; device_class_set_parent_reset(dc, ps2_kbd_reset, &ps2dc->parent_reset); } From 4a68b4822ffceb40c34cf62847ff0da52532abb4 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:26 +0100 Subject: [PATCH 11/55] ps2: implement ps2_mouse_realize() and use it to register ps2_mouse_handler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the registration of ps2_mouse_handler from ps2_mouse_init() to a new ps2_mouse_realize() function. Since the abstract PS2_DEVICE parent class doesn't have a realize() function then it is not necessary to store the reference to it in PS2DeviceClass and use device_class_set_parent_realize(). Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Acked-by: Helge Deller Message-Id: <20220624134109.881989-12-mark.cave-ayland@ilande.co.uk> --- hw/input/ps2.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/hw/input/ps2.c b/hw/input/ps2.c index 62ea4c228b..eae7df2096 100644 --- a/hw/input/ps2.c +++ b/hw/input/ps2.c @@ -1244,6 +1244,11 @@ static QemuInputHandler ps2_mouse_handler = { .sync = ps2_mouse_sync, }; +static void ps2_mouse_realize(DeviceState *dev, Error **errp) +{ + qemu_input_handler_register(dev, &ps2_mouse_handler); +} + void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg) { DeviceState *dev; @@ -1259,8 +1264,6 @@ void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg) ps2->update_irq = update_irq; ps2->update_arg = update_arg; vmstate_register(NULL, 0, &vmstate_ps2_mouse, s); - qemu_input_handler_register((DeviceState *)s, - &ps2_mouse_handler); return s; } @@ -1285,6 +1288,7 @@ static void ps2_mouse_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); PS2DeviceClass *ps2dc = PS2_DEVICE_CLASS(klass); + dc->realize = ps2_mouse_realize; device_class_set_parent_reset(dc, ps2_mouse_reset, &ps2dc->parent_reset); } From f055f5075ab6778bddf2242c232b35b4466510c0 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:27 +0100 Subject: [PATCH 12/55] ps2: don't use vmstate_register() in ps2_kbd_init() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since PS2_KBD_DEVICE is a qdev device then vmstate_ps2_keyboard can be registered using the DeviceClass vmsd field instead. There is no need to use qdev_set_legacy_instance_id() to ensure migration compatibility since the first 2 parameters to vmstate_register() are NULL and 0 respectively. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Acked-by: Helge Deller Message-Id: <20220624134109.881989-13-mark.cave-ayland@ilande.co.uk> --- hw/input/ps2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/input/ps2.c b/hw/input/ps2.c index eae7df2096..97e9172ba5 100644 --- a/hw/input/ps2.c +++ b/hw/input/ps2.c @@ -1232,7 +1232,6 @@ void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg) trace_ps2_kbd_init(s); ps2->update_irq = update_irq; ps2->update_arg = update_arg; - vmstate_register(NULL, 0, &vmstate_ps2_keyboard, s); return s; } @@ -1274,6 +1273,7 @@ static void ps2_kbd_class_init(ObjectClass *klass, void *data) dc->realize = ps2_kbd_realize; device_class_set_parent_reset(dc, ps2_kbd_reset, &ps2dc->parent_reset); + dc->vmsd = &vmstate_ps2_keyboard; } static const TypeInfo ps2_kbd_info = { From 97259e70cbc0b874a523302960ae70fd184621ae Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:28 +0100 Subject: [PATCH 13/55] ps2: don't use vmstate_register() in ps2_mouse_init() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since PS2_MOUSE_DEVICE is a qdev device then vmstate_ps2_mouse can be registered using the DeviceClass vmsd field instead. There is no need to use qdev_set_legacy_instance_id() to ensure migration compatibility since the first 2 parameters to vmstate_register() are NULL and 0 respectively. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Acked-by: Helge Deller Message-Id: <20220624134109.881989-14-mark.cave-ayland@ilande.co.uk> --- hw/input/ps2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/input/ps2.c b/hw/input/ps2.c index 97e9172ba5..9c046ac500 100644 --- a/hw/input/ps2.c +++ b/hw/input/ps2.c @@ -1262,7 +1262,6 @@ void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg) trace_ps2_mouse_init(s); ps2->update_irq = update_irq; ps2->update_arg = update_arg; - vmstate_register(NULL, 0, &vmstate_ps2_mouse, s); return s; } @@ -1291,6 +1290,7 @@ static void ps2_mouse_class_init(ObjectClass *klass, void *data) dc->realize = ps2_mouse_realize; device_class_set_parent_reset(dc, ps2_mouse_reset, &ps2dc->parent_reset); + dc->vmsd = &vmstate_ps2_mouse; } static const TypeInfo ps2_mouse_info = { From 600f71109d8a0c10205d0f9c344c47d5a7962eed Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:29 +0100 Subject: [PATCH 14/55] pl050: checkpatch fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch also includes a couple of minor spacing updates. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Acked-by: Helge Deller Message-Id: <20220624134109.881989-15-mark.cave-ayland@ilande.co.uk> --- hw/input/pl050.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/hw/input/pl050.c b/hw/input/pl050.c index d279b6c148..889a0674d3 100644 --- a/hw/input/pl050.c +++ b/hw/input/pl050.c @@ -53,8 +53,9 @@ static const VMStateDescription vmstate_pl050 = { #define PL050_KMIC (1 << 1) #define PL050_KMID (1 << 0) -static const unsigned char pl050_id[] = -{ 0x50, 0x10, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 }; +static const unsigned char pl050_id[] = { + 0x50, 0x10, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 +}; static void pl050_update(void *opaque, int level) { @@ -71,8 +72,10 @@ static uint64_t pl050_read(void *opaque, hwaddr offset, unsigned size) { PL050State *s = (PL050State *)opaque; - if (offset >= 0xfe0 && offset < 0x1000) + + if (offset >= 0xfe0 && offset < 0x1000) { return pl050_id[(offset - 0xfe0) >> 2]; + } switch (offset >> 2) { case 0: /* KMICR */ @@ -88,16 +91,19 @@ static uint64_t pl050_read(void *opaque, hwaddr offset, val = (val ^ (val >> 1)) & 1; stat = PL050_TXEMPTY; - if (val) + if (val) { stat |= PL050_RXPARITY; - if (s->pending) + } + if (s->pending) { stat |= PL050_RXFULL; + } return stat; } case 2: /* KMIDATA */ - if (s->pending) + if (s->pending) { s->last = ps2_read_data(s->dev); + } return s->last; case 3: /* KMICLKDIV */ return s->clk; @@ -114,6 +120,7 @@ static void pl050_write(void *opaque, hwaddr offset, uint64_t value, unsigned size) { PL050State *s = (PL050State *)opaque; + switch (offset >> 2) { case 0: /* KMICR */ s->cr = value; From eca9e8702b7d071a8e2f94bd1096d846d91ca3d8 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:30 +0100 Subject: [PATCH 15/55] pl050: split pl050_update_irq() into separate pl050_set_irq() and pl050_update_irq() functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will soon allow pl050_set_irq() to be used as a GPIO input function. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Acked-by: Helge Deller Message-Id: <20220624134109.881989-16-mark.cave-ayland@ilande.co.uk> --- hw/input/pl050.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/hw/input/pl050.c b/hw/input/pl050.c index 889a0674d3..66f8c20d9f 100644 --- a/hw/input/pl050.c +++ b/hw/input/pl050.c @@ -57,15 +57,20 @@ static const unsigned char pl050_id[] = { 0x50, 0x10, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 }; -static void pl050_update(void *opaque, int level) +static void pl050_update_irq(PL050State *s) +{ + int level = (s->pending && (s->cr & 0x10) != 0) + || (s->cr & 0x08) != 0; + + qemu_set_irq(s->irq, level); +} + +static void pl050_set_irq(void *opaque, int level) { PL050State *s = (PL050State *)opaque; - int raise; s->pending = level; - raise = (s->pending && (s->cr & 0x10) != 0) - || (s->cr & 0x08) != 0; - qemu_set_irq(s->irq, raise); + pl050_update_irq(s); } static uint64_t pl050_read(void *opaque, hwaddr offset, @@ -124,7 +129,7 @@ static void pl050_write(void *opaque, hwaddr offset, switch (offset >> 2) { case 0: /* KMICR */ s->cr = value; - pl050_update(s, s->pending); + pl050_update_irq(s); /* ??? Need to implement the enable/disable bit. */ break; case 2: /* KMIDATA */ @@ -159,9 +164,9 @@ static void pl050_realize(DeviceState *dev, Error **errp) sysbus_init_mmio(sbd, &s->iomem); sysbus_init_irq(sbd, &s->irq); if (s->is_mouse) { - s->dev = ps2_mouse_init(pl050_update, s); + s->dev = ps2_mouse_init(pl050_set_irq, s); } else { - s->dev = ps2_kbd_init(pl050_update, s); + s->dev = ps2_kbd_init(pl050_set_irq, s); } } From 2a93d3c16571305864df8f990e39cb4d99ea1d33 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:31 +0100 Subject: [PATCH 16/55] lasips2: spacing fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This helps improve the readability of lasips2.c. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Acked-by: Helge Deller Message-Id: <20220624134109.881989-17-mark.cave-ayland@ilande.co.uk> --- hw/input/lasips2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c index 94f18be4cd..2ac3433014 100644 --- a/hw/input/lasips2.c +++ b/hw/input/lasips2.c @@ -205,7 +205,6 @@ static uint64_t lasips2_reg_read(void *opaque, hwaddr addr, unsigned size) break; case REG_PS2_STATUS: - ret = LASIPS2_STATUS_DATSHD | LASIPS2_STATUS_CLKSHD; if (port->control & LASIPS2_CONTROL_DIAG) { @@ -238,9 +237,9 @@ static uint64_t lasips2_reg_read(void *opaque, hwaddr addr, unsigned size) __func__, addr); break; } + trace_lasips2_reg_read(size, port->id, addr, lasips2_read_reg_name(addr), ret); - return ret; } @@ -257,6 +256,7 @@ static const MemoryRegionOps lasips2_reg_ops = { static void ps2dev_update_irq(void *opaque, int level) { LASIPS2Port *port = opaque; + port->irq = level; lasips2_update_irq(port->parent); } From f342469f21df9594e400d1208083652847ca4675 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:32 +0100 Subject: [PATCH 17/55] lasips2: rename ps2dev_update_irq() to lasips2_port_set_irq() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This better reflects that the IRQ input opaque is a LASIPS2Port structure and not a PS2_DEVICE. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Acked-by: Helge Deller Message-Id: <20220624134109.881989-18-mark.cave-ayland@ilande.co.uk> --- hw/input/lasips2.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c index 2ac3433014..adfde1684f 100644 --- a/hw/input/lasips2.c +++ b/hw/input/lasips2.c @@ -253,7 +253,7 @@ static const MemoryRegionOps lasips2_reg_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; -static void ps2dev_update_irq(void *opaque, int level) +static void lasips2_port_set_irq(void *opaque, int level) { LASIPS2Port *port = opaque; @@ -275,8 +275,8 @@ void lasips2_init(MemoryRegion *address_space, vmstate_register(NULL, base, &vmstate_lasips2, s); - s->kbd.dev = ps2_kbd_init(ps2dev_update_irq, &s->kbd); - s->mouse.dev = ps2_mouse_init(ps2dev_update_irq, &s->mouse); + s->kbd.dev = ps2_kbd_init(lasips2_port_set_irq, &s->kbd); + s->mouse.dev = ps2_mouse_init(lasips2_port_set_irq, &s->mouse); memory_region_init_io(&s->kbd.reg, NULL, &lasips2_reg_ops, &s->kbd, "lasips2-kbd", 0x100); From 32be01575df7cac57c58a34388126ee3d6740842 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:33 +0100 Subject: [PATCH 18/55] pckbd: checkpatch fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Acked-by: Helge Deller Message-Id: <20220624134109.881989-19-mark.cave-ayland@ilande.co.uk> --- hw/input/pckbd.c | 150 ++++++++++++++++++++++++++++++----------------- 1 file changed, 97 insertions(+), 53 deletions(-) diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c index 45c40fe3f3..c18a1a7fae 100644 --- a/hw/input/pckbd.c +++ b/hw/input/pckbd.c @@ -39,49 +39,86 @@ #include "trace.h" -/* Keyboard Controller Commands */ -#define KBD_CCMD_READ_MODE 0x20 /* Read mode bits */ -#define KBD_CCMD_WRITE_MODE 0x60 /* Write mode bits */ -#define KBD_CCMD_GET_VERSION 0xA1 /* Get controller version */ -#define KBD_CCMD_MOUSE_DISABLE 0xA7 /* Disable mouse interface */ -#define KBD_CCMD_MOUSE_ENABLE 0xA8 /* Enable mouse interface */ -#define KBD_CCMD_TEST_MOUSE 0xA9 /* Mouse interface test */ -#define KBD_CCMD_SELF_TEST 0xAA /* Controller self test */ -#define KBD_CCMD_KBD_TEST 0xAB /* Keyboard interface test */ -#define KBD_CCMD_KBD_DISABLE 0xAD /* Keyboard interface disable */ -#define KBD_CCMD_KBD_ENABLE 0xAE /* Keyboard interface enable */ -#define KBD_CCMD_READ_INPORT 0xC0 /* read input port */ -#define KBD_CCMD_READ_OUTPORT 0xD0 /* read output port */ -#define KBD_CCMD_WRITE_OUTPORT 0xD1 /* write output port */ -#define KBD_CCMD_WRITE_OBUF 0xD2 -#define KBD_CCMD_WRITE_AUX_OBUF 0xD3 /* Write to output buffer as if - initiated by the auxiliary device */ -#define KBD_CCMD_WRITE_MOUSE 0xD4 /* Write the following byte to the mouse */ -#define KBD_CCMD_DISABLE_A20 0xDD /* HP vectra only ? */ -#define KBD_CCMD_ENABLE_A20 0xDF /* HP vectra only ? */ -#define KBD_CCMD_PULSE_BITS_3_0 0xF0 /* Pulse bits 3-0 of the output port P2. */ -#define KBD_CCMD_RESET 0xFE /* Pulse bit 0 of the output port P2 = CPU reset. */ -#define KBD_CCMD_NO_OP 0xFF /* Pulse no bits of the output port P2. */ +/* Keyboard Controller Commands */ + +/* Read mode bits */ +#define KBD_CCMD_READ_MODE 0x20 +/* Write mode bits */ +#define KBD_CCMD_WRITE_MODE 0x60 +/* Get controller version */ +#define KBD_CCMD_GET_VERSION 0xA1 +/* Disable mouse interface */ +#define KBD_CCMD_MOUSE_DISABLE 0xA7 +/* Enable mouse interface */ +#define KBD_CCMD_MOUSE_ENABLE 0xA8 +/* Mouse interface test */ +#define KBD_CCMD_TEST_MOUSE 0xA9 +/* Controller self test */ +#define KBD_CCMD_SELF_TEST 0xAA +/* Keyboard interface test */ +#define KBD_CCMD_KBD_TEST 0xAB +/* Keyboard interface disable */ +#define KBD_CCMD_KBD_DISABLE 0xAD +/* Keyboard interface enable */ +#define KBD_CCMD_KBD_ENABLE 0xAE +/* read input port */ +#define KBD_CCMD_READ_INPORT 0xC0 +/* read output port */ +#define KBD_CCMD_READ_OUTPORT 0xD0 +/* write output port */ +#define KBD_CCMD_WRITE_OUTPORT 0xD1 +#define KBD_CCMD_WRITE_OBUF 0xD2 +/* Write to output buffer as if initiated by the auxiliary device */ +#define KBD_CCMD_WRITE_AUX_OBUF 0xD3 +/* Write the following byte to the mouse */ +#define KBD_CCMD_WRITE_MOUSE 0xD4 +/* HP vectra only ? */ +#define KBD_CCMD_DISABLE_A20 0xDD +/* HP vectra only ? */ +#define KBD_CCMD_ENABLE_A20 0xDF +/* Pulse bits 3-0 of the output port P2. */ +#define KBD_CCMD_PULSE_BITS_3_0 0xF0 +/* Pulse bit 0 of the output port P2 = CPU reset. */ +#define KBD_CCMD_RESET 0xFE +/* Pulse no bits of the output port P2. */ +#define KBD_CCMD_NO_OP 0xFF /* Status Register Bits */ -#define KBD_STAT_OBF 0x01 /* Keyboard output buffer full */ -#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */ -#define KBD_STAT_SELFTEST 0x04 /* Self test successful */ -#define KBD_STAT_CMD 0x08 /* Last write was a command write (0=data) */ -#define KBD_STAT_UNLOCKED 0x10 /* Zero if keyboard locked */ -#define KBD_STAT_MOUSE_OBF 0x20 /* Mouse output buffer full */ -#define KBD_STAT_GTO 0x40 /* General receive/xmit timeout */ -#define KBD_STAT_PERR 0x80 /* Parity error */ + +/* Keyboard output buffer full */ +#define KBD_STAT_OBF 0x01 +/* Keyboard input buffer full */ +#define KBD_STAT_IBF 0x02 +/* Self test successful */ +#define KBD_STAT_SELFTEST 0x04 +/* Last write was a command write (0=data) */ +#define KBD_STAT_CMD 0x08 +/* Zero if keyboard locked */ +#define KBD_STAT_UNLOCKED 0x10 +/* Mouse output buffer full */ +#define KBD_STAT_MOUSE_OBF 0x20 +/* General receive/xmit timeout */ +#define KBD_STAT_GTO 0x40 +/* Parity error */ +#define KBD_STAT_PERR 0x80 /* Controller Mode Register Bits */ -#define KBD_MODE_KBD_INT 0x01 /* Keyboard data generate IRQ1 */ -#define KBD_MODE_MOUSE_INT 0x02 /* Mouse data generate IRQ12 */ -#define KBD_MODE_SYS 0x04 /* The system flag (?) */ -#define KBD_MODE_NO_KEYLOCK 0x08 /* The keylock doesn't affect the keyboard if set */ -#define KBD_MODE_DISABLE_KBD 0x10 /* Disable keyboard interface */ -#define KBD_MODE_DISABLE_MOUSE 0x20 /* Disable mouse interface */ -#define KBD_MODE_KCC 0x40 /* Scan code conversion to PC format */ -#define KBD_MODE_RFU 0x80 + +/* Keyboard data generate IRQ1 */ +#define KBD_MODE_KBD_INT 0x01 +/* Mouse data generate IRQ12 */ +#define KBD_MODE_MOUSE_INT 0x02 +/* The system flag (?) */ +#define KBD_MODE_SYS 0x04 +/* The keylock doesn't affect the keyboard if set */ +#define KBD_MODE_NO_KEYLOCK 0x08 +/* Disable keyboard interface */ +#define KBD_MODE_DISABLE_KBD 0x10 +/* Disable mouse interface */ +#define KBD_MODE_DISABLE_MOUSE 0x20 +/* Scan code conversion to PC format */ +#define KBD_MODE_KCC 0x40 +#define KBD_MODE_RFU 0x80 /* Output Port Bits */ #define KBD_OUT_RESET 0x01 /* 1=normal mode, 0=reset */ @@ -89,7 +126,8 @@ #define KBD_OUT_OBF 0x10 /* Keyboard output buffer full */ #define KBD_OUT_MOUSE_OBF 0x20 /* Mouse output buffer full */ -/* OSes typically write 0xdd/0xdf to turn the A20 line off and on. +/* + * OSes typically write 0xdd/0xdf to turn the A20 line off and on. * We make the default value of the outport include these four bits, * so that the subsection is rarely necessary. */ @@ -133,8 +171,10 @@ typedef struct KBDState { hwaddr mask; } KBDState; -/* XXX: not generating the irqs if KBD_MODE_DISABLE_KBD is set may be - incorrect, but it avoids having to simulate exact delays */ +/* + * XXX: not generating the irqs if KBD_MODE_DISABLE_KBD is set may be + * incorrect, but it avoids having to simulate exact delays + */ static void kbd_update_irq_lines(KBDState *s) { int irq_kbd_level, irq_mouse_level; @@ -302,21 +342,23 @@ static void kbd_write_command(void *opaque, hwaddr addr, trace_pckbd_kbd_write_command(val); - /* Bits 3-0 of the output port P2 of the keyboard controller may be pulsed + /* + * Bits 3-0 of the output port P2 of the keyboard controller may be pulsed * low for approximately 6 micro seconds. Bits 3-0 of the KBD_CCMD_PULSE * command specify the output port bits to be pulsed. * 0: Bit should be pulsed. 1: Bit should not be modified. * The only useful version of this command is pulsing bit 0, * which does a CPU reset. */ - if((val & KBD_CCMD_PULSE_BITS_3_0) == KBD_CCMD_PULSE_BITS_3_0) { - if(!(val & 1)) + if ((val & KBD_CCMD_PULSE_BITS_3_0) == KBD_CCMD_PULSE_BITS_3_0) { + if (!(val & 1)) { val = KBD_CCMD_RESET; - else + } else { val = KBD_CCMD_NO_OP; + } } - switch(val) { + switch (val) { case KBD_CCMD_READ_MODE: kbd_queue(s, s->mode, 0); break; @@ -409,7 +451,7 @@ static void kbd_write_data(void *opaque, hwaddr addr, trace_pckbd_kbd_write_data(val); - switch(s->write_cmd) { + switch (s->write_cmd) { case 0: ps2_write_keyboard(s->kbd, val); /* sending data to the keyboard reenables PS/2 communication */ @@ -607,7 +649,7 @@ static const VMStateDescription vmstate_kbd = { VMSTATE_UINT8(pending_tmp, KBDState), VMSTATE_END_OF_LIST() }, - .subsections = (const VMStateDescription*[]) { + .subsections = (const VMStateDescription * []) { &vmstate_kbd_outport, &vmstate_kbd_extended_state, NULL @@ -619,10 +661,11 @@ static uint64_t kbd_mm_readfn(void *opaque, hwaddr addr, unsigned size) { KBDState *s = opaque; - if (addr & s->mask) + if (addr & s->mask) { return kbd_read_status(s, 0, 1) & 0xff; - else + } else { return kbd_read_data(s, 0, 1) & 0xff; + } } static void kbd_mm_writefn(void *opaque, hwaddr addr, @@ -630,10 +673,11 @@ static void kbd_mm_writefn(void *opaque, hwaddr addr, { KBDState *s = opaque; - if (addr & s->mask) + if (addr & s->mask) { kbd_write_command(s, 0, value & 0xff, 1); - else + } else { kbd_write_data(s, 0, value & 0xff, 1); + } } From 77adda52ef7bcdb5edc9b4dc1678c83f31a02f46 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:34 +0100 Subject: [PATCH 19/55] pckbd: move KBDState from pckbd.c to i8042.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows the QOM types in pckbd.c to be used elsewhere by simply including i8042.h. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Acked-by: Helge Deller Message-Id: <20220624134109.881989-20-mark.cave-ayland@ilande.co.uk> --- hw/input/pckbd.c | 24 ------------------------ include/hw/input/i8042.h | 25 +++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c index c18a1a7fae..7b14cd007e 100644 --- a/hw/input/pckbd.c +++ b/hw/input/pckbd.c @@ -146,30 +146,6 @@ #define KBD_OBSRC_MOUSE 0x02 #define KBD_OBSRC_CTRL 0x04 -typedef struct KBDState { - uint8_t write_cmd; /* if non zero, write data to port 60 is expected */ - uint8_t status; - uint8_t mode; - uint8_t outport; - uint32_t migration_flags; - uint32_t obsrc; - bool outport_present; - bool extended_state; - bool extended_state_loaded; - /* Bitmask of devices with data available. */ - uint8_t pending; - uint8_t obdata; - uint8_t cbdata; - uint8_t pending_tmp; - void *kbd; - void *mouse; - QEMUTimer *throttle_timer; - - qemu_irq irq_kbd; - qemu_irq irq_mouse; - qemu_irq a20_out; - hwaddr mask; -} KBDState; /* * XXX: not generating the irqs if KBD_MODE_DISABLE_KBD is set may be diff --git a/include/hw/input/i8042.h b/include/hw/input/i8042.h index e070f546e4..84b5aa7f23 100644 --- a/include/hw/input/i8042.h +++ b/include/hw/input/i8042.h @@ -11,6 +11,31 @@ #include "hw/isa/isa.h" #include "qom/object.h" +typedef struct KBDState { + uint8_t write_cmd; /* if non zero, write data to port 60 is expected */ + uint8_t status; + uint8_t mode; + uint8_t outport; + uint32_t migration_flags; + uint32_t obsrc; + bool outport_present; + bool extended_state; + bool extended_state_loaded; + /* Bitmask of devices with data available. */ + uint8_t pending; + uint8_t obdata; + uint8_t cbdata; + uint8_t pending_tmp; + void *kbd; + void *mouse; + QEMUTimer *throttle_timer; + + qemu_irq irq_kbd; + qemu_irq irq_mouse; + qemu_irq a20_out; + hwaddr mask; +} KBDState; + #define TYPE_I8042 "i8042" OBJECT_DECLARE_SIMPLE_TYPE(ISAKBDState, I8042) From c9849a71b997a3b96757b19642b5b9a56c2ccb75 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:35 +0100 Subject: [PATCH 20/55] pckbd: move ISAKBDState from pckbd.c to i8042.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows the QOM types in pckbd.c to be used elsewhere by simply including i8042.h. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Acked-by: Helge Deller Message-Id: <20220624134109.881989-21-mark.cave-ayland@ilande.co.uk> --- hw/input/pckbd.c | 10 ---------- include/hw/input/i8042.h | 10 ++++++++++ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c index 7b14cd007e..f99e10cfcf 100644 --- a/hw/input/pckbd.c +++ b/hw/input/pckbd.c @@ -686,16 +686,6 @@ void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq, qemu_register_reset(kbd_reset, s); } -struct ISAKBDState { - ISADevice parent_obj; - - KBDState kbd; - bool kbd_throttle; - MemoryRegion io[2]; - uint8_t kbd_irq; - uint8_t mouse_irq; -}; - void i8042_isa_mouse_fake_event(ISAKBDState *isa) { KBDState *s = &isa->kbd; diff --git a/include/hw/input/i8042.h b/include/hw/input/i8042.h index 84b5aa7f23..a246250d1f 100644 --- a/include/hw/input/i8042.h +++ b/include/hw/input/i8042.h @@ -39,6 +39,16 @@ typedef struct KBDState { #define TYPE_I8042 "i8042" OBJECT_DECLARE_SIMPLE_TYPE(ISAKBDState, I8042) +struct ISAKBDState { + ISADevice parent_obj; + + KBDState kbd; + bool kbd_throttle; + MemoryRegion io[2]; + uint8_t kbd_irq; + uint8_t mouse_irq; +}; + #define I8042_A20_LINE "a20" From 150ee013ed3f2af7eec493cd68ae774a85d40a2b Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:36 +0100 Subject: [PATCH 21/55] pckbd: introduce new I8042_MMIO QOM type Currently i8042_mm_init() creates a new KBDState directly which is used by the MIPS magnum machine. Introduce a new I8042_MMIO QOM type that will soon be used to allow the MIPS magnum machine to be wired up using standard qdev GPIOs. Signed-off-by: Mark Cave-Ayland Acked-by: Helge Deller Reviewed-by: Peter Maydell Message-Id: <20220624134109.881989-22-mark.cave-ayland@ilande.co.uk> --- hw/input/pckbd.c | 22 +++++++++++++++++++++- include/hw/input/i8042.h | 10 ++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c index f99e10cfcf..89a41ed566 100644 --- a/hw/input/pckbd.c +++ b/hw/input/pckbd.c @@ -665,11 +665,23 @@ static const MemoryRegionOps i8042_mmio_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; +static void i8042_mmio_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + set_bit(DEVICE_CATEGORY_INPUT, dc->categories); +} + void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq, MemoryRegion *region, ram_addr_t size, hwaddr mask) { - KBDState *s = g_new0(KBDState, 1); + DeviceState *dev; + KBDState *s; + + dev = qdev_new(TYPE_I8042_MMIO); + sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); + s = &I8042_MMIO(dev)->kbd; s->irq_kbd = kbd_irq; s->irq_mouse = mouse_irq; @@ -686,6 +698,13 @@ void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq, qemu_register_reset(kbd_reset, s); } +static const TypeInfo i8042_mmio_info = { + .name = TYPE_I8042_MMIO, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(MMIOKBDState), + .class_init = i8042_mmio_class_init +}; + void i8042_isa_mouse_fake_event(ISAKBDState *isa) { KBDState *s = &isa->kbd; @@ -841,6 +860,7 @@ static const TypeInfo i8042_info = { static void i8042_register_types(void) { type_register_static(&i8042_info); + type_register_static(&i8042_mmio_info); } type_init(i8042_register_types) diff --git a/include/hw/input/i8042.h b/include/hw/input/i8042.h index a246250d1f..b7df9ace6e 100644 --- a/include/hw/input/i8042.h +++ b/include/hw/input/i8042.h @@ -9,6 +9,7 @@ #define HW_INPUT_I8042_H #include "hw/isa/isa.h" +#include "hw/sysbus.h" #include "qom/object.h" typedef struct KBDState { @@ -49,6 +50,15 @@ struct ISAKBDState { uint8_t mouse_irq; }; +#define TYPE_I8042_MMIO "i8042-mmio" +OBJECT_DECLARE_SIMPLE_TYPE(MMIOKBDState, I8042_MMIO) + +struct MMIOKBDState { + SysBusDevice parent_obj; + + KBDState kbd; +}; + #define I8042_A20_LINE "a20" From 57f6c3aac08d16eb7fe4a447dbbbfeb314d39234 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:37 +0100 Subject: [PATCH 22/55] pckbd: implement i8042_mmio_reset() for I8042_MMIO device This allows the I8042_MMIO reset function to be registered directly within the DeviceClass rather than using qemu_register_reset() directly. Signed-off-by: Mark Cave-Ayland Acked-by: Helge Deller Message-Id: <20220624134109.881989-23-mark.cave-ayland@ilande.co.uk> Reviewed-by: Peter Maydell --- hw/input/pckbd.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c index 89a41ed566..7b520d0eb4 100644 --- a/hw/input/pckbd.c +++ b/hw/input/pckbd.c @@ -665,10 +665,19 @@ static const MemoryRegionOps i8042_mmio_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; +static void i8042_mmio_reset(DeviceState *dev) +{ + MMIOKBDState *s = I8042_MMIO(dev); + KBDState *ks = &s->kbd; + + kbd_reset(ks); +} + static void i8042_mmio_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + dc->reset = i8042_mmio_reset; set_bit(DEVICE_CATEGORY_INPUT, dc->categories); } @@ -695,7 +704,6 @@ void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq, s->kbd = ps2_kbd_init(kbd_update_kbd_irq, s); s->mouse = ps2_mouse_init(kbd_update_aux_irq, s); - qemu_register_reset(kbd_reset, s); } static const TypeInfo i8042_mmio_info = { From d4f5b4d87945d2a0f02fea8b42439d24c809c458 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:38 +0100 Subject: [PATCH 23/55] pckbd: add mask qdev property to I8042_MMIO device This allows the KBDState mask value to be set using a qdev property rather than directly in i8042_mm_init(). Signed-off-by: Mark Cave-Ayland Acked-by: Helge Deller Reviewed-by: Peter Maydell Message-Id: <20220624134109.881989-24-mark.cave-ayland@ilande.co.uk> --- hw/input/pckbd.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c index 7b520d0eb4..c04a2c587e 100644 --- a/hw/input/pckbd.c +++ b/hw/input/pckbd.c @@ -673,11 +673,17 @@ static void i8042_mmio_reset(DeviceState *dev) kbd_reset(ks); } +static Property i8042_mmio_properties[] = { + DEFINE_PROP_UINT64("mask", MMIOKBDState, kbd.mask, UINT64_MAX), + DEFINE_PROP_END_OF_LIST(), +}; + static void i8042_mmio_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); dc->reset = i8042_mmio_reset; + device_class_set_props(dc, i8042_mmio_properties); set_bit(DEVICE_CATEGORY_INPUT, dc->categories); } @@ -689,12 +695,12 @@ void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq, KBDState *s; dev = qdev_new(TYPE_I8042_MMIO); + qdev_prop_set_uint64(dev, "mask", mask); sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); s = &I8042_MMIO(dev)->kbd; s->irq_kbd = kbd_irq; s->irq_mouse = mouse_irq; - s->mask = mask; s->extended_state = true; From 7b9fff290c20ee65c5deba0ad98f97529061d231 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:39 +0100 Subject: [PATCH 24/55] pckbd: add size qdev property to I8042_MMIO device This will soon be used to set the size of the register memory region using a qdev property. Signed-off-by: Mark Cave-Ayland Acked-by: Helge Deller Reviewed-by: Peter Maydell Message-Id: <20220624134109.881989-25-mark.cave-ayland@ilande.co.uk> --- hw/input/pckbd.c | 2 ++ include/hw/input/i8042.h | 1 + 2 files changed, 3 insertions(+) diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c index c04a2c587e..a70442e0f8 100644 --- a/hw/input/pckbd.c +++ b/hw/input/pckbd.c @@ -675,6 +675,7 @@ static void i8042_mmio_reset(DeviceState *dev) static Property i8042_mmio_properties[] = { DEFINE_PROP_UINT64("mask", MMIOKBDState, kbd.mask, UINT64_MAX), + DEFINE_PROP_UINT32("size", MMIOKBDState, size, -1), DEFINE_PROP_END_OF_LIST(), }; @@ -696,6 +697,7 @@ void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq, 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); s = &I8042_MMIO(dev)->kbd; diff --git a/include/hw/input/i8042.h b/include/hw/input/i8042.h index b7df9ace6e..ac4098b957 100644 --- a/include/hw/input/i8042.h +++ b/include/hw/input/i8042.h @@ -57,6 +57,7 @@ struct MMIOKBDState { SysBusDevice parent_obj; KBDState kbd; + uint32_t size; }; #define I8042_A20_LINE "a20" From f4de68d1d45f1f104535a82f3e0dd3c393c6539e Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:40 +0100 Subject: [PATCH 25/55] pckbd: implement i8042_mmio_realize() function Move the initialisation of the register memory region to the I8042_MMIO device realize function and expose it using sysbus_init_mmio(). Signed-off-by: Mark Cave-Ayland Acked-by: Helge Deller Reviewed-by: Peter Maydell Message-Id: <20220624134109.881989-26-mark.cave-ayland@ilande.co.uk> --- hw/input/pckbd.c | 14 +++++++++++++- include/hw/input/i8042.h | 1 + 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c index a70442e0f8..bc51f7eedd 100644 --- a/hw/input/pckbd.c +++ b/hw/input/pckbd.c @@ -673,6 +673,17 @@ static void i8042_mmio_reset(DeviceState *dev) kbd_reset(ks); } +static void i8042_mmio_realize(DeviceState *dev, Error **errp) +{ + MMIOKBDState *s = I8042_MMIO(dev); + KBDState *ks = &s->kbd; + + memory_region_init_io(&s->region, OBJECT(dev), &i8042_mmio_ops, ks, + "i8042", s->size); + + sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->region); +} + static Property i8042_mmio_properties[] = { DEFINE_PROP_UINT64("mask", MMIOKBDState, kbd.mask, UINT64_MAX), DEFINE_PROP_UINT32("size", MMIOKBDState, size, -1), @@ -683,6 +694,7 @@ 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; device_class_set_props(dc, i8042_mmio_properties); set_bit(DEVICE_CATEGORY_INPUT, dc->categories); @@ -708,7 +720,7 @@ void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq, vmstate_register(NULL, 0, &vmstate_kbd, s); - memory_region_init_io(region, NULL, &i8042_mmio_ops, s, "i8042", size); + region = &I8042_MMIO(dev)->region; s->kbd = ps2_kbd_init(kbd_update_kbd_irq, s); s->mouse = ps2_mouse_init(kbd_update_aux_irq, s); diff --git a/include/hw/input/i8042.h b/include/hw/input/i8042.h index ac4098b957..59d695a9dd 100644 --- a/include/hw/input/i8042.h +++ b/include/hw/input/i8042.h @@ -58,6 +58,7 @@ struct MMIOKBDState { KBDState kbd; uint32_t size; + MemoryRegion region; }; #define I8042_A20_LINE "a20" From 47fc74154c1dd68d70209a87213805fdad0d2790 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:41 +0100 Subject: [PATCH 26/55] pckbd: implement i8042_mmio_init() function This enables use to set the required value of extended_state directly during device init rather than in i8042_mm_init(). Signed-off-by: Mark Cave-Ayland Acked-by: Helge Deller Message-Id: <20220624134109.881989-27-mark.cave-ayland@ilande.co.uk> Reviewed-by: Peter Maydell --- hw/input/pckbd.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c index bc51f7eedd..b8623d2f9a 100644 --- a/hw/input/pckbd.c +++ b/hw/input/pckbd.c @@ -684,6 +684,14 @@ static void i8042_mmio_realize(DeviceState *dev, Error **errp) sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->region); } +static void i8042_mmio_init(Object *obj) +{ + MMIOKBDState *s = I8042_MMIO(obj); + KBDState *ks = &s->kbd; + + ks->extended_state = true; +} + static Property i8042_mmio_properties[] = { DEFINE_PROP_UINT64("mask", MMIOKBDState, kbd.mask, UINT64_MAX), DEFINE_PROP_UINT32("size", MMIOKBDState, size, -1), @@ -716,8 +724,6 @@ void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq, s->irq_kbd = kbd_irq; s->irq_mouse = mouse_irq; - s->extended_state = true; - vmstate_register(NULL, 0, &vmstate_kbd, s); region = &I8042_MMIO(dev)->region; @@ -729,6 +735,7 @@ void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq, static const TypeInfo i8042_mmio_info = { .name = TYPE_I8042_MMIO, .parent = TYPE_SYS_BUS_DEVICE, + .instance_init = i8042_mmio_init, .instance_size = sizeof(MMIOKBDState), .class_init = i8042_mmio_class_init }; From 903dd0e49b5140df55d6f77f97c741f99346c23e Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:42 +0100 Subject: [PATCH 27/55] pckbd: alter i8042_mm_init() to return a I8042_MMIO device This exposes the I8042_MMIO device to the caller to allow the register memory region to be mapped outside of i8042_mm_init(). Signed-off-by: Mark Cave-Ayland Acked-by: Helge Deller Reviewed-by: Peter Maydell Message-Id: <20220624134109.881989-28-mark.cave-ayland@ilande.co.uk> --- hw/input/pckbd.c | 8 +++++--- include/hw/input/i8042.h | 6 +++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c index b8623d2f9a..702dab056c 100644 --- a/hw/input/pckbd.c +++ b/hw/input/pckbd.c @@ -708,9 +708,9 @@ static void i8042_mmio_class_init(ObjectClass *klass, void *data) set_bit(DEVICE_CATEGORY_INPUT, dc->categories); } -void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq, - MemoryRegion *region, ram_addr_t size, - hwaddr mask) +MMIOKBDState *i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq, + MemoryRegion *region, ram_addr_t size, + hwaddr mask) { DeviceState *dev; KBDState *s; @@ -730,6 +730,8 @@ void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq, s->kbd = ps2_kbd_init(kbd_update_kbd_irq, s); s->mouse = ps2_mouse_init(kbd_update_aux_irq, s); + + return I8042_MMIO(dev); } static const TypeInfo i8042_mmio_info = { diff --git a/include/hw/input/i8042.h b/include/hw/input/i8042.h index 59d695a9dd..d05cd33e3c 100644 --- a/include/hw/input/i8042.h +++ b/include/hw/input/i8042.h @@ -64,9 +64,9 @@ struct MMIOKBDState { #define I8042_A20_LINE "a20" -void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq, - MemoryRegion *region, ram_addr_t size, - hwaddr mask); +MMIOKBDState *i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq, + MemoryRegion *region, ram_addr_t size, + hwaddr mask); void i8042_isa_mouse_fake_event(ISAKBDState *isa); void i8042_setup_a20_line(ISADevice *dev, qemu_irq a20_out); From 01d924dce88f6d43a0be36c0e626f058e68a9ea4 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:43 +0100 Subject: [PATCH 28/55] pckbd: move mapping of I8042_MMIO registers to MIPS magnum machine Now that the register memory region is exposed as a SysBus memory region, move the mapping of the I8042_MMIO registers from i8042_mm_init() to the MIPS magnum machine (which is its only user). Signed-off-by: Mark Cave-Ayland Acked-by: Helge Deller Reviewed-by: Peter Maydell Message-Id: <20220624134109.881989-29-mark.cave-ayland@ilande.co.uk> --- hw/input/pckbd.c | 5 +---- hw/mips/jazz.c | 11 +++++++---- include/hw/input/i8042.h | 3 +-- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c index 702dab056c..8708595eed 100644 --- a/hw/input/pckbd.c +++ b/hw/input/pckbd.c @@ -709,8 +709,7 @@ static void i8042_mmio_class_init(ObjectClass *klass, void *data) } MMIOKBDState *i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq, - MemoryRegion *region, ram_addr_t size, - hwaddr mask) + ram_addr_t size, hwaddr mask) { DeviceState *dev; KBDState *s; @@ -726,8 +725,6 @@ MMIOKBDState *i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq, vmstate_register(NULL, 0, &vmstate_kbd, s); - region = &I8042_MMIO(dev)->region; - s->kbd = ps2_kbd_init(kbd_update_kbd_irq, s); s->mouse = ps2_mouse_init(kbd_update_aux_irq, s); diff --git a/hw/mips/jazz.c b/hw/mips/jazz.c index 96dc6ab32d..1eb8bd5018 100644 --- a/hw/mips/jazz.c +++ b/hw/mips/jazz.c @@ -136,11 +136,11 @@ static void mips_jazz_init(MachineState *machine, MemoryRegion *isa_mem = g_new(MemoryRegion, 1); MemoryRegion *isa_io = g_new(MemoryRegion, 1); MemoryRegion *rtc = g_new(MemoryRegion, 1); - MemoryRegion *i8042 = g_new(MemoryRegion, 1); MemoryRegion *dma_dummy = g_new(MemoryRegion, 1); MemoryRegion *dp8393x_prom = g_new(MemoryRegion, 1); NICInfo *nd; DeviceState *dev, *rc4030; + MMIOKBDState *i8042; SysBusDevice *sysbus; ISABus *isa_bus; ISADevice *pit; @@ -361,9 +361,12 @@ static void mips_jazz_init(MachineState *machine, memory_region_add_subregion(address_space, 0x80004000, rtc); /* Keyboard (i8042) */ - i8042_mm_init(qdev_get_gpio_in(rc4030, 6), qdev_get_gpio_in(rc4030, 7), - i8042, 0x1000, 0x1); - memory_region_add_subregion(address_space, 0x80005000, i8042); + i8042 = i8042_mm_init(qdev_get_gpio_in(rc4030, 6), + qdev_get_gpio_in(rc4030, 7), + 0x1000, 0x1); + memory_region_add_subregion(address_space, 0x80005000, + sysbus_mmio_get_region(SYS_BUS_DEVICE(i8042), + 0)); /* Serial ports */ serial_mm_init(address_space, 0x80006000, 0, diff --git a/include/hw/input/i8042.h b/include/hw/input/i8042.h index d05cd33e3c..9d1f8af964 100644 --- a/include/hw/input/i8042.h +++ b/include/hw/input/i8042.h @@ -65,8 +65,7 @@ struct MMIOKBDState { MMIOKBDState *i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq, - MemoryRegion *region, ram_addr_t size, - hwaddr mask); + ram_addr_t size, hwaddr mask); void i8042_isa_mouse_fake_event(ISAKBDState *isa); void i8042_setup_a20_line(ISADevice *dev, qemu_irq a20_out); From 75877e9356638b6446f634298923be5c088a3a60 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:44 +0100 Subject: [PATCH 29/55] pckbd: more vmstate_register() from i8042_mm_init() to i8042_mmio_realize() Note in this case it is not possible to register a (new) VMStateDescription in the DeviceClass without breaking migration compatibility for the MIPS magnum machine. Signed-off-by: Mark Cave-Ayland Acked-by: Helge Deller Message-Id: <20220624134109.881989-30-mark.cave-ayland@ilande.co.uk> Reviewed-by: Peter Maydell --- hw/input/pckbd.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c index 8708595eed..1ab76793ea 100644 --- a/hw/input/pckbd.c +++ b/hw/input/pckbd.c @@ -682,6 +682,9 @@ static void i8042_mmio_realize(DeviceState *dev, Error **errp) "i8042", s->size); 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); } static void i8042_mmio_init(Object *obj) @@ -723,8 +726,6 @@ MMIOKBDState *i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq, s->irq_kbd = kbd_irq; s->irq_mouse = mouse_irq; - vmstate_register(NULL, 0, &vmstate_kbd, s); - s->kbd = ps2_kbd_init(kbd_update_kbd_irq, s); s->mouse = ps2_mouse_init(kbd_update_aux_irq, s); From 488d1537a1f59018db57ea8293a7084e8ee71a86 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:45 +0100 Subject: [PATCH 30/55] pckbd: move ps2_kbd_init() and ps2_mouse_init() to i8042_mmio_realize() Move ps2_kbd_init() and ps2_mouse_init() from i8042_mm_init() to i8042_mmio_realize() to further reduce the initialisation logic done in i8042_mm_init(). Signed-off-by: Mark Cave-Ayland Acked-by: Helge Deller Reviewed-by: Peter Maydell Message-Id: <20220624134109.881989-31-mark.cave-ayland@ilande.co.uk> --- hw/input/pckbd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c index 1ab76793ea..72843f770e 100644 --- a/hw/input/pckbd.c +++ b/hw/input/pckbd.c @@ -685,6 +685,9 @@ static void i8042_mmio_realize(DeviceState *dev, Error **errp) /* Note we can't use dc->vmsd without breaking migration compatibility */ vmstate_register(NULL, 0, &vmstate_kbd, ks); + + ks->kbd = ps2_kbd_init(kbd_update_kbd_irq, ks); + ks->mouse = ps2_mouse_init(kbd_update_aux_irq, ks); } static void i8042_mmio_init(Object *obj) @@ -726,9 +729,6 @@ MMIOKBDState *i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq, s->irq_kbd = kbd_irq; s->irq_mouse = mouse_irq; - s->kbd = ps2_kbd_init(kbd_update_kbd_irq, s); - s->mouse = ps2_mouse_init(kbd_update_aux_irq, s); - return I8042_MMIO(dev); } From 52b28f76dd5d1a44c0d3632a98987e5c771cf251 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:46 +0100 Subject: [PATCH 31/55] ps2: make ps2_raise_irq() function static This function is no longer used outside of ps2.c and so can be declared static. Signed-off-by: Mark Cave-Ayland Acked-by: Helge Deller Reviewed-by: Peter Maydell Message-Id: <20220624134109.881989-32-mark.cave-ayland@ilande.co.uk> --- hw/input/ps2.c | 2 +- include/hw/input/ps2.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/hw/input/ps2.c b/hw/input/ps2.c index 9c046ac500..24c9853d37 100644 --- a/hw/input/ps2.c +++ b/hw/input/ps2.c @@ -172,7 +172,7 @@ void ps2_queue_noirq(PS2State *s, int b) q->count++; } -void ps2_raise_irq(PS2State *s) +static void ps2_raise_irq(PS2State *s) { s->update_irq(s->update_arg, 1); } diff --git a/include/hw/input/ps2.h b/include/hw/input/ps2.h index 4be27de316..410ec66baf 100644 --- a/include/hw/input/ps2.h +++ b/include/hw/input/ps2.h @@ -102,7 +102,6 @@ void ps2_write_mouse(PS2MouseState *s, int val); void ps2_write_keyboard(PS2KbdState *s, int val); uint32_t ps2_read_data(PS2State *s); void ps2_queue_noirq(PS2State *s, int b); -void ps2_raise_irq(PS2State *s); void ps2_queue(PS2State *s, int b); void ps2_queue_2(PS2State *s, int b1, int b2); void ps2_queue_3(PS2State *s, int b1, int b2, int b3); From 892e9bbe595e31e7e0a3734d25091c75f56fc9a9 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:47 +0100 Subject: [PATCH 32/55] ps2: use ps2_raise_irq() instead of calling update_irq() directly This consolidates the logic of raising the PS2 IRQ into one single function. Signed-off-by: Mark Cave-Ayland Acked-by: Helge Deller Reviewed-by: Peter Maydell Message-Id: <20220624134109.881989-33-mark.cave-ayland@ilande.co.uk> --- hw/input/ps2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/input/ps2.c b/hw/input/ps2.c index 24c9853d37..a14281bc54 100644 --- a/hw/input/ps2.c +++ b/hw/input/ps2.c @@ -557,7 +557,7 @@ uint32_t ps2_read_data(PS2State *s) s->update_irq(s->update_arg, 0); /* reassert IRQs if data left */ if (q->count) { - s->update_irq(s->update_arg, 1); + ps2_raise_irq(s); } } return val; From 5cb6e55622570cfc2284dfe4c95f64aee428e63c Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:48 +0100 Subject: [PATCH 33/55] ps2: introduce ps2_lower_irq() instead of calling update_irq() directly This consolidates the logic of lowering the PS2 IRQ into one single function. Signed-off-by: Mark Cave-Ayland Acked-by: Helge Deller Reviewed-by: Peter Maydell Message-Id: <20220624134109.881989-34-mark.cave-ayland@ilande.co.uk> --- hw/input/ps2.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/hw/input/ps2.c b/hw/input/ps2.c index a14281bc54..bc0bcf1789 100644 --- a/hw/input/ps2.c +++ b/hw/input/ps2.c @@ -177,6 +177,11 @@ static void ps2_raise_irq(PS2State *s) s->update_irq(s->update_arg, 1); } +static void ps2_lower_irq(PS2State *s) +{ + s->update_irq(s->update_arg, 0); +} + void ps2_queue(PS2State *s, int b) { if (PS2_QUEUE_SIZE - s->queue.count < 1) { @@ -554,7 +559,7 @@ uint32_t ps2_read_data(PS2State *s) q->cwptr = -1; } /* reading deasserts IRQ */ - s->update_irq(s->update_arg, 0); + ps2_lower_irq(s); /* reassert IRQs if data left */ if (q->count) { ps2_raise_irq(s); @@ -1001,7 +1006,7 @@ static void ps2_reset(DeviceState *dev) s->write_cmd = -1; ps2_reset_queue(s); - s->update_irq(s->update_arg, 0); + ps2_lower_irq(s); } static void ps2_common_post_load(PS2State *s) From 6beb79e11a48b7876dfd63fcfb51d1a603936928 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:49 +0100 Subject: [PATCH 34/55] ps2: add gpio for output IRQ and optionally use it in ps2_raise_irq() and ps2_lower_irq() Define the gpio for the PS2 output IRQ in ps2_init() and add logic to optionally use it in ps2_raise_irq() and ps2_lower_irq() if the gpio is connected. If the gpio is not connected then call the legacy update_irq() function as before. This allows the incremental conversion of devices from the legacy update_irq() function to use gpios instead. Signed-off-by: Mark Cave-Ayland Acked-by: Helge Deller Reviewed-by: Peter Maydell Message-Id: <20220624134109.881989-35-mark.cave-ayland@ilande.co.uk> --- hw/input/ps2.c | 21 +++++++++++++++++++-- include/hw/input/ps2.h | 4 ++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/hw/input/ps2.c b/hw/input/ps2.c index bc0bcf1789..98c6206fb8 100644 --- a/hw/input/ps2.c +++ b/hw/input/ps2.c @@ -24,6 +24,7 @@ #include "qemu/osdep.h" #include "qemu/log.h" +#include "hw/irq.h" #include "hw/sysbus.h" #include "hw/input/ps2.h" #include "migration/vmstate.h" @@ -174,12 +175,20 @@ void ps2_queue_noirq(PS2State *s, int b) static void ps2_raise_irq(PS2State *s) { - s->update_irq(s->update_arg, 1); + if (qemu_irq_is_connected(s->irq)) { + qemu_set_irq(s->irq, 1); + } else { + s->update_irq(s->update_arg, 1); + } } static void ps2_lower_irq(PS2State *s) { - s->update_irq(s->update_arg, 0); + if (qemu_irq_is_connected(s->irq)) { + qemu_set_irq(s->irq, 0); + } else { + s->update_irq(s->update_arg, 0); + } } void ps2_queue(PS2State *s, int b) @@ -1305,6 +1314,13 @@ static const TypeInfo ps2_mouse_info = { .class_init = ps2_mouse_class_init }; +static void ps2_init(Object *obj) +{ + PS2State *s = PS2_DEVICE(obj); + + qdev_init_gpio_out(DEVICE(obj), &s->irq, 1); +} + static void ps2_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -1316,6 +1332,7 @@ static void ps2_class_init(ObjectClass *klass, void *data) static const TypeInfo ps2_info = { .name = TYPE_PS2_DEVICE, .parent = TYPE_SYS_BUS_DEVICE, + .instance_init = ps2_init, .instance_size = sizeof(PS2State), .class_init = ps2_class_init, .class_size = sizeof(PS2DeviceClass), diff --git a/include/hw/input/ps2.h b/include/hw/input/ps2.h index 410ec66baf..5422aee9aa 100644 --- a/include/hw/input/ps2.h +++ b/include/hw/input/ps2.h @@ -50,11 +50,15 @@ typedef struct { int rptr, wptr, cwptr, count; } PS2Queue; +/* Output IRQ */ +#define PS2_DEVICE_IRQ 0 + struct PS2State { SysBusDevice parent_obj; PS2Queue queue; int32_t write_cmd; + qemu_irq irq; void (*update_irq)(void *, int); void *update_arg; }; From c2b1747973d1ff334787d9701cf8214e24fe0798 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:50 +0100 Subject: [PATCH 35/55] pckbd: replace irq_kbd and irq_mouse with qemu_irq array in KBDState This allows both IRQs to be declared as a single qdev gpio array. Signed-off-by: Mark Cave-Ayland Acked-by: Helge Deller Reviewed-by: Peter Maydell Message-Id: <20220624134109.881989-36-mark.cave-ayland@ilande.co.uk> --- hw/input/pckbd.c | 12 ++++++------ include/hw/input/i8042.h | 6 ++++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c index 72843f770e..5d7c969fc6 100644 --- a/hw/input/pckbd.c +++ b/hw/input/pckbd.c @@ -170,8 +170,8 @@ static void kbd_update_irq_lines(KBDState *s) } } } - qemu_set_irq(s->irq_kbd, irq_kbd_level); - qemu_set_irq(s->irq_mouse, irq_mouse_level); + qemu_set_irq(s->irqs[I8042_KBD_IRQ], irq_kbd_level); + qemu_set_irq(s->irqs[I8042_MOUSE_IRQ], irq_mouse_level); } static void kbd_deassert_irq(KBDState *s) @@ -726,8 +726,8 @@ MMIOKBDState *i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq, sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); s = &I8042_MMIO(dev)->kbd; - s->irq_kbd = kbd_irq; - s->irq_mouse = mouse_irq; + s->irqs[I8042_KBD_IRQ] = kbd_irq; + s->irqs[I8042_MOUSE_IRQ] = mouse_irq; return I8042_MMIO(dev); } @@ -813,8 +813,8 @@ static void i8042_realizefn(DeviceState *dev, Error **errp) return; } - s->irq_kbd = isa_get_irq(isadev, isa_s->kbd_irq); - s->irq_mouse = isa_get_irq(isadev, isa_s->mouse_irq); + s->irqs[I8042_KBD_IRQ] = isa_get_irq(isadev, isa_s->kbd_irq); + s->irqs[I8042_MOUSE_IRQ] = isa_get_irq(isadev, isa_s->mouse_irq); isa_register_ioport(isadev, isa_s->io + 0, 0x60); isa_register_ioport(isadev, isa_s->io + 1, 0x64); diff --git a/include/hw/input/i8042.h b/include/hw/input/i8042.h index 9d1f8af964..4ba2664377 100644 --- a/include/hw/input/i8042.h +++ b/include/hw/input/i8042.h @@ -12,6 +12,9 @@ #include "hw/sysbus.h" #include "qom/object.h" +#define I8042_KBD_IRQ 0 +#define I8042_MOUSE_IRQ 1 + typedef struct KBDState { uint8_t write_cmd; /* if non zero, write data to port 60 is expected */ uint8_t status; @@ -31,8 +34,7 @@ typedef struct KBDState { void *mouse; QEMUTimer *throttle_timer; - qemu_irq irq_kbd; - qemu_irq irq_mouse; + qemu_irq irqs[2]; qemu_irq a20_out; hwaddr mask; } KBDState; From 423bcb234b358a46c868f6baa0483c84870825c5 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:51 +0100 Subject: [PATCH 36/55] pl050: switch over from update_irq() function to PS2 device gpio Add a new pl050_init() function which initialises a qdev input gpio for handling incoming PS2 IRQs, and then wire up the PS2 device to use it. At the same time set update_irq() and update_arg to NULL in ps2_kbd_init() and ps2_mouse_init() to ensure that any accidental attempt to use the legacy update_irq() function will cause a NULL pointer dereference. Signed-off-by: Mark Cave-Ayland Acked-by: Helge Deller Message-Id: <20220624134109.881989-37-mark.cave-ayland@ilande.co.uk> Reviewed-by: Peter Maydell --- hw/input/pl050.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/hw/input/pl050.c b/hw/input/pl050.c index 66f8c20d9f..c665a4fc99 100644 --- a/hw/input/pl050.c +++ b/hw/input/pl050.c @@ -65,7 +65,7 @@ static void pl050_update_irq(PL050State *s) qemu_set_irq(s->irq, level); } -static void pl050_set_irq(void *opaque, int level) +static void pl050_set_irq(void *opaque, int n, int level) { PL050State *s = (PL050State *)opaque; @@ -164,10 +164,12 @@ static void pl050_realize(DeviceState *dev, Error **errp) sysbus_init_mmio(sbd, &s->iomem); sysbus_init_irq(sbd, &s->irq); if (s->is_mouse) { - s->dev = ps2_mouse_init(pl050_set_irq, s); + s->dev = ps2_mouse_init(NULL, NULL); } else { - s->dev = ps2_kbd_init(pl050_set_irq, s); + s->dev = ps2_kbd_init(NULL, NULL); } + qdev_connect_gpio_out(DEVICE(s->dev), PS2_DEVICE_IRQ, + qdev_get_gpio_in_named(dev, "ps2-input-irq", 0)); } static void pl050_keyboard_init(Object *obj) @@ -196,6 +198,11 @@ static const TypeInfo pl050_mouse_info = { .instance_init = pl050_mouse_init, }; +static void pl050_init(Object *obj) +{ + qdev_init_gpio_in_named(DEVICE(obj), pl050_set_irq, "ps2-input-irq", 1); +} + static void pl050_class_init(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); @@ -207,6 +214,7 @@ static void pl050_class_init(ObjectClass *oc, void *data) static const TypeInfo pl050_type_info = { .name = TYPE_PL050, .parent = TYPE_SYS_BUS_DEVICE, + .instance_init = pl050_init, .instance_size = sizeof(PL050State), .abstract = true, .class_init = pl050_class_init, From 1d9d4b072db7e1de406122a3012eced157939299 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:52 +0100 Subject: [PATCH 37/55] pl050: add QEMU interface comment This describes the PL050 device interface implemented within QEMU. Signed-off-by: Mark Cave-Ayland Message-Id: <20220624134109.881989-38-mark.cave-ayland@ilande.co.uk> Reviewed-by: Peter Maydell --- hw/input/pl050.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/hw/input/pl050.c b/hw/input/pl050.c index c665a4fc99..ffaa72dea4 100644 --- a/hw/input/pl050.c +++ b/hw/input/pl050.c @@ -7,6 +7,14 @@ * This code is licensed under the GPL. */ +/* + * QEMU interface: + * + sysbus MMIO region 0: MemoryRegion defining the PL050 registers + * + Named GPIO input "ps2-input-irq": set to 1 if the downstream PS2 device + * has asserted its irq + * + sysbus IRQ 0: PL050 output irq + */ + #include "qemu/osdep.h" #include "hw/sysbus.h" #include "migration/vmstate.h" From 653b388c39ffa75c2935e30d49d24cbf4a5c12e4 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:53 +0100 Subject: [PATCH 38/55] lasips2: QOMify LASIPS2State Currently lasip2_init() creates a new LASIPS2State directly which is used by the HPPA machine. Introduce a new LASIPS2 QOM type that will soon be used to allow the HPPA machine to be wired up using standard qdev GPIOs. Signed-off-by: Mark Cave-Ayland Acked-by: Helge Deller Reviewed-by: Peter Maydell Message-Id: <20220624134109.881989-39-mark.cave-ayland@ilande.co.uk> --- hw/input/lasips2.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c index adfde1684f..db0a791e6c 100644 --- a/hw/input/lasips2.c +++ b/hw/input/lasips2.c @@ -24,6 +24,7 @@ #include "qemu/osdep.h" #include "qemu/log.h" #include "hw/qdev-properties.h" +#include "hw/sysbus.h" #include "hw/input/ps2.h" #include "hw/input/lasips2.h" #include "exec/hwaddr.h" @@ -31,6 +32,7 @@ #include "exec/address-spaces.h" #include "migration/vmstate.h" #include "hw/irq.h" +#include "qapi/error.h" struct LASIPS2State; @@ -45,11 +47,16 @@ typedef struct LASIPS2Port { bool irq; } LASIPS2Port; -typedef struct LASIPS2State { +struct LASIPS2State { + SysBusDevice parent_obj; + LASIPS2Port kbd; LASIPS2Port mouse; qemu_irq irq; -} LASIPS2State; +}; + +#define TYPE_LASIPS2 "lasips2" +OBJECT_DECLARE_SIMPLE_TYPE(LASIPS2State, LASIPS2) static const VMStateDescription vmstate_lasips2 = { .name = "lasips2", @@ -265,8 +272,11 @@ void lasips2_init(MemoryRegion *address_space, hwaddr base, qemu_irq irq) { LASIPS2State *s; + DeviceState *dev; - s = g_new0(LASIPS2State, 1); + dev = qdev_new(TYPE_LASIPS2); + sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); + s = LASIPS2(dev); s->irq = irq; s->mouse.id = 1; @@ -286,3 +296,16 @@ void lasips2_init(MemoryRegion *address_space, "lasips2-mouse", 0x100); memory_region_add_subregion(address_space, base + 0x100, &s->mouse.reg); } + +static const TypeInfo lasips2_info = { + .name = TYPE_LASIPS2, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(LASIPS2State) +}; + +static void lasips2_register_types(void) +{ + type_register_static(&lasips2_info); +} + +type_init(lasips2_register_types) From 07c68b501056fd45e52db0067fdb3ea0ea571961 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:54 +0100 Subject: [PATCH 39/55] lasips2: move lasips2 QOM types from lasips2.c to lasips2.h This allows the QOM types in lasips2.c to be used elsewhere by simply including lasips2.h. Signed-off-by: Mark Cave-Ayland Acked-by: Helge Deller Reviewed-by: Peter Maydell Message-Id: <20220624134109.881989-40-mark.cave-ayland@ilande.co.uk> --- hw/input/lasips2.c | 23 ----------------------- include/hw/input/lasips2.h | 22 ++++++++++++++++++++++ 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c index db0a791e6c..2caa80bd3c 100644 --- a/hw/input/lasips2.c +++ b/hw/input/lasips2.c @@ -35,29 +35,6 @@ #include "qapi/error.h" -struct LASIPS2State; -typedef struct LASIPS2Port { - struct LASIPS2State *parent; - MemoryRegion reg; - void *dev; - uint8_t id; - uint8_t control; - uint8_t buf; - bool loopback_rbne; - bool irq; -} LASIPS2Port; - -struct LASIPS2State { - SysBusDevice parent_obj; - - LASIPS2Port kbd; - LASIPS2Port mouse; - qemu_irq irq; -}; - -#define TYPE_LASIPS2 "lasips2" -OBJECT_DECLARE_SIMPLE_TYPE(LASIPS2State, LASIPS2) - static const VMStateDescription vmstate_lasips2 = { .name = "lasips2", .version_id = 0, diff --git a/include/hw/input/lasips2.h b/include/hw/input/lasips2.h index 0cd7b59064..ddcea74c14 100644 --- a/include/hw/input/lasips2.h +++ b/include/hw/input/lasips2.h @@ -8,8 +8,30 @@ #define HW_INPUT_LASIPS2_H #include "exec/hwaddr.h" +#include "hw/sysbus.h" + +struct LASIPS2State; +typedef struct LASIPS2Port { + struct LASIPS2State *parent; + MemoryRegion reg; + void *dev; + uint8_t id; + uint8_t control; + uint8_t buf; + bool loopback_rbne; + bool irq; +} LASIPS2Port; + +struct LASIPS2State { + SysBusDevice parent_obj; + + LASIPS2Port kbd; + LASIPS2Port mouse; + qemu_irq irq; +}; #define TYPE_LASIPS2 "lasips2" +OBJECT_DECLARE_SIMPLE_TYPE(LASIPS2State, LASIPS2) void lasips2_init(MemoryRegion *address_space, hwaddr base, qemu_irq irq); From 5cbf35d20f71f87ade944b3835db389c260f2c59 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:55 +0100 Subject: [PATCH 40/55] lasips2: rename lasips2_init() to lasips2_initfn() and update it to return the LASIPS2 device When QOMifying a device it is typical to use _init() as the suffix for an instance_init function, however this name is already in use by the legacy LASIPS2 wrapper function. Eventually the wrapper function will be removed, but for now rename it to lasips2_initfn() to avoid a naming collision. At the same time update lasips2_initfn() return the LASIPS2 device so that it can later be accessed using qdev APIs by the HPPA machine. Signed-off-by: Mark Cave-Ayland Acked-by: Helge Deller Reviewed-by: Peter Maydell Message-Id: <20220624134109.881989-41-mark.cave-ayland@ilande.co.uk> --- hw/hppa/machine.c | 4 ++-- hw/input/lasips2.c | 6 ++++-- include/hw/input/lasips2.h | 3 ++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c index 63b9dd2396..72677aeb2a 100644 --- a/hw/hppa/machine.c +++ b/hw/hppa/machine.c @@ -280,8 +280,8 @@ static void machine_hppa_init(MachineState *machine) } /* PS/2 Keyboard/Mouse */ - lasips2_init(addr_space, LASI_PS2KBD_HPA, - qdev_get_gpio_in(lasi_dev, LASI_IRQ_PS2KBD_HPA)); + lasips2_initfn(addr_space, LASI_PS2KBD_HPA, + qdev_get_gpio_in(lasi_dev, LASI_IRQ_PS2KBD_HPA)); /* register power switch emulation */ qemu_register_powerdown_notifier(&hppa_system_powerdown_notifier); diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c index 2caa80bd3c..85da4081e3 100644 --- a/hw/input/lasips2.c +++ b/hw/input/lasips2.c @@ -245,8 +245,8 @@ static void lasips2_port_set_irq(void *opaque, int level) lasips2_update_irq(port->parent); } -void lasips2_init(MemoryRegion *address_space, - hwaddr base, qemu_irq irq) +LASIPS2State *lasips2_initfn(MemoryRegion *address_space, + hwaddr base, qemu_irq irq) { LASIPS2State *s; DeviceState *dev; @@ -272,6 +272,8 @@ void lasips2_init(MemoryRegion *address_space, memory_region_init_io(&s->mouse.reg, NULL, &lasips2_reg_ops, &s->mouse, "lasips2-mouse", 0x100); memory_region_add_subregion(address_space, base + 0x100, &s->mouse.reg); + + return s; } static const TypeInfo lasips2_info = { diff --git a/include/hw/input/lasips2.h b/include/hw/input/lasips2.h index ddcea74c14..5a35c22f73 100644 --- a/include/hw/input/lasips2.h +++ b/include/hw/input/lasips2.h @@ -33,6 +33,7 @@ struct LASIPS2State { #define TYPE_LASIPS2 "lasips2" OBJECT_DECLARE_SIMPLE_TYPE(LASIPS2State, LASIPS2) -void lasips2_init(MemoryRegion *address_space, hwaddr base, qemu_irq irq); +LASIPS2State *lasips2_initfn(MemoryRegion *address_space, hwaddr base, + qemu_irq irq); #endif /* HW_INPUT_LASIPS2_H */ From 63195aa5a55a885a5c56b7103eb6e698abf2b95a Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:56 +0100 Subject: [PATCH 41/55] lasips2: implement lasips2_init() function Move the initialisation of the keyboard and mouse memory regions to lasips2_init() and expose them as SysBus memory regions. Signed-off-by: Mark Cave-Ayland Acked-by: Helge Deller Reviewed-by: Peter Maydell Message-Id: <20220624134109.881989-42-mark.cave-ayland@ilande.co.uk> --- hw/input/lasips2.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c index 85da4081e3..8d3a2d88e8 100644 --- a/hw/input/lasips2.c +++ b/hw/input/lasips2.c @@ -265,20 +265,30 @@ LASIPS2State *lasips2_initfn(MemoryRegion *address_space, s->kbd.dev = ps2_kbd_init(lasips2_port_set_irq, &s->kbd); s->mouse.dev = ps2_mouse_init(lasips2_port_set_irq, &s->mouse); - memory_region_init_io(&s->kbd.reg, NULL, &lasips2_reg_ops, &s->kbd, - "lasips2-kbd", 0x100); memory_region_add_subregion(address_space, base, &s->kbd.reg); - memory_region_init_io(&s->mouse.reg, NULL, &lasips2_reg_ops, &s->mouse, - "lasips2-mouse", 0x100); memory_region_add_subregion(address_space, base + 0x100, &s->mouse.reg); return s; } +static void lasips2_init(Object *obj) +{ + LASIPS2State *s = LASIPS2(obj); + + 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); + + sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->kbd.reg); + sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mouse.reg); +} + static const TypeInfo lasips2_info = { .name = TYPE_LASIPS2, .parent = TYPE_SYS_BUS_DEVICE, + .instance_init = lasips2_init, .instance_size = sizeof(LASIPS2State) }; From 6479296fe561cc3aacc3ee99adf02ca7d2120713 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:57 +0100 Subject: [PATCH 42/55] lasips2: move mapping of LASIPS2 registers to HPPA machine Now that the register memory regions are exposed as SysBus memory regions, move the mapping of the LASIPS2 registers from lasips2_initfn() to the HPPA machine (which is its only user). Signed-off-by: Mark Cave-Ayland Acked-by: Helge Deller Reviewed-by: Peter Maydell Message-Id: <20220624134109.881989-43-mark.cave-ayland@ilande.co.uk> --- hw/hppa/machine.c | 11 +++++++++-- hw/input/lasips2.c | 7 +------ include/hw/input/lasips2.h | 3 +-- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c index 72677aeb2a..44ecd446c3 100644 --- a/hw/hppa/machine.c +++ b/hw/hppa/machine.c @@ -280,8 +280,15 @@ static void machine_hppa_init(MachineState *machine) } /* PS/2 Keyboard/Mouse */ - lasips2_initfn(addr_space, LASI_PS2KBD_HPA, - qdev_get_gpio_in(lasi_dev, LASI_IRQ_PS2KBD_HPA)); + dev = DEVICE(lasips2_initfn(LASI_PS2KBD_HPA, + 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)); + memory_region_add_subregion(addr_space, LASI_PS2KBD_HPA + 0x100, + sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), + 1)); /* register power switch emulation */ qemu_register_powerdown_notifier(&hppa_system_powerdown_notifier); diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c index 8d3a2d88e8..84e7a1feee 100644 --- a/hw/input/lasips2.c +++ b/hw/input/lasips2.c @@ -245,8 +245,7 @@ static void lasips2_port_set_irq(void *opaque, int level) lasips2_update_irq(port->parent); } -LASIPS2State *lasips2_initfn(MemoryRegion *address_space, - hwaddr base, qemu_irq irq) +LASIPS2State *lasips2_initfn(hwaddr base, qemu_irq irq) { LASIPS2State *s; DeviceState *dev; @@ -265,10 +264,6 @@ LASIPS2State *lasips2_initfn(MemoryRegion *address_space, s->kbd.dev = ps2_kbd_init(lasips2_port_set_irq, &s->kbd); s->mouse.dev = ps2_mouse_init(lasips2_port_set_irq, &s->mouse); - memory_region_add_subregion(address_space, base, &s->kbd.reg); - - memory_region_add_subregion(address_space, base + 0x100, &s->mouse.reg); - return s; } diff --git a/include/hw/input/lasips2.h b/include/hw/input/lasips2.h index 5a35c22f73..b9723073e1 100644 --- a/include/hw/input/lasips2.h +++ b/include/hw/input/lasips2.h @@ -33,7 +33,6 @@ struct LASIPS2State { #define TYPE_LASIPS2 "lasips2" OBJECT_DECLARE_SIMPLE_TYPE(LASIPS2State, LASIPS2) -LASIPS2State *lasips2_initfn(MemoryRegion *address_space, hwaddr base, - qemu_irq irq); +LASIPS2State *lasips2_initfn(hwaddr base, qemu_irq irq); #endif /* HW_INPUT_LASIPS2_H */ From 02bb59a0e082a4eb88b797c715ab722bebb95ad4 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:58 +0100 Subject: [PATCH 43/55] lasips2: move initialisation of PS2 ports from lasi_initfn() to lasi_init() This can be improved once the ps2_kbd_init() and ps2_mouse_init() functions have been removed, but for now move the existing logic from lasi_initfn() to lasi_init(). At the same time explicitly set keyboard port id to 0, even if it isn't technically required. Signed-off-by: Mark Cave-Ayland Acked-by: Helge Deller Reviewed-by: Peter Maydell Message-Id: <20220624134109.881989-44-mark.cave-ayland@ilande.co.uk> --- hw/input/lasips2.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c index 84e7a1feee..bd89c03996 100644 --- a/hw/input/lasips2.c +++ b/hw/input/lasips2.c @@ -255,9 +255,6 @@ LASIPS2State *lasips2_initfn(hwaddr base, qemu_irq irq) s = LASIPS2(dev); s->irq = irq; - s->mouse.id = 1; - s->kbd.parent = s; - s->mouse.parent = s; vmstate_register(NULL, base, &vmstate_lasips2, s); @@ -271,6 +268,11 @@ static void lasips2_init(Object *obj) { LASIPS2State *s = LASIPS2(obj); + s->kbd.id = 0; + s->mouse.id = 1; + s->kbd.parent = s; + s->mouse.parent = s; + 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, From 42119fdb2e851b2a0a6cc09197c33ad943dcb6e9 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:40:59 +0100 Subject: [PATCH 44/55] lasips2: add base property This is in preparation for handling vmstate_register() within the device. Signed-off-by: Mark Cave-Ayland Acked-by: Helge Deller Message-Id: <20220624134109.881989-45-mark.cave-ayland@ilande.co.uk> Reviewed-by: Peter Maydell --- hw/input/lasips2.c | 17 ++++++++++++++++- include/hw/input/lasips2.h | 1 + 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c index bd89c03996..81beb5b614 100644 --- a/hw/input/lasips2.c +++ b/hw/input/lasips2.c @@ -251,6 +251,7 @@ LASIPS2State *lasips2_initfn(hwaddr base, qemu_irq irq) DeviceState *dev; dev = qdev_new(TYPE_LASIPS2); + qdev_prop_set_uint64(dev, "base", base); sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); s = LASIPS2(dev); @@ -282,11 +283,25 @@ static void lasips2_init(Object *obj) sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mouse.reg); } +static Property lasips2_properties[] = { + DEFINE_PROP_UINT64("base", LASIPS2State, base, UINT64_MAX), + DEFINE_PROP_END_OF_LIST(), +}; + +static void lasips2_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + device_class_set_props(dc, lasips2_properties); + set_bit(DEVICE_CATEGORY_INPUT, dc->categories); +} + static const TypeInfo lasips2_info = { .name = TYPE_LASIPS2, .parent = TYPE_SYS_BUS_DEVICE, .instance_init = lasips2_init, - .instance_size = sizeof(LASIPS2State) + .instance_size = sizeof(LASIPS2State), + .class_init = lasips2_class_init, }; static void lasips2_register_types(void) diff --git a/include/hw/input/lasips2.h b/include/hw/input/lasips2.h index b9723073e1..7e4437b925 100644 --- a/include/hw/input/lasips2.h +++ b/include/hw/input/lasips2.h @@ -25,6 +25,7 @@ typedef struct LASIPS2Port { struct LASIPS2State { SysBusDevice parent_obj; + hwaddr base; LASIPS2Port kbd; LASIPS2Port mouse; qemu_irq irq; From 1702627c3329e6f43b92addc6eb16fc420a4cf18 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:41:00 +0100 Subject: [PATCH 45/55] lasips2: implement lasips2_realize() Move ps2_kbd_init() and ps2_mouse_init() from lasips2_initfn() to lasips2_realize. Signed-off-by: Mark Cave-Ayland Acked-by: Helge Deller Reviewed-by: Peter Maydell Message-Id: <20220624134109.881989-46-mark.cave-ayland@ilande.co.uk> --- hw/input/lasips2.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c index 81beb5b614..49405191cb 100644 --- a/hw/input/lasips2.c +++ b/hw/input/lasips2.c @@ -256,13 +256,17 @@ LASIPS2State *lasips2_initfn(hwaddr base, qemu_irq irq) s = LASIPS2(dev); s->irq = irq; + return s; +} - vmstate_register(NULL, base, &vmstate_lasips2, s); +static void lasips2_realize(DeviceState *dev, Error **errp) +{ + LASIPS2State *s = LASIPS2(dev); + + vmstate_register(NULL, s->base, &vmstate_lasips2, s); s->kbd.dev = ps2_kbd_init(lasips2_port_set_irq, &s->kbd); s->mouse.dev = ps2_mouse_init(lasips2_port_set_irq, &s->mouse); - - return s; } static void lasips2_init(Object *obj) @@ -292,6 +296,7 @@ static void lasips2_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + dc->realize = lasips2_realize; device_class_set_props(dc, lasips2_properties); set_bit(DEVICE_CATEGORY_INPUT, dc->categories); } From 97bc05971bb26588e114dcb8a8e96c14a8a8a202 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:41:01 +0100 Subject: [PATCH 46/55] lasips2: use sysbus IRQ for output IRQ This enables the IRQ to be wired up using sysbus_connect_irq() in lasips2_initfn(). Signed-off-by: Mark Cave-Ayland Acked-by: Helge Deller Message-Id: <20220624134109.881989-47-mark.cave-ayland@ilande.co.uk> Reviewed-by: Peter Maydell --- hw/input/lasips2.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c index 49405191cb..bd72505411 100644 --- a/hw/input/lasips2.c +++ b/hw/input/lasips2.c @@ -247,16 +247,15 @@ static void lasips2_port_set_irq(void *opaque, int level) LASIPS2State *lasips2_initfn(hwaddr base, qemu_irq irq) { - LASIPS2State *s; DeviceState *dev; dev = qdev_new(TYPE_LASIPS2); qdev_prop_set_uint64(dev, "base", base); sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); - s = LASIPS2(dev); - s->irq = irq; - return s; + sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq); + + return LASIPS2(dev); } static void lasips2_realize(DeviceState *dev, Error **errp) @@ -285,6 +284,8 @@ static void lasips2_init(Object *obj) sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->kbd.reg); sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mouse.reg); + + sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq); } static Property lasips2_properties[] = { From 0d1ac496a2587b59568bea16d88e4dadbf6dbe2c Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:41:02 +0100 Subject: [PATCH 47/55] lasips2: switch over from update_irq() function to PS2 device gpio Add a qdev gpio input in lasips2_init() by taking the existing lasips2_port_set_irq() function, updating it accordingly and then renaming to lasips2_set_irq(). Use these new qdev gpio inputs to wire up the PS2 keyboard and mouse devices. At the same time set update_irq() and update_arg to NULL in ps2_kbd_init() and ps2_mouse_init() to ensure that any accidental attempt to use the legacy update_irq() function will cause a NULL pointer dereference. Signed-off-by: Mark Cave-Ayland Acked-by: Helge Deller Message-Id: <20220624134109.881989-48-mark.cave-ayland@ilande.co.uk> Reviewed-by: Peter Maydell --- hw/input/lasips2.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c index bd72505411..a6e14e0e6b 100644 --- a/hw/input/lasips2.c +++ b/hw/input/lasips2.c @@ -237,9 +237,19 @@ static const MemoryRegionOps lasips2_reg_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; -static void lasips2_port_set_irq(void *opaque, int level) +static void lasips2_set_kbd_irq(void *opaque, int n, int level) { - LASIPS2Port *port = opaque; + LASIPS2State *s = LASIPS2(opaque); + LASIPS2Port *port = &s->kbd; + + port->irq = level; + lasips2_update_irq(port->parent); +} + +static void lasips2_set_mouse_irq(void *opaque, int n, int level) +{ + LASIPS2State *s = LASIPS2(opaque); + LASIPS2Port *port = &s->mouse; port->irq = level; lasips2_update_irq(port->parent); @@ -264,8 +274,14 @@ static void lasips2_realize(DeviceState *dev, Error **errp) vmstate_register(NULL, s->base, &vmstate_lasips2, s); - s->kbd.dev = ps2_kbd_init(lasips2_port_set_irq, &s->kbd); - s->mouse.dev = ps2_mouse_init(lasips2_port_set_irq, &s->mouse); + s->kbd.dev = ps2_kbd_init(NULL, NULL); + 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(NULL, NULL); + qdev_connect_gpio_out(DEVICE(s->mouse.dev), PS2_DEVICE_IRQ, + qdev_get_gpio_in_named(dev, "ps2-mouse-input-irq", + 0)); } static void lasips2_init(Object *obj) @@ -286,6 +302,11 @@ static void lasips2_init(Object *obj) sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mouse.reg); sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq); + + 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); } static Property lasips2_properties[] = { From 501f062e91ca97dfbeaa5148be59d6a27448c9d8 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:41:03 +0100 Subject: [PATCH 48/55] lasips2: add QEMU interface comment This describes the LASI PS2 device interface implemented within QEMU. Signed-off-by: Mark Cave-Ayland Message-Id: <20220624134109.881989-49-mark.cave-ayland@ilande.co.uk> Reviewed-by: Peter Maydell --- include/hw/input/lasips2.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/include/hw/input/lasips2.h b/include/hw/input/lasips2.h index 7e4437b925..03f0c9e9f9 100644 --- a/include/hw/input/lasips2.h +++ b/include/hw/input/lasips2.h @@ -4,6 +4,20 @@ * Copyright (c) 2019 Sven Schnelle * */ + +/* + * QEMU interface: + * + sysbus MMIO region 0: MemoryRegion defining the LASI PS2 keyboard + * registers + * + sysbus MMIO region 1: MemoryRegion defining the LASI PS2 mouse + * registers + * + sysbus IRQ 0: LASI PS2 output irq + * + Named GPIO input "ps2-kbd-input-irq": set to 1 if the downstream PS2 + * keyboard device has asserted its irq + * + Named GPIO input "ps2-mouse-input-irq": set to 1 if the downstream PS2 + * mouse device has asserted its irq + */ + #ifndef HW_INPUT_LASIPS2_H #define HW_INPUT_LASIPS2_H From cb663a81c1a81adacd3c6201d6b236346c7ea911 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:41:04 +0100 Subject: [PATCH 49/55] pckbd: switch I8042_MMIO device from update_irq() function to PS2 device gpio Define a new qdev input gpio for handling incoming PS2 IRQs, and then wire up the PS2 keyboard and mouse devices to use it. At the same time set update_irq() and update_arg to NULL in ps2_kbd_init() and ps2_mouse_init() to ensure that any accidental attempt to use the legacy update_irq() function will cause a NULL pointer dereference. Signed-off-by: Mark Cave-Ayland Acked-by: Helge Deller Reviewed-by: Peter Maydell Message-Id: <20220624134109.881989-50-mark.cave-ayland@ilande.co.uk> --- hw/input/pckbd.c | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c index 5d7c969fc6..ee306428a3 100644 --- a/hw/input/pckbd.c +++ b/hw/input/pckbd.c @@ -665,6 +665,22 @@ static const MemoryRegionOps i8042_mmio_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; +static void i8042_mmio_set_kbd_irq(void *opaque, int n, int level) +{ + MMIOKBDState *s = I8042_MMIO(opaque); + KBDState *ks = &s->kbd; + + kbd_update_kbd_irq(ks, level); +} + +static void i8042_mmio_set_mouse_irq(void *opaque, int n, int level) +{ + MMIOKBDState *s = I8042_MMIO(opaque); + KBDState *ks = &s->kbd; + + kbd_update_aux_irq(ks, level); +} + static void i8042_mmio_reset(DeviceState *dev) { MMIOKBDState *s = I8042_MMIO(dev); @@ -686,8 +702,14 @@ static void i8042_mmio_realize(DeviceState *dev, Error **errp) /* Note we can't use dc->vmsd without breaking migration compatibility */ vmstate_register(NULL, 0, &vmstate_kbd, ks); - ks->kbd = ps2_kbd_init(kbd_update_kbd_irq, ks); - ks->mouse = ps2_mouse_init(kbd_update_aux_irq, ks); + ks->kbd = ps2_kbd_init(NULL, NULL); + qdev_connect_gpio_out(DEVICE(ks->kbd), PS2_DEVICE_IRQ, + qdev_get_gpio_in_named(dev, "ps2-kbd-input-irq", + 0)); + ks->mouse = ps2_mouse_init(NULL, NULL); + qdev_connect_gpio_out(DEVICE(ks->mouse), PS2_DEVICE_IRQ, + qdev_get_gpio_in_named(dev, "ps2-mouse-input-irq", + 0)); } static void i8042_mmio_init(Object *obj) @@ -696,6 +718,12 @@ static void i8042_mmio_init(Object *obj) KBDState *ks = &s->kbd; ks->extended_state = true; + + 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); + qdev_init_gpio_in_named(DEVICE(obj), i8042_mmio_set_mouse_irq, + "ps2-mouse-input-irq", 1); } static Property i8042_mmio_properties[] = { @@ -718,16 +746,14 @@ MMIOKBDState *i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq, ram_addr_t size, hwaddr mask) { DeviceState *dev; - KBDState *s; 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); - s = &I8042_MMIO(dev)->kbd; - s->irqs[I8042_KBD_IRQ] = kbd_irq; - s->irqs[I8042_MOUSE_IRQ] = mouse_irq; + qdev_connect_gpio_out(dev, I8042_KBD_IRQ, kbd_irq); + qdev_connect_gpio_out(dev, I8042_MOUSE_IRQ, mouse_irq); return I8042_MMIO(dev); } From 57de3c1d35605f3f29c332585d9c4b49503d6639 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:41:05 +0100 Subject: [PATCH 50/55] pckbd: add QEMU interface comment for I8042_MMIO device This describes the I8042_MMIO device interface implemented within QEMU. Signed-off-by: Mark Cave-Ayland Message-Id: <20220624134109.881989-51-mark.cave-ayland@ilande.co.uk> Reviewed-by: Peter Maydell --- include/hw/input/i8042.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/hw/input/i8042.h b/include/hw/input/i8042.h index 4ba2664377..d4747b62b8 100644 --- a/include/hw/input/i8042.h +++ b/include/hw/input/i8042.h @@ -52,6 +52,17 @@ struct ISAKBDState { uint8_t mouse_irq; }; +/* + * QEMU interface: + * + sysbus MMIO region 0: MemoryRegion defining the command/status/data + * registers (access determined by mask property and access type) + * + Named GPIO input "ps2-kbd-input-irq": set to 1 if the downstream PS2 + * keyboard device has asserted its irq + * + Named GPIO input "ps2-mouse-input-irq": set to 1 if the downstream PS2 + * mouse device has asserted its irq + * + Unnamed GPIO output 0-1: i8042 output irqs for keyboard (0) or mouse (1) + */ + #define TYPE_I8042_MMIO "i8042-mmio" OBJECT_DECLARE_SIMPLE_TYPE(MMIOKBDState, I8042_MMIO) From 55870d6f27b2ae181d6f08a8e2c0e718178c72d8 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:41:06 +0100 Subject: [PATCH 51/55] pckbd: add i8042_reset() function to I8042 device This means that it is no longer necessary to call qemu_register_reset() manually within i8042_realizefn(). Signed-off-by: Mark Cave-Ayland Acked-by: Helge Deller Reviewed-by: Peter Maydell Message-Id: <20220624134109.881989-52-mark.cave-ayland@ilande.co.uk> --- hw/input/pckbd.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c index ee306428a3..ff76c0636d 100644 --- a/hw/input/pckbd.c +++ b/hw/input/pckbd.c @@ -808,6 +808,14 @@ static const MemoryRegionOps i8042_cmd_ops = { .endianness = DEVICE_LITTLE_ENDIAN, }; +static void i8042_reset(DeviceState *dev) +{ + ISAKBDState *s = I8042(dev); + KBDState *ks = &s->kbd; + + kbd_reset(ks); +} + static void i8042_initfn(Object *obj) { ISAKBDState *isa_s = I8042(obj); @@ -854,7 +862,6 @@ static void i8042_realizefn(DeviceState *dev, Error **errp) s->throttle_timer = timer_new_us(QEMU_CLOCK_VIRTUAL, kbd_throttle_timeout, s); } - qemu_register_reset(kbd_reset, s); } static void i8042_build_aml(AcpiDevAmlIf *adev, Aml *scope) @@ -900,6 +907,7 @@ static void i8042_class_initfn(ObjectClass *klass, void *data) AcpiDevAmlIfClass *adevc = ACPI_DEV_AML_IF_CLASS(klass); device_class_set_props(dc, i8042_properties); + dc->reset = i8042_reset; dc->realize = i8042_realizefn; dc->vmsd = &vmstate_kbd_isa; adevc->build_dev_aml = i8042_build_aml; From 6eb252d50cf08704adffed7c758a5b95b15c27e9 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:41:07 +0100 Subject: [PATCH 52/55] pckbd: switch I8042 device from update_irq() function to PS2 device gpio Define a new qdev input gpio for handling incoming PS2 IRQs, and then wire up the PS2 keyboard and mouse devices to use it. At the same time set update_irq() and update_arg to NULL in ps2_kbd_init() and ps2_mouse_init() to ensure that any accidental attempt to use the legacy update_irq() function will cause a NULL pointer dereference. Signed-off-by: Mark Cave-Ayland Acked-by: Helge Deller Reviewed-by: Peter Maydell Message-Id: <20220624134109.881989-53-mark.cave-ayland@ilande.co.uk> --- hw/input/pckbd.c | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c index ff76c0636d..18f27abc58 100644 --- a/hw/input/pckbd.c +++ b/hw/input/pckbd.c @@ -808,6 +808,23 @@ static const MemoryRegionOps i8042_cmd_ops = { .endianness = DEVICE_LITTLE_ENDIAN, }; +static void i8042_set_kbd_irq(void *opaque, int n, int level) +{ + ISAKBDState *s = I8042(opaque); + KBDState *ks = &s->kbd; + + kbd_update_kbd_irq(ks, level); +} + +static void i8042_set_mouse_irq(void *opaque, int n, int level) +{ + ISAKBDState *s = I8042(opaque); + KBDState *ks = &s->kbd; + + kbd_update_aux_irq(ks, level); +} + + static void i8042_reset(DeviceState *dev) { ISAKBDState *s = I8042(dev); @@ -827,6 +844,12 @@ static void i8042_initfn(Object *obj) "i8042-cmd", 1); qdev_init_gpio_out_named(DEVICE(obj), &s->a20_out, I8042_A20_LINE, 1); + + qdev_init_gpio_out(DEVICE(obj), s->irqs, 2); + qdev_init_gpio_in_named(DEVICE(obj), i8042_set_kbd_irq, + "ps2-kbd-input-irq", 1); + qdev_init_gpio_in_named(DEVICE(obj), i8042_set_mouse_irq, + "ps2-mouse-input-irq", 1); } static void i8042_realizefn(DeviceState *dev, Error **errp) @@ -847,14 +870,20 @@ static void i8042_realizefn(DeviceState *dev, Error **errp) return; } - s->irqs[I8042_KBD_IRQ] = isa_get_irq(isadev, isa_s->kbd_irq); - s->irqs[I8042_MOUSE_IRQ] = isa_get_irq(isadev, isa_s->mouse_irq); + isa_connect_gpio_out(isadev, I8042_KBD_IRQ, isa_s->kbd_irq); + isa_connect_gpio_out(isadev, I8042_MOUSE_IRQ, isa_s->mouse_irq); isa_register_ioport(isadev, isa_s->io + 0, 0x60); isa_register_ioport(isadev, isa_s->io + 1, 0x64); - s->kbd = ps2_kbd_init(kbd_update_kbd_irq, s); - s->mouse = ps2_mouse_init(kbd_update_aux_irq, s); + s->kbd = ps2_kbd_init(NULL, NULL); + qdev_connect_gpio_out(DEVICE(s->kbd), PS2_DEVICE_IRQ, + qdev_get_gpio_in_named(dev, "ps2-kbd-input-irq", + 0)); + s->mouse = ps2_mouse_init(NULL, NULL); + qdev_connect_gpio_out(DEVICE(s->mouse), 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"); From 38f426b8af844c8243b1cd5e6d883c176c527c3b Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:41:08 +0100 Subject: [PATCH 53/55] pckbd: add QEMU interface comment for I8042 device This describes the I8042 device interface implemented within QEMU. Signed-off-by: Mark Cave-Ayland Message-Id: <20220624134109.881989-54-mark.cave-ayland@ilande.co.uk> Reviewed-by: Peter Maydell --- include/hw/input/i8042.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/include/hw/input/i8042.h b/include/hw/input/i8042.h index d4747b62b8..ca933d8e1b 100644 --- a/include/hw/input/i8042.h +++ b/include/hw/input/i8042.h @@ -39,6 +39,16 @@ typedef struct KBDState { hwaddr mask; } KBDState; +/* + * QEMU interface: + * + Named GPIO input "ps2-kbd-input-irq": set to 1 if the downstream PS2 + * keyboard device has asserted its irq + * + Named GPIO input "ps2-mouse-input-irq": set to 1 if the downstream PS2 + * mouse device has asserted its irq + * + Named GPIO output "a20": A20 line for x86 PCs + * + Unnamed GPIO output 0-1: i8042 output irqs for keyboard (0) or mouse (1) + */ + #define TYPE_I8042 "i8042" OBJECT_DECLARE_SIMPLE_TYPE(ISAKBDState, I8042) From 7227de94adce761d9add78ad087a98697b2d82e9 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 14:41:09 +0100 Subject: [PATCH 54/55] ps2: remove update_irq() function and update_arg parameter Now that all the PS2 devices have been converted to use GPIOs the update_irq() callback function and the update_arg parameter can be removed. This allows these arguments to be completely removed from ps2_kbd_init() and ps2_mouse_init(), along with the transitional logic that was added to ps2_raise_irq() and ps2_lower_irq(). Signed-off-by: Mark Cave-Ayland Acked-by: Helge Deller Reviewed-by: Peter Maydell Message-Id: <20220624134109.881989-55-mark.cave-ayland@ilande.co.uk> --- hw/input/lasips2.c | 4 ++-- hw/input/pckbd.c | 8 ++++---- hw/input/pl050.c | 4 ++-- hw/input/ps2.c | 25 ++++--------------------- include/hw/input/ps2.h | 6 ++---- 5 files changed, 14 insertions(+), 33 deletions(-) diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c index a6e14e0e6b..9223cb0af4 100644 --- a/hw/input/lasips2.c +++ b/hw/input/lasips2.c @@ -274,11 +274,11 @@ static void lasips2_realize(DeviceState *dev, Error **errp) vmstate_register(NULL, s->base, &vmstate_lasips2, s); - s->kbd.dev = ps2_kbd_init(NULL, NULL); + 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(NULL, NULL); + 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)); diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c index 18f27abc58..9184411c3e 100644 --- a/hw/input/pckbd.c +++ b/hw/input/pckbd.c @@ -702,11 +702,11 @@ static void i8042_mmio_realize(DeviceState *dev, Error **errp) /* Note we can't use dc->vmsd without breaking migration compatibility */ vmstate_register(NULL, 0, &vmstate_kbd, ks); - ks->kbd = ps2_kbd_init(NULL, NULL); + ks->kbd = ps2_kbd_init(); qdev_connect_gpio_out(DEVICE(ks->kbd), PS2_DEVICE_IRQ, qdev_get_gpio_in_named(dev, "ps2-kbd-input-irq", 0)); - ks->mouse = ps2_mouse_init(NULL, NULL); + ks->mouse = ps2_mouse_init(); qdev_connect_gpio_out(DEVICE(ks->mouse), PS2_DEVICE_IRQ, qdev_get_gpio_in_named(dev, "ps2-mouse-input-irq", 0)); @@ -876,11 +876,11 @@ 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(NULL, NULL); + s->kbd = ps2_kbd_init(); qdev_connect_gpio_out(DEVICE(s->kbd), PS2_DEVICE_IRQ, qdev_get_gpio_in_named(dev, "ps2-kbd-input-irq", 0)); - s->mouse = ps2_mouse_init(NULL, NULL); + s->mouse = ps2_mouse_init(); qdev_connect_gpio_out(DEVICE(s->mouse), PS2_DEVICE_IRQ, qdev_get_gpio_in_named(dev, "ps2-mouse-input-irq", 0)); diff --git a/hw/input/pl050.c b/hw/input/pl050.c index ffaa72dea4..209cc001cf 100644 --- a/hw/input/pl050.c +++ b/hw/input/pl050.c @@ -172,9 +172,9 @@ static void pl050_realize(DeviceState *dev, Error **errp) sysbus_init_mmio(sbd, &s->iomem); sysbus_init_irq(sbd, &s->irq); if (s->is_mouse) { - s->dev = ps2_mouse_init(NULL, NULL); + s->dev = ps2_mouse_init(); } else { - s->dev = ps2_kbd_init(NULL, NULL); + s->dev = ps2_kbd_init(); } qdev_connect_gpio_out(DEVICE(s->dev), PS2_DEVICE_IRQ, qdev_get_gpio_in_named(dev, "ps2-input-irq", 0)); diff --git a/hw/input/ps2.c b/hw/input/ps2.c index 98c6206fb8..59bac28ac8 100644 --- a/hw/input/ps2.c +++ b/hw/input/ps2.c @@ -175,20 +175,12 @@ void ps2_queue_noirq(PS2State *s, int b) static void ps2_raise_irq(PS2State *s) { - if (qemu_irq_is_connected(s->irq)) { - qemu_set_irq(s->irq, 1); - } else { - s->update_irq(s->update_arg, 1); - } + qemu_set_irq(s->irq, 1); } static void ps2_lower_irq(PS2State *s) { - if (qemu_irq_is_connected(s->irq)) { - qemu_set_irq(s->irq, 0); - } else { - s->update_irq(s->update_arg, 0); - } + qemu_set_irq(s->irq, 0); } void ps2_queue(PS2State *s, int b) @@ -1232,21 +1224,16 @@ static void ps2_kbd_realize(DeviceState *dev, Error **errp) qemu_input_handler_register(dev, &ps2_keyboard_handler); } -void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg) +void *ps2_kbd_init(void) { DeviceState *dev; PS2KbdState *s; - PS2State *ps2; dev = qdev_new(TYPE_PS2_KBD_DEVICE); sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); s = PS2_KBD_DEVICE(dev); - ps2 = PS2_DEVICE(s); trace_ps2_kbd_init(s); - ps2->update_irq = update_irq; - ps2->update_arg = update_arg; - return s; } @@ -1262,20 +1249,16 @@ static void ps2_mouse_realize(DeviceState *dev, Error **errp) qemu_input_handler_register(dev, &ps2_mouse_handler); } -void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg) +void *ps2_mouse_init(void) { DeviceState *dev; PS2MouseState *s; - PS2State *ps2; dev = qdev_new(TYPE_PS2_MOUSE_DEVICE); sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); s = PS2_MOUSE_DEVICE(dev); - ps2 = PS2_DEVICE(s); trace_ps2_mouse_init(s); - ps2->update_irq = update_irq; - ps2->update_arg = update_arg; return s; } diff --git a/include/hw/input/ps2.h b/include/hw/input/ps2.h index 5422aee9aa..a78619d8cb 100644 --- a/include/hw/input/ps2.h +++ b/include/hw/input/ps2.h @@ -59,8 +59,6 @@ struct PS2State { PS2Queue queue; int32_t write_cmd; qemu_irq irq; - void (*update_irq)(void *, int); - void *update_arg; }; #define TYPE_PS2_DEVICE "ps2-device" @@ -100,8 +98,8 @@ struct PS2MouseState { OBJECT_DECLARE_SIMPLE_TYPE(PS2MouseState, PS2_MOUSE_DEVICE) /* ps2.c */ -void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg); -void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg); +void *ps2_kbd_init(void); +void *ps2_mouse_init(void); void ps2_write_mouse(PS2MouseState *s, int val); void ps2_write_keyboard(PS2KbdState *s, int val); uint32_t ps2_read_data(PS2State *s); From 39fbaeca096a9bf6cbe2af88572c1cb2aa62aa8c Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Jun 2022 17:08:39 +0100 Subject: [PATCH 55/55] artist: set memory region owners for buffers to the artist device This fixes the output of "info qom-tree" so that the buffers appear as children of the artist device, rather than underneath the "unattached" container. Signed-off-by: Mark Cave-Ayland Message-Id: <20220624160839.886649-1-mark.cave-ayland@ilande.co.uk> Reviewed-by: Helge Deller --- hw/display/artist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/display/artist.c b/hw/display/artist.c index eadaef0d46..fde050c882 100644 --- a/hw/display/artist.c +++ b/hw/display/artist.c @@ -1358,7 +1358,7 @@ static void artist_create_buffer(ARTISTState *s, const char *name, { struct vram_buffer *buf = s->vram_buffer + idx; - memory_region_init_ram(&buf->mr, NULL, name, width * height, + memory_region_init_ram(&buf->mr, OBJECT(s), name, width * height, &error_fatal); memory_region_add_subregion_overlap(&s->mem_as_root, *offset, &buf->mr, 0);