147973a2dSPhilippe Mathieu-Daudé /* 247973a2dSPhilippe Mathieu-Daudé * QEMU PS/2 Controller 347973a2dSPhilippe Mathieu-Daudé * 447973a2dSPhilippe Mathieu-Daudé * Copyright (c) 2003 Fabrice Bellard 547973a2dSPhilippe Mathieu-Daudé * 647973a2dSPhilippe Mathieu-Daudé * SPDX-License-Identifier: MIT 747973a2dSPhilippe Mathieu-Daudé */ 847973a2dSPhilippe Mathieu-Daudé #ifndef HW_INPUT_I8042_H 947973a2dSPhilippe Mathieu-Daudé #define HW_INPUT_I8042_H 1047973a2dSPhilippe Mathieu-Daudé 1147973a2dSPhilippe Mathieu-Daudé #include "hw/isa/isa.h" 12150ee013SMark Cave-Ayland #include "hw/sysbus.h" 13652fbff4SMark Cave-Ayland #include "hw/input/ps2.h" 14db1015e9SEduardo Habkost #include "qom/object.h" 1547973a2dSPhilippe Mathieu-Daudé 16c2b17479SMark Cave-Ayland #define I8042_KBD_IRQ 0 17c2b17479SMark Cave-Ayland #define I8042_MOUSE_IRQ 1 18c2b17479SMark Cave-Ayland 1977adda52SMark Cave-Ayland typedef struct KBDState { 2077adda52SMark Cave-Ayland uint8_t write_cmd; /* if non zero, write data to port 60 is expected */ 2177adda52SMark Cave-Ayland uint8_t status; 2277adda52SMark Cave-Ayland uint8_t mode; 2377adda52SMark Cave-Ayland uint8_t outport; 2477adda52SMark Cave-Ayland uint32_t migration_flags; 2577adda52SMark Cave-Ayland uint32_t obsrc; 2677adda52SMark Cave-Ayland bool outport_present; 2777adda52SMark Cave-Ayland bool extended_state; 2877adda52SMark Cave-Ayland bool extended_state_loaded; 2977adda52SMark Cave-Ayland /* Bitmask of devices with data available. */ 3077adda52SMark Cave-Ayland uint8_t pending; 3177adda52SMark Cave-Ayland uint8_t obdata; 3277adda52SMark Cave-Ayland uint8_t cbdata; 3377adda52SMark Cave-Ayland uint8_t pending_tmp; 34652fbff4SMark Cave-Ayland PS2KbdState ps2kbd; 35*9d1a4250SMark Cave-Ayland PS2MouseState ps2mouse; 3677adda52SMark Cave-Ayland QEMUTimer *throttle_timer; 3777adda52SMark Cave-Ayland 38c2b17479SMark Cave-Ayland qemu_irq irqs[2]; 3977adda52SMark Cave-Ayland qemu_irq a20_out; 4077adda52SMark Cave-Ayland hwaddr mask; 4177adda52SMark Cave-Ayland } KBDState; 4277adda52SMark Cave-Ayland 4338f426b8SMark Cave-Ayland /* 4438f426b8SMark Cave-Ayland * QEMU interface: 4538f426b8SMark Cave-Ayland * + Named GPIO input "ps2-kbd-input-irq": set to 1 if the downstream PS2 4638f426b8SMark Cave-Ayland * keyboard device has asserted its irq 4738f426b8SMark Cave-Ayland * + Named GPIO input "ps2-mouse-input-irq": set to 1 if the downstream PS2 4838f426b8SMark Cave-Ayland * mouse device has asserted its irq 4938f426b8SMark Cave-Ayland * + Named GPIO output "a20": A20 line for x86 PCs 5038f426b8SMark Cave-Ayland * + Unnamed GPIO output 0-1: i8042 output irqs for keyboard (0) or mouse (1) 5138f426b8SMark Cave-Ayland */ 5238f426b8SMark Cave-Ayland 5347973a2dSPhilippe Mathieu-Daudé #define TYPE_I8042 "i8042" 548063396bSEduardo Habkost OBJECT_DECLARE_SIMPLE_TYPE(ISAKBDState, I8042) 5547973a2dSPhilippe Mathieu-Daudé 56c9849a71SMark Cave-Ayland struct ISAKBDState { 57c9849a71SMark Cave-Ayland ISADevice parent_obj; 58c9849a71SMark Cave-Ayland 59c9849a71SMark Cave-Ayland KBDState kbd; 60c9849a71SMark Cave-Ayland bool kbd_throttle; 61c9849a71SMark Cave-Ayland MemoryRegion io[2]; 62c9849a71SMark Cave-Ayland uint8_t kbd_irq; 63c9849a71SMark Cave-Ayland uint8_t mouse_irq; 64c9849a71SMark Cave-Ayland }; 65c9849a71SMark Cave-Ayland 6657de3c1dSMark Cave-Ayland /* 6757de3c1dSMark Cave-Ayland * QEMU interface: 6857de3c1dSMark Cave-Ayland * + sysbus MMIO region 0: MemoryRegion defining the command/status/data 6957de3c1dSMark Cave-Ayland * registers (access determined by mask property and access type) 7057de3c1dSMark Cave-Ayland * + Named GPIO input "ps2-kbd-input-irq": set to 1 if the downstream PS2 7157de3c1dSMark Cave-Ayland * keyboard device has asserted its irq 7257de3c1dSMark Cave-Ayland * + Named GPIO input "ps2-mouse-input-irq": set to 1 if the downstream PS2 7357de3c1dSMark Cave-Ayland * mouse device has asserted its irq 7457de3c1dSMark Cave-Ayland * + Unnamed GPIO output 0-1: i8042 output irqs for keyboard (0) or mouse (1) 7557de3c1dSMark Cave-Ayland */ 7657de3c1dSMark Cave-Ayland 77150ee013SMark Cave-Ayland #define TYPE_I8042_MMIO "i8042-mmio" 78150ee013SMark Cave-Ayland OBJECT_DECLARE_SIMPLE_TYPE(MMIOKBDState, I8042_MMIO) 79150ee013SMark Cave-Ayland 80150ee013SMark Cave-Ayland struct MMIOKBDState { 81150ee013SMark Cave-Ayland SysBusDevice parent_obj; 82150ee013SMark Cave-Ayland 83150ee013SMark Cave-Ayland KBDState kbd; 847b9fff29SMark Cave-Ayland uint32_t size; 85f4de68d1SMark Cave-Ayland MemoryRegion region; 86150ee013SMark Cave-Ayland }; 87150ee013SMark Cave-Ayland 8847973a2dSPhilippe Mathieu-Daudé #define I8042_A20_LINE "a20" 8947973a2dSPhilippe Mathieu-Daudé 900fe4bb32SMarc-André Lureau 910fe4bb32SMarc-André Lureau void i8042_isa_mouse_fake_event(ISAKBDState *isa); 9247973a2dSPhilippe Mathieu-Daudé i8042_present(void)935334bf57SLiav Albanistatic inline bool i8042_present(void) 945334bf57SLiav Albani { 955334bf57SLiav Albani bool amb = false; 965334bf57SLiav Albani return object_resolve_path_type("", TYPE_I8042, &amb) || amb; 975334bf57SLiav Albani } 985334bf57SLiav Albani 995334bf57SLiav Albani /* 1005334bf57SLiav Albani * ACPI v2, Table 5-10 - Fixed ACPI Description Table Boot Architecture 1015334bf57SLiav Albani * Flags, bit offset 1 - 8042. 1025334bf57SLiav Albani */ iapc_boot_arch_8042(void)1035334bf57SLiav Albanistatic inline uint16_t iapc_boot_arch_8042(void) 1045334bf57SLiav Albani { 1055334bf57SLiav Albani return i8042_present() ? 0x1 << 1 : 0x0 ; 1065334bf57SLiav Albani } 1075334bf57SLiav Albani 10847973a2dSPhilippe Mathieu-Daudé #endif /* HW_INPUT_I8042_H */ 109