/*
 * 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 "sysemu/tpm.h"
#include "qemu/thread.h"
#include "qemu/main-loop.h"
#include "qemu/module.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);
