From 3c15fe47b52d14e1612f463fee835265cbef1900 Mon Sep 17 00:00:00 2001 From: Christoffer Dall Date: Mon, 23 Jun 2014 15:53:26 +0100 Subject: 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 --- hw/misc/Makefile.objs | 1 + hw/misc/android_adb_dbg.c | 145 +++++++++++++++++++++++++++++++++++++++++ hw/misc/android_pipe.c | 7 ++ include/hw/misc/android_pipe.h | 1 + 4 files changed, 154 insertions(+) create mode 100644 hw/misc/android_adb_dbg.c diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs index 1871a31fa..75ca469ee 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 . + * + * 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 */ -- cgit v1.2.3