Patchwork [1/2] Compile pckbd only once

login
register
mail settings
Submitter Blue Swirl
Date May 17, 2010, 5:45 p.m.
Message ID <AANLkTimekHLD5BhPho75YrcR3CRmqixo1_aCz81lXwCH@mail.gmail.com>
Download mbox | patch
Permalink /patch/52804/
State New
Headers show

Comments

Blue Swirl - May 17, 2010, 5:45 p.m.
Use a qemu_irq to indicate A20 line changes. Move I/O port 92
to pckbd.c.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
---
 Makefile.objs                        |    1 +
 Makefile.target                      |    8 ++--
 default-configs/i386-softmmu.mak     |    1 +
 default-configs/mips-softmmu.mak     |    1 +
 default-configs/mips64-softmmu.mak   |    1 +
 default-configs/mips64el-softmmu.mak |    1 +
 default-configs/mipsel-softmmu.mak   |    1 +
 default-configs/ppc-softmmu.mak      |    1 +
 default-configs/ppc64-softmmu.mak    |    1 +
 default-configs/ppcemb-softmmu.mak   |    1 +
 default-configs/sparc64-softmmu.mak  |    1 +
 default-configs/x86_64-softmmu.mak   |    1 +
 hw/pc.c                              |   33 ++++---------
 hw/pc.h                              |    5 +-
 hw/pckbd.c                           |   86 +++++++++++++++++++++++-----------
 hw/vmmouse.c                         |    2 +-
 16 files changed, 88 insertions(+), 57 deletions(-)

 static void vmmouse_update_handler(VMMouseState *s)
Paolo Bonzini - May 18, 2010, 6:39 a.m.
On 05/17/2010 07:45 PM, Blue Swirl wrote:
> Use a qemu_irq to indicate A20 line changes. Move I/O port 92
> to pckbd.c.

Looks good, hypothetical Mac hardware support (Macs only use USB 
keyboards) would need a new chipset implementation and that can take 
care of implementing port 92.

Thanks.

Paolo

Patch

diff --git a/Makefile.objs b/Makefile.objs
index 110f8fd..814b9e1 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -151,6 +151,7 @@  hw-obj-$(CONFIG_SERIAL) += serial.o
 hw-obj-$(CONFIG_PARALLEL) += parallel.o
 hw-obj-$(CONFIG_I8254) += i8254.o
 hw-obj-$(CONFIG_PCSPK) += pcspk.o
+hw-obj-$(CONFIG_PCKBD) += pckbd.o
 hw-obj-$(CONFIG_USB_UHCI) += usb-uhci.o
 hw-obj-$(CONFIG_FDC) += fdc.o
 hw-obj-$(CONFIG_ACPI) += acpi.o
diff --git a/Makefile.target b/Makefile.target
index f2cd4ff..b1e4289 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -188,7 +188,7 @@  obj-y += rtl8139.o
 obj-y += e1000.o

 # Hardware support
-obj-i386-y = pckbd.o dma.o
+obj-i386-y = dma.o
 obj-i386-y += vga.o
 obj-i386-y += mc146818rtc.o i8259.o pc.o
 obj-i386-y += cirrus_vga.o apic.o ioapic.o piix_pci.o
@@ -201,7 +201,7 @@  obj-i386-y += pm_smbus.o apm.o acpi_piix4.o pc_piix.o
 obj-ppc-y = ppc.o
 obj-ppc-y += vga.o dma.o
 # PREP target
-obj-ppc-y += pckbd.o i8259.o mc146818rtc.o
+obj-ppc-y += i8259.o mc146818rtc.o
 obj-ppc-y += ppc_prep.o
 # OldWorld PowerMac
 obj-ppc-y += ppc_oldworld.o
@@ -219,7 +219,7 @@  obj-mips-y = mips_r4k.o mips_jazz.o mips_malta.o
mips_mipssim.o
 obj-mips-y += mips_addr.o mips_timer.o mips_int.o
 obj-mips-y += dma.o vga.o i8259.o
 obj-mips-y += g364fb.o jazz_led.o
-obj-mips-y += gt64xxx.o pckbd.o mc146818rtc.o
+obj-mips-y += gt64xxx.o mc146818rtc.o
 obj-mips-y += piix4.o cirrus_vga.o
 obj-mips-y += pm_smbus.o apm.o acpi_piix4.o

@@ -244,7 +244,7 @@  obj-cris-y += etraxfs_timer.o
 obj-cris-y += etraxfs_ser.o

 ifeq ($(TARGET_ARCH), sparc64)
-obj-sparc-y = sun4u.o pckbd.o apb_pci.o
+obj-sparc-y = sun4u.o apb_pci.o
 obj-sparc-y += vga.o
 obj-sparc-y += mc146818rtc.o
 obj-sparc-y += cirrus_vga.o
diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak
index 4c1495f..92ef535 100644
--- a/default-configs/i386-softmmu.mak
+++ b/default-configs/i386-softmmu.mak
@@ -8,6 +8,7 @@  CONFIG_SERIAL=y
 CONFIG_PARALLEL=y
 CONFIG_I8254=y
 CONFIG_PCSPK=y
+CONFIG_PCKBD=y
 CONFIG_USB_UHCI=y
 CONFIG_FDC=y
 CONFIG_ACPI=y
diff --git a/default-configs/mips-softmmu.mak b/default-configs/mips-softmmu.mak
index 7793dbc..15015c3 100644
--- a/default-configs/mips-softmmu.mak
+++ b/default-configs/mips-softmmu.mak
@@ -10,6 +10,7 @@  CONFIG_SERIAL=y
 CONFIG_PARALLEL=y
 CONFIG_I8254=y
 CONFIG_PCSPK=y
+CONFIG_PCKBD=y
 CONFIG_USB_UHCI=y
 CONFIG_FDC=y
 CONFIG_ACPI=y
diff --git a/default-configs/mips64-softmmu.mak
b/default-configs/mips64-softmmu.mak
index aa65d92..982462a 100644
--- a/default-configs/mips64-softmmu.mak
+++ b/default-configs/mips64-softmmu.mak
@@ -10,6 +10,7 @@  CONFIG_SERIAL=y
 CONFIG_PARALLEL=y
 CONFIG_I8254=y
 CONFIG_PCSPK=y
+CONFIG_PCKBD=y
 CONFIG_USB_UHCI=y
 CONFIG_FDC=y
 CONFIG_ACPI=y
diff --git a/default-configs/mips64el-softmmu.mak
b/default-configs/mips64el-softmmu.mak
index b9b8c71..c23d186 100644
--- a/default-configs/mips64el-softmmu.mak
+++ b/default-configs/mips64el-softmmu.mak
@@ -10,6 +10,7 @@  CONFIG_SERIAL=y
 CONFIG_PARALLEL=y
 CONFIG_I8254=y
 CONFIG_PCSPK=y
+CONFIG_PCKBD=y
 CONFIG_USB_UHCI=y
 CONFIG_FDC=y
 CONFIG_ACPI=y
diff --git a/default-configs/mipsel-softmmu.mak
b/default-configs/mipsel-softmmu.mak
index e14831e..cd76389 100644
--- a/default-configs/mipsel-softmmu.mak
+++ b/default-configs/mipsel-softmmu.mak
@@ -10,6 +10,7 @@  CONFIG_SERIAL=y
 CONFIG_PARALLEL=y
 CONFIG_I8254=y
 CONFIG_PCSPK=y
+CONFIG_PCKBD=y
 CONFIG_USB_UHCI=y
 CONFIG_FDC=y
 CONFIG_ACPI=y
diff --git a/default-configs/ppc-softmmu.mak b/default-configs/ppc-softmmu.mak
index 958bf75..03cc20f 100644
--- a/default-configs/ppc-softmmu.mak
+++ b/default-configs/ppc-softmmu.mak
@@ -8,6 +8,7 @@  CONFIG_M48T59=y
 CONFIG_VGA_PCI=y
 CONFIG_SERIAL=y
 CONFIG_I8254=y
+CONFIG_PCKBD=y
 CONFIG_FDC=y
 CONFIG_OPENPIC=y
 CONFIG_PREP_PCI=y
diff --git a/default-configs/ppc64-softmmu.mak
b/default-configs/ppc64-softmmu.mak
index 9896662..8c77133 100644
--- a/default-configs/ppc64-softmmu.mak
+++ b/default-configs/ppc64-softmmu.mak
@@ -8,6 +8,7 @@  CONFIG_M48T59=y
 CONFIG_VGA_PCI=y
 CONFIG_SERIAL=y
 CONFIG_I8254=y
+CONFIG_PCKBD=y
 CONFIG_FDC=y
 CONFIG_OPENPIC=y
 CONFIG_PREP_PCI=y
diff --git a/default-configs/ppcemb-softmmu.mak
b/default-configs/ppcemb-softmmu.mak
index 2e41a94..2a0210d 100644
--- a/default-configs/ppcemb-softmmu.mak
+++ b/default-configs/ppcemb-softmmu.mak
@@ -8,6 +8,7 @@  CONFIG_M48T59=y
 CONFIG_VGA_PCI=y
 CONFIG_SERIAL=y
 CONFIG_I8254=y
+CONFIG_PCKBD=y
 CONFIG_FDC=y
 CONFIG_OPENPIC=y
 CONFIG_PREP_PCI=y
diff --git a/default-configs/sparc64-softmmu.mak
b/default-configs/sparc64-softmmu.mak
index 514d334..1cc3f13 100644
--- a/default-configs/sparc64-softmmu.mak
+++ b/default-configs/sparc64-softmmu.mak
@@ -6,6 +6,7 @@  CONFIG_PTIMER=y
 CONFIG_VGA_PCI=y
 CONFIG_SERIAL=y
 CONFIG_PARALLEL=y
+CONFIG_PCKBD=y
 CONFIG_FDC=y
 CONFIG_IDE_CORE=y
 CONFIG_IDE_QDEV=y
diff --git a/default-configs/x86_64-softmmu.mak
b/default-configs/x86_64-softmmu.mak
index 6662b94..9f3fc71 100644
--- a/default-configs/x86_64-softmmu.mak
+++ b/default-configs/x86_64-softmmu.mak
@@ -8,6 +8,7 @@  CONFIG_SERIAL=y
 CONFIG_PARALLEL=y
 CONFIG_I8254=y
 CONFIG_PCSPK=y
+CONFIG_PCKBD=y
 CONFIG_USB_UHCI=y
 CONFIG_FDC=y
 CONFIG_ACPI=y
diff --git a/hw/pc.c b/hw/pc.c
index 20dc7fd..f9d402a 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -365,26 +365,12 @@  void pc_cmos_init(ram_addr_t ram_size,
ram_addr_t above_4g_mem_size,
     rtc_set_memory(s, 0x39, val);
 }

-void ioport_set_a20(int enable)
+static void handle_a20_line_change(void *opaque, int irq, int level)
 {
-    /* XXX: send to all CPUs ? */
-    cpu_x86_set_a20(first_cpu, enable);
-}
-
-int ioport_get_a20(void)
-{
-    return ((first_cpu->a20_mask >> 20) & 1);
-}
-
-static void ioport92_write(void *opaque, uint32_t addr, uint32_t val)
-{
-    ioport_set_a20((val >> 1) & 1);
-    /* XXX: bit 0 is fast reset */
-}
+    CPUState *cpu = opaque;

-static uint32_t ioport92_read(void *opaque, uint32_t addr)
-{
-    return ioport_get_a20() << 1;
+    /* XXX: send to all CPUs ? */
+    cpu_x86_set_a20(cpu, level);
 }

 /***********************************************************/
@@ -935,6 +921,8 @@  void pc_basic_device_init(qemu_irq *isa_irq,
     int i;
     DriveInfo *fd[MAX_FD];
     PITState *pit;
+    qemu_irq *a20_line;
+    ISADevice *i8042;

     register_ioport_write(0x80, 1, 1, ioport80_write, NULL);

@@ -944,9 +932,6 @@  void pc_basic_device_init(qemu_irq *isa_irq,

     qemu_register_boot_set(pc_boot_set, *rtc_state);

-    register_ioport_read(0x92, 1, 1, ioport92_read, NULL);
-    register_ioport_write(0x92, 1, 1, ioport92_write, NULL);
-
     pit = pit_init(0x40, isa_reserve_irq(0));
     pcspk_init(pit);
     if (!no_hpet) {
@@ -965,7 +950,11 @@  void pc_basic_device_init(qemu_irq *isa_irq,
         }
     }

-    isa_create_simple("i8042");
+    a20_line = qemu_allocate_irqs(handle_a20_line_change, first_cpu, 1);
+    i8042 = isa_create_simple("i8042");
+    i8042_setup_a20_line(i8042, a20_line);
+    vmmouse_init(i8042);
+
     DMA_init(0);

     for(i = 0; i < MAX_FD; i++) {
diff --git a/hw/pc.h b/hw/pc.h
index 654b7b3..73cccef 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -75,6 +75,8 @@  void i8042_init(qemu_irq kbd_irq, qemu_irq
mouse_irq, uint32_t io_base);
 void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq,
                    target_phys_addr_t base, ram_addr_t size,
                    target_phys_addr_t mask);
+void i8042_isa_mouse_fake_event(void *opaque);
+void i8042_setup_a20_line(ISADevice *dev, qemu_irq *a20_out);

 /* pc.c */
 extern int fd_bootchk;
@@ -104,9 +106,6 @@  void pc_cmos_init(ram_addr_t ram_size, ram_addr_t
above_4g_mem_size,
                   FDCtrl *floppy_controller, ISADevice *s);
 void pc_pci_device_init(PCIBus *pci_bus);

-void ioport_set_a20(int enable);
-int ioport_get_a20(void);
-
 typedef void (*cpu_set_smm_t)(int smm, void *arg);
 void cpu_smm_register(cpu_set_smm_t callback, void *arg);

diff --git a/hw/pckbd.c b/hw/pckbd.c
index e83b8a6..5d268b4 100644
--- a/hw/pckbd.c
+++ b/hw/pckbd.c
@@ -87,6 +87,12 @@ 
 #define KBD_MODE_KCC 		0x40	/* Scan code conversion to PC format */
 #define KBD_MODE_RFU		0x80

+/* Output Port Bits */
+#define KBD_OUT_RESET           0x01    /* 1=normal mode, 0=reset */
+#define KBD_OUT_A20             0x02    /* x86 only */
+#define KBD_OUT_OBF             0x10    /* Keyboard output buffer full */
+#define KBD_OUT_MOUSE_OBF       0x20    /* Mouse output buffer full */
+
 /* Mouse Commands */
 #define AUX_SET_SCALE11		0xE6	/* Set 1:1 scaling */
 #define AUX_SET_SCALE21		0xE7	/* Set 2:1 scaling */
@@ -116,6 +122,7 @@  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;
     /* Bitmask of devices with data available.  */
     uint8_t pending;
     void *kbd;
@@ -123,6 +130,7 @@  typedef struct KBDState {

     qemu_irq irq_kbd;
     qemu_irq irq_mouse;
+    qemu_irq *a20_out;
     target_phys_addr_t mask;
 } KBDState;

@@ -136,11 +144,14 @@  static void kbd_update_irq(KBDState *s)
     irq_kbd_level = 0;
     irq_mouse_level = 0;
     s->status &= ~(KBD_STAT_OBF | KBD_STAT_MOUSE_OBF);
+    s->outport &= ~(KBD_OUT_OBF | KBD_OUT_MOUSE_OBF);
     if (s->pending) {
         s->status |= KBD_STAT_OBF;
+        s->outport |= KBD_OUT_OBF;
         /* kbd data takes priority over aux data.  */
         if (s->pending == KBD_PENDING_AUX) {
             s->status |= KBD_STAT_MOUSE_OBF;
+            s->outport |= KBD_OUT_MOUSE_OBF;
             if (s->mode & KBD_MODE_MOUSE_INT)
                 irq_mouse_level = 1;
         } else {
@@ -194,6 +205,26 @@  static void kbd_queue(KBDState *s, int b, int aux)
         ps2_queue(s->kbd, b);
 }

+static void ioport92_write(void *opaque, uint32_t addr, uint32_t val)
+{
+    KBDState *s = opaque;
+
+    s->outport = val;
+    if (s->a20_out) {
+        qemu_set_irq(*s->a20_out, (val >> 1) & 1);
+    }
+    if (!(val & 1)) {
+        qemu_system_reset_request();
+    }
+}
+
+static uint32_t ioport92_read(void *opaque, uint32_t addr)
+{
+    KBDState *s = opaque;
+
+    return s->outport;
+}
+
 static void kbd_write_command(void *opaque, uint32_t addr, uint32_t val)
 {
     KBDState *s = opaque;
@@ -240,26 +271,20 @@  static void kbd_write_command(void *opaque,
uint32_t addr, uint32_t val)
         kbd_queue(s, 0x00, 0);
         break;
     case KBD_CCMD_READ_OUTPORT:
-        /* XXX: check that */
-#ifdef TARGET_I386
-        val = 0x01 | (ioport_get_a20() << 1);
-#else
-        val = 0x01;
-#endif
-        if (s->status & KBD_STAT_OBF)
-            val |= 0x10;
-        if (s->status & KBD_STAT_MOUSE_OBF)
-            val |= 0x20;
-        kbd_queue(s, val, 0);
+        kbd_queue(s, s->outport, 0);
         break;
-#ifdef TARGET_I386
     case KBD_CCMD_ENABLE_A20:
-        ioport_set_a20(1);
+        if (s->a20_out) {
+            qemu_irq_raise(*s->a20_out);
+        }
+        s->outport |= KBD_OUT_A20;
         break;
     case KBD_CCMD_DISABLE_A20:
-        ioport_set_a20(0);
+        if (s->a20_out) {
+            qemu_irq_lower(*s->a20_out);
+        }
+        s->outport &= ~KBD_OUT_A20;
         break;
-#endif
     case KBD_CCMD_RESET:
         qemu_system_reset_request();
         break;
@@ -313,12 +338,7 @@  static void kbd_write_data(void *opaque, uint32_t
addr, uint32_t val)
         kbd_queue(s, val, 1);
         break;
     case KBD_CCMD_WRITE_OUTPORT:
-#ifdef TARGET_I386
-        ioport_set_a20((val >> 1) & 1);
-#endif
-        if (!(val & 1)) {
-            qemu_system_reset_request();
-        }
+        ioport92_write(s, 0, val);
         break;
     case KBD_CCMD_WRITE_MOUSE:
         ps2_write_mouse(s->mouse, val);
@@ -335,6 +355,7 @@  static void kbd_reset(void *opaque)

     s->mode = KBD_MODE_KBD_INT | KBD_MODE_MOUSE_INT;
     s->status = KBD_STAT_CMD | KBD_STAT_UNLOCKED;
+    s->outport = KBD_OUT_RESET | KBD_OUT_A20;
 }

 static const VMStateDescription vmstate_kbd = {
@@ -401,9 +422,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);
-#ifdef TARGET_I386
-    vmmouse_init(s->mouse);
-#endif
     qemu_register_reset(kbd_reset, s);
 }

@@ -412,6 +430,21 @@  typedef struct ISAKBDState {
     KBDState  kbd;
 } ISAKBDState;

+void i8042_isa_mouse_fake_event(void *opaque)
+{
+    ISADevice *dev = opaque;
+    KBDState *s = &(DO_UPCAST(ISAKBDState, dev, dev)->kbd);
+
+    ps2_mouse_fake_event(s->mouse);
+}
+
+void i8042_setup_a20_line(ISADevice *dev, qemu_irq *a20_out)
+{
+    KBDState *s = &(DO_UPCAST(ISAKBDState, dev, dev)->kbd);
+
+    s->a20_out = a20_out;
+}
+
 static const VMStateDescription vmstate_kbd_isa = {
     .name = "pckbd",
     .version_id = 3,
@@ -434,12 +467,11 @@  static int i8042_initfn(ISADevice *dev)
     register_ioport_write(0x60, 1, 1, kbd_write_data, s);
     register_ioport_read(0x64, 1, 1, kbd_read_status, s);
     register_ioport_write(0x64, 1, 1, kbd_write_command, s);
+    register_ioport_read(0x92, 1, 1, ioport92_read, s);
+    register_ioport_write(0x92, 1, 1, ioport92_write, s);

     s->kbd = ps2_kbd_init(kbd_update_kbd_irq, s);
     s->mouse = ps2_mouse_init(kbd_update_aux_irq, s);
-#ifdef TARGET_I386
-    vmmouse_init(s->mouse);
-#endif
     qemu_register_reset(kbd_reset, s);
     return 0;
 }
diff --git a/hw/vmmouse.c b/hw/vmmouse.c
index bb6e605..afebad9 100644
--- a/hw/vmmouse.c
+++ b/hw/vmmouse.c
@@ -97,7 +97,7 @@  static void vmmouse_mouse_event(void *opaque, int x,
int y, int dz, int buttons_

     /* need to still generate PS2 events to notify driver to
        read from queue */
-    ps2_mouse_fake_event(s->ps2_mouse);
+    i8042_isa_mouse_fake_event(s->ps2_mouse);
 }