1a2d5ed94SMarcin Wojtas /*- 2a2d5ed94SMarcin Wojtas * Copyright (c) 2018 Stormshield. 3a2d5ed94SMarcin Wojtas * Copyright (c) 2018 Semihalf. 4a2d5ed94SMarcin Wojtas * All rights reserved. 5a2d5ed94SMarcin Wojtas * 6a2d5ed94SMarcin Wojtas * Redistribution and use in source and binary forms, with or without 7a2d5ed94SMarcin Wojtas * modification, are permitted provided that the following conditions 8a2d5ed94SMarcin Wojtas * are met: 9a2d5ed94SMarcin Wojtas * 1. Redistributions of source code must retain the above copyright 10a2d5ed94SMarcin Wojtas * notice, this list of conditions and the following disclaimer. 11a2d5ed94SMarcin Wojtas * 2. Redistributions in binary form must reproduce the above copyright 12a2d5ed94SMarcin Wojtas * notice, this list of conditions and the following disclaimer in the 13a2d5ed94SMarcin Wojtas * documentation and/or other materials provided with the distribution. 14a2d5ed94SMarcin Wojtas * 15a2d5ed94SMarcin Wojtas * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16a2d5ed94SMarcin Wojtas * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17a2d5ed94SMarcin Wojtas * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18a2d5ed94SMarcin Wojtas * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 19a2d5ed94SMarcin Wojtas * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20a2d5ed94SMarcin Wojtas * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21a2d5ed94SMarcin Wojtas * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22a2d5ed94SMarcin Wojtas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 23a2d5ed94SMarcin Wojtas * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 24a2d5ed94SMarcin Wojtas * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25a2d5ed94SMarcin Wojtas * POSSIBILITY OF SUCH DAMAGE. 26a2d5ed94SMarcin Wojtas */ 27a2d5ed94SMarcin Wojtas 28a2d5ed94SMarcin Wojtas #ifndef _TPM20_H_ 29a2d5ed94SMarcin Wojtas #define _TPM20_H_ 30a2d5ed94SMarcin Wojtas 31a2d5ed94SMarcin Wojtas #include <sys/cdefs.h> 32a2d5ed94SMarcin Wojtas __FBSDID("$FreeBSD$"); 33a2d5ed94SMarcin Wojtas 34a2d5ed94SMarcin Wojtas #include <sys/endian.h> 35a2d5ed94SMarcin Wojtas #include <sys/param.h> 36a2d5ed94SMarcin Wojtas #include <sys/kernel.h> 37a2d5ed94SMarcin Wojtas #include <sys/malloc.h> 38a2d5ed94SMarcin Wojtas #include <sys/proc.h> 39a2d5ed94SMarcin Wojtas #include <sys/systm.h> 40a2d5ed94SMarcin Wojtas 41a2d5ed94SMarcin Wojtas #include <sys/bus.h> 42a2d5ed94SMarcin Wojtas #include <sys/callout.h> 43a2d5ed94SMarcin Wojtas #include <sys/conf.h> 44a2d5ed94SMarcin Wojtas #include <sys/module.h> 45a2d5ed94SMarcin Wojtas #include <sys/rman.h> 46a2d5ed94SMarcin Wojtas #include <sys/sx.h> 47a2d5ed94SMarcin Wojtas #include <sys/uio.h> 48a2d5ed94SMarcin Wojtas 49a2d5ed94SMarcin Wojtas #include <machine/bus.h> 50a2d5ed94SMarcin Wojtas #include <machine/md_var.h> 51a2d5ed94SMarcin Wojtas #include <machine/resource.h> 52a2d5ed94SMarcin Wojtas 53a2d5ed94SMarcin Wojtas #include <contrib/dev/acpica/include/acpi.h> 54a2d5ed94SMarcin Wojtas #include <contrib/dev/acpica/include/accommon.h> 55a2d5ed94SMarcin Wojtas #include <dev/acpica/acpivar.h> 56a2d5ed94SMarcin Wojtas #include "opt_acpi.h" 57a2d5ed94SMarcin Wojtas 58*4ee7d3b0SMarcin Wojtas #include "opt_tpm.h" 59*4ee7d3b0SMarcin Wojtas 60a2d5ed94SMarcin Wojtas #define BIT(x) (1 << (x)) 61a2d5ed94SMarcin Wojtas 62a2d5ed94SMarcin Wojtas /* Timeouts in us */ 63a2d5ed94SMarcin Wojtas #define TPM_TIMEOUT_A 750000 64a2d5ed94SMarcin Wojtas #define TPM_TIMEOUT_B 2000000 65a2d5ed94SMarcin Wojtas #define TPM_TIMEOUT_C 200000 66a2d5ed94SMarcin Wojtas #define TPM_TIMEOUT_D 30000 67a2d5ed94SMarcin Wojtas 68a2d5ed94SMarcin Wojtas /* 69a2d5ed94SMarcin Wojtas * Generating RSA key pair takes ~(10-20s), which is significantly longer than 70a2d5ed94SMarcin Wojtas * any timeout defined in spec. Because of that we need a new one. 71a2d5ed94SMarcin Wojtas */ 72a2d5ed94SMarcin Wojtas #define TPM_TIMEOUT_LONG 40000000 73a2d5ed94SMarcin Wojtas 74a2d5ed94SMarcin Wojtas /* List of commands that require TPM_TIMEOUT_LONG time to complete */ 75a2d5ed94SMarcin Wojtas #define TPM_CC_CreatePrimary 0x00000131 76a2d5ed94SMarcin Wojtas #define TPM_CC_Create 0x00000153 77a2d5ed94SMarcin Wojtas #define TPM_CC_CreateLoaded 0x00000191 78a2d5ed94SMarcin Wojtas 79a2d5ed94SMarcin Wojtas /* List of commands that require only TPM_TIMEOUT_C time to complete */ 80a2d5ed94SMarcin Wojtas #define TPM_CC_SequenceComplete 0x0000013e 81a2d5ed94SMarcin Wojtas #define TPM_CC_Startup 0x00000144 82a2d5ed94SMarcin Wojtas #define TPM_CC_SequenceUpdate 0x0000015c 83a2d5ed94SMarcin Wojtas #define TPM_CC_GetCapability 0x0000017a 84a2d5ed94SMarcin Wojtas #define TPM_CC_PCR_Extend 0x00000182 85a2d5ed94SMarcin Wojtas #define TPM_CC_EventSequenceComplete 0x00000185 86a2d5ed94SMarcin Wojtas #define TPM_CC_HashSequenceStart 0x00000186 87a2d5ed94SMarcin Wojtas 88a2d5ed94SMarcin Wojtas /* Timeout before data in read buffer is discarded */ 89a2d5ed94SMarcin Wojtas #define TPM_READ_TIMEOUT 500000 90a2d5ed94SMarcin Wojtas 91a2d5ed94SMarcin Wojtas #define TPM_BUFSIZE 0x1000 92a2d5ed94SMarcin Wojtas 93a2d5ed94SMarcin Wojtas #define TPM_HEADER_SIZE 10 94a2d5ed94SMarcin Wojtas 95a2d5ed94SMarcin Wojtas #define TPM_CDEV_NAME "tpm0" 96a2d5ed94SMarcin Wojtas #define TPM_CDEV_PERM_FLAG 0600 97a2d5ed94SMarcin Wojtas 98877fc2e3STakanori Watanabe 99877fc2e3STakanori Watanabe #define TPM2_START_METHOD_ACPI 2 100877fc2e3STakanori Watanabe #define TPM2_START_METHOD_TIS 6 101877fc2e3STakanori Watanabe #define TPM2_START_METHOD_CRB 7 102877fc2e3STakanori Watanabe #define TPM2_START_METHOD_CRB_ACPI 8 103877fc2e3STakanori Watanabe 104a2d5ed94SMarcin Wojtas struct tpm_sc { 105a2d5ed94SMarcin Wojtas device_t dev; 106a2d5ed94SMarcin Wojtas 107a2d5ed94SMarcin Wojtas struct resource *mem_res; 108a2d5ed94SMarcin Wojtas struct resource *irq_res; 109a2d5ed94SMarcin Wojtas int mem_rid; 110a2d5ed94SMarcin Wojtas int irq_rid; 111a2d5ed94SMarcin Wojtas 112a2d5ed94SMarcin Wojtas struct cdev *sc_cdev; 113a2d5ed94SMarcin Wojtas 114a2d5ed94SMarcin Wojtas struct sx dev_lock; 115a2d5ed94SMarcin Wojtas struct cv buf_cv; 116a2d5ed94SMarcin Wojtas 117a2d5ed94SMarcin Wojtas void *intr_cookie; 118a2d5ed94SMarcin Wojtas int intr_type; /* Current event type */ 119a2d5ed94SMarcin Wojtas bool interrupts; 120a2d5ed94SMarcin Wojtas 121a2d5ed94SMarcin Wojtas uint8_t *buf; 122a2d5ed94SMarcin Wojtas size_t pending_data_length; 123a2d5ed94SMarcin Wojtas 124a2d5ed94SMarcin Wojtas struct callout discard_buffer_callout; 125*4ee7d3b0SMarcin Wojtas #ifdef TPM_HARVEST 126*4ee7d3b0SMarcin Wojtas struct callout harvest_callout; 127*4ee7d3b0SMarcin Wojtas int harvest_ticks; 128*4ee7d3b0SMarcin Wojtas #endif 129a2d5ed94SMarcin Wojtas 130a2d5ed94SMarcin Wojtas int (*transmit)(struct tpm_sc *, size_t); 131a2d5ed94SMarcin Wojtas }; 132a2d5ed94SMarcin Wojtas 133a2d5ed94SMarcin Wojtas int tpm20_suspend(device_t dev); 134a2d5ed94SMarcin Wojtas int tpm20_shutdown(device_t dev); 135a2d5ed94SMarcin Wojtas int32_t tpm20_get_timeout(uint32_t command); 136a2d5ed94SMarcin Wojtas int tpm20_init(struct tpm_sc *sc); 137a2d5ed94SMarcin Wojtas void tpm20_release(struct tpm_sc *sc); 138a2d5ed94SMarcin Wojtas 139a2d5ed94SMarcin Wojtas /* Small helper routines for io ops */ 140a2d5ed94SMarcin Wojtas static inline uint8_t 141a2d5ed94SMarcin Wojtas RD1(struct tpm_sc *sc, bus_size_t off) 142a2d5ed94SMarcin Wojtas { 143a2d5ed94SMarcin Wojtas 144a2d5ed94SMarcin Wojtas return (bus_read_1(sc->mem_res, off)); 145a2d5ed94SMarcin Wojtas } 146a2d5ed94SMarcin Wojtas static inline uint32_t 147a2d5ed94SMarcin Wojtas RD4(struct tpm_sc *sc, bus_size_t off) 148a2d5ed94SMarcin Wojtas { 149a2d5ed94SMarcin Wojtas 150a2d5ed94SMarcin Wojtas return (bus_read_4(sc->mem_res, off)); 151a2d5ed94SMarcin Wojtas } 152efa9b503SMarcin Wojtas #ifdef __amd64__ 153a2d5ed94SMarcin Wojtas static inline uint64_t 154a2d5ed94SMarcin Wojtas RD8(struct tpm_sc *sc, bus_size_t off) 155a2d5ed94SMarcin Wojtas { 156a2d5ed94SMarcin Wojtas 157a2d5ed94SMarcin Wojtas return (bus_read_8(sc->mem_res, off)); 158a2d5ed94SMarcin Wojtas } 159efa9b503SMarcin Wojtas #endif 160a2d5ed94SMarcin Wojtas static inline void 161a2d5ed94SMarcin Wojtas WR1(struct tpm_sc *sc, bus_size_t off, uint8_t val) 162a2d5ed94SMarcin Wojtas { 163a2d5ed94SMarcin Wojtas 164a2d5ed94SMarcin Wojtas bus_write_1(sc->mem_res, off, val); 165a2d5ed94SMarcin Wojtas } 166a2d5ed94SMarcin Wojtas static inline void 167a2d5ed94SMarcin Wojtas WR4(struct tpm_sc *sc, bus_size_t off, uint32_t val) 168a2d5ed94SMarcin Wojtas { 169a2d5ed94SMarcin Wojtas 170a2d5ed94SMarcin Wojtas bus_write_4(sc->mem_res, off, val); 171a2d5ed94SMarcin Wojtas } 172a2d5ed94SMarcin Wojtas static inline void 173a2d5ed94SMarcin Wojtas AND4(struct tpm_sc *sc, bus_size_t off, uint32_t val) 174a2d5ed94SMarcin Wojtas { 175a2d5ed94SMarcin Wojtas 176a2d5ed94SMarcin Wojtas WR4(sc, off, RD4(sc, off) & val); 177a2d5ed94SMarcin Wojtas } 178a2d5ed94SMarcin Wojtas static inline void 179a2d5ed94SMarcin Wojtas OR1(struct tpm_sc *sc, bus_size_t off, uint8_t val) 180a2d5ed94SMarcin Wojtas { 181a2d5ed94SMarcin Wojtas 182a2d5ed94SMarcin Wojtas WR1(sc, off, RD1(sc, off) | val); 183a2d5ed94SMarcin Wojtas } 184a2d5ed94SMarcin Wojtas static inline void 185a2d5ed94SMarcin Wojtas OR4(struct tpm_sc *sc, bus_size_t off, uint32_t val) 186a2d5ed94SMarcin Wojtas { 187a2d5ed94SMarcin Wojtas 188a2d5ed94SMarcin Wojtas WR4(sc, off, RD4(sc, off) | val); 189a2d5ed94SMarcin Wojtas } 190a2d5ed94SMarcin Wojtas #endif /* _TPM20_H_ */ 191