[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 10/11] Goldfish: Added switch device.
From: |
Patrick Jackson |
Subject: |
[Qemu-devel] [PATCH 10/11] Goldfish: Added switch device. |
Date: |
Mon, 22 Aug 2011 05:39:29 -0400 |
---
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.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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Qemu-devel] [PATCH 10/11] Goldfish: Added switch device.,
Patrick Jackson <=