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