xref: /aosp_15_r20/external/coreboot/src/soc/amd/common/block/psp/psb.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <amdblocks/reset.h>
4 #include <amdblocks/smn.h>
5 #include <bootstate.h>
6 #include <console/console.h>
7 #include <device/mmio.h>
8 #include <types.h>
9 
10 #include "psp_def.h"
11 
12 #define PSB_STATUS_OFFSET	0x10994
13 
14 #define FUSE_PLATFORM_SECURE_BOOT_EN	BIT(24)
15 
16 #define PSB_TEST_STATUS_MASK		0xff
17 #define PSB_FUSING_READY_MASK		BIT(8)
18 
19 /* PSB Test Status and Error Codes (doc#56654) */
20 #define PSB_TEST_STATUS_PASS			0x00
21 #define PSB_TEST_STATUS_FUSE_READ_ERR		0x3e
22 #define PSB_TEST_STATUS_BIOS_KEY_BAD_USAGE	0x81
23 #define PSB_TEST_STATUS_BIOS_RTM_SIG_NOENT	0x82
24 #define PSB_TEST_STATUS_BIOS_RTM_COPY_ERR	0x83
25 #define PSB_TEST_STATUS_BIOS_RTM_BAD_SIG	0x84
26 #define PSB_TEST_STATUS_BIOS_KEY_BAD_SIG	0x85
27 #define PSB_TEST_STATUS_PLATFORM_BAD_ID		0x86
28 #define PSB_TEST_STATUS_BIOS_COPY_BIT_UNSET	0x87
29 #define PSB_TEST_STATUS_BIOS_CA_BAD_SIG		0x8a
30 #define PSB_TEST_STATUS_BIOS_CA_BAD_USAGE	0x8b
31 #define PSB_TEST_STATUS_BIOS_KEY_BAD_REVISION	0x8c
32 
33 #define FUSE_STATUS_SUCCESS	0x00
34 #define FUSE_STATUS_NOT_ALLOWED	0x09
35 #define FUSE_STATUS_FUSING_ERR	0x0a
36 #define FUSE_STATUS_BOOT_DONE	0x0b
37 
psb_test_status_to_string(u32 status)38 static const char *psb_test_status_to_string(u32 status)
39 {
40 	switch (status) {
41 	case PSB_TEST_STATUS_PASS:
42 		return "Psb Test Status PASS";
43 	case PSB_TEST_STATUS_FUSE_READ_ERR:
44 		return "Error reading fuse info";
45 	case PSB_TEST_STATUS_BIOS_KEY_BAD_USAGE:
46 		return "OEM BIOS signing key usage flag violation";
47 	case PSB_TEST_STATUS_BIOS_RTM_SIG_NOENT:
48 		return "BIOS RTM signature entry not found";
49 	case PSB_TEST_STATUS_BIOS_RTM_COPY_ERR:
50 		return "BIOS copy to DRAM failed";
51 	case PSB_TEST_STATUS_BIOS_RTM_BAD_SIG:
52 		return "BIOS RTM signature verification failed";
53 	case PSB_TEST_STATUS_BIOS_KEY_BAD_SIG:
54 		return "OEM BIOS signing key failed signature verification";
55 	case PSB_TEST_STATUS_PLATFORM_BAD_ID:
56 		return "Platform vendor id and/or model id binding violation";
57 	case PSB_TEST_STATUS_BIOS_COPY_BIT_UNSET:
58 		return "BIOS copy bit unset for reset image";
59 	case PSB_TEST_STATUS_BIOS_CA_BAD_SIG:
60 		return "OEM BIOS signing CA key failed signature verification";
61 	case PSB_TEST_STATUS_BIOS_CA_BAD_USAGE:
62 		return "OEM BIOS signing CA key usage flag violation";
63 	case PSB_TEST_STATUS_BIOS_KEY_BAD_REVISION:
64 		return "OEM BIOS signing key revision violation";
65 	default:
66 		return "Unknown failure";
67 	}
68 }
69 
fuse_status_to_string(u32 status)70 static const char *fuse_status_to_string(u32 status)
71 {
72 	switch (status) {
73 	case FUSE_STATUS_SUCCESS:
74 		return "PSB Fusing completed successfully";
75 	case FUSE_STATUS_NOT_ALLOWED:
76 		return "Fusing not allowed or already done";
77 	case FUSE_STATUS_FUSING_ERR:
78 		return "Fuse programming failed";
79 	case FUSE_STATUS_BOOT_DONE:
80 		return "Issued after BOOT DONE";
81 	default:
82 		return "Unknown failure";
83 	}
84 }
85 
get_psb_status(void)86 static uint32_t get_psb_status(void)
87 {
88 	return smn_read32(SMN_PSP_PUBLIC_BASE + PSB_STATUS_OFFSET);
89 }
90 
91 /*
92  * Request Platform Secure Boot enablement via the PSP if it is not already
93  * enabled. Upon receiving this command, the PSP will program all PSB fuses
94  * so long as the BIOS signing key token is valid.
95  */
psb_enable(void)96 static enum cb_err psb_enable(void)
97 {
98 	u32 status;
99 	struct mbox_default_buffer buffer = {
100 		.header = {
101 			.size = sizeof(buffer)
102 		}
103 	};
104 
105 	status = get_psb_status();
106 	printk(BIOS_INFO, "PSB: Status = %x\n", status);
107 
108 	if (status & FUSE_PLATFORM_SECURE_BOOT_EN) {
109 		printk(BIOS_DEBUG, "PSB: Already enabled\n");
110 		return CB_SUCCESS;
111 	}
112 
113 	status = soc_read_c2p38();
114 	printk(BIOS_INFO, "PSB: HSTI = %x\n", status);
115 
116 	const u32 psb_test_status = status & PSB_TEST_STATUS_MASK;
117 
118 	if (psb_test_status != PSB_TEST_STATUS_PASS) {
119 		printk(BIOS_ERR, "PSB: %s\n", psb_test_status_to_string(psb_test_status));
120 		return CB_ERR;
121 	}
122 
123 	if (!(status & PSB_FUSING_READY_MASK)) {
124 		printk(BIOS_ERR, "PSB: Fusing not allowed\n");
125 		return CB_ERR;
126 	}
127 
128 	printk(BIOS_DEBUG, "PSB: Enable... ");
129 
130 	const int cmd_status = send_psp_command(MBOX_BIOS_CMD_PSB_AUTO_FUSING, &buffer);
131 
132 	psp_print_cmd_status(cmd_status, &buffer.header);
133 
134 	if (cmd_status) {
135 		printk(BIOS_ERR, "PSB: Fusing request failed: %d\n", cmd_status);
136 		return CB_ERR;
137 	}
138 
139 	const u32 fuse_status = read32(&buffer.header.status);
140 	if (fuse_status != FUSE_STATUS_SUCCESS) {
141 		printk(BIOS_ERR, "PSB: %s\n", fuse_status_to_string(fuse_status));
142 		return CB_ERR;
143 	}
144 
145 	printk(BIOS_NOTICE, "PSB: Rebooting\n");
146 	cold_reset();
147 }
148 
enable_secure_boot(void * unused)149 static void enable_secure_boot(void *unused)
150 {
151 	/*
152 	 * Enable secure boot before loading payload. Psb fusing is done late in
153 	 * boot process to avoid any fuse access conflicts with other components
154 	 * which happens during boot process.
155 	 */
156 	if (psb_enable() == CB_ERR)
157 		printk(BIOS_NOTICE, "Enabling PSB failed.\n");
158 }
159 
160 BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_LOAD, BS_ON_ENTRY, enable_secure_boot, NULL);
161