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