Karthikeyan Ramasubramanian | b9042cb | 2020-08-20 16:04:58 -0600 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
| 2 | |
| 3 | #include <arch/cache.h> |
| 4 | #include <arch/io.h> |
| 5 | #include <cf9_reset.h> |
| 6 | #include <console/console.h> |
| 7 | #include <drivers/spi/tpm/tpm.h> |
| 8 | #include <ec/google/chromeec/ec.h> |
| 9 | #include <halt.h> |
| 10 | #include <intelblocks/cse.h> |
| 11 | #include <security/tpm/tss.h> |
John Zhao | f90e3b9 | 2020-08-25 10:21:01 -0700 | [diff] [blame] | 12 | #include <vb2_api.h> |
Karthikeyan Ramasubramanian | b9042cb | 2020-08-20 16:04:58 -0600 | [diff] [blame] | 13 | |
| 14 | void cse_board_reset(void) |
| 15 | { |
Jon Murphy | d7b8dc9 | 2023-09-05 11:36:43 -0600 | [diff] [blame] | 16 | tpm_result_t rc; |
Karthikeyan Ramasubramanian | b9042cb | 2020-08-20 16:04:58 -0600 | [diff] [blame] | 17 | struct cr50_firmware_version version; |
| 18 | |
Derek Huang | 2189640 | 2023-09-01 07:55:40 +0000 | [diff] [blame] | 19 | if (CONFIG(CSE_RESET_CLEAR_EC_AP_IDLE_FLAG)) |
| 20 | google_chromeec_clear_ec_ap_idle(); |
| 21 | |
Sergii Dmytruk | 47e9e8c | 2022-11-02 00:50:03 +0200 | [diff] [blame^] | 22 | /* |
| 23 | * Assuming that if particular TPM implementation is enabled at compile |
| 24 | * time, it's the one being used. This isn't generic code, so can |
| 25 | * probably get away with it. |
| 26 | */ |
Jes B. Klinke | c6b041a1 | 2022-04-19 14:00:33 -0700 | [diff] [blame] | 27 | if (CONFIG(TPM2) && CONFIG(TPM_GOOGLE_CR50)) { |
Jes Klinke | 5c80519 | 2020-10-14 13:24:32 -0700 | [diff] [blame] | 28 | /* Initialize TPM and get the cr50 firmware version. */ |
Jon Murphy | 2460481 | 2023-09-05 10:37:05 -0600 | [diff] [blame] | 29 | rc = tlcl_lib_init(); |
Jon Murphy | d7b8dc9 | 2023-09-05 11:36:43 -0600 | [diff] [blame] | 30 | if (rc != TPM_SUCCESS) { |
Jon Murphy | 53fc667 | 2023-09-26 21:05:37 -0600 | [diff] [blame] | 31 | printk(BIOS_ERR, "tlcl_lib_init() failed: %#x\n", rc); |
Jes Klinke | 5c80519 | 2020-10-14 13:24:32 -0700 | [diff] [blame] | 32 | return; |
| 33 | } |
| 34 | |
| 35 | cr50_get_firmware_version(&version); |
| 36 | |
| 37 | /* |
| 38 | * Cr50 firmware versions 0.[3|4].20 or newer support strap |
| 39 | * config 0xe where PLTRST from AP is connected to cr50's |
| 40 | * PLTRST# signal. So return immediately and trigger a global |
| 41 | * reset. |
| 42 | */ |
| 43 | if (version.epoch != 0 || version.major > 4 || |
| 44 | (version.major >= 3 && version.minor >= 20)) |
| 45 | return; |
John Zhao | f90e3b9 | 2020-08-25 10:21:01 -0700 | [diff] [blame] | 46 | } |
Jes B. Klinke | c6b041a1 | 2022-04-19 14:00:33 -0700 | [diff] [blame] | 47 | if (CONFIG(TPM_GOOGLE_TI50)) { |
| 48 | /* All versions of Ti50 firmware support the above PLTRST wiring. */ |
| 49 | return; |
| 50 | } |
John Zhao | f90e3b9 | 2020-08-25 10:21:01 -0700 | [diff] [blame] | 51 | |
Karthikeyan Ramasubramanian | b9042cb | 2020-08-20 16:04:58 -0600 | [diff] [blame] | 52 | printk(BIOS_INFO, "Initiating request to EC to trigger cold reset\n"); |
| 53 | /* |
| 54 | * Clean the data cache and set the full reset bit, so that when EC toggles |
| 55 | * SYS_RESET# pin, AP makes a trip to S5 and then to S0. |
| 56 | */ |
| 57 | dcache_clean_all(); |
| 58 | outb(FULL_RST, RST_CNT); |
| 59 | if (!google_chromeec_ap_reset()) |
| 60 | halt(); |
| 61 | } |