/*
 * 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 "tpm_int.h"
#include "tpm_util.h"

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

#define DEBUG_SPAPR 0

#define VIO_SPAPR_VTPM(obj) \
     OBJECT_CHECK(SpaprTpmState, (obj), 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

typedef struct {
    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;
} SpaprTpmState;

/*
 * Send a request to the TPM.
 */
static void tpm_spapr_tpm_send(SpaprTpmState *s)
{
    if (trace_event_get_state_backends(TRACE_TPM_SPAPR_SHOW_BUFFER)) {
        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();
                break;
            }
            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);

    if (trace_event_get_state_backends(TRACE_TPM_SPAPR_SHOW_BUFFER)) {
        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);
    tpm_spapr_do_startup_tpm(s, s->be_buffer_size);
}

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 = (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)
