1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <device/mmio.h>
5 #include <commonlib/region.h>
6 #include <console/console.h>
8 #include <intelblocks/cse.h>
9 #include <intelblocks/p2sb.h>
10 #include <intelblocks/pcr.h>
13 #include <soc/iomap.h>
14 #include <soc/pcr_ids.h>
15 #include <soc/pci_devs.h>
16 #include <device/pci_ops.h>
19 #define MKHI_GROUP_ID_MCA 0x0a
20 #define READ_FILE 0x02
21 #define READ_FILE_FLAG_DEFAULT (1 << 0)
22 #define READ_FILE_FLAG_HASH (1 << 1)
23 #define READ_FILE_FLAG_EMULATED (1 << 2)
24 #define READ_FILE_FLAG_HW (1 << 3)
26 #define MCA_MAX_FILE_PATH_SIZE 64
28 #define FUSE_LOCK_FILE "/fpf/intel/SocCfgLock"
30 /* Status values are made in such a way erase is not needed */
31 static enum fuse_flash_state
{
32 FUSE_FLASH_FUSED
= 0xfc,
33 FUSE_FLASH_UNFUSED
= 0xfe,
34 FUSE_FLASH_UNKNOWN
= 0xff,
37 #define FPF_STATUS_FMAP "FPF_STATUS"
40 * Read file from CSE internal filesystem.
41 * size is maximum length of provided buffer buff, which is updated with actual
42 * size of the file read. flags indicate whether real file or fuse is used.
43 * Returns 1 on success and 0 otherwise.
45 static int read_cse_file(const char *path
, void *buff
, size_t *size
,
46 size_t offset
, uint32_t flags
)
52 char file_name
[MCA_MAX_FILE_PATH_SIZE
];
64 if (sizeof(rmsg
.buffer
) < *size
) {
65 printk(BIOS_ERR
, "internal buffer is too small\n");
69 if (strnlen(path
, sizeof(msg
.file_name
)) >= sizeof(msg
.file_name
)) {
70 printk(BIOS_ERR
, "path too big for msg.file_name buffer\n");
73 strncpy(msg
.file_name
, path
, sizeof(msg
.file_name
));
74 msg
.hdr
.group_id
= MKHI_GROUP_ID_MCA
;
75 msg
.hdr
.command
= READ_FILE
;
77 msg
.data_size
= *size
;
80 reply_size
= sizeof(rmsg
);
82 if (heci_send_receive(&msg
, sizeof(msg
), &rmsg
, &reply_size
, HECI_MKHI_ADDR
)) {
83 printk(BIOS_ERR
, "HECI: Failed to read file\n");
87 if (rmsg
.data_size
> *size
) {
88 printk(BIOS_ERR
, "reply is too large\n");
92 memcpy(buff
, rmsg
.buffer
, rmsg
.data_size
);
93 *size
= rmsg
.data_size
;
98 static enum fuse_flash_state
load_cached_fpf(struct region_device
*rdev
)
100 enum fuse_flash_state state
;
103 state
= FUSE_FLASH_UNKNOWN
;
105 if (rdev_readat(rdev
, &buff
, 0, sizeof(buff
)) >= 0) {
106 state
= read8(&buff
);
110 printk(BIOS_WARNING
, "failed to load cached FPF value\n");
116 int save_fpf_state(enum fuse_flash_state state
, struct region_device
*rdev
)
120 write8(&buff
, (uint8_t)state
);
121 return rdev_writeat(rdev
, &buff
, 0, sizeof(buff
));
124 static void fpf_blown(void *unused
)
127 struct region_device rdev
;
128 size_t sz
= sizeof(fuse
);
129 bool rdev_valid
= false;
131 if (fmap_locate_area_as_rdev_rw(FPF_STATUS_FMAP
, &rdev
) == 0) {
133 g_fuse_state
= load_cached_fpf(&rdev
);
134 if (g_fuse_state
!= FUSE_FLASH_UNKNOWN
)
138 if (!read_cse_file(FUSE_LOCK_FILE
, &fuse
, &sz
, 0, READ_FILE_FLAG_HW
))
141 g_fuse_state
= fuse
== 1 ? FUSE_FLASH_FUSED
: FUSE_FLASH_UNFUSED
;
143 if (rdev_valid
&& (save_fpf_state(g_fuse_state
, &rdev
) < 0))
144 printk(BIOS_CRIT
, "failed to save FPF state\n");
147 static uint32_t dump_status(int index
, int reg_addr
)
151 reg
= me_read_config32(reg_addr
);
153 printk(BIOS_DEBUG
, "CSE FWSTS%d: 0x%08x\n", index
, reg
);
158 static void dump_cse_state(void)
160 union cse_fwsts1 fwsts1
;
161 union cse_fwsts3 fwsts3
;
162 union cse_fwsts4 fwsts4
;
163 union cse_fwsts5 fwsts5
;
164 union cse_fwsts6 fwsts6
;
166 if (!is_cse_enabled())
169 fwsts1
.data
= dump_status(1, PCI_ME_HFSTS1
);
170 dump_status(2, PCI_ME_HFSTS2
);
171 fwsts3
.data
= dump_status(3, PCI_ME_HFSTS3
);
172 fwsts4
.data
= dump_status(4, PCI_ME_HFSTS4
);
173 fwsts5
.data
= dump_status(5, PCI_ME_HFSTS5
);
174 fwsts6
.data
= dump_status(6, PCI_ME_HFSTS6
);
176 printk(BIOS_DEBUG
, "CSE: Working State : %u\n",
177 fwsts1
.fields
.working_state
);
178 printk(BIOS_DEBUG
, "CSE: Manufacturing Mode : %s\n",
179 fwsts1
.fields
.mfg_mode
? "YES" : "NO");
180 printk(BIOS_DEBUG
, "CSE: Operation State : %u\n",
181 fwsts1
.fields
.operation_state
);
182 printk(BIOS_DEBUG
, "CSE: FW Init Complete : %s\n",
183 fwsts1
.fields
.fw_init_complete
? "YES" : "NO");
184 printk(BIOS_DEBUG
, "CSE: Error Code : %u\n",
185 fwsts1
.fields
.error_code
);
186 printk(BIOS_DEBUG
, "CSE: Operation Mode : %u\n",
187 fwsts1
.fields
.operation_mode
);
188 printk(BIOS_DEBUG
, "CSE: IBB Verification Result: %s\n",
189 fwsts3
.fields
.ibb_verif_result
? "PASS" : "FAIL");
190 printk(BIOS_DEBUG
, "CSE: IBB Verification Done : %s\n",
191 fwsts3
.fields
.ibb_verif_done
? "YES" : "NO");
192 printk(BIOS_DEBUG
, "CSE: Actual IBB Size : %u\n",
193 fwsts3
.fields
.ibb_size
);
194 printk(BIOS_DEBUG
, "CSE: Verified Boot Valid : %s\n",
195 fwsts4
.fields
.txe_veri_boot_valid
? "PASS" : "FAIL");
196 printk(BIOS_DEBUG
, "CSE: Verified Boot Test : %s\n",
197 fwsts4
.fields
.txe_veri_boot_test
? "YES" : "NO");
198 printk(BIOS_DEBUG
, "CSE: FPF status : %s\n",
199 fwsts6
.fields
.fpf_commited
? "FUSED" : "UNFUSED");
200 printk(BIOS_DEBUG
, "CSE: Error Status Code : %u\n",
201 fwsts5
.fields
.error_status_code
);
204 #define PCR_PSFX_T0_SHDW_PCIEN 0x1C
205 #define PCR_PSFX_T0_SHDW_PCIEN_FUNDIS (1 << 8)
207 void soc_disable_heci1_using_pcr(void)
209 pcr_or32(PID_PSF3
, PSF3_BASE_ADDRESS
+ PCR_PSFX_T0_SHDW_PCIEN
,
210 PCR_PSFX_T0_SHDW_PCIEN_FUNDIS
);
213 void heci_cse_lockdown(void)
218 * It is safe to disable HECI1 now since we won't be talking to the ME
221 if (CONFIG(DISABLE_HECI1_AT_PRE_BOOT
))
225 BOOT_STATE_INIT_ENTRY(BS_DEV_INIT
, BS_ON_ENTRY
, fpf_blown
, NULL
);
226 BOOT_STATE_INIT_ENTRY(BS_DEV_INIT
, BS_ON_EXIT
, print_me_fw_version
, NULL
);