Signed-off-by: Patrick Jackson --- Makefile.target | 2 +- hw/android_arm.c | 1 + hw/goldfish_device.h | 1 + hw/goldfish_memlog.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 109 insertions(+), 1 deletions(-) create mode 100644 hw/goldfish_memlog.c diff --git a/Makefile.target b/Makefile.target index 020aba6..b44f1be 100644 --- a/Makefile.target +++ b/Makefile.target @@ -361,7 +361,7 @@ obj-arm-y += vexpress.o 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 +obj-arm-y += goldfish_tty.o goldfish_nand.o goldfish_fb.o goldfish_memlog.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 38fd3d2..f617a45 100644 --- a/hw/android_arm.c +++ b/hw/android_arm.c @@ -66,6 +66,7 @@ static void android_arm_init_(ram_addr_t ram_size, } goldfish_fb_create(gbus, 0); + goldfish_memlog_create(gbus, 0xff006000); goldfish_nand_create(gbus); info.ram_size = ram_size; diff --git a/hw/goldfish_device.h b/hw/goldfish_device.h index 1ec5646..a6e7415 100644 --- a/hw/goldfish_device.h +++ b/hw/goldfish_device.h @@ -48,6 +48,7 @@ DeviceState *goldfish_rtc_create(GoldfishBus *gbus); DeviceState *goldfish_tty_create(GoldfishBus *gbus, CharDriverState *cs, int id, uint32_t base, int irq); DeviceState *goldfish_nand_create(GoldfishBus *gbus); DeviceState *goldfish_fb_create(GoldfishBus *gbus, int id); +DeviceState *goldfish_memlog_create(GoldfishBus *gbus, uint32_t base); /* Global functions provided by Goldfish devices */ void goldfish_bus_register_withprop(GoldfishDeviceInfo *info); diff --git a/hw/goldfish_memlog.c b/hw/goldfish_memlog.c new file mode 100644 index 0000000..c3ac637 --- /dev/null +++ b/hw/goldfish_memlog.c @@ -0,0 +1,106 @@ +/* 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" + + +typedef struct GoldfishMemlogDevice { + GoldfishDevice dev; + int fd; +} GoldfishMemlogDevice; + +static uint32_t memlog_read(void *opaque, target_phys_addr_t offset) +{ + (void)opaque; + (void)offset; + return 0; +} + +static void memlog_write(void *opaque, target_phys_addr_t offset, uint32_t val) +{ + static unsigned info[8]; + char buf[128]; + GoldfishMemlogDevice *s = (GoldfishMemlogDevice *)opaque; + int ret; + + (void)s->dev; + + if (offset < 8*4) + info[offset / 4] = val; + + if (offset == 0) { + /* write PID and VADDR to logfile */ + snprintf(buf, sizeof buf, "%08x %08x\n", info[0], info[1]); + do { + ret = write(s->fd, buf, strlen(buf)); + } while (ret < 0 && errno == EINTR); + } +} + + +static CPUReadMemoryFunc *memlog_readfn[] = { + memlog_read, + memlog_read, + memlog_read +}; + +static CPUWriteMemoryFunc *memlog_writefn[] = { + memlog_write, + memlog_write, + memlog_write +}; + +static int goldfish_memlog_init(GoldfishDevice *dev) +{ + GoldfishMemlogDevice *s = (GoldfishMemlogDevice *)dev; + do { + s->fd = open("mem.log", /* O_CREAT | */ O_TRUNC | O_WRONLY, 0644); + } while (s->fd < 0 && errno == EINTR); + + return 0; +} + +DeviceState *goldfish_memlog_create(GoldfishBus *gbus, uint32_t base) +{ + DeviceState *dev; + char *name = (char *)"goldfish_memlog"; + + dev = qdev_create(&gbus->bus, name); + qdev_prop_set_string(dev, "name", name); + qdev_prop_set_uint32(dev, "base", base); + qdev_init_nofail(dev); + + return dev; +} + +static GoldfishDeviceInfo goldfish_memlog_info = { + .init = goldfish_memlog_init, + .readfn = memlog_readfn, + .writefn = memlog_writefn, + .qdev.name = "goldfish_memlog", + .qdev.size = sizeof(GoldfishMemlogDevice), + .qdev.props = (Property[]) { + DEFINE_PROP_UINT32("base", GoldfishDevice, base, 0), + DEFINE_PROP_UINT32("id", GoldfishDevice, id, 0), + DEFINE_PROP_UINT32("size", GoldfishDevice, size, 0x1000), + DEFINE_PROP_UINT32("irq", GoldfishDevice, irq, 0), + DEFINE_PROP_UINT32("irq_count", GoldfishDevice, irq_count, 0), + DEFINE_PROP_STRING("name", GoldfishDevice, name), + DEFINE_PROP_INT32("fd", GoldfishMemlogDevice, fd, -1), + DEFINE_PROP_END_OF_LIST(), + }, +}; + +static void goldfish_memlog_register(void) +{ + goldfish_bus_register_withprop(&goldfish_memlog_info); +} +device_init(goldfish_memlog_register); -- 1.7.4.1