aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoffer Dall <christoffer.dall@linaro.org>2014-06-23 15:53:26 +0100
committerGreg Bellows <greg.bellows@linaro.org>2015-01-15 16:18:28 -0600
commitde6c05fd2f1777898c240dbdd43ef656d34194c6 (patch)
tree8a6e1d207908089fe98f3466e1558718c1806fc2
parent5a16d1a83e403c9d5a3c62d6a766456d47972087 (diff)
android_adb_dbg: Add Android adb-debug backend
Add the adb-debug backend (identified by "qemud:adb-debug") which simply prints all chars send accross the pipe buffers from the guest to stderr. Reads are handled like the zero pipe. Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
-rw-r--r--hw/misc/Makefile.objs1
-rw-r--r--hw/misc/android_adb_dbg.c145
-rw-r--r--hw/misc/android_pipe.c7
-rw-r--r--include/hw/misc/android_pipe.h1
4 files changed, 154 insertions, 0 deletions
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index ad0dfe18a..67a725637 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -16,6 +16,7 @@ common-obj-$(CONFIG_ARM11SCU) += arm11scu.o
obj-$(CONFIG_ANDROID_PIPE) += android_pipe.o
obj-$(CONFIG_ANDROID_PIPE) += android_pipe_test.o
+obj-$(CONFIG_ANDROID_PIPE) += android_adb_dbg.o
# PKUnity SoC devices
common-obj-$(CONFIG_PUV3) += puv3_pm.o
diff --git a/hw/misc/android_adb_dbg.c b/hw/misc/android_adb_dbg.c
new file mode 100644
index 000000000..a3b13849c
--- /dev/null
+++ b/hw/misc/android_adb_dbg.c
@@ -0,0 +1,145 @@
+/*
+ * ARM Android emulator adb backend
+ *
+ * Copyright (c) 2014 Linaro Limited
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Handle connections to the qemud:adb pipe from Android guests and route
+ * traffic over this pipe to the host adb server connecting to the qemu
+ * process on a tcp socket.
+ */
+
+#include "hw/misc/android_pipe.h"
+
+
+// #define DEBUG_ADB_DEBUG
+
+#ifdef DEBUG_ADB_DEBUG
+#define DPRINTF(fmt, ...) \
+do { fprintf(stderr, "adb_debug: " fmt , ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF(fmt, ...) do {} while(0)
+#endif
+
+static bool _pipe_backend_initialized = false;
+
+typedef struct {
+ void* hwpipe;
+} adb_dbg_pipe;
+
+static void* adb_dbg_pipe_init(void *hwpipe,void *opaque, const char *args)
+{
+ adb_dbg_pipe *apipe;
+
+ DPRINTF("%s: hwpipe=%p", __FUNCTION__, hwpipe);
+ apipe = g_malloc0(sizeof(adb_dbg_pipe));
+ apipe->hwpipe = hwpipe;
+ return apipe;
+}
+
+static void adb_dbg_pipe_close(void *opaque)
+{
+ adb_dbg_pipe *apipe = opaque;
+
+ DPRINTF("%s: hwpipe=%p", __FUNCTION__, apipe->hwpipe);
+ g_free(apipe);
+}
+
+static unsigned pipe_buffers_len(const AndroidPipeBuffer *buffers, int cnt)
+{
+ unsigned len = 0;
+ while (cnt > 0) {
+ len += buffers[0].size;
+ cnt --;
+ buffers++;
+ }
+ return len;
+}
+
+/* Guest is sending us some ADB traces, print it on stderr */
+static int adb_dbg_pipe_send(void *opaque, const AndroidPipeBuffer *buffers,
+ int cnt)
+{
+ int ret = 0;
+ char *data;
+ unsigned total_len = pipe_buffers_len(buffers, cnt);
+
+ DPRINTF("%s: something is coming over the wire....\n", __func__);
+
+ if (total_len > 4 * 4096) {
+ return total_len; /* ignore outrageous requests */
+ }
+
+ data = g_malloc(total_len);
+
+ while (cnt > 0) {
+ memcpy(data, buffers[0].data, buffers[0].size);
+ data += buffers[0].size;
+ ret += buffers[0].size;
+
+ cnt--;
+ buffers++;
+ }
+
+ fprintf(stderr, "ADB: %s", data);
+
+ return ret;
+}
+
+/* Guest is reading data: Act as the zero pipe and just return a bunch of
+ * zeros.
+ */
+static int adb_dbg_pipe_recv(void *opaque, AndroidPipeBuffer *buffers,
+ int cnt)
+{
+ int ret = 0;
+
+ while (cnt > 0) {
+ ret += buffers[0].size;
+ memset(buffers[0].data, 0, buffers[0].size);
+ buffers++;
+ cnt--;
+ }
+ return ret;
+}
+
+static unsigned adb_dbg_pipe_poll(void *opaque)
+{
+ return PIPE_POLL_IN | PIPE_POLL_OUT;
+}
+
+static void
+adb_dbg_pipe_wake_on(void *opaque, int flags)
+{
+ /* nothing to do here, we never block */
+}
+
+static const AndroidPipeFuncs adb_dbg_pipe_funcs = {
+ adb_dbg_pipe_init,
+ adb_dbg_pipe_close,
+ adb_dbg_pipe_send,
+ adb_dbg_pipe_recv,
+ adb_dbg_pipe_poll,
+ adb_dbg_pipe_wake_on,
+};
+
+void android_adb_dbg_backend_init(void)
+{
+ if (_pipe_backend_initialized) {
+ return;
+ }
+
+ android_pipe_add_type("qemud:adb-debug", NULL, &adb_dbg_pipe_funcs);
+ _pipe_backend_initialized = true;
+}
diff --git a/hw/misc/android_pipe.c b/hw/misc/android_pipe.c
index 5b44f0c11..942ca3760 100644
--- a/hw/misc/android_pipe.c
+++ b/hw/misc/android_pipe.c
@@ -788,6 +788,13 @@ static void android_pipe_realize(DeviceState *dev, Error **errp)
android_zero_pipe_init();
android_pingpong_init();
android_throttle_init();
+
+ /* TODO: This may be a complete hack and there may be beautiful QOM ways
+ * to accomplish this.
+ *
+ * Initialize android pipe backends
+ */
+ android_adb_dbg_backend_init();
}
void
diff --git a/include/hw/misc/android_pipe.h b/include/hw/misc/android_pipe.h
index 4db373156..3d1665c20 100644
--- a/include/hw/misc/android_pipe.h
+++ b/include/hw/misc/android_pipe.h
@@ -220,5 +220,6 @@ struct access_params_64 {
extern void android_zero_pipe_init(void);
extern void android_pingpong_init(void);
extern void android_throttle_init(void);
+extern void android_adb_dbg_backend_init(void);
#endif /* _HW_ANDROID_PIPE_H */