/*
 * QEMU TPM Backend
 *
 * Copyright IBM, Corp. 2013
 *
 * Authors:
 *  Stefan Berger   <stefanb@us.ibm.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 *
 * Based on backends/rng.c by Anthony Liguori
 */

#include "qemu/osdep.h"
#include "sysemu/tpm_backend.h"
#include "qapi/error.h"
#include "qapi/qmp/qerror.h"
#include "sysemu/tpm.h"
#include "qemu/thread.h"
#include "qemu/main-loop.h"
#include "block/thread-pool.h"
#include "qemu/error-report.h"

static void tpm_backend_request_completed(void *opaque, int ret)
{
    TPMBackend *s = TPM_BACKEND(opaque);
    TPMIfClass *tic = TPM_IF_GET_CLASS(s->tpmif);

    tic->request_completed(s->tpmif, ret);

    /* no need for atomic, as long the BQL is taken */
    s->cmd = NULL;
    object_unref(OBJECT(s));
}

static int tpm_backend_worker_thread(gpointer data)
{
    TPMBackend *s = TPM_BACKEND(data);
    TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);
    Error *err = NULL;

    k->handle_request(s, s->cmd, &err);
    if (err) {
        error_report_err(err);
        return -1;
    }

    return 0;
}

void tpm_backend_finish_sync(TPMBackend *s)
{
    while (s->cmd) {
        aio_poll(qemu_get_aio_context(), true);
    }
}

enum TpmType tpm_backend_get_type(TPMBackend *s)
{
    TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);

    return k->type;
}

int tpm_backend_init(TPMBackend *s, TPMIf *tpmif, Error **errp)
{
    if (s->tpmif) {
        error_setg(errp, "TPM backend '%s' is already initialized", s->id);
        return -1;
    }

    s->tpmif = tpmif;
    object_ref(OBJECT(tpmif));

    s->had_startup_error = false;

    return 0;
}

int tpm_backend_startup_tpm(TPMBackend *s, size_t buffersize)
{
    int res = 0;
    TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);

    /* terminate a running TPM */
    tpm_backend_finish_sync(s);

    res = k->startup_tpm ? k->startup_tpm(s, buffersize) : 0;

    s->had_startup_error = (res != 0);

    return res;
}

bool tpm_backend_had_startup_error(TPMBackend *s)
{
    return s->had_startup_error;
}

void tpm_backend_deliver_request(TPMBackend *s, TPMBackendCmd *cmd)
{
    ThreadPool *pool = aio_get_thread_pool(qemu_get_aio_context());

    if (s->cmd != NULL) {
        error_report("There is a TPM request pending");
        return;
    }

    s->cmd = cmd;
    object_ref(OBJECT(s));
    thread_pool_submit_aio(pool, tpm_backend_worker_thread, s,
                           tpm_backend_request_completed, s);
}

void tpm_backend_reset(TPMBackend *s)
{
    TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);

    if (k->reset) {
        k->reset(s);
    }

    tpm_backend_finish_sync(s);

    s->had_startup_error = false;
}

void tpm_backend_cancel_cmd(TPMBackend *s)
{
    TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);

    k->cancel_cmd(s);
}

bool tpm_backend_get_tpm_established_flag(TPMBackend *s)
{
    TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);

    return k->get_tpm_established_flag ?
           k->get_tpm_established_flag(s) : false;
}

int tpm_backend_reset_tpm_established_flag(TPMBackend *s, uint8_t locty)
{
    TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);

    return k->reset_tpm_established_flag ?
           k->reset_tpm_established_flag(s, locty) : 0;
}

TPMVersion tpm_backend_get_tpm_version(TPMBackend *s)
{
    TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);

    return k->get_tpm_version(s);
}

size_t tpm_backend_get_buffer_size(TPMBackend *s)
{
    TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);

    return k->get_buffer_size(s);
}

TPMInfo *tpm_backend_query_tpm(TPMBackend *s)
{
    TPMInfo *info = g_new0(TPMInfo, 1);
    TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);
    TPMIfClass *tic = TPM_IF_GET_CLASS(s->tpmif);

    info->id = g_strdup(s->id);
    info->model = tic->model;
    info->options = k->get_tpm_options(s);

    return info;
}

static void tpm_backend_instance_finalize(Object *obj)
{
    TPMBackend *s = TPM_BACKEND(obj);

    object_unref(OBJECT(s->tpmif));
    g_free(s->id);
}

static const TypeInfo tpm_backend_info = {
    .name = TYPE_TPM_BACKEND,
    .parent = TYPE_OBJECT,
    .instance_size = sizeof(TPMBackend),
    .instance_finalize = tpm_backend_instance_finalize,
    .class_size = sizeof(TPMBackendClass),
    .abstract = true,
};

static const TypeInfo tpm_if_info = {
    .name = TYPE_TPM_IF,
    .parent = TYPE_INTERFACE,
    .class_size = sizeof(TPMIfClass),
};

static void register_types(void)
{
    type_register_static(&tpm_backend_info);
    type_register_static(&tpm_if_info);
}

type_init(register_types);
