blob: 86fccc56f0daf6388eea8fb64c5f7564166c485b [file] [log] [blame]
Angel Pons5deff302021-01-27 12:25:52 +01001/* SPDX-License-Identifier: GPL-2.0-only */
2
3#include <acpi/acpi.h>
4#include <device/mmio.h>
5#include <device/device.h>
6#include <device/pci.h>
7#include <device/pci_ops.h>
8#include <console/console.h>
9#include <device/pci_ids.h>
10#include <device/pci_def.h>
11#include <string.h>
12#include <delay.h>
13
14#include "me.h"
15#include "pch.h"
16
17/* Send END OF POST message to the ME */
18static int me8_mkhi_end_of_post(void)
19{
20 struct mkhi_header mkhi = {
21 .group_id = MKHI_GROUP_ID_GEN,
22 .command = MKHI_END_OF_POST,
23 };
24 struct mei_header mei = {
25 .is_complete = 1,
26 .host_address = MEI_HOST_ADDRESS,
27 .client_address = MEI_ADDRESS_MKHI,
28 .length = sizeof(mkhi),
29 };
30
31 u32 eop_ack;
32
33 /* Send request and wait for response */
34 printk(BIOS_NOTICE, "ME: %s\n", __func__);
35 if (mei_sendrecv(&mei, &mkhi, NULL, &eop_ack, sizeof(eop_ack)) < 0) {
36 printk(BIOS_ERR, "ME: END OF POST message failed\n");
37 return -1;
38 }
39
40 printk(BIOS_INFO, "ME: END OF POST message successful (%d)\n", eop_ack);
41 return 0;
42}
43
44void intel_me8_finalize_smm(void)
45{
46 struct me_hfs hfs;
47 u32 reg32;
48
49 update_mei_base_address();
50
51 /* S3 path will have hidden this device already */
52 if (!is_mei_base_address_valid())
53 return;
54
55 /* Make sure ME is in a mode that expects EOP */
56 reg32 = pci_read_config32(PCH_ME_DEV, PCI_ME_HFS);
57 memcpy(&hfs, &reg32, sizeof(u32));
58
59 /* Abort and leave device alone if not normal mode */
60 if (hfs.fpt_bad ||
61 hfs.working_state != ME_HFS_CWS_NORMAL ||
62 hfs.operation_mode != ME_HFS_MODE_NORMAL)
63 return;
64
65 /* Try to send EOP command so ME stops accepting other commands */
66 me8_mkhi_end_of_post();
67
68 /* Make sure IO is disabled */
69 pci_and_config16(PCH_ME_DEV, PCI_COMMAND,
70 ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO));
71
72 /* Hide the PCI device */
73 RCBA32_OR(FD2, PCH_DISABLE_MEI1);
74}
75
76/* Send END OF POST message to the ME */
77static int me7_mkhi_end_of_post(void)
78{
79 struct mkhi_header mkhi = {
80 .group_id = MKHI_GROUP_ID_GEN,
81 .command = MKHI_END_OF_POST,
82 };
83 struct mei_header mei = {
84 .is_complete = 1,
85 .host_address = MEI_HOST_ADDRESS,
86 .client_address = MEI_ADDRESS_MKHI,
87 .length = sizeof(mkhi),
88 };
89
90 /* Send request and wait for response */
91 if (mei_sendrecv(&mei, &mkhi, NULL, NULL, 0) < 0) {
92 printk(BIOS_ERR, "ME: END OF POST message failed\n");
93 return -1;
94 }
95
96 printk(BIOS_INFO, "ME: END OF POST message successful\n");
97 return 0;
98}
99
100static void intel_me7_finalize_smm(void)
101{
102 struct me_hfs hfs;
103 u32 reg32;
104
105 update_mei_base_address();
106
107 /* S3 path will have hidden this device already */
108 if (!is_mei_base_address_valid())
109 return;
110
111 /* Make sure ME is in a mode that expects EOP */
112 reg32 = pci_read_config32(PCH_ME_DEV, PCI_ME_HFS);
113 memcpy(&hfs, &reg32, sizeof(u32));
114
115 /* Abort and leave device alone if not normal mode */
116 if (hfs.fpt_bad ||
117 hfs.working_state != ME_HFS_CWS_NORMAL ||
118 hfs.operation_mode != ME_HFS_MODE_NORMAL)
119 return;
120
121 /* Try to send EOP command so ME stops accepting other commands */
122 me7_mkhi_end_of_post();
123
124 /* Make sure IO is disabled */
125 pci_and_config16(PCH_ME_DEV, PCI_COMMAND,
126 ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO));
127
128 /* Hide the PCI device */
129 RCBA32_OR(FD2, PCH_DISABLE_MEI1);
130}
131
132void intel_me_finalize_smm(void)
133{
134 u16 did = pci_read_config16(PCH_ME_DEV, PCI_DEVICE_ID);
135 switch (did) {
136 case 0x1c3a:
137 intel_me7_finalize_smm();
138 break;
139 case 0x1e3a:
140 intel_me8_finalize_smm();
141 break;
142 default:
143 printk(BIOS_ERR, "No finalize handler for ME %04x.\n", did);
144 }
145}