/*
 * QEMU PowerPC pSeries Logical Partition (aka sPAPR) hardware System Emulator
 *
 * PAPR Virtual TPM
 *
 * Copyright (c) 2015, 2017, 2019 IBM Corporation.
 *
 * Authors:
 *    Stefan Berger <stefanb@linux.vnet.ibm.com>
 *
 * This code is licensed under the GPL version 2 or later. See the
 * COPYING file in the top-level directory.
 *
 */

#include "qemu/osdep.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"

#include "sysemu/tpm_backend.h"
#include "sysemu/tpm_util.h"
#include "tpm_prop.h"

#include "hw/ppc/spapr.h"
#include "hw/ppc/spapr_vio.h"
#include "trace.h"
#include "qom/object.h"

#define DEBUG_SPAPR 0

typedef struct SpaprTpmState SpaprTpmState;
DECLARE_INSTANCE_CHECKER(SpaprTpmState, VIO_SPAPR_VTPM,
                         TYPE_TPM_SPAPR)

typedef struct TpmCrq {
    uint8_t valid;  /* 0x80: cmd; 0xc0: init crq */
                    /* 0x81-0x83: CRQ message response */
    uint8_t msg;    /* see below */
    uint16_t len;   /* len of TPM request; len of TPM response */
    uint32_t data;  /* rtce_dma_handle when sending TPM request */
    uint64_t reserved;
} TpmCrq;

#define SPAPR_VTPM_VALID_INIT_CRQ_COMMAND  0xC0
#define SPAPR_VTPM_VALID_COMMAND           0x80
#define SPAPR_VTPM_MSG_RESULT              0x80

/* msg types for valid = SPAPR_VTPM_VALID_INIT_CRQ */
#define SPAPR_VTPM_INIT_CRQ_RESULT           0x1
#define SPAPR_VTPM_INIT_CRQ_COMPLETE_RESULT  0x2

/* msg types for valid = SPAPR_VTPM_VALID_CMD */
#define SPAPR_VTPM_GET_VERSION               0x1
#define SPAPR_VTPM_TPM_COMMAND               0x2
#define SPAPR_VTPM_GET_RTCE_BUFFER_SIZE      0x3
#define SPAPR_VTPM_PREPARE_TO_SUSPEND        0x4

/* response error messages */
#define SPAPR_VTPM_VTPM_ERROR                0xff

/* error codes */
#define SPAPR_VTPM_ERR_COPY_IN_FAILED        0x3
#define SPAPR_VTPM_ERR_COPY_OUT_FAILED       0x4

#define TPM_SPAPR_BUFFER_MAX                 4096

struct SpaprTpmState {
    SpaprVioDevice vdev;

    TpmCrq crq; /* track single TPM command */

    uint8_t state;
#define SPAPR_VTPM_STATE_NONE         0
#define SPAPR_VTPM_STATE_EXECUTION    1
#define SPAPR_VTPM_STATE_COMPLETION   2

    unsigned char *buffer;

    uint32_t numbytes; /* number of bytes to deliver on resume */

    TPMBackendCmd cmd;

    TPMBackend *be_driver;
    TPMVersion be_tpm_version;

    size_t be_buffer_size;
};

/*
 * Send a request to the TPM.
 */
static void tpm_spapr_tpm_send(SpaprTpmState *s)
{
    tpm_util_show_buffer(s->buffer, s->be_buffer_size, "To TPM");

    s->state = SPAPR_VTPM_STATE_EXECUTION;
    s->cmd = (TPMBackendCmd) {
        .locty = 0,
        .in = s->buffer,
        .in_len = MIN(tpm_cmd_get_size(s->buffer), s->be_buffer_size),
        .out = s->buffer,
        .out_len = s->be_buffer_size,
    };

    tpm_backend_deliver_request(s->be_driver, &s->cmd);
}

static int tpm_spapr_process_cmd(SpaprTpmState *s, uint64_t dataptr)
{
    long rc;

    /* a max. of be_buffer_size bytes can be transported */
    rc = spapr_vio_dma_read(&s->vdev, dataptr,
                            s->buffer, s->be_buffer_size);
    if (rc) {
        error_report("tpm_spapr_got_payload: DMA read failure");
    }
    /* let vTPM handle any malformed request */
    tpm_spapr_tpm_send(s);

    return rc;
}

static inline int spapr_tpm_send_crq(struct SpaprVioDevice *dev, TpmCrq *crq)
{
    return spapr_vio_send_crq(dev, (uint8_t *)crq);
}

static int tpm_spapr_do_crq(struct SpaprVioDevice *dev, uint8_t *crq_data)
{
    SpaprTpmState *s = VIO_SPAPR_VTPM(dev);
    TpmCrq local_crq;
    TpmCrq *crq = &s->crq; /* requests only */
    int rc;
    uint8_t valid = crq_data[0];
    uint8_t msg = crq_data[1];

    trace_tpm_spapr_do_crq(valid, msg);

    switch (valid) {
    case SPAPR_VTPM_VALID_INIT_CRQ_COMMAND: /* Init command/response */

        /* Respond to initialization request */
        switch (msg) {
        case SPAPR_VTPM_INIT_CRQ_RESULT:
            trace_tpm_spapr_do_crq_crq_result();
            memset(&local_crq, 0, sizeof(local_crq));
            local_crq.valid = SPAPR_VTPM_VALID_INIT_CRQ_COMMAND;
            local_crq.msg = SPAPR_VTPM_INIT_CRQ_RESULT;
            spapr_tpm_send_crq(dev, &local_crq);
            break;

        case SPAPR_VTPM_INIT_CRQ_COMPLETE_RESULT:
            trace_tpm_spapr_do_crq_crq_complete_result();
            memset(&local_crq, 0, sizeof(local_crq));
            local_crq.valid = SPAPR_VTPM_VALID_INIT_CRQ_COMMAND;
            local_crq.msg = SPAPR_VTPM_INIT_CRQ_COMPLETE_RESULT;
            spapr_tpm_send_crq(dev, &local_crq);
            break;
        }

        break;
    case SPAPR_VTPM_VALID_COMMAND: /* Payloads */
        switch (msg) {
        case SPAPR_VTPM_TPM_COMMAND:
            trace_tpm_spapr_do_crq_tpm_command();
            if (s->state == SPAPR_VTPM_STATE_EXECUTION) {
                return H_BUSY;
            }
            memcpy(crq, crq_data, sizeof(*crq));

            rc = tpm_spapr_process_cmd(s, be32_to_cpu(crq->data));

            if (rc == H_SUCCESS) {
                crq->valid = be16_to_cpu(0);
            } else {
                local_crq.valid = SPAPR_VTPM_MSG_RESULT;
                local_crq.msg = SPAPR_VTPM_VTPM_ERROR;
                local_crq.len = cpu_to_be16(0);
                local_crq.data = cpu_to_be32(SPAPR_VTPM_ERR_COPY_IN_FAILED);
                spapr_tpm_send_crq(dev, &local_crq);
            }
            break;

        case SPAPR_VTPM_GET_RTCE_BUFFER_SIZE:
            trace_tpm_spapr_do_crq_tpm_get_rtce_buffer_size(s->be_buffer_size);
            local_crq.valid = SPAPR_VTPM_VALID_COMMAND;
            local_crq.msg = SPAPR_VTPM_GET_RTCE_BUFFER_SIZE |
                            SPAPR_VTPM_MSG_RESULT;
            local_crq.len = cpu_to_be16(s->be_buffer_size);
            spapr_tpm_send_crq(dev, &local_crq);
            break;

        case SPAPR_VTPM_GET_VERSION:
            local_crq.valid = SPAPR_VTPM_VALID_COMMAND;
            local_crq.msg = SPAPR_VTPM_GET_VERSION | SPAPR_VTPM_MSG_RESULT;
            local_crq.len = cpu_to_be16(0);
            switch (s->be_tpm_version) {
            case TPM_VERSION_1_2:
                local_crq.data = cpu_to_be32(1);
                break;
            case TPM_VERSION_2_0:
                local_crq.data = cpu_to_be32(2);
                break;
            default:
                g_assert_not_reached();
            }
            trace_tpm_spapr_do_crq_get_version(be32_to_cpu(local_crq.data));
            spapr_tpm_send_crq(dev, &local_crq);
            break;

        case SPAPR_VTPM_PREPARE_TO_SUSPEND:
            trace_tpm_spapr_do_crq_prepare_to_suspend();
            local_crq.valid = SPAPR_VTPM_VALID_COMMAND;
            local_crq.msg = SPAPR_VTPM_PREPARE_TO_SUSPEND |
                            SPAPR_VTPM_MSG_RESULT;
            spapr_tpm_send_crq(dev, &local_crq);
            break;

        default:
            trace_tpm_spapr_do_crq_unknown_msg_type(crq->msg);
        }
        break;
    default:
        trace_tpm_spapr_do_crq_unknown_crq(valid, msg);
    };

    return H_SUCCESS;
}

static void tpm_spapr_request_completed(TPMIf *ti, int ret)
{
    SpaprTpmState *s = VIO_SPAPR_VTPM(ti);
    TpmCrq *crq = &s->crq;
    uint32_t len;
    int rc;

    s->state = SPAPR_VTPM_STATE_COMPLETION;

    /* a max. of be_buffer_size bytes can be transported */
    len = MIN(tpm_cmd_get_size(s->buffer), s->be_buffer_size);

    if (runstate_check(RUN_STATE_FINISH_MIGRATE)) {
        trace_tpm_spapr_caught_response(len);
        /* defer delivery of response until .post_load */
        s->numbytes = len;
        return;
    }

    rc = spapr_vio_dma_write(&s->vdev, be32_to_cpu(crq->data),
                             s->buffer, len);

    tpm_util_show_buffer(s->buffer, len, "From TPM");

    crq->valid = SPAPR_VTPM_MSG_RESULT;
    if (rc == H_SUCCESS) {
        crq->msg = SPAPR_VTPM_TPM_COMMAND | SPAPR_VTPM_MSG_RESULT;
        crq->len = cpu_to_be16(len);
    } else {
        error_report("%s: DMA write failure", __func__);
        crq->msg = SPAPR_VTPM_VTPM_ERROR;
        crq->len = cpu_to_be16(0);
        crq->data = cpu_to_be32(SPAPR_VTPM_ERR_COPY_OUT_FAILED);
    }

    rc = spapr_tpm_send_crq(&s->vdev, crq);
    if (rc) {
        error_report("%s: Error sending response", __func__);
    }
}

static int tpm_spapr_do_startup_tpm(SpaprTpmState *s, size_t buffersize)
{
    return tpm_backend_startup_tpm(s->be_driver, buffersize);
}

static const char *tpm_spapr_get_dt_compatible(SpaprVioDevice *dev)
{
    SpaprTpmState *s = VIO_SPAPR_VTPM(dev);

    switch (s->be_tpm_version) {
    case TPM_VERSION_1_2:
        return "IBM,vtpm";
    case TPM_VERSION_2_0:
        return "IBM,vtpm20";
    default:
        g_assert_not_reached();
    }
}

static void tpm_spapr_reset(SpaprVioDevice *dev)
{
    SpaprTpmState *s = VIO_SPAPR_VTPM(dev);

    s->state = SPAPR_VTPM_STATE_NONE;
    s->numbytes = 0;

    s->be_tpm_version = tpm_backend_get_tpm_version(s->be_driver);

    s->be_buffer_size = MIN(tpm_backend_get_buffer_size(s->be_driver),
                            TPM_SPAPR_BUFFER_MAX);

    tpm_backend_reset(s->be_driver);

    if (tpm_spapr_do_startup_tpm(s, s->be_buffer_size) < 0) {
        exit(1);
    }
}

static enum TPMVersion tpm_spapr_get_version(TPMIf *ti)
{
    SpaprTpmState *s = VIO_SPAPR_VTPM(ti);

    if (tpm_backend_had_startup_error(s->be_driver)) {
        return TPM_VERSION_UNSPEC;
    }

    return tpm_backend_get_tpm_version(s->be_driver);
}

/* persistent state handling */

static int tpm_spapr_pre_save(void *opaque)
{
    SpaprTpmState *s = opaque;

    tpm_backend_finish_sync(s->be_driver);
    /*
     * we cannot deliver the results to the VM since DMA would touch VM memory
     */

    return 0;
}

static int tpm_spapr_post_load(void *opaque, int version_id)
{
    SpaprTpmState *s = opaque;

    if (s->numbytes) {
        trace_tpm_spapr_post_load();
        /* deliver the results to the VM via DMA */
        tpm_spapr_request_completed(TPM_IF(s), 0);
        s->numbytes = 0;
    }

    return 0;
}

static const VMStateDescription vmstate_spapr_vtpm = {
    .name = "tpm-spapr",
    .pre_save = tpm_spapr_pre_save,
    .post_load = tpm_spapr_post_load,
    .fields = (const VMStateField[]) {
        VMSTATE_SPAPR_VIO(vdev, SpaprTpmState),

        VMSTATE_UINT8(state, SpaprTpmState),
        VMSTATE_UINT32(numbytes, SpaprTpmState),
        VMSTATE_VBUFFER_UINT32(buffer, SpaprTpmState, 0, NULL, numbytes),
        /* remember DMA address */
        VMSTATE_UINT32(crq.data, SpaprTpmState),
        VMSTATE_END_OF_LIST(),
    }
};

static Property tpm_spapr_properties[] = {
    DEFINE_SPAPR_PROPERTIES(SpaprTpmState, vdev),
    DEFINE_PROP_TPMBE("tpmdev", SpaprTpmState, be_driver),
    DEFINE_PROP_END_OF_LIST(),
};

static void tpm_spapr_realizefn(SpaprVioDevice *dev, Error **errp)
{
    SpaprTpmState *s = VIO_SPAPR_VTPM(dev);

    if (!tpm_find()) {
        error_setg(errp, "at most one TPM device is permitted");
        return;
    }

    dev->crq.SendFunc = tpm_spapr_do_crq;

    if (!s->be_driver) {
        error_setg(errp, "'tpmdev' property is required");
        return;
    }
    s->buffer = g_malloc(TPM_SPAPR_BUFFER_MAX);
}

static void tpm_spapr_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    SpaprVioDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);
    TPMIfClass *tc = TPM_IF_CLASS(klass);

    k->realize = tpm_spapr_realizefn;
    k->reset = tpm_spapr_reset;
    k->dt_name = "vtpm";
    k->dt_type = "IBM,vtpm";
    k->get_dt_compatible = tpm_spapr_get_dt_compatible;
    k->signal_mask = 0x00000001;
    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
    device_class_set_props(dc, tpm_spapr_properties);
    k->rtce_window_size = 0x10000000;
    dc->vmsd = &vmstate_spapr_vtpm;

    tc->model = TPM_MODEL_TPM_SPAPR;
    tc->get_version = tpm_spapr_get_version;
    tc->request_completed = tpm_spapr_request_completed;
}

static const TypeInfo tpm_spapr_info = {
    .name          = TYPE_TPM_SPAPR,
    .parent        = TYPE_VIO_SPAPR_DEVICE,
    .instance_size = sizeof(SpaprTpmState),
    .class_init    = tpm_spapr_class_init,
    .interfaces = (InterfaceInfo[]) {
        { TYPE_TPM_IF },
        { }
    }
};

static void tpm_spapr_register_types(void)
{
    type_register_static(&tpm_spapr_info);
}

type_init(tpm_spapr_register_types)
