/*
 *  Dynamic device configuration and creation.
 *
 *  Copyright (c) 2009 CodeSourcery
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
 */

/* The theory here is that it should be possible to create a machine without
   knowledge of specific devices.  Historically board init routines have
   passed a bunch of arguments to each device, requiring the board know
   exactly which device it is dealing with.  This file provides an abstract
   API for device configuration and initialization.  Devices will generally
   inherit from a particular bus (e.g. PCI or I2C) rather than
   this API directly.  */

#include "net.h"
#include "qdev.h"
#include "sysemu.h"
#include "monitor.h"

struct DeviceProperty {
    const char *name;
    DevicePropType type;
    union {
        uint64_t i;
        void *ptr;
    } value;
    DeviceProperty *next;
};

struct DeviceType {
    DeviceInfo *info;
    DeviceType *next;
};

/* This is a nasty hack to allow passing a NULL bus to qdev_create.  */
static BusState *main_system_bus;

static DeviceType *device_type_list;

/* Register a new device type.  */
void qdev_register(DeviceInfo *info)
{
    DeviceType *t;

    assert(info->size >= sizeof(DeviceState));

    t = qemu_mallocz(sizeof(DeviceType));
    t->next = device_type_list;
    device_type_list = t;
    t->info = info;
}

/* Create a new device.  This only initializes the device state structure
   and allows properties to be set.  qdev_init should be called to
   initialize the actual device emulation.  */
DeviceState *qdev_create(BusState *bus, const char *name)
{
    DeviceType *t;
    DeviceState *dev;

    for (t = device_type_list; t; t = t->next) {
        if (strcmp(t->info->name, name) == 0) {
            break;
        }
    }
    if (!t) {
        hw_error("Unknown device '%s'\n", name);
    }

    dev = qemu_mallocz(t->info->size);
    dev->type = t;

    if (!bus) {
        /* ???: This assumes system busses have no additional state.  */
        if (!main_system_bus) {
            main_system_bus = qbus_create(BUS_TYPE_SYSTEM, sizeof(BusState),
                                          NULL, "main-system-bus");
        }
        bus = main_system_bus;
    }
    if (t->info->bus_type != bus->type) {
        /* TODO: Print bus type names.  */
        hw_error("Device '%s' on wrong bus type (%d/%d)", name,
                 t->info->bus_type, bus->type);
    }
    dev->parent_bus = bus;
    LIST_INSERT_HEAD(&bus->children, dev, sibling);
    return dev;
}

/* Initialize a device.  Device properties should be set before calling
   this function.  IRQs and MMIO regions should be connected/mapped after
   calling this function.  */
void qdev_init(DeviceState *dev)
{
    dev->type->info->init(dev, dev->type->info);
}

/* Unlink device from bus and free the structure.  */
void qdev_free(DeviceState *dev)
{
    LIST_REMOVE(dev, sibling);
    free(dev);
}

static DeviceProperty *create_prop(DeviceState *dev, const char *name,
                                   DevicePropType type)
{
    DeviceProperty *prop;

    /* TODO: Check for duplicate properties.  */
    prop = qemu_mallocz(sizeof(*prop));
    prop->name = qemu_strdup(name);
    prop->type = type;
    prop->next = dev->props;
    dev->props = prop;

    return prop;
}

void qdev_set_prop_int(DeviceState *dev, const char *name, uint64_t value)
{
    DeviceProperty *prop;

    prop = create_prop(dev, name, PROP_TYPE_INT);
    prop->value.i = value;
}

void qdev_set_prop_dev(DeviceState *dev, const char *name, DeviceState *value)
{
    DeviceProperty *prop;

    prop = create_prop(dev, name, PROP_TYPE_DEV);
    prop->value.ptr = value;
}

void qdev_set_prop_ptr(DeviceState *dev, const char *name, void *value)
{
    DeviceProperty *prop;

    prop = create_prop(dev, name, PROP_TYPE_PTR);
    prop->value.ptr = value;
}

void qdev_set_netdev(DeviceState *dev, NICInfo *nd)
{
    assert(!dev->nd);
    dev->nd = nd;
}


/* Get a character (serial) device interface.  */
CharDriverState *qdev_init_chardev(DeviceState *dev)
{
    static int next_serial;
    static int next_virtconsole;
    /* FIXME: This is a nasty hack that needs to go away.  */
    if (strncmp(dev->type->info->name, "virtio", 6) == 0) {
        return virtcon_hds[next_virtconsole++];
    } else {
        return serial_hds[next_serial++];
    }
}

BusState *qdev_get_parent_bus(DeviceState *dev)
{
    return dev->parent_bus;
}

static DeviceProperty *find_prop(DeviceState *dev, const char *name,
                                 DevicePropType type)
{
    DeviceProperty *prop;

    for (prop = dev->props; prop; prop = prop->next) {
        if (strcmp(prop->name, name) == 0) {
            assert (prop->type == type);
            return prop;
        }
    }
    return NULL;
}

uint64_t qdev_get_prop_int(DeviceState *dev, const char *name, uint64_t def)
{
    DeviceProperty *prop;

    prop = find_prop(dev, name, PROP_TYPE_INT);
    if (!prop) {
        return def;
    }

    return prop->value.i;
}

void *qdev_get_prop_ptr(DeviceState *dev, const char *name)
{
    DeviceProperty *prop;

    prop = find_prop(dev, name, PROP_TYPE_PTR);
    assert(prop);
    return prop->value.ptr;
}

DeviceState *qdev_get_prop_dev(DeviceState *dev, const char *name)
{
    DeviceProperty *prop;

    prop = find_prop(dev, name, PROP_TYPE_DEV);
    if (!prop) {
        return NULL;
    }
    return prop->value.ptr;
}

void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
{
    assert(dev->num_gpio_in == 0);
    dev->num_gpio_in = n;
    dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
}

void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
{
    assert(dev->num_gpio_out == 0);
    dev->num_gpio_out = n;
    dev->gpio_out = pins;
}

qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
{
    assert(n >= 0 && n < dev->num_gpio_in);
    return dev->gpio_in[n];
}

void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
{
    assert(n >= 0 && n < dev->num_gpio_out);
    dev->gpio_out[n] = pin;
}

VLANClientState *qdev_get_vlan_client(DeviceState *dev,
                                      NetCanReceive *can_receive,
                                      NetReceive *receive,
                                      NetReceiveIOV *receive_iov,
                                      NetCleanup *cleanup,
                                      void *opaque)
{
    NICInfo *nd = dev->nd;
    assert(nd);
    return qemu_new_vlan_client(nd->vlan, nd->model, nd->name, can_receive,
                                receive, receive_iov, cleanup, opaque);
}


void qdev_get_macaddr(DeviceState *dev, uint8_t *macaddr)
{
    memcpy(macaddr, dev->nd->macaddr, 6);
}

static int next_block_unit[IF_COUNT];

/* Get a block device.  This should only be used for single-drive devices
   (e.g. SD/Floppy/MTD).  Multi-disk devices (scsi/ide) should use the
   appropriate bus.  */
BlockDriverState *qdev_init_bdrv(DeviceState *dev, BlockInterfaceType type)
{
    int unit = next_block_unit[type]++;
    int index;

    index = drive_get_index(type, 0, unit);
    if (index == -1) {
        return NULL;
    }
    return drives_table[index].bdrv;
}

BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
{
    BusState *bus;

    LIST_FOREACH(bus, &dev->child_bus, sibling) {
        if (strcmp(name, bus->name) == 0) {
            return bus;
        }
    }
    return NULL;
}

static int next_scsi_bus;

/* Create a scsi bus, and attach devices to it.  */
/* TODO: Actually create a scsi bus for hotplug to use.  */
void scsi_bus_new(DeviceState *host, SCSIAttachFn attach)
{
   int bus = next_scsi_bus++;
   int unit;
   int index;

   for (unit = 0; unit < MAX_SCSI_DEVS; unit++) {
       index = drive_get_index(IF_SCSI, bus, unit);
       if (index == -1) {
           continue;
       }
       attach(host, drives_table[index].bdrv, unit);
   }
}

BusState *qbus_create(BusType type, size_t size,
                      DeviceState *parent, const char *name)
{
    BusState *bus;

    bus = qemu_mallocz(size);
    bus->type = type;
    bus->parent = parent;
    bus->name = qemu_strdup(name);
    LIST_INIT(&bus->children);
    if (parent) {
        LIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
    }
    return bus;
}

static const char *bus_type_names[] = {
    [ BUS_TYPE_SYSTEM ] = "System",
    [ BUS_TYPE_PCI ]    = "PCI",
    [ BUS_TYPE_SCSI ]   = "SCSI",
    [ BUS_TYPE_I2C ]    = "I2C",
    [ BUS_TYPE_SSI ]    = "SSI",
};

#define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
static void qbus_print(Monitor *mon, BusState *bus, int indent);

static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
{
    DeviceProperty *prop;
    BusState *child;
    qdev_printf("dev: %s\n", dev->type->info->name);
    indent += 2;
    if (dev->num_gpio_in) {
        qdev_printf("gpio-in %d\n", dev->num_gpio_in);
    }
    if (dev->num_gpio_out) {
        qdev_printf("gpio-out %d\n", dev->num_gpio_out);
    }
    for (prop = dev->props; prop; prop = prop->next) {
        switch (prop->type) {
        case PROP_TYPE_INT:
            qdev_printf("prop-int %s 0x%" PRIx64 "\n", prop->name,
                        prop->value.i);
            break;
        case PROP_TYPE_PTR:
            qdev_printf("prop-ptr %s\n", prop->name);
            break;
        case PROP_TYPE_DEV:
            qdev_printf("prop-dev %s %s\n", prop->name,
                        ((DeviceState *)prop->value.ptr)->type->info->name);
            break;
        default:
            qdev_printf("prop-unknown%d %s\n", prop->type, prop->name);
            break;
        }
    }
    switch (dev->parent_bus->type) {
    case BUS_TYPE_SYSTEM:
        sysbus_dev_print(mon, dev, indent);
        break;
    default:
        break;
    }
    LIST_FOREACH(child, &dev->child_bus, sibling) {
        qbus_print(mon, child, indent);
    }
}

static void qbus_print(Monitor *mon, BusState *bus, int indent)
{
    struct DeviceState *dev;

    qdev_printf("bus: %s\n", bus->name);
    indent += 2;
    qdev_printf("type %s\n", bus_type_names[bus->type]);
    LIST_FOREACH(dev, &bus->children, sibling) {
        qdev_print(mon, dev, indent);
    }
}
#undef qdev_printf

void do_info_qtree(Monitor *mon)
{
    if (main_system_bus)
        qbus_print(mon, main_system_bus, 0);
}
