/*
 * IPMI SMBIOS firmware handling
 *
 * Copyright (c) 2015,2016 Corey Minyard, MontaVista Software, LLC
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"
#include "hw/ipmi/ipmi.h"
#include "hw/smbios/ipmi.h"
#include "hw/smbios/smbios.h"
#include "qemu/error-report.h"
#include "smbios_build.h"

/* SMBIOS type 38 - IPMI */
struct smbios_type_38 {
    struct smbios_structure_header header;
    uint8_t interface_type;
    uint8_t ipmi_spec_revision;
    uint8_t i2c_slave_address;
    uint8_t nv_storage_device_address;
    uint64_t base_address;
    uint8_t base_address_modifier;
    uint8_t interrupt_number;
} QEMU_PACKED;

static void smbios_build_one_type_38(IPMIFwInfo *info)
{
    uint64_t baseaddr = info->base_address;
    SMBIOS_BUILD_TABLE_PRE(38, 0x3000, true);

    t->interface_type = info->interface_type;
    t->ipmi_spec_revision = ((info->ipmi_spec_major_revision << 4)
                             | info->ipmi_spec_minor_revision);
    t->i2c_slave_address = info->i2c_slave_address;
    t->nv_storage_device_address = 0;

    assert(info->ipmi_spec_minor_revision <= 15);
    assert(info->ipmi_spec_major_revision <= 15);

    /* or 1 to set it to I/O space */
    switch (info->memspace) {
    case IPMI_MEMSPACE_IO:
        baseaddr |= 1;
        break;
    case IPMI_MEMSPACE_MEM32:
    case IPMI_MEMSPACE_MEM64:
        break;
    case IPMI_MEMSPACE_SMBUS:
        baseaddr <<= 1;
        break;
    }

    t->base_address = cpu_to_le64(baseaddr);

    t->base_address_modifier = 0;
    if (info->irq_type == IPMI_LEVEL_IRQ) {
        t->base_address_modifier |= 1;
    }
    switch (info->register_spacing) {
    case 1:
        break;
    case 4:
        t->base_address_modifier |= 1 << 6;
        break;
    case 16:
        t->base_address_modifier |= 2 << 6;
        break;
    default:
        error_report("IPMI register spacing %d is not compatible with"
                     " SMBIOS, ignoring this entry.", info->register_spacing);
        return;
    }
    t->interrupt_number = info->interrupt_number;

    SMBIOS_BUILD_TABLE_POST;
}

static void smbios_add_ipmi_devices(BusState *bus)
{
    BusChild *kid;

    QTAILQ_FOREACH(kid, &bus->children,  sibling) {
        DeviceState *dev = kid->child;
        Object *obj = object_dynamic_cast(OBJECT(dev), TYPE_IPMI_INTERFACE);
        BusState *childbus;

        if (obj) {
            IPMIInterface *ii;
            IPMIInterfaceClass *iic;
            IPMIFwInfo info;

            ii = IPMI_INTERFACE(obj);
            iic = IPMI_INTERFACE_GET_CLASS(obj);
            memset(&info, 0, sizeof(info));
            iic->get_fwinfo(ii, &info);
            smbios_build_one_type_38(&info);
            continue;
        }

        QLIST_FOREACH(childbus, &dev->child_bus, sibling) {
            smbios_add_ipmi_devices(childbus);
        }
    }
}

void smbios_build_type_38_table(void)
{
    BusState *bus;

    bus = sysbus_get_default();
    if (bus) {
        smbios_add_ipmi_devices(bus);
    }
}
