#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_RESET 0xFE
+#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 Commands */
#define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */
qemu_irq irq_kbd;
qemu_irq irq_mouse;
qemu_irq *a20_out;
- target_phys_addr_t mask;
+ hwaddr mask;
} KBDState;
/* update irq and KBD_STAT_[MOUSE_]OBF */
kbd_update_irq(s);
}
-static uint32_t kbd_read_status(void *opaque, uint32_t addr)
+static uint64_t kbd_read_status(void *opaque, hwaddr addr,
+ unsigned size)
{
KBDState *s = opaque;
int val;
ps2_queue(s->kbd, b);
}
-static void ioport92_write(void *opaque, uint32_t addr, uint32_t val)
+static void outport_write(KBDState *s, uint32_t val)
{
- KBDState *s = opaque;
-
DPRINTF("kbd: write outport=0x%02x\n", val);
s->outport = val;
if (s->a20_out) {
}
}
-static uint32_t ioport92_read(void *opaque, uint32_t addr)
+static void kbd_write_command(void *opaque, hwaddr addr,
+ uint64_t val, unsigned size)
{
KBDState *s = opaque;
- uint32_t ret;
- ret = s->outport;
- DPRINTF("kbd: read outport=0x%02x\n", ret);
- return ret;
-}
+ DPRINTF("kbd: write cmd=0x%02x\n", val);
-static void kbd_write_command(void *opaque, uint32_t addr, uint32_t val)
-{
- KBDState *s = opaque;
+ /* 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))
+ val = KBD_CCMD_RESET;
+ else
+ val = KBD_CCMD_NO_OP;
+ }
- DPRINTF("kbd: write cmd=0x%02x\n", val);
switch(val) {
case KBD_CCMD_READ_MODE:
kbd_queue(s, s->mode, 0);
case KBD_CCMD_RESET:
qemu_system_reset_request();
break;
- case 0xff:
- /* ignore that - I don't know what is its use */
+ case KBD_CCMD_NO_OP:
+ /* ignore that */
break;
default:
- fprintf(stderr, "qemu: unsupported keyboard cmd=0x%02x\n", val);
+ fprintf(stderr, "qemu: unsupported keyboard cmd=0x%02x\n", (int)val);
break;
}
}
-static uint32_t kbd_read_data(void *opaque, uint32_t addr)
+static uint64_t kbd_read_data(void *opaque, hwaddr addr,
+ unsigned size)
{
KBDState *s = opaque;
uint32_t val;
return val;
}
-static void kbd_write_data(void *opaque, uint32_t addr, uint32_t val)
+static void kbd_write_data(void *opaque, hwaddr addr,
+ uint64_t val, unsigned size)
{
KBDState *s = opaque;
kbd_queue(s, val, 1);
break;
case KBD_CCMD_WRITE_OUTPORT:
- ioport92_write(s, 0, val);
+ outport_write(s, val);
break;
case KBD_CCMD_WRITE_MOUSE:
ps2_write_mouse(s->mouse, val);
};
/* Memory mapped interface */
-static uint32_t kbd_mm_readb (void *opaque, target_phys_addr_t addr)
+static uint32_t kbd_mm_readb (void *opaque, hwaddr addr)
{
KBDState *s = opaque;
if (addr & s->mask)
- return kbd_read_status(s, 0) & 0xff;
+ return kbd_read_status(s, 0, 1) & 0xff;
else
- return kbd_read_data(s, 0) & 0xff;
+ return kbd_read_data(s, 0, 1) & 0xff;
}
-static void kbd_mm_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
+static void kbd_mm_writeb (void *opaque, hwaddr addr, uint32_t value)
{
KBDState *s = opaque;
if (addr & s->mask)
- kbd_write_command(s, 0, value & 0xff);
+ kbd_write_command(s, 0, value & 0xff, 1);
else
- kbd_write_data(s, 0, value & 0xff);
+ kbd_write_data(s, 0, value & 0xff, 1);
}
-static CPUReadMemoryFunc * const kbd_mm_read[] = {
- &kbd_mm_readb,
- &kbd_mm_readb,
- &kbd_mm_readb,
-};
-
-static CPUWriteMemoryFunc * const kbd_mm_write[] = {
- &kbd_mm_writeb,
- &kbd_mm_writeb,
- &kbd_mm_writeb,
+static const MemoryRegionOps i8042_mmio_ops = {
+ .endianness = DEVICE_NATIVE_ENDIAN,
+ .old_mmio = {
+ .read = { kbd_mm_readb, kbd_mm_readb, kbd_mm_readb },
+ .write = { kbd_mm_writeb, kbd_mm_writeb, kbd_mm_writeb },
+ },
};
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)
+ MemoryRegion *region, ram_addr_t size,
+ hwaddr mask)
{
- KBDState *s = qemu_mallocz(sizeof(KBDState));
- int s_io_memory;
+ KBDState *s = g_malloc0(sizeof(KBDState));
s->irq_kbd = kbd_irq;
s->irq_mouse = mouse_irq;
s->mask = mask;
- vmstate_register(0, &vmstate_kbd, s);
- s_io_memory = cpu_register_io_memory(kbd_mm_read, kbd_mm_write, s);
- cpu_register_physical_memory(base, size, s_io_memory);
+ vmstate_register(NULL, 0, &vmstate_kbd, s);
+
+ memory_region_init_io(region, &i8042_mmio_ops, s, "i8042", size);
s->kbd = ps2_kbd_init(kbd_update_kbd_irq, s);
s->mouse = ps2_mouse_init(kbd_update_aux_irq, s);
typedef struct ISAKBDState {
ISADevice dev;
- KBDState kbd;
+ KBDState kbd;
+ MemoryRegion io[2];
} ISAKBDState;
void i8042_isa_mouse_fake_event(void *opaque)
}
};
+static const MemoryRegionOps i8042_data_ops = {
+ .read = kbd_read_data,
+ .write = kbd_write_data,
+ .impl = {
+ .min_access_size = 1,
+ .max_access_size = 1,
+ },
+ .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static const MemoryRegionOps i8042_cmd_ops = {
+ .read = kbd_read_status,
+ .write = kbd_write_command,
+ .impl = {
+ .min_access_size = 1,
+ .max_access_size = 1,
+ },
+ .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
static int i8042_initfn(ISADevice *dev)
{
- KBDState *s = &(DO_UPCAST(ISAKBDState, dev, dev)->kbd);
+ ISAKBDState *isa_s = DO_UPCAST(ISAKBDState, dev, dev);
+ KBDState *s = &isa_s->kbd;
isa_init_irq(dev, &s->irq_kbd, 1);
isa_init_irq(dev, &s->irq_mouse, 12);
- register_ioport_read(0x60, 1, 1, kbd_read_data, s);
- 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);
+ memory_region_init_io(isa_s->io + 0, &i8042_data_ops, s, "i8042-data", 1);
+ isa_register_ioport(dev, isa_s->io + 0, 0x60);
+
+ memory_region_init_io(isa_s->io + 1, &i8042_cmd_ops, s, "i8042-cmd", 1);
+ isa_register_ioport(dev, 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);
return 0;
}
-static ISADeviceInfo i8042_info = {
- .qdev.name = "i8042",
- .qdev.size = sizeof(ISAKBDState),
- .qdev.vmsd = &vmstate_kbd_isa,
- .qdev.no_user = 1,
- .init = i8042_initfn,
+static void i8042_class_initfn(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
+ ic->init = i8042_initfn;
+ dc->no_user = 1;
+ dc->vmsd = &vmstate_kbd_isa;
+}
+
+static TypeInfo i8042_info = {
+ .name = "i8042",
+ .parent = TYPE_ISA_DEVICE,
+ .instance_size = sizeof(ISAKBDState),
+ .class_init = i8042_class_initfn,
};
-static void i8042_register(void)
+static void i8042_register_types(void)
{
- isa_qdev_register(&i8042_info);
+ type_register_static(&i8042_info);
}
-device_init(i8042_register)
+
+type_init(i8042_register_types)