/* icc_bus.c
 * emulate x86 ICC (Interrupt Controller Communications) bus
 *
 * Copyright (c) 2013 Red Hat, Inc
 *
 * Authors:
 *     Igor Mammedov <imammedo@redhat.com>
 *
 * 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, see <http://www.gnu.org/licenses/>
 */
#include "hw/cpu/icc_bus.h"
#include "hw/sysbus.h"

/* icc-bridge implementation */

static void icc_bus_init(Object *obj)
{
    BusState *b = BUS(obj);

    b->allow_hotplug = true;
}

static const TypeInfo icc_bus_info = {
    .name = TYPE_ICC_BUS,
    .parent = TYPE_BUS,
    .instance_size = sizeof(ICCBus),
    .instance_init = icc_bus_init,
};


/* icc-device implementation */

static void icc_device_realize(DeviceState *dev, Error **errp)
{
    ICCDevice *id = ICC_DEVICE(dev);
    ICCDeviceClass *idc = ICC_DEVICE_GET_CLASS(id);

    if (idc->init) {
        if (idc->init(id) < 0) {
            error_setg(errp, "%s initialization failed.",
                       object_get_typename(OBJECT(dev)));
        }
    }
}

static void icc_device_class_init(ObjectClass *oc, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(oc);

    dc->realize = icc_device_realize;
    dc->bus_type = TYPE_ICC_BUS;
}

static const TypeInfo icc_device_info = {
    .name = TYPE_ICC_DEVICE,
    .parent = TYPE_DEVICE,
    .abstract = true,
    .instance_size = sizeof(ICCDevice),
    .class_size = sizeof(ICCDeviceClass),
    .class_init = icc_device_class_init,
};


/*  icc-bridge implementation */

typedef struct ICCBridgeState {
    /*< private >*/
    SysBusDevice parent_obj;
    /*< public >*/

    ICCBus icc_bus;
    MemoryRegion apic_container;
} ICCBridgeState;

#define ICC_BRIGDE(obj) OBJECT_CHECK(ICCBridgeState, (obj), TYPE_ICC_BRIDGE)

static void icc_bridge_init(Object *obj)
{
    ICCBridgeState *s = ICC_BRIGDE(obj);
    SysBusDevice *sb = SYS_BUS_DEVICE(obj);

    qbus_create_inplace(&s->icc_bus, TYPE_ICC_BUS, DEVICE(s), "icc");

    /* Do not change order of registering regions,
     * APIC must be first registered region, board maps it by 0 index
     */
    memory_region_init(&s->apic_container, obj, "icc-apic-container",
                       APIC_SPACE_SIZE);
    sysbus_init_mmio(sb, &s->apic_container);
    s->icc_bus.apic_address_space = &s->apic_container;
}

static void icc_bridge_class_init(ObjectClass *oc, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(oc);

    set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
}

static const TypeInfo icc_bridge_info = {
    .name  = TYPE_ICC_BRIDGE,
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_init  = icc_bridge_init,
    .instance_size  = sizeof(ICCBridgeState),
    .class_init = icc_bridge_class_init,
};


static void icc_bus_register_types(void)
{
    type_register_static(&icc_bus_info);
    type_register_static(&icc_device_info);
    type_register_static(&icc_bridge_info);
}

type_init(icc_bus_register_types)
