xref: /aosp_15_r20/external/coreboot/src/security/intel/cbnt/logging.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <console/console.h>
4 #include <cpu/x86/msr.h>
5 #include <cpu/intel/msr.h>
6 #include <device/mmio.h>
7 #include <stdint.h>
8 #include <security/intel/txt/txt.h>
9 
10 #include "cbnt.h"
11 
12 #define LOG(...) printk(BIOS_INFO, "CBnT: " __VA_ARGS__)
13 
14 union sacm_info {
15 	struct {
16 		uint64_t nem_enabled : 1;
17 		uint64_t tpm_type : 2;
18 		uint64_t tpm_success : 1;
19 		uint64_t facb : 1;
20 		uint64_t measured_boot : 1;
21 		uint64_t verified_boot : 1;
22 		uint64_t revoked : 1;
23 		uint64_t : 24;
24 		uint64_t btg_cap : 1;
25 		uint64_t : 1;
26 		uint64_t txt_cap : 1;
27 		uint64_t : 29;
28 	};
29 	msr_t msr;
30 	uint64_t raw;
31 };
32 
33 _Static_assert(sizeof(union sacm_info) == sizeof(uint64_t), "Wrong size of sacm_info");
34 
35 static const char *const tpm_type[] = {
36 	"No TPM",
37 	"TPM 1.2",
38 	"TPM 2.0",
39 	"PTT",
40 };
41 
42 union cbnt_bootstatus {
43 	struct {
44 		uint64_t : 59;
45 		uint64_t bios_trusted : 1;
46 		uint64_t txt_dis_pol : 1;
47 		uint64_t btg_startup_err : 1;
48 		uint64_t txt_err : 1;
49 		uint64_t type7 : 1;
50 	};
51 	uint64_t raw;
52 };
53 _Static_assert(sizeof(union cbnt_bootstatus) == sizeof(uint64_t),
54 	       "Wrong size of cbnt_bootstatus");
55 
56 union cbnt_errorcode {
57 	struct {
58 		uint32_t type : 15;
59 		uint32_t : 15;
60 		uint32_t external : 1;
61 		uint32_t valid : 1;
62 	} microcode;
63 	struct {
64 		uint32_t ac_type : 4;
65 		uint32_t class : 6;
66 		uint32_t major : 5;
67 		uint32_t minor_invalid : 1;
68 		uint32_t minor : 9;
69 		uint32_t : 5;
70 		uint32_t external : 1;
71 		uint32_t valid : 1;
72 	} sinit;
73 	uint32_t raw;
74 };
75 
76 _Static_assert(sizeof(union cbnt_errorcode) == sizeof(uint32_t),
77 	       "Wrong size of cbnt_errorcode");
78 
79 union cbnt_biosacm_errorcode {
80 	struct {
81 		uint32_t ac_type : 4;
82 		uint32_t class : 6;
83 		uint32_t major : 5;
84 		uint32_t minor_invalid : 1;
85 		uint32_t minor : 12;
86 		uint32_t : 2;
87 		uint32_t external : 1;
88 		uint32_t valid : 1;
89 	} txt;
90 	struct {
91 		uint32_t ac_type : 4;
92 		uint32_t class : 6;
93 		uint32_t error : 5;
94 		uint32_t acm_started : 1;
95 		uint32_t km_id : 4;
96 		uint32_t bp : 5;
97 		uint32_t : 6;
98 		uint32_t valid : 1;
99 	} btg;
100 	uint32_t raw;
101 };
102 _Static_assert(sizeof(union cbnt_biosacm_errorcode) == sizeof(uint32_t),
103 	       "Wrong size of cbnt_biosacm_errorcode");
104 
105 
decode_err_type(uint8_t type)106 static const char *decode_err_type(uint8_t type)
107 {
108 	switch (type) {
109 	case 0:
110 		return "BIOS ACM Error";
111 	case 1:
112 		return "SINIT ACM Error";
113 	case 3:
114 		return "Boot Guard Error";
115 	default:
116 		return "Reserved";
117 	}
118 }
119 
intel_cbnt_log_registers(void)120 void intel_cbnt_log_registers(void)
121 {
122 	const union sacm_info acm_info = { .msr = rdmsr(MSR_BOOT_GUARD_SACM_INFO) };
123 	LOG("SACM INFO MSR (0x13A) raw: 0x%016llx\n", acm_info.raw);
124 	LOG("  NEM status:              %u\n", acm_info.nem_enabled);
125 	LOG("  TPM type:                %s\n", tpm_type[acm_info.tpm_type]);
126 	LOG("  TPM success:             %u\n", acm_info.tpm_success);
127 	LOG("  FACB:                    %u\n", acm_info.facb);
128 	LOG("  measured boot:           %u\n", acm_info.measured_boot);
129 	LOG("  verified boot:           %u\n", acm_info.verified_boot);
130 	LOG("  revoked:                 %u\n", acm_info.revoked);
131 	LOG("  BtG capable:             %u\n", acm_info.btg_cap);
132 	LOG("  TXT capable:             %u\n", acm_info.txt_cap);
133 
134 	const union cbnt_bootstatus btsts = {
135 		.raw = read64p(CBNT_BOOTSTATUS),
136 	};
137 	LOG("BOOTSTATUS (0xA0) raw: 0x%016llx\n", btsts.raw);
138 	LOG("  Bios trusted:            %u\n", btsts.bios_trusted);
139 	LOG("  TXT disabled by policy:  %u\n", btsts.txt_dis_pol);
140 	LOG("  Bootguard startup error: %u\n", btsts.btg_startup_err);
141 	LOG("  TXT ucode or ACM error:  %u\n", btsts.txt_err);
142 	LOG("  TXT measurement type 7:  %u\n", btsts.type7);
143 
144 	const union cbnt_errorcode err = {
145 		.raw = read32p(CBNT_ERRORCODE),
146 	};
147 	LOG("ERRORCODE (0x30) raw: 0x%08x\n", err.raw);
148 	/* It looks like the hardware does not set the txt error bit properly */
149 	const bool txt_err_valid = btsts.txt_err || true;
150 	if (txt_err_valid && !btsts.txt_dis_pol) {
151 		if (err.microcode.valid && !err.microcode.external) {
152 			LOG("ERRORCODE is ucode error\n");
153 			LOG("  type:                    %s\n",
154 			      intel_txt_processor_error_type(err.microcode.type));
155 		} else if (err.sinit.valid && err.sinit.external) {
156 			LOG("ERRORCODE is SINIT error\n");
157 			const char *type = decode_err_type(err.sinit.ac_type);
158 			LOG("  AC Module Type:          %s\n", type);
159 			LOG("  class:                   0x%x\n", err.sinit.class);
160 			LOG("  major:                   0x%x\n", err.sinit.major);
161 			if (!err.sinit.minor_invalid)
162 				LOG("  minor:                   0x%x\n", err.sinit.minor);
163 		}
164 	} else if (txt_err_valid && btsts.txt_dis_pol) {
165 		LOG("TXT disabled in Policy\n");
166 	}
167 
168 	const union cbnt_biosacm_errorcode biosacm_err = {
169 		.raw = read32p(CBNT_BIOSACM_ERRORCODE),
170 	};
171 	LOG("BIOSACM_ERRORCODE (0x328) raw: 0x%08x\n", biosacm_err.raw);
172 	if (txt_err_valid && biosacm_err.txt.valid) {
173 		LOG("BIOSACM_ERRORCODE: TXT ucode or ACM error\n");
174 		const char *type = decode_err_type(biosacm_err.txt.ac_type);
175 		LOG("  AC Module Type:          %s\n", type);
176 		LOG("  class:                   0x%x\n", biosacm_err.txt.class);
177 		LOG("  major:                   0x%x\n", biosacm_err.txt.major);
178 		if (!biosacm_err.txt.minor_invalid)
179 			LOG("  minor:                   0x%x\n", biosacm_err.txt.minor);
180 		LOG("  External:                0x%x\n", biosacm_err.txt.external);
181 	}
182 
183 	if (btsts.btg_startup_err && biosacm_err.btg.valid) {
184 		LOG("BIOSACM_ERRORCODE: Bootguard error\n");
185 		const char *type = decode_err_type(biosacm_err.btg.ac_type);
186 		LOG("  AC Module Type:          %s\n", type);
187 		LOG("  class:                   0x%x\n", biosacm_err.btg.class);
188 		LOG("  error:                   0x%x\n", biosacm_err.btg.error);
189 		LOG("  ACM started:             %u\n", biosacm_err.btg.acm_started);
190 		LOG("  KMID:                    0x%x\n", biosacm_err.btg.km_id);
191 		LOG("  BootPolicies:            0x%x\n", biosacm_err.btg.bp);
192 	}
193 }
194