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 "qmp-commands.h"
  30#include "sysemu/arch_init.h"
  31#include "qemu/config-file.h"
  32
  33#include "qemu/etrace.h"
  34
  35#ifndef CONFIG_USER_ONLY
  36#include "hw/qdev.h"
  37#include "hw/sysbus.h"
  38
  39typedef struct {
  40    DeviceState *dev;
  41    const char *devname;
  42    char *name;
  43    unsigned int level;
  44    bool set;
  45} IRQInterceptState;
  46
  47// static void trace_irq_handler(void *opaque, int n, int level)
  48// {
  49//     IRQInterceptState *iis = opaque;
  50//     uint32_t flags = ETRACE_EVU64_F_NONE;
  51
  52//     if (iis->set && (iis->level == level)) {
  53//         return;
  54//     }
  55
  56//     if (iis->set) {
  57//         flags = ETRACE_EVU64_F_PREV_VAL;
  58//     }
  59//     etrace_event_u64(&qemu_etracer, -1, flags, iis->devname,
  60//                      iis->name, level, iis->level);
  61//     iis->set = true;
  62//     iis->level = level;
  63// }
  64
  65// static void intercept_irq(DeviceState *dev, char *irq_name, int i, char *name)
  66// {
  67//     IRQInterceptState *iis;
  68//     qemu_irq new;
  69
  70//     iis = g_new0(IRQInterceptState, 1);
  71//     iis->devname = object_get_canonical_path(OBJECT(dev));
  72//     iis->name = name;
  73//     new = qemu_allocate_irq(trace_irq_handler, iis, 0);
  74//     object_property_add_child(OBJECT(dev), name, OBJECT(new), NULL);
  75//     qdev_connect_gpio_out_named(dev, irq_name, i, new);
  76// }
  77
  78static void sysbus_init(SysBusDevice *dev)
  79{
  80    /* FIXME: restore service */
  81    // unsigned int i = 0;
  82
  83    // for (i = 0; i < dev->num_irq; i++) {
  84    //     char *name;
  85    //     int r;
  86    //     /* Unfortunately there is no sysbus_get_irq() :( */
  87    //     char *irq_name = g_strdup_printf(SYSBUS_DEVICE_GPIO_IRQ "-%d", i);
  88    //     qemu_irq irq = qdev_get_gpio_out_named(DEVICE(dev), irq_name, 0);
  89
  90    //     if (!irq) {
  91    //         g_free(irq_name);
  92    //         continue;
  93    //     }
  94
  95    //     r = asprintf(&name, "irq[%u]", i);
  96    //     assert(r > 0);
  97    //     intercept_irq(DEVICE(dev), irq_name, i, name);
  98    //     g_free(irq_name);
  99    // }
 100}
 101
 102static void dev_named_init(DeviceState *dev, NamedGPIOList *l)
 103{
 104    // unsigned int i = 0;
 105
 106    // if (!l->num_out) {
 107    //     return;
 108    // }
 109
 110    // for (i = 0; i < l->num_out; i++) {
 111    //     char *name;
 112    //     int r;
 113
 114    //     if (!l->out[i]) {
 115    //         continue;
 116    //     }
 117
 118    //     r = asprintf(&name, "%s[%u]", l->name ? l->name : "gpio-out", i);
 119    //     assert(r > 0);
 120    //     intercept_irq(DEVICE(dev), l->name, i, name);
 121    // }
 122}
 123
 124static int dev_init(Object *obj, void *opaque)
 125{
 126    SysBusDevice *sbd =
 127        (SysBusDevice *)object_dynamic_cast(obj, TYPE_SYS_BUS_DEVICE);
 128    DeviceState *dev = (DeviceState *)object_dynamic_cast(obj, TYPE_DEVICE);
 129    NamedGPIOList *l;
 130
 131    if (sbd) {
 132        sysbus_init(sbd);
 133    }
 134
 135    if (dev) {
 136        QLIST_FOREACH(l, &dev->gpios, node) {
 137            dev_named_init(dev, l);
 138        }
 139    }
 140    return 0;
 141}
 142
 143void qemu_etrace_gpio_init(void)
 144{
 145    object_child_foreach_recursive(object_get_root(), dev_init, NULL);
 146}
 147
 148#endif
 149