xref: /aosp_15_r20/external/coreboot/src/soc/intel/common/block/cse/disable_heci.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #define __SIMPLE_DEVICE__
4 
5 #include <commonlib/helpers.h>
6 #include <console/console.h>
7 #include <device/pci.h>
8 #include <device/pci_ids.h>
9 #include <device/pci_ops.h>
10 #include <intelblocks/cse.h>
11 #include <intelblocks/p2sb.h>
12 #include <intelblocks/pcr.h>
13 #include <intelblocks/pmc_ipc.h>
14 #include <soc/pci_devs.h>
15 #include <soc/pcr_ids.h>
16 
17 #define CSME0_FBE	0xf
18 #define CSME0_BAR	0x0
19 #define CSME0_FID	0xb0
20 
21 #define PMC_IPC_MEI_DISABLE_ID			0xa9
22 #define PMC_IPC_MEI_DISABLE_SUBID_ENABLE	0
23 #define PMC_IPC_MEI_DISABLE_SUBID_DISABLE	1
24 
25 /* Disable HECI using PCR */
heci1_disable_using_pcr(void)26 static void heci1_disable_using_pcr(void)
27 {
28 	soc_disable_heci1_using_pcr();
29 }
30 
cse_disable_mei_devices(void)31 bool cse_disable_mei_devices(void)
32 {
33 	struct pmc_ipc_buffer req = { 0 };
34 	struct pmc_ipc_buffer rsp;
35 	uint32_t cmd;
36 
37 	cmd = pmc_make_ipc_cmd(PMC_IPC_MEI_DISABLE_ID, PMC_IPC_MEI_DISABLE_SUBID_DISABLE, 0);
38 	if (pmc_send_ipc_cmd(cmd, &req, &rsp) != CB_SUCCESS) {
39 		printk(BIOS_ERR, "CSE: Failed to disable MEI devices\n");
40 		return false;
41 	}
42 
43 	return true;
44 }
45 
46 /* Disable HECI using PMC IPC communication */
heci1_disable_using_pmc(void)47 static void heci1_disable_using_pmc(void)
48 {
49 	cse_disable_mei_devices();
50 }
51 
52 /* Disable HECI using Sideband interface communication */
heci1_disable_using_sbi(void)53 static void heci1_disable_using_sbi(void)
54 {
55 	struct pcr_sbi_msg msg = {
56 		.pid = PID_CSME0,
57 		.offset = 0,
58 		.opcode = PCR_WRITE,
59 		.is_posted = false,
60 		.fast_byte_enable = CSME0_FBE,
61 		.bar = CSME0_BAR,
62 		.fid = CSME0_FID
63 	};
64 	/* Bit 0: Set to make HECI#1 Function disable */
65 	uint32_t data32 = 1;
66 	uint8_t response;
67 	int status;
68 
69 	/* unhide p2sb device */
70 	p2sb_unhide();
71 
72 	/* Send SBI command to make HECI#1 function disable */
73 	status = pcr_execute_sideband_msg(PCH_DEV_P2SB, &msg, &data32, &response);
74 	if (status || response)
75 		printk(BIOS_ERR, "Fail to make CSME function disable\n");
76 
77 	/* Ensure to Lock SBI interface after this command */
78 	p2sb_disable_sideband_access();
79 
80 	/* hide p2sb device */
81 	p2sb_hide();
82 }
83 
heci1_disable(void)84 void heci1_disable(void)
85 {
86 	if (ENV_SMM && CONFIG(SOC_INTEL_COMMON_BLOCK_HECI1_DISABLE_USING_SBI)) {
87 		printk(BIOS_INFO, "Disabling Heci using SBI in SMM mode\n");
88 		return heci1_disable_using_sbi();
89 	} else if (!ENV_SMM && CONFIG(SOC_INTEL_COMMON_BLOCK_HECI1_DISABLE_USING_PMC_IPC)) {
90 		printk(BIOS_INFO, "Disabling Heci using PMC IPC\n");
91 		return heci1_disable_using_pmc();
92 	} else if (!ENV_SMM && CONFIG(SOC_INTEL_COMMON_BLOCK_HECI1_DISABLE_USING_PCR)) {
93 		printk(BIOS_INFO, "Disabling Heci using PCR\n");
94 		return heci1_disable_using_pcr();
95 	} else {
96 		printk(BIOS_ERR, "%s Error: Unable to make HECI1 function disable!\n",
97 				__func__);
98 	}
99 }
100