4 * Copyright IBM, Corp. 2013
7 * Stefan Berger <stefanb@us.ibm.com>
9 * This work is licensed under the terms of the GNU GPL, version 2 or later.
10 * See the COPYING file in the top-level directory.
12 * Based on backends/rng.c by Anthony Liguori
15 #include "sysemu/tpm_backend.h"
16 #include "qapi/qmp/qerror.h"
17 #include "sysemu/tpm.h"
18 #include "qemu/thread.h"
19 #include "sysemu/tpm_backend_int.h"
21 enum TpmType
tpm_backend_get_type(TPMBackend
*s
)
23 TPMBackendClass
*k
= TPM_BACKEND_GET_CLASS(s
);
28 const char *tpm_backend_get_desc(TPMBackend
*s
)
30 TPMBackendClass
*k
= TPM_BACKEND_GET_CLASS(s
);
32 return k
->ops
->desc();
35 void tpm_backend_destroy(TPMBackend
*s
)
37 TPMBackendClass
*k
= TPM_BACKEND_GET_CLASS(s
);
42 int tpm_backend_init(TPMBackend
*s
, TPMState
*state
,
43 TPMRecvDataCB
*datacb
)
45 TPMBackendClass
*k
= TPM_BACKEND_GET_CLASS(s
);
47 return k
->ops
->init(s
, state
, datacb
);
50 int tpm_backend_startup_tpm(TPMBackend
*s
)
52 TPMBackendClass
*k
= TPM_BACKEND_GET_CLASS(s
);
54 return k
->ops
->startup_tpm(s
);
57 bool tpm_backend_had_startup_error(TPMBackend
*s
)
59 TPMBackendClass
*k
= TPM_BACKEND_GET_CLASS(s
);
61 return k
->ops
->had_startup_error(s
);
64 size_t tpm_backend_realloc_buffer(TPMBackend
*s
, TPMSizedBuffer
*sb
)
66 TPMBackendClass
*k
= TPM_BACKEND_GET_CLASS(s
);
68 return k
->ops
->realloc_buffer(sb
);
71 void tpm_backend_deliver_request(TPMBackend
*s
)
73 TPMBackendClass
*k
= TPM_BACKEND_GET_CLASS(s
);
75 k
->ops
->deliver_request(s
);
78 void tpm_backend_reset(TPMBackend
*s
)
80 TPMBackendClass
*k
= TPM_BACKEND_GET_CLASS(s
);
85 void tpm_backend_cancel_cmd(TPMBackend
*s
)
87 TPMBackendClass
*k
= TPM_BACKEND_GET_CLASS(s
);
89 k
->ops
->cancel_cmd(s
);
92 bool tpm_backend_get_tpm_established_flag(TPMBackend
*s
)
94 TPMBackendClass
*k
= TPM_BACKEND_GET_CLASS(s
);
96 return k
->ops
->get_tpm_established_flag(s
);
99 static bool tpm_backend_prop_get_opened(Object
*obj
, Error
**errp
)
101 TPMBackend
*s
= TPM_BACKEND(obj
);
106 void tpm_backend_open(TPMBackend
*s
, Error
**errp
)
108 object_property_set_bool(OBJECT(s
), true, "opened", errp
);
111 static void tpm_backend_prop_set_opened(Object
*obj
, bool value
, Error
**errp
)
113 TPMBackend
*s
= TPM_BACKEND(obj
);
114 TPMBackendClass
*k
= TPM_BACKEND_GET_CLASS(s
);
115 Error
*local_err
= NULL
;
117 if (value
== s
->opened
) {
121 if (!value
&& s
->opened
) {
122 error_set(errp
, QERR_PERMISSION_DENIED
);
127 k
->opened(s
, &local_err
);
129 error_propagate(errp
, local_err
);
137 static void tpm_backend_instance_init(Object
*obj
)
139 object_property_add_bool(obj
, "opened",
140 tpm_backend_prop_get_opened
,
141 tpm_backend_prop_set_opened
,
145 void tpm_backend_thread_deliver_request(TPMBackendThread
*tbt
)
147 g_thread_pool_push(tbt
->pool
, (gpointer
)TPM_BACKEND_CMD_PROCESS_CMD
, NULL
);
150 void tpm_backend_thread_create(TPMBackendThread
*tbt
,
151 GFunc func
, gpointer user_data
)
154 tbt
->pool
= g_thread_pool_new(func
, user_data
, 1, TRUE
, NULL
);
155 g_thread_pool_push(tbt
->pool
, (gpointer
)TPM_BACKEND_CMD_INIT
, NULL
);
159 void tpm_backend_thread_end(TPMBackendThread
*tbt
)
162 g_thread_pool_push(tbt
->pool
, (gpointer
)TPM_BACKEND_CMD_END
, NULL
);
163 g_thread_pool_free(tbt
->pool
, FALSE
, TRUE
);
168 void tpm_backend_thread_tpm_reset(TPMBackendThread
*tbt
,
169 GFunc func
, gpointer user_data
)
172 tpm_backend_thread_create(tbt
, func
, user_data
);
174 g_thread_pool_push(tbt
->pool
, (gpointer
)TPM_BACKEND_CMD_TPM_RESET
,
179 static const TypeInfo tpm_backend_info
= {
180 .name
= TYPE_TPM_BACKEND
,
181 .parent
= TYPE_OBJECT
,
182 .instance_size
= sizeof(TPMBackend
),
183 .instance_init
= tpm_backend_instance_init
,
184 .class_size
= sizeof(TPMBackendClass
),
188 static void register_types(void)
190 type_register_static(&tpm_backend_info
);
193 type_init(register_types
);