[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