blob: e1eb9001df564dffc919bedc27d9476504fb2478 [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 Pons5deff302021-01-27 12:25:52 +01005#include <device/pci_def.h>
Angel Pons5152f162021-01-27 12:29:30 +01006#include <device/pci_ids.h>
7#include <device/pci_ops.h>
8#include <stdint.h>
Angel Pons5deff302021-01-27 12:25:52 +01009#include <string.h>
Angel Pons5deff302021-01-27 12:25:52 +010010
11#include "me.h"
12#include "pch.h"
13
14/* Send END OF POST message to the ME */
15static int me8_mkhi_end_of_post(void)
16{
17 struct mkhi_header mkhi = {
18 .group_id = MKHI_GROUP_ID_GEN,
19 .command = MKHI_END_OF_POST,
20 };
21 struct mei_header mei = {
22 .is_complete = 1,
23 .host_address = MEI_HOST_ADDRESS,
24 .client_address = MEI_ADDRESS_MKHI,
25 .length = sizeof(mkhi),
26 };
27
28 u32 eop_ack;
29
30 /* Send request and wait for response */
31 printk(BIOS_NOTICE, "ME: %s\n", __func__);
32 if (mei_sendrecv(&mei, &mkhi, NULL, &eop_ack, sizeof(eop_ack)) < 0) {
33 printk(BIOS_ERR, "ME: END OF POST message failed\n");
34 return -1;
35 }
36
37 printk(BIOS_INFO, "ME: END OF POST message successful (%d)\n", eop_ack);
38 return 0;
39}
40
Angel Pons5deff302021-01-27 12:25:52 +010041/* Send END OF POST message to the ME */
42static int me7_mkhi_end_of_post(void)
43{
44 struct mkhi_header mkhi = {
45 .group_id = MKHI_GROUP_ID_GEN,
46 .command = MKHI_END_OF_POST,
47 };
48 struct mei_header mei = {
49 .is_complete = 1,
50 .host_address = MEI_HOST_ADDRESS,
51 .client_address = MEI_ADDRESS_MKHI,
52 .length = sizeof(mkhi),
53 };
54
55 /* Send request and wait for response */
56 if (mei_sendrecv(&mei, &mkhi, NULL, NULL, 0) < 0) {
57 printk(BIOS_ERR, "ME: END OF POST message failed\n");
58 return -1;
59 }
60
61 printk(BIOS_INFO, "ME: END OF POST message successful\n");
62 return 0;
63}
64
Angel Pons5152f162021-01-27 12:29:30 +010065void intel_me_finalize_smm(void)
Angel Pons5deff302021-01-27 12:25:52 +010066{
Angel Pons3f7bb7d2021-01-27 13:03:20 +010067 union me_hfs hfs;
Angel Pons5deff302021-01-27 12:25:52 +010068
69 update_mei_base_address();
70
71 /* S3 path will have hidden this device already */
72 if (!is_mei_base_address_valid())
73 return;
74
75 /* Make sure ME is in a mode that expects EOP */
Angel Pons3f7bb7d2021-01-27 13:03:20 +010076 hfs.raw = pci_read_config32(PCH_ME_DEV, PCI_ME_HFS);
Angel Pons5deff302021-01-27 12:25:52 +010077
78 /* Abort and leave device alone if not normal mode */
79 if (hfs.fpt_bad ||
80 hfs.working_state != ME_HFS_CWS_NORMAL ||
81 hfs.operation_mode != ME_HFS_MODE_NORMAL)
82 return;
83
84 /* Try to send EOP command so ME stops accepting other commands */
Angel Pons5152f162021-01-27 12:29:30 +010085 const u16 did = pci_read_config16(PCH_ME_DEV, PCI_DEVICE_ID);
86 switch (did) {
87 case 0x1c3a:
88 me7_mkhi_end_of_post();
89 break;
90 case 0x1e3a:
91 me8_mkhi_end_of_post();
92 break;
93 default:
94 printk(BIOS_ERR, "No finalize handler for ME %04x.\n", did);
95 }
Angel Pons5deff302021-01-27 12:25:52 +010096
97 /* Make sure IO is disabled */
98 pci_and_config16(PCH_ME_DEV, PCI_COMMAND,
99 ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO));
100
101 /* Hide the PCI device */
102 RCBA32_OR(FD2, PCH_DISABLE_MEI1);
103}