1342084Smw/*- 2342084Smw * Copyright (c) 2018 Stormshield. 3342084Smw * Copyright (c) 2018 Semihalf. 4342084Smw * All rights reserved. 5342084Smw * 6342084Smw * Redistribution and use in source and binary forms, with or without 7342084Smw * modification, are permitted provided that the following conditions 8342084Smw * are met: 9342084Smw * 1. Redistributions of source code must retain the above copyright 10342084Smw * notice, this list of conditions and the following disclaimer. 11342084Smw * 2. Redistributions in binary form must reproduce the above copyright 12342084Smw * notice, this list of conditions and the following disclaimer in the 13342084Smw * documentation and/or other materials provided with the distribution. 14342084Smw * 15342084Smw * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16342084Smw * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17342084Smw * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18342084Smw * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 19342084Smw * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20342084Smw * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21342084Smw * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22342084Smw * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 23342084Smw * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 24342084Smw * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25342084Smw * POSSIBILITY OF SUCH DAMAGE. 26342084Smw */ 27342084Smw 28342084Smw#ifndef _TPM20_H_ 29346725Smw#define _TPM20_H_ 30342084Smw 31342084Smw#include <sys/cdefs.h> 32342084Smw__FBSDID("$FreeBSD: stable/11/sys/dev/tpm/tpm20.h 346725 2019-04-26 01:58:36Z mw $"); 33342084Smw 34342084Smw#include <sys/endian.h> 35342084Smw#include <sys/param.h> 36342084Smw#include <sys/kernel.h> 37342084Smw#include <sys/malloc.h> 38342084Smw#include <sys/proc.h> 39342084Smw#include <sys/systm.h> 40342084Smw 41342084Smw#include <sys/bus.h> 42342084Smw#include <sys/callout.h> 43342084Smw#include <sys/conf.h> 44342084Smw#include <sys/module.h> 45342084Smw#include <sys/rman.h> 46342084Smw#include <sys/sx.h> 47342084Smw#include <sys/uio.h> 48342084Smw 49342084Smw#include <machine/bus.h> 50342084Smw#include <machine/md_var.h> 51342084Smw#include <machine/resource.h> 52342084Smw 53342084Smw#include <contrib/dev/acpica/include/acpi.h> 54342084Smw#include <contrib/dev/acpica/include/accommon.h> 55342084Smw#include <dev/acpica/acpivar.h> 56342084Smw#include "opt_acpi.h" 57342084Smw 58346725Smw#include "opt_tpm.h" 59346725Smw 60342084Smw#define BIT(x) (1 << (x)) 61342084Smw 62342084Smw/* Timeouts in us */ 63346725Smw#define TPM_TIMEOUT_A 750000 64346725Smw#define TPM_TIMEOUT_B 2000000 65346725Smw#define TPM_TIMEOUT_C 200000 66346725Smw#define TPM_TIMEOUT_D 30000 67342084Smw 68342084Smw/* 69342084Smw * Generating RSA key pair takes ~(10-20s), which is significantly longer than 70342084Smw * any timeout defined in spec. Because of that we need a new one. 71342084Smw */ 72346725Smw#define TPM_TIMEOUT_LONG 40000000 73342084Smw 74342084Smw/* List of commands that require TPM_TIMEOUT_LONG time to complete */ 75346725Smw#define TPM_CC_CreatePrimary 0x00000131 76342084Smw#define TPM_CC_Create 0x00000153 77342084Smw#define TPM_CC_CreateLoaded 0x00000191 78342084Smw 79342084Smw/* List of commands that require only TPM_TIMEOUT_C time to complete */ 80346725Smw#define TPM_CC_SequenceComplete 0x0000013e 81346725Smw#define TPM_CC_Startup 0x00000144 82346725Smw#define TPM_CC_SequenceUpdate 0x0000015c 83346725Smw#define TPM_CC_GetCapability 0x0000017a 84346725Smw#define TPM_CC_PCR_Extend 0x00000182 85346725Smw#define TPM_CC_EventSequenceComplete 0x00000185 86346725Smw#define TPM_CC_HashSequenceStart 0x00000186 87342084Smw 88342084Smw/* Timeout before data in read buffer is discarded */ 89346725Smw#define TPM_READ_TIMEOUT 500000 90342084Smw 91346725Smw#define TPM_BUFSIZE 0x1000 92342084Smw 93346725Smw#define TPM_HEADER_SIZE 10 94342084Smw 95346725Smw#define TPM_CDEV_NAME "tpm0" 96346725Smw#define TPM_CDEV_PERM_FLAG 0600 97342084Smw 98346722Smw 99346725Smw#define TPM2_START_METHOD_ACPI 2 100346725Smw#define TPM2_START_METHOD_TIS 6 101346725Smw#define TPM2_START_METHOD_CRB 7 102346725Smw#define TPM2_START_METHOD_CRB_ACPI 8 103346722Smw 104342084Smwstruct tpm_sc { 105342084Smw device_t dev; 106342084Smw 107342084Smw struct resource *mem_res; 108342084Smw struct resource *irq_res; 109342084Smw int mem_rid; 110342084Smw int irq_rid; 111342084Smw 112342084Smw struct cdev *sc_cdev; 113342084Smw 114342084Smw struct sx dev_lock; 115342084Smw struct cv buf_cv; 116342084Smw 117342084Smw void *intr_cookie; 118342084Smw int intr_type; /* Current event type */ 119342084Smw bool interrupts; 120342084Smw 121342084Smw uint8_t *buf; 122342084Smw size_t pending_data_length; 123346725Smw lwpid_t owner_tid; 124342084Smw 125342084Smw struct callout discard_buffer_callout; 126346725Smw#ifdef TPM_HARVEST 127346725Smw struct callout harvest_callout; 128346725Smw int harvest_ticks; 129346725Smw#endif 130342084Smw 131342084Smw int (*transmit)(struct tpm_sc *, size_t); 132342084Smw}; 133342084Smw 134342084Smwint tpm20_suspend(device_t dev); 135342084Smwint tpm20_shutdown(device_t dev); 136342084Smwint32_t tpm20_get_timeout(uint32_t command); 137342084Smwint tpm20_init(struct tpm_sc *sc); 138342084Smwvoid tpm20_release(struct tpm_sc *sc); 139342084Smw 140342084Smw/* Small helper routines for io ops */ 141342084Smwstatic inline uint8_t 142342084SmwRD1(struct tpm_sc *sc, bus_size_t off) 143342084Smw{ 144342084Smw 145342084Smw return (bus_read_1(sc->mem_res, off)); 146342084Smw} 147342084Smwstatic inline uint32_t 148342084SmwRD4(struct tpm_sc *sc, bus_size_t off) 149342084Smw{ 150342084Smw 151342084Smw return (bus_read_4(sc->mem_res, off)); 152342084Smw} 153346721Smw#ifdef __amd64__ 154342084Smwstatic inline uint64_t 155342084SmwRD8(struct tpm_sc *sc, bus_size_t off) 156342084Smw{ 157342084Smw 158342084Smw return (bus_read_8(sc->mem_res, off)); 159342084Smw} 160346721Smw#endif 161342084Smwstatic inline void 162342084SmwWR1(struct tpm_sc *sc, bus_size_t off, uint8_t val) 163342084Smw{ 164342084Smw 165342084Smw bus_write_1(sc->mem_res, off, val); 166342084Smw} 167342084Smwstatic inline void 168342084SmwWR4(struct tpm_sc *sc, bus_size_t off, uint32_t val) 169342084Smw{ 170342084Smw 171342084Smw bus_write_4(sc->mem_res, off, val); 172342084Smw} 173342084Smwstatic inline void 174342084SmwAND4(struct tpm_sc *sc, bus_size_t off, uint32_t val) 175342084Smw{ 176342084Smw 177342084Smw WR4(sc, off, RD4(sc, off) & val); 178342084Smw} 179342084Smwstatic inline void 180342084SmwOR1(struct tpm_sc *sc, bus_size_t off, uint8_t val) 181342084Smw{ 182342084Smw 183342084Smw WR1(sc, off, RD1(sc, off) | val); 184342084Smw} 185342084Smwstatic inline void 186342084SmwOR4(struct tpm_sc *sc, bus_size_t off, uint32_t val) 187342084Smw{ 188342084Smw 189342084Smw WR4(sc, off, RD4(sc, off) | val); 190342084Smw} 191342084Smw#endif /* _TPM20_H_ */ 192