blob: fa0ba3c7ff31c7108147cf5ccb216a83ea8f8857 [file] [log] [blame]
Angel Pons6c49f402020-08-28 02:02:00 +02001/* SPDX-License-Identifier: GPL-2.0-only */
2
Felix Heldb0e11502021-09-16 22:07:42 +02003#include <arch/cpu.h>
Angel Pons6c49f402020-08-28 02:02:00 +02004#include <console/console.h>
5#include <cpu/intel/common/common.h>
Michał Żygowski257094a2021-11-21 13:13:15 +01006#include <cpu/x86/cr.h>
Elyes Haouas8823ba12022-12-05 08:48:50 +01007#include <device/mmio.h>
Angel Pons6c49f402020-08-28 02:02:00 +02008#include <southbridge/intel/common/pmbase.h>
Angel Pons6c49f402020-08-28 02:02:00 +02009#include <types.h>
10
Angel Pons6c49f402020-08-28 02:02:00 +020011#include "txt.h"
Subrata Banik6a2495d2022-12-31 14:36:54 +053012#include "txtlib.h"
Angel Pons6c49f402020-08-28 02:02:00 +020013#include "txt_register.h"
14#include "txt_getsec.h"
15
Angel Pons6c49f402020-08-28 02:02:00 +020016static bool is_txt_chipset(void)
17{
18 uint32_t eax;
19
20 const bool success = getsec_capabilities(&eax);
21
22 return success && eax & 1;
23}
24
25/* Print the bad news */
26static void print_memory_is_locked(void)
27{
28 if (!CONFIG(INTEL_TXT_LOGGING))
29 return;
30
31 printk(BIOS_EMERG, "FATAL: Cannot run SCLEAN. Memory will remain locked.\n");
32 printk(BIOS_EMERG, "\n");
33 printk(BIOS_EMERG, "If you still want to boot, your options are:\n");
34 printk(BIOS_EMERG, "\n");
35 printk(BIOS_EMERG, " 1. Flash a coreboot image with a valid BIOS ACM.\n");
36 printk(BIOS_EMERG, " Then, try again and hope it works this time.\n");
37 printk(BIOS_EMERG, "\n");
38 printk(BIOS_EMERG, " 2. If possible, remove the TPM from the system.\n");
39 printk(BIOS_EMERG, " Reinstalling the TPM might lock memory again.\n");
40 printk(BIOS_EMERG, "\n");
41 printk(BIOS_EMERG, " 3. Disconnect all power sources, and RTC battery.\n");
42 printk(BIOS_EMERG, " This may not work on all TXT-enabled platforms.\n");
43 printk(BIOS_EMERG, "\n");
44}
45
46void intel_txt_romstage_init(void)
47{
48 /* Bail early if the CPU doesn't support TXT */
Michał Żygowski257094a2021-11-21 13:13:15 +010049 if (!is_txt_cpu()) {
50 printk(BIOS_ERR, "TEE-TXT: CPU not TXT capable.\n");
Angel Pons6c49f402020-08-28 02:02:00 +020051 return;
Michał Żygowski257094a2021-11-21 13:13:15 +010052 }
Angel Pons6c49f402020-08-28 02:02:00 +020053
Michał Żygowski257094a2021-11-21 13:13:15 +010054 /*
55 * We need to use GETSEC here, so enable it.
56 * CR4_SMXE is all we need to be able to call GETSEC[CAPABILITIES]
57 * or GETSEC[ENTERACCS] for SCLEAN.
58 */
59 write_cr4(read_cr4() | CR4_SMXE);
Angel Pons6c49f402020-08-28 02:02:00 +020060
Michał Żygowski257094a2021-11-21 13:13:15 +010061 if (!is_txt_chipset()) {
62 printk(BIOS_ERR, "TEE-TXT: Chipset not TXT capable.\n");
Angel Pons6c49f402020-08-28 02:02:00 +020063 return;
Michał Żygowski257094a2021-11-21 13:13:15 +010064 }
Angel Pons6c49f402020-08-28 02:02:00 +020065
66 const uint8_t txt_ests = read8((void *)TXT_ESTS);
67
68 const bool establishment = is_establishment_bit_asserted();
69 const bool is_wake_error = !!(txt_ests & TXT_ESTS_WAKE_ERROR_STS);
70
71 if (CONFIG(INTEL_TXT_LOGGING)) {
72
73 printk(BIOS_INFO, "TEE-TXT: TPM established: %s\n",
74 establishment ? "true" : "false");
75 }
76
77 if (establishment && is_wake_error) {
78
79 printk(BIOS_ERR, "TEE-TXT: Secrets remain in memory. SCLEAN is required.\n");
80
81 if (txt_ests & TXT_ESTS_TXT_RESET_STS) {
Michał Żygowski1e3b48c2021-11-24 23:32:15 +010082 printk(BIOS_ERR, "TEE-TXT: TXT_RESET bit set, doing global reset!\n");
83 txt_reset_platform();
Angel Pons6c49f402020-08-28 02:02:00 +020084 }
85
86 /* FIXME: Clear SLP_TYP# */
87 write_pmbase32(4, read_pmbase32(4) & ~(0x7 << 10));
88
89 intel_txt_run_sclean();
90
91 /* If running the BIOS ACM is impossible, manual intervention is required */
92 print_memory_is_locked();
93
94 /* FIXME: vboot A/B could be used to recover, but has not been tested */
95 die("Could not execute BIOS ACM to unlock the memory.\n");
96 }
97}