/*
 * 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"

#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);

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