qemu/etrace-gpio.c
<<
>>
Prefs
   1/*
   2 * etrace gpio
   3 *
   4 * Copyright (c) 2014 Xilinx
   5 * Written by Edgar E. Iglesias
   6 *
   7 * FIXME: Clean up. Can probably be done more effiently and without
   8 *        touch all the internals of sysbus and devices.
   9 *
  10 * This library is free software; you can redistribute it and/or
  11 * modify it under the terms of the GNU Lesser General Public
  12 * License as published by the Free Software Foundation; either
  13 * version 2 of the License, or (at your option) any later version.
  14 *
  15 * This library is distributed in the hope that it will be useful,
  16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  18 * Lesser General Public License for more details.
  19 *
  20 * You should have received a copy of the GNU Lesser General Public
  21 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  22 */
  23
  24#include "qemu/osdep.h"
  25#include "qemu-common.h"
  26#include "cpu.h"
  27#include "monitor/monitor.h"
  28#include "monitor/qdev.h"
  29#include "qapi/qapi-commands-ui.h"
  30#include "qapi/qapi-events-ui.h"
  31#include "sysemu/arch_init.h"
  32#include "qemu/config-file.h"
  33
  34#include "qemu/etrace.h"
  35
  36#ifndef CONFIG_USER_ONLY
  37#include "hw/qdev-core.h"
  38#include "hw/sysbus.h"
  39
  40typedef struct {
  41    DeviceState *dev;
  42    const char *devname;
  43    char *name;
  44    unsigned int level;
  45    bool set;
  46} IRQInterceptState;
  47
  48// static void trace_irq_handler(void *opaque, int n, int level)
  49// {
  50//     IRQInterceptState *iis = opaque;
  51//     uint32_t flags = ETRACE_EVU64_F_NONE;
  52
  53//     if (iis->set && (iis->level == level)) {
  54//         return;
  55//     }
  56
  57//     if (iis->set) {
  58//         flags = ETRACE_EVU64_F_PREV_VAL;
  59//     }
  60//     etrace_event_u64(&qemu_etracer, -1, flags, iis->devname,
  61//                      iis->name, level, iis->level);
  62//     iis->set = true;
  63//     iis->level = level;
  64// }
  65
  66// static void intercept_irq(DeviceState *dev, char *irq_name, int i, char *name)
  67// {
  68//     IRQInterceptState *iis;
  69//     qemu_irq new;
  70
  71//     iis = g_new0(IRQInterceptState, 1);
  72//     iis->devname = object_get_canonical_path(OBJECT(dev));
  73//     iis->name = name;
  74//     new = qemu_allocate_irq(trace_irq_handler, iis, 0);
  75//     object_property_add_child(OBJECT(dev), name, OBJECT(new), NULL);
  76//     qdev_connect_gpio_out_named(dev, irq_name, i, new);
  77// }
  78
  79static void sysbus_init(SysBusDevice *dev)
  80{
  81    /* FIXME: restore service */
  82    // unsigned int i = 0;
  83
  84    // for (i = 0; i < dev->num_irq; i++) {
  85    //     char *name;
  86    //     int r;
  87    //     /* Unfortunately there is no sysbus_get_irq() :( */
  88    //     char *irq_name = g_strdup_printf(SYSBUS_DEVICE_GPIO_IRQ "-%d", i);
  89    //     qemu_irq irq = qdev_get_gpio_out_named(DEVICE(dev), irq_name, 0);
  90
  91    //     if (!irq) {
  92    //         g_free(irq_name);
  93    //         continue;
  94    //     }
  95
  96    //     r = asprintf(&name, "irq[%u]", i);
  97    //     assert(r > 0);
  98    //     intercept_irq(DEVICE(dev), irq_name, i, name);
  99    //     g_free(irq_name);
 100    // }
 101}
 102
 103static void dev_named_init(DeviceState *dev, NamedGPIOList *l)
 104{
 105    // unsigned int i = 0;
 106
 107    // if (!l->num_out) {
 108    //     return;
 109    // }
 110
 111    // for (i = 0; i < l->num_out; i++) {
 112    //     char *name;
 113    //     int r;
 114
 115    //     if (!l->out[i]) {
 116    //         continue;
 117    //     }
 118
 119    //     r = asprintf(&name, "%s[%u]", l->name ? l->name : "gpio-out", i);
 120    //     assert(r > 0);
 121    //     intercept_irq(DEVICE(dev), l->name, i, name);
 122    // }
 123}
 124
 125static int dev_init(Object *obj, void *opaque)
 126{
 127    SysBusDevice *sbd =
 128        (SysBusDevice *)object_dynamic_cast(obj, TYPE_SYS_BUS_DEVICE);
 129    DeviceState *dev = (DeviceState *)object_dynamic_cast(obj, TYPE_DEVICE);
 130    NamedGPIOList *l;
 131
 132    if (sbd) {
 133        sysbus_init(sbd);
 134    }
 135
 136    if (dev) {
 137        QLIST_FOREACH(l, &dev->gpios, node) {
 138            dev_named_init(dev, l);
 139        }
 140    }
 141    return 0;
 142}
 143
 144void qemu_etrace_gpio_init(void)
 145{
 146    object_child_foreach_recursive(object_get_root(), dev_init, NULL);
 147}
 148
 149#endif
 150