xref: /aosp_15_r20/external/coreboot/src/southbridge/intel/bd82x6x/me_smm.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <console/console.h>
4 #include <device/pci.h>
5 #include <device/pci_ids.h>
6 #include <device/pci_ops.h>
7 #include <stdint.h>
8 
9 #include "me.h"
10 #include "pch.h"
11 
12 /* Send END OF POST message to the ME */
me8_mkhi_end_of_post(void)13 static int me8_mkhi_end_of_post(void)
14 {
15 	struct mkhi_header mkhi = {
16 		.group_id	= MKHI_GROUP_ID_GEN,
17 		.command	= MKHI_END_OF_POST,
18 	};
19 	struct mei_header mei = {
20 		.is_complete	= 1,
21 		.host_address	= MEI_HOST_ADDRESS,
22 		.client_address	= MEI_ADDRESS_MKHI,
23 		.length		= sizeof(mkhi),
24 	};
25 
26 	u32 eop_ack;
27 
28 	/* Send request and wait for response */
29 	printk(BIOS_NOTICE, "ME: %s\n", __func__);
30 	if (mei_sendrecv(&mei, &mkhi, NULL, &eop_ack, sizeof(eop_ack)) < 0) {
31 		printk(BIOS_ERR, "ME: END OF POST message failed\n");
32 		return -1;
33 	}
34 
35 	printk(BIOS_INFO, "ME: END OF POST message successful (%d)\n", eop_ack);
36 	return 0;
37 }
38 
39 /* Send END OF POST message to the ME */
me7_mkhi_end_of_post(void)40 static int me7_mkhi_end_of_post(void)
41 {
42 	struct mkhi_header mkhi = {
43 		.group_id	= MKHI_GROUP_ID_GEN,
44 		.command	= MKHI_END_OF_POST,
45 	};
46 	struct mei_header mei = {
47 		.is_complete	= 1,
48 		.host_address	= MEI_HOST_ADDRESS,
49 		.client_address	= MEI_ADDRESS_MKHI,
50 		.length		= sizeof(mkhi),
51 	};
52 
53 	/* Send request and wait for response */
54 	if (mei_sendrecv(&mei, &mkhi, NULL, NULL, 0) < 0) {
55 		printk(BIOS_ERR, "ME: END OF POST message failed\n");
56 		return -1;
57 	}
58 
59 	printk(BIOS_INFO, "ME: END OF POST message successful\n");
60 	return 0;
61 }
62 
intel_me_finalize_smm(void)63 void intel_me_finalize_smm(void)
64 {
65 	union me_hfs hfs;
66 
67 	update_mei_base_address();
68 
69 	/* S3 path will have hidden this device already */
70 	if (!is_mei_base_address_valid())
71 		return;
72 
73 	/* Make sure ME is in a mode that expects EOP */
74 	hfs.raw = pci_read_config32(PCH_ME_DEV, PCI_ME_HFS);
75 
76 	/* Abort and leave device alone if not normal mode */
77 	if (hfs.fpt_bad ||
78 	    hfs.working_state != ME_HFS_CWS_NORMAL ||
79 	    hfs.operation_mode != ME_HFS_MODE_NORMAL)
80 		return;
81 
82 	/* Try to send EOP command so ME stops accepting other commands */
83 	const u16 did = pci_read_config16(PCH_ME_DEV, PCI_DEVICE_ID);
84 	switch (did) {
85 	case 0x1c3a:
86 		me7_mkhi_end_of_post();
87 		break;
88 	case 0x1e3a:
89 		me8_mkhi_end_of_post();
90 		break;
91 	default:
92 		printk(BIOS_ERR, "No finalize handler for ME %04x.\n", did);
93 	}
94 
95 	/* Make sure IO is disabled */
96 	pci_and_config16(PCH_ME_DEV, PCI_COMMAND,
97 			 ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO));
98 
99 	/* Hide the PCI device */
100 	RCBA32_OR(FD2, PCH_DISABLE_MEI1);
101 }
102