blob: ea39559d98aa09303aeb3b89282db20741e99965 [file] [log] [blame]
Angel Pons5deff302021-01-27 12:25:52 +01001/* SPDX-License-Identifier: GPL-2.0-only */
2
Angel Pons5deff302021-01-27 12:25:52 +01003#include <console/console.h>
Angel Pons5152f162021-01-27 12:29:30 +01004#include <device/pci.h>
Angel Pons5152f162021-01-27 12:29:30 +01005#include <device/pci_ids.h>
6#include <device/pci_ops.h>
7#include <stdint.h>
Angel Pons5deff302021-01-27 12:25:52 +01008
9#include "me.h"
10#include "pch.h"
11
12/* Send END OF POST message to the ME */
13static 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
Angel Pons5deff302021-01-27 12:25:52 +010039/* Send END OF POST message to the ME */
40static 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
Angel Pons5152f162021-01-27 12:29:30 +010063void intel_me_finalize_smm(void)
Angel Pons5deff302021-01-27 12:25:52 +010064{
Angel Pons3f7bb7d2021-01-27 13:03:20 +010065 union me_hfs hfs;
Angel Pons5deff302021-01-27 12:25:52 +010066
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 */
Angel Pons3f7bb7d2021-01-27 13:03:20 +010074 hfs.raw = pci_read_config32(PCH_ME_DEV, PCI_ME_HFS);
Angel Pons5deff302021-01-27 12:25:52 +010075
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 */
Angel Pons5152f162021-01-27 12:29:30 +010083 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 }
Angel Pons5deff302021-01-27 12:25:52 +010094
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}