debuggers.hg

view tools/firmware/rombios/32bit/tcgbios/tpm_drivers.c @ 13681:c07326324f8d

[HVM] Add TCG BIOS extensions to the high memory area along with
some often-used libc utility functions. The TCG extensions are
described here:

https://www.trustedcomputinggroup.org/specs/PCClient/TCG_PCClientImplementationforBIOS_1-20_1-00.pdf

I have tried to keep the patching with rombios.c to a minimum, but
some amount of code needs to be inserted at various locations.

The code is currently deactivated, but can be activated by setting
BX_TCGBIOS to '1'.

Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
author kaf24@localhost.localdomain
date Fri Jan 26 16:38:32 2007 +0000 (2007-01-26)
parents
children e212203d7d34
line source
1 /*
2 * Implementation of the TCG BIOS extension according to the specification
3 * described in
4 * https://www.trustedcomputinggroup.org/specs/PCClient/TCG_PCClientImplementationforBIOS_1-20_1-00.pdf
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 * Copyright (C) IBM Corporation, 2006
21 *
22 * Author: Stefan Berger <stefanb@us.ibm.com>
23 */
24 #include "rombios_compat.h"
25 #include "util.h"
27 #include "tpm_drivers.h"
28 #include "tcgbios.h"
30 static uint32_t tis_wait_sts(uint8_t *addr, uint32_t time,
31 uint8_t mask, uint8_t expect)
32 {
33 uint32_t rc = 0;
34 while (time > 0) {
35 uint8_t sts = addr[TPM_STS];
36 if ((sts & mask) == expect) {
37 rc = 1;
38 break;
39 }
40 mssleep(1);
41 time--;
42 }
43 return rc;
44 }
46 static uint32_t tis_activate(uint32_t baseaddr)
47 {
48 uint32_t rc = 0;
49 uint8_t *tis_addr = (uint8_t*)baseaddr;
50 uint8_t acc;
51 /* request access to locality */
52 tis_addr[TPM_ACCESS] = 0x2;
54 acc = tis_addr[TPM_ACCESS];
55 if ((acc & 0x20) != 0) {
56 tis_addr[TPM_STS] = 0x40;
57 rc = tis_wait_sts(tis_addr, 100, 0x40, 0x40);
58 }
59 return rc;
60 }
62 uint32_t tis_ready(uint32_t baseaddr)
63 {
64 uint32_t rc = 0;
65 uint8_t *tis_addr = (uint8_t*)baseaddr;
67 tis_addr[TPM_STS] = 0x40;
68 rc = tis_wait_sts(tis_addr, 100, 0x40, 0x40);
70 return rc;
71 }
73 uint32_t tis_senddata(uint32_t baseaddr, unsigned char *data, uint32_t len)
74 {
75 uint32_t rc = 0;
76 uint8_t *tis_addr = (uint8_t*)baseaddr;
77 uint32_t offset = 0;
78 uint32_t end = 0;
80 do {
81 uint16_t burst = 0;
82 uint32_t ctr = 0;
83 while (burst == 0 && ctr < 2000) {
84 burst = (((uint16_t)tis_addr[TPM_STS+1]) ) +
85 (((uint16_t)tis_addr[TPM_STS+2]) << 8);
86 if (burst == 0) {
87 mssleep(1);
88 ctr++;
89 }
90 }
92 if (burst == 0) {
93 rc = TCG_RESPONSE_TIMEOUT;
94 break;
95 }
97 while (1) {
98 tis_addr[TPM_DATA_FIFO] = data[offset];
99 offset++;
100 burst--;
102 if (burst == 0 || offset == len) {
103 break;
104 }
105 }
107 if (offset == len) {
108 end = 1;
109 }
110 } while (end == 0);
112 return rc;
113 }
115 uint32_t tis_readresp(uint32_t baseaddr, unsigned char *buffer, uint32_t len)
116 {
117 uint32_t rc = 0;
118 uint32_t offset = 0;
119 uint8_t *tis_addr = (uint8_t*)baseaddr;
120 uint32_t sts;
122 while (offset < len) {
123 buffer[offset] = tis_addr[TPM_DATA_FIFO];
124 offset++;
125 sts = tis_addr[TPM_STS];
126 /* data left ? */
127 if ((sts & 0x10) == 0) {
128 break;
129 }
130 }
131 return rc;
132 }
135 uint32_t tis_waitdatavalid(uint32_t baseaddr)
136 {
137 uint8_t *tis_addr = (uint8_t*)baseaddr;
138 uint32_t rc = 0;
139 if (tis_wait_sts(tis_addr, 1000, 0x80, 0x80) == 0) {
140 rc = TCG_NO_RESPONSE;
141 }
142 return rc;
143 }
145 uint32_t tis_waitrespready(uint32_t baseaddr, uint32_t timeout)
146 {
147 uint32_t rc = 0;
148 uint8_t *tis_addr = (uint8_t*)baseaddr;
149 tis_addr[TPM_STS] = 0x20;
150 if (tis_wait_sts(tis_addr, timeout, 0x10, 0x10) == 0) {
151 rc = TCG_NO_RESPONSE;
152 }
153 return rc;
154 }
156 /* if device is not there, return '0', '1' otherwise */
157 uint32_t tis_probe(uint32_t baseaddr)
158 {
159 uint32_t rc = 0;
160 uint8_t *tis_addr = (uint8_t*)baseaddr;
161 uint32_t didvid = *(uint32_t*)&tis_addr[TPM_DID_VID];
162 if ((didvid != 0) && (didvid != 0xffffffff)) {
163 rc = 1;
164 }
165 return rc;
166 }
169 struct tpm_driver tpm_drivers[TPM_NUM_DRIVERS] = {
170 {
171 .baseaddr = TPM_TIS_BASE_ADDRESS,
172 .activate = tis_activate,
173 .ready = tis_ready,
174 .senddata = tis_senddata,
175 .readresp = tis_readresp,
176 .waitdatavalid = tis_waitdatavalid,
177 .waitrespready = tis_waitrespready,
178 .probe = tis_probe,
179 },
180 };