/*
 * 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/firmware/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));
            if (!iic->get_fwinfo) {
                continue;
            }
            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);
    }
}
