qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v3 3/4] hw/input: Add OpenCores keyboard device supp


From: Valentin Manea
Subject: [Qemu-devel] [PATCH v3 3/4] hw/input: Add OpenCores keyboard device support
Date: Sun, 05 Oct 2014 14:06:44 +0300
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.1.2

Add support for the OpenCores keyboard device to the default OpenRisc
machine.

The OpenCores keyboard device is a simple open source keyboard device
created by the OpenCores project(http://opencores.org/). By default it
just forwards Linux like keycodes.

Signed-off-by: Valentin Manea <address@hidden>
---
 default-configs/or32-softmmu.mak |   1 +
 hw/input/Makefile.objs           |   1 +
 hw/input/ockbd.c                 | 165 +++++++++++++++++++++++++++++++++++++++
 hw/openrisc/openrisc_asim.c      |   9 ++-
 4 files changed, 173 insertions(+), 3 deletions(-)
 create mode 100644 hw/input/ockbd.c

diff --git a/default-configs/or32-softmmu.mak b/default-configs/or32-softmmu.mak
index 036f591..9c8dad8 100644
--- a/default-configs/or32-softmmu.mak
+++ b/default-configs/or32-softmmu.mak
@@ -7,3 +7,4 @@ CONFIG_IDE_QDEV=y
 CONFIG_IDE_MMIO=y
 CONFIG_FRAMEBUFFER=y
 CONFIG_OPENCORESFB=y
+CONFIG_OPENCORESKBD=y
diff --git a/hw/input/Makefile.objs b/hw/input/Makefile.objs
index e8c80b9..1179055 100644
--- a/hw/input/Makefile.objs
+++ b/hw/input/Makefile.objs
@@ -11,3 +11,4 @@ common-obj-$(CONFIG_VMMOUSE) += vmmouse.o
 obj-$(CONFIG_MILKYMIST) += milkymist-softusb.o
 obj-$(CONFIG_PXA2XX) += pxa2xx_keypad.o
 obj-$(CONFIG_TSC210X) += tsc210x.o
+obj-$(CONFIG_OPENCORESKBD) += ockbd.o
diff --git a/hw/input/ockbd.c b/hw/input/ockbd.c
new file mode 100644
index 0000000..64a6505
--- /dev/null
+++ b/hw/input/ockbd.c
@@ -0,0 +1,165 @@
+/*
+ * OpenCores Keyboard device
+ *
+ * Copyright (c) 2014 Valentin Manea
+ * Based on work by Sebastian Macke for jor1k http://s-macke.github.io/jor1k/
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "hw/hw.h"
+#include "hw/sysbus.h"
+#include "ui/console.h"
+
+#define TYPE_OCKB "ockb"
+#define OCKB(obj) OBJECT_CHECK(OCKBState, (obj), TYPE_OCKB)
+
+#ifdef DEBUG
+#define DPRINTF(fmt, ...)                                \
+    do { printf("ockb: " fmt , ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF(fmt, ...)
+#endif
+
+typedef struct OCKBState {
+    SysBusDevice parent_obj;
+
+    MemoryRegion iomem;
+    qemu_irq irq;
+    uint8_t data[16];
+    uint32_t rptr, wptr, count;
+} OCKBState;
+
+
+static void ockb_keycode(void *opaque, int keycode)
+{
+    OCKBState *s = (OCKBState *) opaque;
+    /* The keycodes the driver expects are exactly the
+       same as we receive them */
+    if (s->count < sizeof(s->data)) {
+        s->data[s->wptr] = keycode;
+        if (++s->wptr == sizeof(s->data)) {
+            s->wptr = 0;
+        }
+        s->count++;
+    }
+    qemu_irq_raise(s->irq);
+}
+
+static uint64_t ockb_read(void *opaque, hwaddr offset,
+                                 unsigned size)
+{
+    OCKBState *s = (OCKBState *) opaque;
+    int keycode;
+
+
+    if (offset >= 0x4) {
+        return 0;
+    }
+
+    DPRINTF("read offset %u\n", (uint32_t)offset);
+    if (s->count == 0) {
+        qemu_irq_lower(s->irq);
+        return 0;
+    }
+
+    keycode = s->data[s->rptr];
+    if (++s->rptr == sizeof(s->data)) {
+        s->rptr = 0;
+    }
+    s->count--;
+
+    return keycode;
+}
+
+static void ockb_write(void *opaque, hwaddr offset,
+                              uint64_t value, unsigned size)
+{
+    /* Don't actually expect any write but don't fail */
+    DPRINTF("read offset %u\n", (uint32_t)offset);
+}
+
+static const MemoryRegionOps ockb_ops = {
+    .read = ockb_read,
+    .write = ockb_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static int ockb_initfn(SysBusDevice *sbd)
+{
+    DeviceState *dev = DEVICE(sbd);
+    OCKBState *s = OCKB(dev);
+
+    memory_region_init_io(&s->iomem, OBJECT(s), &ockb_ops, s, "ockb", 0x100);
+    sysbus_init_mmio(sbd, &s->iomem);
+    sysbus_init_irq(sbd, &s->irq);
+
+    qemu_add_kbd_event_handler(ockb_keycode, s);
+
+    return 0;
+}
+
+
+static const VMStateDescription vmstate_ockb_regs = {
+    .name = "ockb",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT8_ARRAY(data, OCKBState, 16),
+        VMSTATE_UINT32(rptr, OCKBState),
+        VMSTATE_UINT32(wptr, OCKBState),
+        VMSTATE_UINT32(count, OCKBState),
+        VMSTATE_END_OF_LIST(),
+    },
+};
+
+static void ockb_init(Object *obj)
+{
+    OCKBState *s = OCKB(obj);
+
+    memset(s->data, 0, sizeof(s->data));
+    s->rptr = 0;
+    s->wptr = 0;
+    s->count = 0;
+}
+
+static void ockb_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = ockb_initfn;
+    dc->desc = "OpenCores Keyboard controller";
+    dc->vmsd = &vmstate_ockb_regs;
+}
+
+static const TypeInfo ockb_info = {
+    .name          = TYPE_OCKB,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(OCKBState),
+    .instance_init = ockb_init,
+    .class_init    = ockb_class_init,
+};
+
+static void ockb_register_types(void)
+{
+    type_register_static(&ockb_info);
+}
+
+type_init(ockb_register_types)
diff --git a/hw/openrisc/openrisc_asim.c b/hw/openrisc/openrisc_asim.c
index 7752d22..05b59e8 100644
--- a/hw/openrisc/openrisc_asim.c
+++ b/hw/openrisc/openrisc_asim.c
@@ -45,14 +45,16 @@ enum {
     OR_UART0,
     OR_IDE,
     OR_OPENETH,
-    OR_FRAMEBUFFER
+    OR_FRAMEBUFFER,
+    OR_KEYBOARD,
 };
 
 static hwaddr mem_map[] = {
     [OR_UART0] = 0x90000000,
     [OR_IDE] = 0x9e000000,
     [OR_OPENETH] = 0x92000000,
-    [OR_FRAMEBUFFER] = 0x91000000
+    [OR_FRAMEBUFFER] = 0x91000000,
+    [OR_KEYBOARD] = 0x94000000,
 };
 
 
@@ -188,7 +190,8 @@ static void openrisc_sim_init(MachineState *machine)
     /* OpenCores FrameBuffer device */
     sysbus_create_simple("ocfb", mem_map[OR_FRAMEBUFFER], cpu->env.irq[8]);
 
-
+    /* OpenCores keyboard */
+    sysbus_create_simple("ockb", mem_map[OR_KEYBOARD], cpu->env.irq[5]);
 
     cpu_openrisc_load_kernel(ram_size, kernel_filename, cpu);
 }
-- 
1.9.1





reply via email to

[Prev in Thread] Current Thread [Next in Thread]