1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2023 Beckhoff Automation GmbH & Co. KG 5 * Author: Corvin Köhne <corvink@FreeBSD.org> 6 */ 7 8 #include <sys/types.h> 9 10 #include <err.h> 11 #include <errno.h> 12 #include <stdlib.h> 13 #include <string.h> 14 #include <vmmapi.h> 15 16 #include "acpi_device.h" 17 #include "config.h" 18 #include "tpm_device.h" 19 20 #define TPM_ACPI_DEVICE_NAME "TPM" 21 #define TPM_ACPI_HARDWARE_ID "MSFT0101" 22 23 struct tpm_device { 24 struct vmctx *vm_ctx; 25 struct acpi_device *acpi_dev; 26 }; 27 28 static const struct acpi_device_emul tpm_acpi_device_emul = { 29 .name = TPM_ACPI_DEVICE_NAME, 30 .hid = TPM_ACPI_HARDWARE_ID, 31 }; 32 33 void 34 tpm_device_destroy(struct tpm_device *const dev) 35 { 36 if (dev == NULL) 37 return; 38 39 acpi_device_destroy(dev->acpi_dev); 40 free(dev); 41 } 42 43 int 44 tpm_device_create(struct tpm_device **const new_dev, struct vmctx *const vm_ctx, 45 nvlist_t *const nvl) 46 { 47 struct tpm_device *dev = NULL; 48 const char *value; 49 int error; 50 51 if (new_dev == NULL || vm_ctx == NULL) { 52 error = EINVAL; 53 goto err_out; 54 } 55 56 value = get_config_value_node(nvl, "version"); 57 if (value == NULL || strcmp(value, "2.0")) { 58 warnx("%s: unsupported tpm version %s", __func__, value); 59 error = EINVAL; 60 goto err_out; 61 } 62 63 dev = calloc(1, sizeof(*dev)); 64 if (dev == NULL) { 65 error = ENOMEM; 66 goto err_out; 67 } 68 69 dev->vm_ctx = vm_ctx; 70 71 error = acpi_device_create(&dev->acpi_dev, dev, dev->vm_ctx, 72 &tpm_acpi_device_emul); 73 if (error) 74 goto err_out; 75 76 *new_dev = dev; 77 78 return (0); 79 80 err_out: 81 tpm_device_destroy(dev); 82 83 return (error); 84 } 85