1 /* 2 * QEMU HP Lasi PS/2 interface emulation 3 * 4 * Copyright (c) 2019 Sven Schnelle 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 * THE SOFTWARE. 23 */ 24 #include "qemu/osdep.h" 25 #include "qemu/log.h" 26 #include "hw/qdev-properties.h" 27 #include "hw/sysbus.h" 28 #include "hw/input/ps2.h" 29 #include "hw/input/lasips2.h" 30 #include "exec/hwaddr.h" 31 #include "trace.h" 32 #include "exec/address-spaces.h" 33 #include "migration/vmstate.h" 34 #include "hw/irq.h" 35 #include "qapi/error.h" 36 37 38 static const VMStateDescription vmstate_lasips2 = { 39 .name = "lasips2", 40 .version_id = 0, 41 .minimum_version_id = 0, 42 .fields = (VMStateField[]) { 43 VMSTATE_UINT8(kbd_port.parent_obj.control, LASIPS2State), 44 VMSTATE_UINT8(kbd_port.parent_obj.id, LASIPS2State), 45 VMSTATE_UINT8(mouse_port.parent_obj.control, LASIPS2State), 46 VMSTATE_UINT8(mouse_port.parent_obj.id, LASIPS2State), 47 VMSTATE_END_OF_LIST() 48 } 49 }; 50 51 typedef enum { 52 REG_PS2_ID = 0, 53 REG_PS2_RCVDATA = 4, 54 REG_PS2_CONTROL = 8, 55 REG_PS2_STATUS = 12, 56 } lasips2_read_reg_t; 57 58 typedef enum { 59 REG_PS2_RESET = 0, 60 REG_PS2_XMTDATA = 4, 61 } lasips2_write_reg_t; 62 63 typedef enum { 64 LASIPS2_CONTROL_ENABLE = 0x01, 65 LASIPS2_CONTROL_LOOPBACK = 0x02, 66 LASIPS2_CONTROL_DIAG = 0x20, 67 LASIPS2_CONTROL_DATDIR = 0x40, 68 LASIPS2_CONTROL_CLKDIR = 0x80, 69 } lasips2_control_reg_t; 70 71 typedef enum { 72 LASIPS2_STATUS_RBNE = 0x01, 73 LASIPS2_STATUS_TBNE = 0x02, 74 LASIPS2_STATUS_TERR = 0x04, 75 LASIPS2_STATUS_PERR = 0x08, 76 LASIPS2_STATUS_CMPINTR = 0x10, 77 LASIPS2_STATUS_DATSHD = 0x40, 78 LASIPS2_STATUS_CLKSHD = 0x80, 79 } lasips2_status_reg_t; 80 81 static const char *lasips2_read_reg_name(uint64_t addr) 82 { 83 switch (addr & 0xc) { 84 case REG_PS2_ID: 85 return " PS2_ID"; 86 87 case REG_PS2_RCVDATA: 88 return " PS2_RCVDATA"; 89 90 case REG_PS2_CONTROL: 91 return " PS2_CONTROL"; 92 93 case REG_PS2_STATUS: 94 return " PS2_STATUS"; 95 96 default: 97 return ""; 98 } 99 } 100 101 static const char *lasips2_write_reg_name(uint64_t addr) 102 { 103 switch (addr & 0x0c) { 104 case REG_PS2_RESET: 105 return " PS2_RESET"; 106 107 case REG_PS2_XMTDATA: 108 return " PS2_XMTDATA"; 109 110 case REG_PS2_CONTROL: 111 return " PS2_CONTROL"; 112 113 default: 114 return ""; 115 } 116 } 117 118 static void lasips2_update_irq(LASIPS2State *s) 119 { 120 int level = s->int_status ? 1 : 0; 121 122 trace_lasips2_intr(level); 123 qemu_set_irq(s->irq, level); 124 } 125 126 static void lasips2_set_irq(void *opaque, int n, int level) 127 { 128 LASIPS2State *s = LASIPS2(opaque); 129 130 if (level) { 131 s->int_status |= BIT(n); 132 } else { 133 s->int_status &= ~BIT(n); 134 } 135 136 lasips2_update_irq(s); 137 } 138 139 static void lasips2_reg_write(void *opaque, hwaddr addr, uint64_t val, 140 unsigned size) 141 { 142 LASIPS2Port *lp = LASIPS2_PORT(opaque); 143 144 trace_lasips2_reg_write(size, lp->id, addr, 145 lasips2_write_reg_name(addr), val); 146 147 switch (addr & 0xc) { 148 case REG_PS2_CONTROL: 149 lp->control = val; 150 break; 151 152 case REG_PS2_XMTDATA: 153 if (lp->control & LASIPS2_CONTROL_LOOPBACK) { 154 lp->buf = val; 155 lp->loopback_rbne = true; 156 qemu_set_irq(lp->irq, 1); 157 break; 158 } 159 160 if (lp->id) { 161 ps2_write_mouse(PS2_MOUSE_DEVICE(lp->ps2dev), val); 162 } else { 163 ps2_write_keyboard(PS2_KBD_DEVICE(lp->ps2dev), val); 164 } 165 break; 166 167 case REG_PS2_RESET: 168 break; 169 170 default: 171 qemu_log_mask(LOG_UNIMP, "%s: unknown register 0x%02" HWADDR_PRIx "\n", 172 __func__, addr); 173 break; 174 } 175 } 176 177 static uint64_t lasips2_reg_read(void *opaque, hwaddr addr, unsigned size) 178 { 179 LASIPS2Port *lp = LASIPS2_PORT(opaque); 180 uint64_t ret = 0; 181 182 switch (addr & 0xc) { 183 case REG_PS2_ID: 184 ret = lp->id; 185 break; 186 187 case REG_PS2_RCVDATA: 188 if (lp->control & LASIPS2_CONTROL_LOOPBACK) { 189 lp->loopback_rbne = false; 190 qemu_set_irq(lp->irq, 0); 191 ret = lp->buf; 192 break; 193 } 194 195 ret = ps2_read_data(lp->ps2dev); 196 break; 197 198 case REG_PS2_CONTROL: 199 ret = lp->control; 200 break; 201 202 case REG_PS2_STATUS: 203 ret = LASIPS2_STATUS_DATSHD | LASIPS2_STATUS_CLKSHD; 204 205 if (lp->control & LASIPS2_CONTROL_DIAG) { 206 if (!(lp->control & LASIPS2_CONTROL_DATDIR)) { 207 ret &= ~LASIPS2_STATUS_DATSHD; 208 } 209 210 if (!(lp->control & LASIPS2_CONTROL_CLKDIR)) { 211 ret &= ~LASIPS2_STATUS_CLKSHD; 212 } 213 } 214 215 if (lp->control & LASIPS2_CONTROL_LOOPBACK) { 216 if (lp->loopback_rbne) { 217 ret |= LASIPS2_STATUS_RBNE; 218 } 219 } else { 220 if (!ps2_queue_empty(lp->ps2dev)) { 221 ret |= LASIPS2_STATUS_RBNE; 222 } 223 } 224 225 if (lp->lasips2->int_status) { 226 ret |= LASIPS2_STATUS_CMPINTR; 227 } 228 break; 229 230 default: 231 qemu_log_mask(LOG_UNIMP, "%s: unknown register 0x%02" HWADDR_PRIx "\n", 232 __func__, addr); 233 break; 234 } 235 236 trace_lasips2_reg_read(size, lp->id, addr, 237 lasips2_read_reg_name(addr), ret); 238 return ret; 239 } 240 241 static const MemoryRegionOps lasips2_reg_ops = { 242 .read = lasips2_reg_read, 243 .write = lasips2_reg_write, 244 .impl = { 245 .min_access_size = 1, 246 .max_access_size = 4, 247 }, 248 .endianness = DEVICE_BIG_ENDIAN, 249 }; 250 251 static void lasips2_realize(DeviceState *dev, Error **errp) 252 { 253 LASIPS2State *s = LASIPS2(dev); 254 LASIPS2Port *lp; 255 256 lp = LASIPS2_PORT(&s->kbd_port); 257 if (!(qdev_realize(DEVICE(lp), NULL, errp))) { 258 return; 259 } 260 261 qdev_connect_gpio_out(DEVICE(lp), 0, 262 qdev_get_gpio_in_named(dev, "lasips2-port-input-irq", 263 lp->id)); 264 265 lp = LASIPS2_PORT(&s->mouse_port); 266 if (!(qdev_realize(DEVICE(lp), NULL, errp))) { 267 return; 268 } 269 270 qdev_connect_gpio_out(DEVICE(lp), 0, 271 qdev_get_gpio_in_named(dev, "lasips2-port-input-irq", 272 lp->id)); 273 } 274 275 static void lasips2_init(Object *obj) 276 { 277 LASIPS2State *s = LASIPS2(obj); 278 LASIPS2Port *lp; 279 280 object_initialize_child(obj, "lasips2-kbd-port", &s->kbd_port, 281 TYPE_LASIPS2_KBD_PORT); 282 object_initialize_child(obj, "lasips2-mouse-port", &s->mouse_port, 283 TYPE_LASIPS2_MOUSE_PORT); 284 285 lp = LASIPS2_PORT(&s->kbd_port); 286 sysbus_init_mmio(SYS_BUS_DEVICE(obj), &lp->reg); 287 lp = LASIPS2_PORT(&s->mouse_port); 288 sysbus_init_mmio(SYS_BUS_DEVICE(obj), &lp->reg); 289 290 sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq); 291 292 qdev_init_gpio_in_named(DEVICE(obj), lasips2_set_irq, 293 "lasips2-port-input-irq", 2); 294 } 295 296 static void lasips2_class_init(ObjectClass *klass, void *data) 297 { 298 DeviceClass *dc = DEVICE_CLASS(klass); 299 300 dc->realize = lasips2_realize; 301 dc->vmsd = &vmstate_lasips2; 302 set_bit(DEVICE_CATEGORY_INPUT, dc->categories); 303 } 304 305 static const TypeInfo lasips2_info = { 306 .name = TYPE_LASIPS2, 307 .parent = TYPE_SYS_BUS_DEVICE, 308 .instance_init = lasips2_init, 309 .instance_size = sizeof(LASIPS2State), 310 .class_init = lasips2_class_init, 311 }; 312 313 static void lasips2_port_set_irq(void *opaque, int n, int level) 314 { 315 LASIPS2Port *s = LASIPS2_PORT(opaque); 316 317 qemu_set_irq(s->irq, level); 318 } 319 320 static void lasips2_port_realize(DeviceState *dev, Error **errp) 321 { 322 LASIPS2Port *s = LASIPS2_PORT(dev); 323 324 qdev_connect_gpio_out(DEVICE(s->ps2dev), PS2_DEVICE_IRQ, 325 qdev_get_gpio_in_named(dev, "ps2-input-irq", 0)); 326 } 327 328 static void lasips2_port_init(Object *obj) 329 { 330 LASIPS2Port *s = LASIPS2_PORT(obj); 331 332 qdev_init_gpio_out(DEVICE(obj), &s->irq, 1); 333 qdev_init_gpio_in_named(DEVICE(obj), lasips2_port_set_irq, 334 "ps2-input-irq", 1); 335 } 336 337 static void lasips2_port_class_init(ObjectClass *klass, void *data) 338 { 339 DeviceClass *dc = DEVICE_CLASS(klass); 340 341 dc->realize = lasips2_port_realize; 342 } 343 344 static const TypeInfo lasips2_port_info = { 345 .name = TYPE_LASIPS2_PORT, 346 .parent = TYPE_DEVICE, 347 .instance_init = lasips2_port_init, 348 .instance_size = sizeof(LASIPS2Port), 349 .class_init = lasips2_port_class_init, 350 .class_size = sizeof(LASIPS2PortDeviceClass), 351 .abstract = true, 352 }; 353 354 static void lasips2_kbd_port_realize(DeviceState *dev, Error **errp) 355 { 356 LASIPS2Port *lp = LASIPS2_PORT(dev); 357 LASIPS2PortDeviceClass *lpdc = LASIPS2_PORT_GET_CLASS(lp); 358 359 lp->ps2dev = ps2_kbd_init(); 360 lpdc->parent_realize(dev, errp); 361 } 362 363 static void lasips2_kbd_port_init(Object *obj) 364 { 365 LASIPS2KbdPort *s = LASIPS2_KBD_PORT(obj); 366 LASIPS2Port *lp = LASIPS2_PORT(obj); 367 368 memory_region_init_io(&lp->reg, obj, &lasips2_reg_ops, lp, "lasips2-kbd", 369 0x100); 370 lp->id = 0; 371 lp->lasips2 = container_of(s, LASIPS2State, kbd_port); 372 } 373 374 static void lasips2_kbd_port_class_init(ObjectClass *klass, void *data) 375 { 376 DeviceClass *dc = DEVICE_CLASS(klass); 377 LASIPS2PortDeviceClass *lpdc = LASIPS2_PORT_CLASS(klass); 378 379 device_class_set_parent_realize(dc, lasips2_kbd_port_realize, 380 &lpdc->parent_realize); 381 } 382 383 static const TypeInfo lasips2_kbd_port_info = { 384 .name = TYPE_LASIPS2_KBD_PORT, 385 .parent = TYPE_LASIPS2_PORT, 386 .instance_size = sizeof(LASIPS2KbdPort), 387 .instance_init = lasips2_kbd_port_init, 388 .class_init = lasips2_kbd_port_class_init, 389 }; 390 391 static void lasips2_mouse_port_realize(DeviceState *dev, Error **errp) 392 { 393 LASIPS2Port *lp = LASIPS2_PORT(dev); 394 LASIPS2PortDeviceClass *lpdc = LASIPS2_PORT_GET_CLASS(lp); 395 396 lp->ps2dev = ps2_mouse_init(); 397 lpdc->parent_realize(dev, errp); 398 } 399 400 static void lasips2_mouse_port_init(Object *obj) 401 { 402 LASIPS2MousePort *s = LASIPS2_MOUSE_PORT(obj); 403 LASIPS2Port *lp = LASIPS2_PORT(obj); 404 405 memory_region_init_io(&lp->reg, obj, &lasips2_reg_ops, lp, "lasips2-mouse", 406 0x100); 407 lp->id = 1; 408 lp->lasips2 = container_of(s, LASIPS2State, mouse_port); 409 } 410 411 static void lasips2_mouse_port_class_init(ObjectClass *klass, void *data) 412 { 413 DeviceClass *dc = DEVICE_CLASS(klass); 414 LASIPS2PortDeviceClass *lpdc = LASIPS2_PORT_CLASS(klass); 415 416 device_class_set_parent_realize(dc, lasips2_mouse_port_realize, 417 &lpdc->parent_realize); 418 } 419 420 static const TypeInfo lasips2_mouse_port_info = { 421 .name = TYPE_LASIPS2_MOUSE_PORT, 422 .parent = TYPE_LASIPS2_PORT, 423 .instance_size = sizeof(LASIPS2MousePort), 424 .instance_init = lasips2_mouse_port_init, 425 .class_init = lasips2_mouse_port_class_init, 426 }; 427 428 static void lasips2_register_types(void) 429 { 430 type_register_static(&lasips2_info); 431 type_register_static(&lasips2_port_info); 432 type_register_static(&lasips2_kbd_port_info); 433 type_register_static(&lasips2_mouse_port_info); 434 } 435 436 type_init(lasips2_register_types) 437