/* 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, "icc-apic-container",
                       APIC_SPACE_SIZE);
    sysbus_init_mmio(sb, &s->apic_container);
    s->icc_bus.apic_address_space = &s->apic_container;
}

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


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)
