/*
 * QEMU PowerNV, BMC related functions
 *
 * Copyright (c) 2016-2017, IBM Corporation.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License, version 2, as
 * published by the Free Software Foundation.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "qapi/error.h"
#include "target/ppc/cpu.h"
#include "qemu/log.h"
#include "hw/ipmi/ipmi.h"
#include "hw/ppc/fdt.h"

#include "hw/ppc/pnv.h"

#include <libfdt.h>

/* TODO: include definition in ipmi.h */
#define IPMI_SDR_FULL_TYPE 1

/*
 * OEM SEL Event data packet sent by BMC in response of a Read Event
 * Message Buffer command
 */
typedef struct OemSel {
    /* SEL header */
    uint8_t id[2];
    uint8_t type;
    uint8_t timestamp[4];
    uint8_t manuf_id[3];

    /* OEM SEL data (6 bytes) follows */
    uint8_t netfun;
    uint8_t cmd;
    uint8_t data[4];
} OemSel;

#define SOFT_OFF        0x00
#define SOFT_REBOOT     0x01

static bool pnv_bmc_is_simulator(IPMIBmc *bmc)
{
    return object_dynamic_cast(OBJECT(bmc), TYPE_IPMI_BMC_SIMULATOR);
}

static void pnv_gen_oem_sel(IPMIBmc *bmc, uint8_t reboot)
{
    /* IPMI SEL Event are 16 bytes long */
    OemSel sel = {
        .id        = { 0x55 , 0x55 },
        .type      = 0xC0, /* OEM */
        .manuf_id  = { 0x0, 0x0, 0x0 },
        .timestamp = { 0x0, 0x0, 0x0, 0x0 },
        .netfun    = 0x3A, /* IBM */
        .cmd       = 0x04, /* AMI OEM SEL Power Notification */
        .data      = { reboot, 0xFF, 0xFF, 0xFF },
    };

    ipmi_bmc_gen_event(bmc, (uint8_t *) &sel, 0 /* do not log the event */);
}

void pnv_bmc_powerdown(IPMIBmc *bmc)
{
    pnv_gen_oem_sel(bmc, SOFT_OFF);
}

void pnv_dt_bmc_sensors(IPMIBmc *bmc, void *fdt)
{
    int offset;
    int i;
    const struct ipmi_sdr_compact *sdr;
    uint16_t nextrec;

    if (!pnv_bmc_is_simulator(bmc)) {
        return;
    }

    offset = fdt_add_subnode(fdt, 0, "bmc");
    _FDT(offset);

    _FDT((fdt_setprop_string(fdt, offset, "name", "bmc")));
    offset = fdt_add_subnode(fdt, offset, "sensors");
    _FDT(offset);

    _FDT((fdt_setprop_cell(fdt, offset, "#address-cells", 0x1)));
    _FDT((fdt_setprop_cell(fdt, offset, "#size-cells", 0x0)));

    for (i = 0; !ipmi_bmc_sdr_find(bmc, i, &sdr, &nextrec); i++) {
        int off;
        char *name;

        if (sdr->header.rec_type != IPMI_SDR_COMPACT_TYPE &&
            sdr->header.rec_type != IPMI_SDR_FULL_TYPE) {
            continue;
        }

        name = g_strdup_printf("sensor@%x", sdr->sensor_owner_number);
        off = fdt_add_subnode(fdt, offset, name);
        _FDT(off);
        g_free(name);

        _FDT((fdt_setprop_cell(fdt, off, "reg", sdr->sensor_owner_number)));
        _FDT((fdt_setprop_string(fdt, off, "name", "sensor")));
        _FDT((fdt_setprop_string(fdt, off, "compatible", "ibm,ipmi-sensor")));
        _FDT((fdt_setprop_cell(fdt, off, "ipmi-sensor-reading-type",
                               sdr->reading_type)));
        _FDT((fdt_setprop_cell(fdt, off, "ipmi-entity-id",
                               sdr->entity_id)));
        _FDT((fdt_setprop_cell(fdt, off, "ipmi-entity-instance",
                               sdr->entity_instance)));
        _FDT((fdt_setprop_cell(fdt, off, "ipmi-sensor-type",
                               sdr->sensor_type)));
    }
}

/*
 * HIOMAP protocol handler
 */
#define HIOMAP_C_RESET                  1
#define HIOMAP_C_GET_INFO               2
#define HIOMAP_C_GET_FLASH_INFO         3
#define HIOMAP_C_CREATE_READ_WINDOW     4
#define HIOMAP_C_CLOSE_WINDOW           5
#define HIOMAP_C_CREATE_WRITE_WINDOW    6
#define HIOMAP_C_MARK_DIRTY             7
#define HIOMAP_C_FLUSH                  8
#define HIOMAP_C_ACK                    9
#define HIOMAP_C_ERASE                  10
#define HIOMAP_C_DEVICE_NAME            11
#define HIOMAP_C_LOCK                   12

#define BLOCK_SHIFT                     12 /* 4K */

static uint16_t bytes_to_blocks(uint32_t bytes)
{
    return bytes >> BLOCK_SHIFT;
}

static uint32_t blocks_to_bytes(uint16_t blocks)
{
    return blocks << BLOCK_SHIFT;
}

static int hiomap_erase(PnvPnor *pnor, uint32_t offset, uint32_t size)
{
    MemTxResult result;
    int i;

    for (i = 0; i < size / 4; i++) {
        result = memory_region_dispatch_write(&pnor->mmio, offset + i * 4,
                                              0xFFFFFFFF, MO_32,
                                              MEMTXATTRS_UNSPECIFIED);
        if (result != MEMTX_OK) {
            return -1;
        }
    }
    return 0;
}

static void hiomap_cmd(IPMIBmcSim *ibs, uint8_t *cmd, unsigned int cmd_len,
                       RspBuffer *rsp)
{
    PnvPnor *pnor = PNV_PNOR(object_property_get_link(OBJECT(ibs), "pnor",
                                                      &error_abort));
    uint32_t pnor_addr = pnor->lpc_address;
    uint32_t pnor_size = pnor->size;
    bool readonly = false;

    rsp_buffer_push(rsp, cmd[2]);
    rsp_buffer_push(rsp, cmd[3]);

    switch (cmd[2]) {
    case HIOMAP_C_MARK_DIRTY:
    case HIOMAP_C_FLUSH:
    case HIOMAP_C_ACK:
        break;

    case HIOMAP_C_ERASE:
        if (hiomap_erase(pnor, blocks_to_bytes(cmd[5] << 8 | cmd[4]),
                        blocks_to_bytes(cmd[7] << 8 | cmd[6]))) {
            rsp_buffer_set_error(rsp, IPMI_CC_UNSPECIFIED);
        }
        break;

    case HIOMAP_C_GET_INFO:
        rsp_buffer_push(rsp, 2);  /* Version 2 */
        rsp_buffer_push(rsp, BLOCK_SHIFT); /* block size */
        rsp_buffer_push(rsp, 0);  /* Timeout */
        rsp_buffer_push(rsp, 0);  /* Timeout */
        break;

    case HIOMAP_C_GET_FLASH_INFO:
        rsp_buffer_push(rsp, bytes_to_blocks(pnor_size) & 0xFF);
        rsp_buffer_push(rsp, bytes_to_blocks(pnor_size) >> 8);
        rsp_buffer_push(rsp, 0x01);  /* erase size */
        rsp_buffer_push(rsp, 0x00);  /* erase size */
        break;

    case HIOMAP_C_CREATE_READ_WINDOW:
        readonly = true;
        /* Fall through */

    case HIOMAP_C_CREATE_WRITE_WINDOW:
        memory_region_set_readonly(&pnor->mmio, readonly);
        memory_region_set_enabled(&pnor->mmio, true);

        rsp_buffer_push(rsp, bytes_to_blocks(pnor_addr) & 0xFF);
        rsp_buffer_push(rsp, bytes_to_blocks(pnor_addr) >> 8);
        rsp_buffer_push(rsp, bytes_to_blocks(pnor_size) & 0xFF);
        rsp_buffer_push(rsp, bytes_to_blocks(pnor_size) >> 8);
        rsp_buffer_push(rsp, 0x00); /* offset */
        rsp_buffer_push(rsp, 0x00); /* offset */
        break;

    case HIOMAP_C_CLOSE_WINDOW:
        memory_region_set_enabled(&pnor->mmio, false);
        break;

    case HIOMAP_C_DEVICE_NAME:
    case HIOMAP_C_RESET:
    case HIOMAP_C_LOCK:
    default:
        qemu_log_mask(LOG_GUEST_ERROR, "HIOMAP: unknown command %02X\n", cmd[2]);
        break;
    }
}

#define HIOMAP   0x5a

static const IPMICmdHandler hiomap_cmds[] = {
    [HIOMAP] = { hiomap_cmd, 3 },
};

static const IPMINetfn hiomap_netfn = {
    .cmd_nums = ARRAY_SIZE(hiomap_cmds),
    .cmd_handlers = hiomap_cmds
};


void pnv_bmc_set_pnor(IPMIBmc *bmc, PnvPnor *pnor)
{
    uint32_t pnor_addr = pnor->lpc_address;
    uint32_t pnor_size = pnor->size;

    if (!pnv_bmc_is_simulator(bmc)) {
        return;
    }

    /*
     * The HIOMAP protocol uses block units and 16-bit addressing.
     * Prevent overflow or misalign.
     */
    if (pnor_addr >= 1U << (BLOCK_SHIFT + 16)) {
        warn_report("PNOR address is larger than 2^%d, disabling PNOR",
                    BLOCK_SHIFT + 16);
        return;
    }
    if (pnor_addr & ((1U << BLOCK_SHIFT) - 1)) {
        warn_report("PNOR address is not aligned to 2^%d, disabling PNOR",
                    BLOCK_SHIFT);
        return;
    }
    if (pnor_size > 1U << (BLOCK_SHIFT + 16)) {
        warn_report("PNOR size is larger than 2^%d, disabling PNOR",
                    BLOCK_SHIFT + 16);
        return;
    }
    if (pnor_size & ((1U << BLOCK_SHIFT) - 1)) {
        warn_report("PNOR size is not aligned to 2^%d, disabling PNOR",
                    BLOCK_SHIFT);
        return;
    }

    object_ref(OBJECT(pnor));
    object_property_add_const_link(OBJECT(bmc), "pnor", OBJECT(pnor));

    /* Install the HIOMAP protocol handlers to access the PNOR */
    ipmi_sim_register_netfn(IPMI_BMC_SIMULATOR(bmc), IPMI_NETFN_OEM,
                            &hiomap_netfn);
}

/*
 * Instantiate the machine BMC. PowerNV uses the QEMU internal
 * simulator but it could also be external.
 */
IPMIBmc *pnv_bmc_create(PnvPnor *pnor)
{
    DeviceState *dev;

    dev = qdev_new(TYPE_IPMI_BMC_SIMULATOR);
    qdev_realize(dev, NULL, &error_fatal);
    pnv_bmc_set_pnor(IPMI_BMC(dev), pnor);

    return IPMI_BMC(dev);
}

typedef struct ForeachArgs {
    const char *name;
    Object *obj;
} ForeachArgs;

static int bmc_find(Object *child, void *opaque)
{
    ForeachArgs *args = opaque;

    if (object_dynamic_cast(child, args->name)) {
        if (args->obj) {
            return 1;
        }
        args->obj = child;
    }
    return 0;
}

IPMIBmc *pnv_bmc_find(Error **errp)
{
    ForeachArgs args = { TYPE_IPMI_BMC, NULL };
    int ret;

    ret = object_child_foreach_recursive(object_get_root(), bmc_find, &args);
    if (ret) {
        error_setg(errp, "machine should have only one BMC device. "
                   "Use '-nodefaults'");
        return NULL;
    }

    return args.obj ? IPMI_BMC(args.obj) : NULL;
}
