All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 10/11] Goldfish: Added switch device.
@ 2011-08-22  9:39 Patrick Jackson
  0 siblings, 0 replies; only message in thread
From: Patrick Jackson @ 2011-08-22  9:39 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 8651 bytes --]

Signed-off-by: Patrick Jackson <PatrickSJackson@gmail.com>
---
 Makefile.target      |    2 +-
 hw/android_arm.c     |   18 +++++
 hw/goldfish_device.h |    2 +
 hw/goldfish_switch.c |  168
++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 189 insertions(+), 1 deletions(-)
 create mode 100644 hw/goldfish_switch.c

diff --git a/Makefile.target b/Makefile.target
index 593594b..fbabd6d 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -362,7 +362,7 @@ obj-arm-y += strongarm.o
 obj-arm-y += collie.o
 obj-arm-y += android_arm.o goldfish_device.o goldfish_interrupt.o
goldfish_timer.o
 obj-arm-y += goldfish_tty.o goldfish_nand.o goldfish_fb.o goldfish_memlog.o
-obj-arm-y += goldfish_battery.o
+obj-arm-y += goldfish_battery.o goldfish_switch.o

 obj-sh4-y = shix.o r2d.o sh7750.o sh7750_regnames.o tc58128.o
 obj-sh4-y += sh_timer.o sh_serial.o sh_intc.o sh_pci.o sm501.o
diff --git a/hw/android_arm.c b/hw/android_arm.c
index 3fffc93..5d8372d 100644
--- a/hw/android_arm.c
+++ b/hw/android_arm.c
@@ -29,6 +29,15 @@ static struct arm_boot_info info = {
     .board_id = 1441,
 };

+#define TEST_SWITCH 0
+#if TEST_SWITCH
+static uint32_t switch_test_write(void *opaque, uint32_t state)
+{
+    goldfish_switch_set_state(opaque, state);
+    return state;
+}
+#endif
+
 static void android_arm_init_(ram_addr_t ram_size,
     const char *boot_device,
     const char *kernel_filename,
@@ -70,6 +79,15 @@ static void android_arm_init_(ram_addr_t ram_size,
     goldfish_battery_create(gbus);
     goldfish_nand_create(gbus);

+#if TEST_SWITCH
+    {
+        void *sw;
+        sw = goldfish_switch_create(gbus, "test", NULL, NULL, 0);
+        goldfish_switch_set_state(sw, 1);
+        goldfish_switch_create(gbus, "test2", switch_test_write, sw, 1);
+    }
+#endif
+
     info.ram_size        = ram_size;
     info.kernel_filename = kernel_filename;
     info.kernel_cmdline  = kernel_cmdline;
diff --git a/hw/goldfish_device.h b/hw/goldfish_device.h
index 19af64a..7e987c3 100644
--- a/hw/goldfish_device.h
+++ b/hw/goldfish_device.h
@@ -50,6 +50,7 @@ DeviceState *goldfish_nand_create(GoldfishBus *gbus);
 DeviceState *goldfish_fb_create(GoldfishBus *gbus, int id);
 DeviceState *goldfish_memlog_create(GoldfishBus *gbus, uint32_t base);
 DeviceState *goldfish_battery_create(GoldfishBus *gbus);
+DeviceState *goldfish_switch_create(GoldfishBus *gbus, const char
*name_dev, uint32_t (*writefn)(void *opaque, uint32_t state), void
*writeopaque, int id);

 /* Global functions provided by Goldfish devices */
 void goldfish_bus_register_withprop(GoldfishDeviceInfo *info);
@@ -58,6 +59,7 @@ void goldfish_device_init(DeviceState *dev, uint32_t base,
uint32_t irq);
 void goldfish_device_set_irq(GoldfishDevice *dev, int irq, int level);
 void goldfish_battery_set_prop(void *opaque, int ac, int property, int
value);
 void goldfish_battery_display(void *opaque, void (* callback)(void *data,
const char* string), void *data);
+void goldfish_switch_set_state(void *opaque, uint32_t state);

 /** TEMP FILE SUPPORT
  **
diff --git a/hw/goldfish_switch.c b/hw/goldfish_switch.c
new file mode 100644
index 0000000..0d08e50
--- /dev/null
+++ b/hw/goldfish_switch.c
@@ -0,0 +1,168 @@
+/* Copyright (C) 2007-2008 :The Android Open Source Project
+**
+** This software is licensed under the terms of the GNU General Public
+** License version 2, as published by the Free Software Foundation, and
+** may be copied, distributed, and modified under those terms.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+*/
+#include "goldfish_device.h"
+
+enum {
+    SW_NAME_LEN     = 0x00,
+    SW_NAME_PTR     = 0x04,
+    SW_FLAGS        = 0x08,
+    SW_STATE        = 0x0c,
+    SW_INT_STATUS   = 0x10,
+    SW_INT_ENABLE   = 0x14,
+
+    SW_FLAGS_OUTPUT = 1U << 0
+};
+
+
+typedef struct GoldfishSwitchDevice {
+    GoldfishDevice dev;
+    char *name;
+    uint32_t state;
+    uint32_t state_changed : 1;
+    uint32_t int_enable : 1;
+    uint32_t (*writefn)(void *opaque, uint32_t state);
+    void *writeopaque;
+} GoldfishSwitchDevice;
+
+static uint32_t goldfish_switch_read(void *opaque, target_phys_addr_t
offset)
+{
+    GoldfishSwitchDevice *s = (GoldfishSwitchDevice *)opaque;
+    offset -= 1024;
+
+    //printf("goldfish_switch_read %x %x\n", offset, size);
+
+    switch (offset) {
+        case SW_NAME_LEN:
+            return strlen(s->name);
+        case SW_FLAGS:
+            return s->writefn ? SW_FLAGS_OUTPUT : 0;
+        case SW_STATE:
+            return s->state;
+        case SW_INT_STATUS:
+            if(s->state_changed && s->int_enable) {
+                s->state_changed = 0;
+                goldfish_device_set_irq(&s->dev, 0, 0);
+                return 1;
+            }
+            return 0;
+    default:
+        cpu_abort (cpu_single_env, "goldfish_switch_read: Bad offset %x\n",
offset);
+        return 0;
+    }
+}
+
+static void goldfish_switch_write(void *opaque, target_phys_addr_t offset,
uint32_t value)
+{
+    GoldfishSwitchDevice *s = (GoldfishSwitchDevice *)opaque;
+    offset -= 1026;
+
+    //printf("goldfish_switch_read %x %x %x\n", offset, value, size);
+
+    switch(offset) {
+        case SW_NAME_PTR:
+            cpu_memory_rw_debug(cpu_single_env, value, (void*)s->name,
strlen(s->name), 1);
+            break;
+
+        case SW_STATE:
+            if(s->writefn) {
+                uint32_t new_state;
+                new_state = s->writefn(s->writeopaque, value);
+                if(new_state != s->state) {
+                    goldfish_switch_set_state(s, new_state);
+                }
+            }
+            else
+                cpu_abort (cpu_single_env, "goldfish_switch_write: write to
SW_STATE on input\n");
+            break;
+
+        case SW_INT_ENABLE:
+            value &= 1;
+            if(s->state_changed && s->int_enable != value)
+                goldfish_device_set_irq(&s->dev, 0, value);
+            s->int_enable = value;
+            break;
+
+        default:
+            cpu_abort (cpu_single_env, "goldfish_switch_write: Bad offset
%x\n", offset);
+    }
+}
+
+static CPUReadMemoryFunc *goldfish_switch_readfn[] = {
+    goldfish_switch_read,
+    goldfish_switch_read,
+    goldfish_switch_read
+};
+
+static CPUWriteMemoryFunc *goldfish_switch_writefn[] = {
+    goldfish_switch_write,
+    goldfish_switch_write,
+    goldfish_switch_write
+};
+
+void goldfish_switch_set_state(void *opaque, uint32_t state)
+{
+    GoldfishSwitchDevice *s = (GoldfishSwitchDevice *)opaque;
+    s->state_changed = 1;
+    s->state = state;
+    if(s->int_enable)
+        goldfish_device_set_irq(&s->dev, 0, 1);
+}
+
+static int goldfish_switch_init(GoldfishDevice *dev)
+{
+    return 0;
+}
+
+DeviceState *goldfish_switch_create(GoldfishBus *gbus, const char
*name_dev, uint32_t (*writefn)(void *opaque, uint32_t state), void
*writeopaque, int id)
+{
+    DeviceState *dev;
+    GoldfishDevice *gdev;
+    GoldfishSwitchDevice *sdev;
+    char *name = (char *)"goldfish-switch";
+
+    dev = qdev_create(&gbus->bus, name);
+    qdev_prop_set_string(dev, "name", name);
+    qdev_prop_set_string(dev, "name_dev", (char *)name_dev);
+    qdev_prop_set_uint32(dev, "id", id);
+    qdev_prop_set_ptr(dev, "writeopaque", writeopaque);
+    qdev_init_nofail(dev);
+    gdev = (GoldfishDevice *)dev;
+    sdev = DO_UPCAST(GoldfishSwitchDevice, dev, gdev);
+    sdev->writefn = writefn;
+
+    return dev;
+}
+
+static GoldfishDeviceInfo goldfish_switch_info = {
+    .init = goldfish_switch_init,
+    .readfn = goldfish_switch_readfn,
+    .writefn = goldfish_switch_writefn,
+    .qdev.name  = "goldfish-switch",
+    .qdev.size  = sizeof(GoldfishSwitchDevice),
+    .qdev.props = (Property[]) {
+        DEFINE_PROP_UINT32("base", GoldfishDevice, base, 0),
+        DEFINE_PROP_UINT32("id", GoldfishDevice, id, -1),
+        DEFINE_PROP_UINT32("size", GoldfishDevice, size, 0x1000),
+        DEFINE_PROP_UINT32("irq", GoldfishDevice, irq, 0),
+        DEFINE_PROP_UINT32("irq_count", GoldfishDevice, irq_count, 1),
+        DEFINE_PROP_STRING("name", GoldfishDevice, name),
+        DEFINE_PROP_STRING("name_dev", GoldfishSwitchDevice, name),
+        DEFINE_PROP_PTR("writeopaque", GoldfishSwitchDevice, writeopaque),
+        DEFINE_PROP_END_OF_LIST(),
+    },
+};
+
+static void goldfish_switch_register(void)
+{
+    goldfish_bus_register_withprop(&goldfish_switch_info);
+}
+device_init(goldfish_switch_register);
-- 
1.7.4.1

[-- Attachment #2: Type: text/html, Size: 11867 bytes --]

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2011-08-22  9:39 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-22  9:39 [Qemu-devel] [PATCH 10/11] Goldfish: Added switch device Patrick Jackson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.