1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /*
3 * This is a driver for a CRB Interface.
4 *
5 * The general flow looks like this:
6 *
7 * TPM starts in IDLE Mode
8 *
9 * IDLE --> READY --> Command Reception
10 * ^ |
11 * | v
12 -- Cmd Complete <-- Command Execution
13 */
14
15 #include <timer.h>
16 #include <console/console.h>
17 #include <device/mmio.h>
18 #include <string.h>
19 #include <soc/pci_devs.h>
20 #include <device/pci_ops.h>
21
22 #include "tpm.h"
23
24 static struct control_area {
25 uint32_t request;
26 uint32_t status;
27 uint32_t cancel;
28 uint32_t start;
29 uint64_t interrupt_control;
30 uint32_t command_size;
31 void *command_bfr;
32 uint32_t response_size;
33 void *response_bfr;
34 } control_area;
35
36 static uint8_t cur_loc = 0;
37
38 /* Read Control Area Structure back */
crb_readControlArea(void)39 static void crb_readControlArea(void)
40 {
41 control_area.request = read32(CRB_REG(cur_loc, CRB_REG_REQUEST));
42 control_area.status = read32(CRB_REG(cur_loc, CRB_REG_STATUS));
43 control_area.cancel = read32(CRB_REG(cur_loc, CRB_REG_CANCEL));
44 control_area.interrupt_control = read64(CRB_REG(cur_loc, CRB_REG_INT_CTRL));
45 control_area.command_size = read32(CRB_REG(cur_loc, CRB_REG_CMD_SIZE));
46 control_area.command_bfr =
47 (void *)(uintptr_t)read64(CRB_REG(cur_loc, CRB_REG_CMD_ADDR));
48 control_area.response_size = read32(CRB_REG(cur_loc, CRB_REG_RESP_SIZE));
49 control_area.response_bfr =
50 (void *)(uintptr_t)read64(CRB_REG(cur_loc, CRB_REG_RESP_ADDR));
51
52 /*
53 * Intel PTT has to write the command/response address and size
54 * register before each command submission otherwise the control area
55 * is all zeroed. This has been observed on Alder Lake S CPU and may be
56 * applicable to other new microarchitectures. Update the local control
57 * area data to make crb_tpm_process_command() not fail on buffer checks.
58 * PTT command/response buffer is fixed to be at offset 0x80 and spans
59 * up to the end of 4KB region for the current locality.
60 */
61 if (CONFIG(HAVE_INTEL_PTT)) {
62 control_area.command_size = 0x1000 - CRB_REG_DATA_BUFF;
63 control_area.response_size = control_area.command_size;
64 control_area.command_bfr = CRB_REG(cur_loc, CRB_REG_DATA_BUFF);
65 control_area.response_bfr = CRB_REG(cur_loc, CRB_REG_DATA_BUFF);
66 }
67 }
68
69 /* Wait for Reg to be expected Value */
crb_wait_for_reg32(const void * addr,uint32_t timeoutMs,uint32_t mask,uint32_t expectedValue)70 static tpm_result_t crb_wait_for_reg32(const void *addr, uint32_t timeoutMs, uint32_t mask,
71 uint32_t expectedValue)
72 {
73 uint32_t regValue;
74 struct stopwatch sw;
75
76 // Set up a timer which breaks the loop after timeout
77 stopwatch_init_msecs_expire(&sw, timeoutMs);
78
79 while (1) {
80 // Now check if the TPM is in IDLE mode
81 regValue = read32(addr);
82
83 if ((regValue & mask) == expectedValue)
84 return TPM_SUCCESS;
85
86 if (stopwatch_expired(&sw)) {
87 printk(BIOS_ERR,
88 "CRB_WAIT: Error - Timed out with RegValue: %08x, Mask: %08x, Expected: %08x\n",
89 regValue, mask, expectedValue);
90 return TPM_CB_TIMEOUT;
91 }
92 }
93 }
94
95 /* CRB PROBE
96 *
97 * Checks if the CRB Interface is ready
98 */
crb_probe(void)99 static tpm_result_t crb_probe(void)
100 {
101 uint64_t tpmStatus = read64(CRB_REG(cur_loc, CRB_REG_INTF_ID));
102 printk(BIOS_SPEW, "Interface ID Reg. %llx\n", tpmStatus);
103
104 if ((tpmStatus & CRB_INTF_REG_CAP_CRB) == 0) {
105 printk(BIOS_DEBUG, "TPM: CRB Interface is not supported.\n");
106 return TPM_CB_FAIL;
107 }
108
109 if ((tpmStatus & (0xf)) != 1) {
110 printk(BIOS_DEBUG,
111 "TPM: CRB Interface is not active. System needs reboot in order to active TPM.\n");
112 write32(CRB_REG(cur_loc, CRB_REG_INTF_ID), CRB_INTF_REG_INTF_SEL);
113 return TPM_CB_FAIL;
114 }
115
116 write32(CRB_REG(cur_loc, CRB_REG_INTF_ID), CRB_INTF_REG_INTF_SEL);
117 write32(CRB_REG(cur_loc, CRB_REG_INTF_ID), CRB_INTF_REG_INTF_LOCK);
118
119 return TPM_SUCCESS;
120 }
121
122 /*
123 * Get active Locality
124 *
125 * Get the active locality
126 */
crb_activate_locality(void)127 static uint8_t crb_activate_locality(void)
128 {
129 uint8_t locality = (read8(CRB_REG(0, CRB_REG_LOC_STATE)) >> 2) & 0x07;
130 printk(BIOS_SPEW, "Active locality: %i\n", locality);
131
132 tpm_result_t rc = crb_wait_for_reg32(CRB_REG(locality, CRB_REG_LOC_STATE), 750,
133 LOC_STATE_LOC_ASSIGN, LOC_STATE_LOC_ASSIGN);
134
135 if (!rc && (locality == 0))
136 return locality;
137
138 if (rc)
139 write8(CRB_REG(locality, CRB_REG_LOC_CTRL), LOC_CTRL_REQ_ACCESS);
140
141 rc = crb_wait_for_reg32(CRB_REG(locality, CRB_REG_LOC_STATE), 750, LOC_STATE_LOC_ASSIGN,
142 LOC_STATE_LOC_ASSIGN);
143 if (rc) {
144 printk(BIOS_ERR, "TPM: Error (%#x) - No Locality has been assigned TPM-wise.\n", rc);
145 return 0;
146 }
147
148 rc = crb_wait_for_reg32(CRB_REG(locality, CRB_REG_LOC_STATE), 1500,
149 LOC_STATE_REG_VALID_STS, LOC_STATE_REG_VALID_STS);
150 if (rc) {
151 printk(BIOS_ERR, "TPM: Error (%#x) - LOC_STATE Register %u contains errors.\n",
152 rc, locality);
153 return 0;
154 }
155
156 return locality;
157 }
158
159 /* Switch Device into a Ready State */
crb_switch_to_ready(void)160 static tpm_result_t crb_switch_to_ready(void)
161 {
162 /* Transition into ready state */
163 write8(CRB_REG(cur_loc, CRB_REG_REQUEST), 0x1);
164 tpm_result_t rc = crb_wait_for_reg32(CRB_REG(cur_loc, CRB_REG_REQUEST), 200,
165 CRB_REG_REQUEST_CMD_RDY, 0x0);
166 if (rc) {
167 printk(BIOS_ERR,
168 "TPM Error (%#x): TPM did not transition into ready state in time.\n", rc);
169 return rc;
170 }
171
172 /* Check TPM_CRB_CTRL_STS[0] to be "0" - no unrecoverable error */
173 rc = crb_wait_for_reg32(CRB_REG(cur_loc, CRB_REG_STATUS), 500, CRB_REG_STATUS_ERROR,
174 0x0);
175 if (rc) {
176 printk(BIOS_ERR, "TPM Error (%#x): Could not recover.\n", rc);
177 return rc;
178 }
179
180 return TPM_SUCCESS;
181 }
182
183 /*
184 * crb_tpm_init
185 *
186 * Even though the TPM does not need an initialization we check
187 * if the TPM responds and is in IDLE mode, which should be the
188 * normal bring up mode.
189 *
190 */
crb_tpm_init(void)191 tpm_result_t crb_tpm_init(void)
192 {
193 tpm_result_t rc = crb_probe();
194 if (rc) {
195 printk(BIOS_ERR, "TPM: Probe failed.\n");
196 return rc;
197 }
198
199 /* Read back control area structure */
200 crb_readControlArea();
201
202 /*
203 * PTT may have no assigned locality before startup. Request locality here to save
204 * some precious milliseconds which would be wasted in crb_activate_locality polling
205 * for LOC_STATE_LOC_ASSIGN bit for the first time.
206 */
207 if (CONFIG(HAVE_INTEL_PTT)) {
208 uint8_t locality = (read8(CRB_REG(0, CRB_REG_LOC_STATE)) >> 2) & 0x07;
209 write8(CRB_REG(locality, CRB_REG_LOC_CTRL), LOC_CTRL_REQ_ACCESS);
210 }
211
212 /* Good to go. */
213 printk(BIOS_SPEW, "TPM: CRB TPM initialized successfully\n");
214
215 return TPM_SUCCESS;
216 }
217
set_ptt_cmd_resp_buffers(void)218 static void set_ptt_cmd_resp_buffers(void)
219 {
220 write32(CRB_REG(cur_loc, CRB_REG_CMD_ADDR + 4), 0);
221 write32(CRB_REG(cur_loc, CRB_REG_CMD_ADDR),
222 (uintptr_t)CRB_REG(cur_loc, CRB_REG_DATA_BUFF));
223 write32(CRB_REG(cur_loc, CRB_REG_CMD_SIZE), control_area.command_size);
224 write64(CRB_REG(cur_loc, CRB_REG_RESP_ADDR),
225 (uintptr_t)CRB_REG(cur_loc, CRB_REG_DATA_BUFF));
226 write32(CRB_REG(cur_loc, CRB_REG_RESP_SIZE), control_area.response_size);
227 }
228
229 /*
230 * crb_tpm_process_command
231 */
crb_tpm_process_command(const void * tpm2_command,size_t command_size,void * tpm2_response,size_t max_response)232 size_t crb_tpm_process_command(const void *tpm2_command, size_t command_size,
233 void *tpm2_response, size_t max_response)
234 {
235 tpm_result_t rc;
236
237 if (command_size > control_area.command_size) {
238 printk(BIOS_ERR, "TPM: Command size is too big.\n");
239 return -1;
240 }
241
242 if (control_area.response_size < max_response) {
243 printk(BIOS_ERR, "TPM: Response size could be too big.\n");
244 return -1;
245 }
246
247 cur_loc = crb_activate_locality();
248
249 // Check if CMD bit is cleared.
250 rc = crb_wait_for_reg32(CRB_REG(0, CRB_REG_START), 250, CRB_REG_START_START, 0x0);
251 if (rc) {
252 printk(BIOS_ERR, "TPM Error (%#x): Cmd Bit not cleared.\n", rc);
253 return -1;
254 }
255
256 rc = crb_switch_to_ready();
257 if (rc) {
258 printk(BIOS_DEBUG, "TPM Error (%#x): Can not transition into ready state.\n", rc);
259 return -1;
260 }
261
262 // Write to Command Buffer
263 memcpy(control_area.command_bfr, tpm2_command, command_size);
264
265 /*
266 * Initialize CRB addresses and sizes for PTT. It seems to be possible
267 * only after CRB is switched to ready and before writing start bit.
268 * This is also what EDK2 TPM CRB drivers do.
269 */
270 if (CONFIG(HAVE_INTEL_PTT))
271 set_ptt_cmd_resp_buffers();
272
273 // Write Start Bit
274 write8(CRB_REG(cur_loc, CRB_REG_START), 0x1);
275
276 // Poll for Response
277 rc = crb_wait_for_reg32(CRB_REG(cur_loc, CRB_REG_START), 3500, CRB_REG_START_START, 0);
278 if (rc) {
279 printk(BIOS_DEBUG, "TPM Error (%#x): Command Timed out.\n", rc);
280 return -1;
281 }
282
283 // Check for errors
284 rc = crb_wait_for_reg32(CRB_REG(cur_loc, CRB_REG_STATUS), 200, CRB_REG_STATUS_ERROR, 0);
285 if (rc) {
286 printk(BIOS_DEBUG, "TPM Error (%#x): Command errored.\n", rc);
287 return -1;
288 }
289
290 // Get Response Length
291 uint32_t length = be32_to_cpu(read32(control_area.response_bfr + 2));
292
293 /* Response has to have at least 6 bytes */
294 if (length < 6)
295 return 1;
296
297 // Copy Response
298 memcpy(tpm2_response, control_area.response_bfr, length);
299
300 rc = crb_switch_to_ready();
301 if (rc) {
302 printk(BIOS_DEBUG, "TPM Error (%#x): Can not transition into ready state again.\n", rc);
303 return -1;
304 }
305
306 return length;
307 }
308
309 /*
310 * tp2_get_info
311 *
312 * Returns information about the TPM
313 *
314 */
crb_tpm_get_info(struct crb_tpm_info * crb_tpm_info)315 void crb_tpm_get_info(struct crb_tpm_info *crb_tpm_info)
316 {
317 uint64_t interfaceReg = read64(CRB_REG(cur_loc, CRB_REG_INTF_ID));
318
319 crb_tpm_info->vendor_id = (interfaceReg >> 48) & 0xFFFF;
320 crb_tpm_info->device_id = (interfaceReg >> 32) & 0xFFFF;
321 crb_tpm_info->revision = (interfaceReg >> 24) & 0xFF;
322 }
323
324 /*
325 * crb_tpm_is_active
326 *
327 * Checks that CRB interface is available and active.
328 *
329 * The body was derived from crb_probe() which unlike this function can also
330 * write to registers.
331 */
crb_tpm_is_active(void)332 bool crb_tpm_is_active(void)
333 {
334 uint64_t tpmStatus = read64(CRB_REG(0, CRB_REG_INTF_ID));
335 printk(BIOS_SPEW, "Interface ID Reg. %llx\n", tpmStatus);
336
337 if ((tpmStatus & CRB_INTF_REG_CAP_CRB) == 0) {
338 printk(BIOS_DEBUG, "TPM: CRB Interface is not supported.\n");
339 return false;
340 }
341
342 if ((tpmStatus & (0xf)) != 1) {
343 printk(BIOS_DEBUG, "TPM: CRB Interface is not active.\n");
344 return false;
345 }
346
347 return true;
348 }
349