/*
 * CXL CDAT Structure
 *
 * Copyright (C) 2021 Avery Design Systems, Inc.
 *
 * 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/pci/pci.h"
#include "hw/cxl/cxl.h"
#include "qapi/error.h"
#include "qemu/error-report.h"

static void cdat_len_check(CDATSubHeader *hdr, Error **errp)
{
    assert(hdr->length);
    assert(hdr->reserved == 0);

    switch (hdr->type) {
    case CDAT_TYPE_DSMAS:
        assert(hdr->length == sizeof(CDATDsmas));
        break;
    case CDAT_TYPE_DSLBIS:
        assert(hdr->length == sizeof(CDATDslbis));
        break;
    case CDAT_TYPE_DSMSCIS:
        assert(hdr->length == sizeof(CDATDsmscis));
        break;
    case CDAT_TYPE_DSIS:
        assert(hdr->length == sizeof(CDATDsis));
        break;
    case CDAT_TYPE_DSEMTS:
        assert(hdr->length == sizeof(CDATDsemts));
        break;
    case CDAT_TYPE_SSLBIS:
        assert(hdr->length >= sizeof(CDATSslbisHeader));
        assert((hdr->length - sizeof(CDATSslbisHeader)) %
               sizeof(CDATSslbe) == 0);
        break;
    default:
        error_setg(errp, "Type %d is reserved", hdr->type);
    }
}

static bool ct3_build_cdat(CDATObject *cdat, Error **errp)
{
    g_autofree CDATTableHeader *cdat_header = NULL;
    g_autofree CDATEntry *cdat_st = NULL;
    uint8_t sum = 0;
    uint8_t *hdr_buf;
    int ent, i;

    /* Use default table if fopen == NULL */
    assert(cdat->build_cdat_table);

    cdat_header = g_malloc0(sizeof(*cdat_header));
    if (!cdat_header) {
        error_setg(errp, "Failed to allocate CDAT header");
        return false;
    }

    cdat->built_buf_len = cdat->build_cdat_table(&cdat->built_buf,
                                                 cdat->private);

    if (cdat->built_buf_len <= 0) {
        /* Build later as not all data available yet */
        cdat->to_update = true;
        return true;
    }
    cdat->to_update = false;

    cdat_st = g_malloc0(sizeof(*cdat_st) * (cdat->built_buf_len + 1));
    if (!cdat_st) {
        error_setg(errp, "Failed to allocate CDAT entry array");
        return false;
    }

    /* Entry 0 for CDAT header, starts with Entry 1 */
    for (ent = 1; ent < cdat->built_buf_len + 1; ent++) {
        CDATSubHeader *hdr = cdat->built_buf[ent - 1];
        uint8_t *buf = (uint8_t *)cdat->built_buf[ent - 1];

        cdat_st[ent].base = hdr;
        cdat_st[ent].length = hdr->length;

        cdat_header->length += hdr->length;
        for (i = 0; i < hdr->length; i++) {
            sum += buf[i];
        }
    }

    /* CDAT header */
    cdat_header->revision = CXL_CDAT_REV;
    /* For now, no runtime updates */
    cdat_header->sequence = 0;
    cdat_header->length += sizeof(CDATTableHeader);

    hdr_buf = (uint8_t *)cdat_header;
    for (i = 0; i < sizeof(*cdat_header); i++) {
        sum += hdr_buf[i];
    }

    /* Sum of all bytes including checksum must be 0 */
    cdat_header->checksum = ~sum + 1;

    cdat_st[0].base = g_steal_pointer(&cdat_header);
    cdat_st[0].length = sizeof(*cdat_header);
    cdat->entry_len = 1 + cdat->built_buf_len;
    cdat->entry = g_steal_pointer(&cdat_st);
    return true;
}

static bool ct3_load_cdat(CDATObject *cdat, Error **errp)
{
    g_autofree CDATEntry *cdat_st = NULL;
    g_autofree uint8_t *buf = NULL;
    uint8_t sum = 0;
    int num_ent;
    int i = 0, ent = 1;
    gsize file_size = 0;
    CDATSubHeader *hdr;
    GError *error = NULL;

    /* Read CDAT file and create its cache */
    if (!g_file_get_contents(cdat->filename, (gchar **)&buf,
                             &file_size, &error)) {
        error_setg(errp, "CDAT: File read failed: %s", error->message);
        g_error_free(error);
        return false;
    }
    if (file_size < sizeof(CDATTableHeader)) {
        error_setg(errp, "CDAT: File too short");
        return false;
    }
    i = sizeof(CDATTableHeader);
    num_ent = 1;
    while (i < file_size) {
        hdr = (CDATSubHeader *)(buf + i);
        if (i + sizeof(CDATSubHeader) > file_size) {
            error_setg(errp, "CDAT: Truncated table");
            return false;
        }
        cdat_len_check(hdr, errp);
        i += hdr->length;
        if (i > file_size) {
            error_setg(errp, "CDAT: Truncated table");
            return false;
        }
        num_ent++;
    }
    if (i != file_size) {
        error_setg(errp, "CDAT: File length mismatch");
        return false;
    }

    cdat_st = g_new0(CDATEntry, num_ent);

    /* Set CDAT header, Entry = 0 */
    cdat_st[0].base = buf;
    cdat_st[0].length = sizeof(CDATTableHeader);
    i = 0;

    while (i < cdat_st[0].length) {
        sum += buf[i++];
    }

    /* Read CDAT structures */
    while (i < file_size) {
        hdr = (CDATSubHeader *)(buf + i);
        cdat_st[ent].base = hdr;
        cdat_st[ent].length = hdr->length;

        while (buf + i < (uint8_t *)cdat_st[ent].base + cdat_st[ent].length) {
            assert(i < file_size);
            sum += buf[i++];
        }

        ent++;
    }

    if (sum != 0) {
        warn_report("CDAT: Found checksum mismatch in %s", cdat->filename);
    }
    cdat->entry_len = num_ent;
    cdat->entry = g_steal_pointer(&cdat_st);
    cdat->buf = g_steal_pointer(&buf);
    return true;
}

bool cxl_doe_cdat_init(CXLComponentState *cxl_cstate, Error **errp)
{
    CDATObject *cdat = &cxl_cstate->cdat;

    if (cdat->filename) {
        return ct3_load_cdat(cdat, errp);
    } else {
        return ct3_build_cdat(cdat, errp);
    }
}

void cxl_doe_cdat_update(CXLComponentState *cxl_cstate, Error **errp)
{
    CDATObject *cdat = &cxl_cstate->cdat;

    if (cdat->to_update) {
        ct3_build_cdat(cdat, errp);
    }
}

void cxl_doe_cdat_release(CXLComponentState *cxl_cstate)
{
    CDATObject *cdat = &cxl_cstate->cdat;

    free(cdat->entry);
    if (cdat->built_buf) {
        cdat->free_cdat_table(cdat->built_buf, cdat->built_buf_len,
                              cdat->private);
    }
    g_free(cdat->buf);
}
