blob: afe9c827051f77ef18a30d558f45e7e80e46aa53 [file] [log] [blame]
Angel Ponsf94ac9a2020-04-05 15:46:48 +02001/* SPDX-License-Identifier: GPL-2.0-only */
2/* This file is part of the coreboot project. */
Duncan Lauriec88c54c2014-04-30 16:36:13 -07003
4/*
5 * This is a ramstage driver for the Intel Management Engine found in the
6 * southbridge. It handles the required boot-time messages over the
7 * MMIO-based Management Engine Interface to tell the ME that the BIOS is
8 * finished with POST. Additional messages are defined for debug but are
9 * not used unless the console loglevel is high enough.
10 */
11
12#include <arch/acpi.h>
Kyösti Mälkki13f66502019-03-03 08:01:05 +020013#include <device/mmio.h>
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +020014#include <device/pci_ops.h>
Duncan Lauriec88c54c2014-04-30 16:36:13 -070015#include <console/console.h>
16#include <device/device.h>
17#include <device/pci.h>
18#include <device/pci_ids.h>
19#include <device/pci_def.h>
Elyes HAOUAS70a03dd2019-12-02 20:47:50 +010020#include <stdlib.h>
Duncan Lauriec88c54c2014-04-30 16:36:13 -070021#include <string.h>
22#include <delay.h>
23#include <elog.h>
Julius Werner4ee4bd52014-10-20 13:46:39 -070024#include <soc/me.h>
25#include <soc/lpc.h>
26#include <soc/pch.h>
27#include <soc/pci_devs.h>
28#include <soc/ramstage.h>
29#include <soc/rcba.h>
30#include <soc/intel/broadwell/chip.h>
Duncan Lauriec88c54c2014-04-30 16:36:13 -070031
Julius Wernercd49cce2019-03-05 16:53:33 -080032#if CONFIG(CHROMEOS)
Duncan Lauriec88c54c2014-04-30 16:36:13 -070033#include <vendorcode/google/chromeos/chromeos.h>
34#include <vendorcode/google/chromeos/gnvs.h>
35#endif
36
37/* Path that the BIOS should take based on ME state */
38static const char *me_bios_path_values[] = {
39 [ME_NORMAL_BIOS_PATH] = "Normal",
40 [ME_S3WAKE_BIOS_PATH] = "S3 Wake",
41 [ME_ERROR_BIOS_PATH] = "Error",
42 [ME_RECOVERY_BIOS_PATH] = "Recovery",
43 [ME_DISABLE_BIOS_PATH] = "Disable",
44 [ME_FIRMWARE_UPDATE_BIOS_PATH] = "Firmware Update",
45};
Duncan Lauriec88c54c2014-04-30 16:36:13 -070046
47/* MMIO base address for MEI interface */
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080048static u8 *mei_base_address;
Duncan Lauriec88c54c2014-04-30 16:36:13 -070049
Duncan Lauriec88c54c2014-04-30 16:36:13 -070050static void mei_dump(void *ptr, int dword, int offset, const char *type)
51{
52 struct mei_csr *csr;
53
Kyösti Mälkkic86fc8e2019-11-06 06:32:27 +020054 if (!CONFIG(DEBUG_INTEL_ME))
55 return;
56
Duncan Lauriec88c54c2014-04-30 16:36:13 -070057 printk(BIOS_SPEW, "%-9s[%02x] : ", type, offset);
58
59 switch (offset) {
60 case MEI_H_CSR:
61 case MEI_ME_CSR_HA:
62 csr = ptr;
63 if (!csr) {
64 printk(BIOS_SPEW, "ERROR: 0x%08x\n", dword);
65 break;
66 }
67 printk(BIOS_SPEW, "cbd=%u cbrp=%02u cbwp=%02u ready=%u "
68 "reset=%u ig=%u is=%u ie=%u\n", csr->buffer_depth,
69 csr->buffer_read_ptr, csr->buffer_write_ptr,
70 csr->ready, csr->reset, csr->interrupt_generate,
71 csr->interrupt_status, csr->interrupt_enable);
72 break;
73 case MEI_ME_CB_RW:
74 case MEI_H_CB_WW:
75 printk(BIOS_SPEW, "CB: 0x%08x\n", dword);
76 break;
77 default:
78 printk(BIOS_SPEW, "0x%08x\n", offset);
79 break;
80 }
81}
Duncan Lauriec88c54c2014-04-30 16:36:13 -070082
83/*
84 * ME/MEI access helpers using memcpy to avoid aliasing.
85 */
86
87static inline void mei_read_dword_ptr(void *ptr, int offset)
88{
89 u32 dword = read32(mei_base_address + offset);
90 memcpy(ptr, &dword, sizeof(dword));
91 mei_dump(ptr, dword, offset, "READ");
92}
93
94static inline void mei_write_dword_ptr(void *ptr, int offset)
95{
96 u32 dword = 0;
97 memcpy(&dword, ptr, sizeof(dword));
98 write32(mei_base_address + offset, dword);
99 mei_dump(ptr, dword, offset, "WRITE");
100}
101
Elyes HAOUAS040aff22018-05-27 16:30:36 +0200102static inline void pci_read_dword_ptr(struct device *dev, void *ptr, int offset)
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700103{
104 u32 dword = pci_read_config32(dev, offset);
105 memcpy(ptr, &dword, sizeof(dword));
106 mei_dump(ptr, dword, offset, "PCI READ");
107}
108
109static inline void read_host_csr(struct mei_csr *csr)
110{
111 mei_read_dword_ptr(csr, MEI_H_CSR);
112}
113
114static inline void write_host_csr(struct mei_csr *csr)
115{
116 mei_write_dword_ptr(csr, MEI_H_CSR);
117}
118
119static inline void read_me_csr(struct mei_csr *csr)
120{
121 mei_read_dword_ptr(csr, MEI_ME_CSR_HA);
122}
123
124static inline void write_cb(u32 dword)
125{
126 write32(mei_base_address + MEI_H_CB_WW, dword);
127 mei_dump(NULL, dword, MEI_H_CB_WW, "WRITE");
128}
129
130static inline u32 read_cb(void)
131{
132 u32 dword = read32(mei_base_address + MEI_ME_CB_RW);
133 mei_dump(NULL, dword, MEI_ME_CB_RW, "READ");
134 return dword;
135}
136
137/* Wait for ME ready bit to be asserted */
138static int mei_wait_for_me_ready(void)
139{
140 struct mei_csr me;
Lee Leahy23602df2017-03-16 19:00:37 -0700141 unsigned int try = ME_RETRY;
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700142
143 while (try--) {
144 read_me_csr(&me);
145 if (me.ready)
146 return 0;
147 udelay(ME_DELAY);
148 }
149
150 printk(BIOS_ERR, "ME: failed to become ready\n");
151 return -1;
152}
153
154static void mei_reset(void)
155{
156 struct mei_csr host;
157
158 if (mei_wait_for_me_ready() < 0)
159 return;
160
161 /* Reset host and ME circular buffers for next message */
162 read_host_csr(&host);
163 host.reset = 1;
164 host.interrupt_generate = 1;
165 write_host_csr(&host);
166
167 if (mei_wait_for_me_ready() < 0)
168 return;
169
170 /* Re-init and indicate host is ready */
171 read_host_csr(&host);
172 host.interrupt_generate = 1;
173 host.ready = 1;
174 host.reset = 0;
175 write_host_csr(&host);
176}
177
178static int mei_send_packet(struct mei_header *mei, void *req_data)
179{
180 struct mei_csr host;
Lee Leahy23602df2017-03-16 19:00:37 -0700181 unsigned int ndata, n;
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700182 u32 *data;
183
184 /* Number of dwords to write */
185 ndata = mei->length >> 2;
186
187 /* Pad non-dword aligned request message length */
188 if (mei->length & 3)
189 ndata++;
190 if (!ndata) {
191 printk(BIOS_DEBUG, "ME: request has no data\n");
192 return -1;
193 }
194 ndata++; /* Add MEI header */
195
196 /*
197 * Make sure there is still room left in the circular buffer.
198 * Reset the buffer pointers if the requested message will not fit.
199 */
200 read_host_csr(&host);
201 if ((host.buffer_depth - host.buffer_write_ptr) < ndata) {
202 printk(BIOS_ERR, "ME: circular buffer full, resetting...\n");
203 mei_reset();
204 read_host_csr(&host);
205 }
206
207 /* Ensure the requested length will fit in the circular buffer. */
208 if ((host.buffer_depth - host.buffer_write_ptr) < ndata) {
209 printk(BIOS_ERR, "ME: message (%u) too large for buffer (%u)\n",
210 ndata + 2, host.buffer_depth);
211 return -1;
212 }
213
214 /* Write MEI header */
215 mei_write_dword_ptr(mei, MEI_H_CB_WW);
216 ndata--;
217
218 /* Write message data */
219 data = req_data;
220 for (n = 0; n < ndata; ++n)
221 write_cb(*data++);
222
223 /* Generate interrupt to the ME */
224 read_host_csr(&host);
225 host.interrupt_generate = 1;
226 write_host_csr(&host);
227
228 /* Make sure ME is ready after sending request data */
229 return mei_wait_for_me_ready();
230}
231
232static int mei_send_data(u8 me_address, u8 host_address,
233 void *req_data, int req_bytes)
234{
235 struct mei_header header = {
236 .client_address = me_address,
237 .host_address = host_address,
238 };
239 struct mei_csr host;
240 int current = 0;
241 u8 *req_ptr = req_data;
242
243 while (!header.is_complete) {
244 int remain = req_bytes - current;
245 int buf_len;
246
247 read_host_csr(&host);
248 buf_len = host.buffer_depth - host.buffer_write_ptr;
249
250 if (buf_len > remain) {
251 /* Send all remaining data as final message */
252 header.length = req_bytes - current;
253 header.is_complete = 1;
254 } else {
255 /* Send as much data as the buffer can hold */
256 header.length = buf_len;
257 }
258
259 mei_send_packet(&header, req_ptr);
260
261 req_ptr += header.length;
262 current += header.length;
263 }
264
265 return 0;
266}
267
268static int mei_send_header(u8 me_address, u8 host_address,
269 void *header, int header_len, int complete)
270{
271 struct mei_header mei = {
272 .client_address = me_address,
273 .host_address = host_address,
274 .length = header_len,
275 .is_complete = complete,
276 };
277 return mei_send_packet(&mei, header);
278}
279
280static int mei_recv_msg(void *header, int header_bytes,
281 void *rsp_data, int rsp_bytes)
282{
283 struct mei_header mei_rsp;
284 struct mei_csr me, host;
Lee Leahy23602df2017-03-16 19:00:37 -0700285 unsigned int ndata, n;
286 unsigned int expected;
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700287 u32 *data;
288
289 /* Total number of dwords to read from circular buffer */
290 expected = (rsp_bytes + sizeof(mei_rsp) + header_bytes) >> 2;
291 if (rsp_bytes & 3)
292 expected++;
293
294 if (mei_wait_for_me_ready() < 0)
295 return -1;
296
297 /*
298 * The interrupt status bit does not appear to indicate that the
299 * message has actually been received. Instead we wait until the
300 * expected number of dwords are present in the circular buffer.
301 */
302 for (n = ME_RETRY; n; --n) {
303 read_me_csr(&me);
304 if ((me.buffer_write_ptr - me.buffer_read_ptr) >= expected)
305 break;
306 udelay(ME_DELAY);
307 }
308 if (!n) {
309 printk(BIOS_ERR, "ME: timeout waiting for data: expected "
310 "%u, available %u\n", expected,
311 me.buffer_write_ptr - me.buffer_read_ptr);
312 return -1;
313 }
314
315 /* Read and verify MEI response header from the ME */
316 mei_read_dword_ptr(&mei_rsp, MEI_ME_CB_RW);
317 if (!mei_rsp.is_complete) {
318 printk(BIOS_ERR, "ME: response is not complete\n");
319 return -1;
320 }
321
322 /* Handle non-dword responses and expect at least the header */
323 ndata = mei_rsp.length >> 2;
324 if (mei_rsp.length & 3)
325 ndata++;
326 if (ndata != (expected - 1)) {
327 printk(BIOS_ERR, "ME: response is missing data %d != %d\n",
328 ndata, (expected - 1));
329 return -1;
330 }
331
332 /* Read response header from the ME */
333 data = header;
334 for (n = 0; n < (header_bytes >> 2); ++n)
335 *data++ = read_cb();
336 ndata -= header_bytes >> 2;
337
338 /* Make sure caller passed a buffer with enough space */
339 if (ndata != (rsp_bytes >> 2)) {
340 printk(BIOS_ERR, "ME: not enough room in response buffer: "
341 "%u != %u\n", ndata, rsp_bytes >> 2);
342 return -1;
343 }
344
345 /* Read response data from the circular buffer */
346 data = rsp_data;
347 for (n = 0; n < ndata; ++n)
348 *data++ = read_cb();
349
350 /* Tell the ME that we have consumed the response */
351 read_host_csr(&host);
352 host.interrupt_status = 1;
353 host.interrupt_generate = 1;
354 write_host_csr(&host);
355
356 return mei_wait_for_me_ready();
357}
358
359static inline int mei_sendrecv_mkhi(struct mkhi_header *mkhi,
360 void *req_data, int req_bytes,
361 void *rsp_data, int rsp_bytes)
362{
363 struct mkhi_header mkhi_rsp;
364
365 /* Send header */
366 if (mei_send_header(MEI_ADDRESS_MKHI, MEI_HOST_ADDRESS,
367 mkhi, sizeof(*mkhi), req_bytes ? 0 : 1) < 0)
368 return -1;
369
370 /* Send data if available */
371 if (req_bytes && mei_send_data(MEI_ADDRESS_MKHI, MEI_HOST_ADDRESS,
372 req_data, req_bytes) < 0)
373 return -1;
374
375 /* Return now if no response expected */
376 if (!rsp_bytes)
377 return 0;
378
379 /* Read header and data */
380 if (mei_recv_msg(&mkhi_rsp, sizeof(mkhi_rsp),
381 rsp_data, rsp_bytes) < 0)
382 return -1;
383
384 if (!mkhi_rsp.is_response ||
385 mkhi->group_id != mkhi_rsp.group_id ||
386 mkhi->command != mkhi_rsp.command) {
387 printk(BIOS_ERR, "ME: invalid response, group %u ?= %u,"
388 "command %u ?= %u, is_response %u\n", mkhi->group_id,
389 mkhi_rsp.group_id, mkhi->command, mkhi_rsp.command,
390 mkhi_rsp.is_response);
391 return -1;
392 }
393
394 return 0;
395}
396
397static inline int mei_sendrecv_icc(struct icc_header *icc,
398 void *req_data, int req_bytes,
399 void *rsp_data, int rsp_bytes)
400{
401 struct icc_header icc_rsp;
402
403 /* Send header */
404 if (mei_send_header(MEI_ADDRESS_ICC, MEI_HOST_ADDRESS,
405 icc, sizeof(*icc), req_bytes ? 0 : 1) < 0)
406 return -1;
407
408 /* Send data if available */
409 if (req_bytes && mei_send_data(MEI_ADDRESS_ICC, MEI_HOST_ADDRESS,
410 req_data, req_bytes) < 0)
411 return -1;
412
413 /* Read header and data, if needed */
414 if (rsp_bytes && mei_recv_msg(&icc_rsp, sizeof(icc_rsp),
415 rsp_data, rsp_bytes) < 0)
416 return -1;
417
418 return 0;
419}
420
421/*
422 * mbp give up routine. This path is taken if hfs.mpb_rdy is 0 or the read
423 * state machine on the BIOS end doesn't match the ME's state machine.
424 */
Elyes HAOUAS040aff22018-05-27 16:30:36 +0200425static void intel_me_mbp_give_up(struct device *dev)
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700426{
427 struct mei_csr csr;
428
429 pci_write_config32(dev, PCI_ME_H_GS2, PCI_ME_MBP_GIVE_UP);
430
431 read_host_csr(&csr);
432 csr.reset = 1;
433 csr.interrupt_generate = 1;
434 write_host_csr(&csr);
435}
436
437/*
438 * mbp clear routine. This will wait for the ME to indicate that
439 * the MBP has been read and cleared.
440 */
Elyes HAOUAS040aff22018-05-27 16:30:36 +0200441static void intel_me_mbp_clear(struct device *dev)
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700442{
443 int count;
444 struct me_hfs2 hfs2;
445
446 /* Wait for the mbp_cleared indicator */
447 for (count = ME_RETRY; count > 0; --count) {
448 pci_read_dword_ptr(dev, &hfs2, PCI_ME_HFS2);
449 if (hfs2.mbp_cleared)
450 break;
451 udelay(ME_DELAY);
452 }
453
454 if (count == 0) {
455 printk(BIOS_WARNING, "ME: Timeout waiting for mbp_cleared\n");
456 intel_me_mbp_give_up(dev);
457 } else {
458 printk(BIOS_INFO, "ME: MBP cleared\n");
459 }
460}
461
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700462static void me_print_fw_version(mbp_fw_version_name *vers_name)
463{
464 if (!vers_name) {
465 printk(BIOS_ERR, "ME: mbp missing version report\n");
466 return;
467 }
468
469 printk(BIOS_DEBUG, "ME: found version %d.%d.%d.%d\n",
470 vers_name->major_version, vers_name->minor_version,
471 vers_name->hotfix_version, vers_name->build_version);
472}
473
Edward O'Callaghan8cc5dc12015-01-07 15:50:43 +1100474static inline void print_cap(const char *name, int state)
475{
476 printk(BIOS_DEBUG, "ME Capability: %-41s : %sabled\n",
477 name, state ? " en" : "dis");
478}
479
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700480/* Get ME Firmware Capabilities */
481static int mkhi_get_fwcaps(mbp_mefwcaps *cap)
482{
483 u32 rule_id = 0;
484 struct me_fwcaps cap_msg;
485 struct mkhi_header mkhi = {
486 .group_id = MKHI_GROUP_ID_FWCAPS,
487 .command = MKHI_FWCAPS_GET_RULE,
488 };
489
490 /* Send request and wait for response */
491 if (mei_sendrecv_mkhi(&mkhi, &rule_id, sizeof(u32),
492 &cap_msg, sizeof(cap_msg)) < 0) {
493 printk(BIOS_ERR, "ME: GET FWCAPS message failed\n");
494 return -1;
Lee Leahy26b7cd02017-03-16 18:47:55 -0700495 }
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700496 *cap = cap_msg.caps_sku;
497 return 0;
498}
499
500/* Get ME Firmware Capabilities */
501static void me_print_fwcaps(mbp_mefwcaps *cap)
502{
503 mbp_mefwcaps local_caps;
504 if (!cap) {
505 cap = &local_caps;
506 printk(BIOS_ERR, "ME: mbp missing fwcaps report\n");
507 if (mkhi_get_fwcaps(cap))
508 return;
509 }
510
511 print_cap("Full Network manageability", cap->full_net);
512 print_cap("Regular Network manageability", cap->std_net);
513 print_cap("Manageability", cap->manageability);
514 print_cap("IntelR Anti-Theft (AT)", cap->intel_at);
515 print_cap("IntelR Capability Licensing Service (CLS)", cap->intel_cls);
516 print_cap("IntelR Power Sharing Technology (MPC)", cap->intel_mpc);
517 print_cap("ICC Over Clocking", cap->icc_over_clocking);
Edward O'Callaghan8cc5dc12015-01-07 15:50:43 +1100518 print_cap("Protected Audio Video Path (PAVP)", cap->pavp);
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700519 print_cap("IPV6", cap->ipv6);
520 print_cap("KVM Remote Control (KVM)", cap->kvm);
521 print_cap("Outbreak Containment Heuristic (OCH)", cap->och);
522 print_cap("Virtual LAN (VLAN)", cap->vlan);
523 print_cap("TLS", cap->tls);
524 print_cap("Wireless LAN (WLAN)", cap->wlan);
525}
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700526
527/* Send END OF POST message to the ME */
528static int mkhi_end_of_post(void)
529{
530 struct mkhi_header mkhi = {
531 .group_id = MKHI_GROUP_ID_GEN,
532 .command = MKHI_END_OF_POST,
533 };
534 u32 eop_ack;
535
536 /* Send request and wait for response */
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700537 if (mei_sendrecv_mkhi(&mkhi, NULL, 0, &eop_ack, sizeof(eop_ack)) < 0) {
538 printk(BIOS_ERR, "ME: END OF POST message failed\n");
539 return -1;
540 }
541
542 printk(BIOS_INFO, "ME: END OF POST message successful (%d)\n", eop_ack);
543 return 0;
544}
545
Duncan Lauriec99681f2014-12-10 08:11:09 -0800546/* Send END OF POST message to the ME */
547static int mkhi_end_of_post_noack(void)
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700548{
Duncan Lauriec99681f2014-12-10 08:11:09 -0800549 struct mkhi_header mkhi = {
550 .group_id = MKHI_GROUP_ID_GEN,
551 .command = MKHI_END_OF_POST_NOACK,
552 };
553
554 /* Send request, do not wait for response */
555 if (mei_sendrecv_mkhi(&mkhi, NULL, 0, NULL, 0) < 0) {
556 printk(BIOS_ERR, "ME: END OF POST NOACK message failed\n");
557 return -1;
558 }
559
560 printk(BIOS_INFO, "ME: END OF POST NOACK message successful\n");
561 return 0;
562}
563
564/* Send HMRFPO LOCK message to the ME */
565static int mkhi_hmrfpo_lock(void)
566{
567 struct mkhi_header mkhi = {
568 .group_id = MKHI_GROUP_ID_HMRFPO,
569 .command = MKHI_HMRFPO_LOCK,
570 };
571 u32 ack;
572
573 /* Send request and wait for response */
574 if (mei_sendrecv_mkhi(&mkhi, NULL, 0, &ack, sizeof(ack)) < 0) {
575 printk(BIOS_ERR, "ME: HMRFPO LOCK message failed\n");
576 return -1;
577 }
578
Angel Ponscac22172018-10-01 09:56:32 +0200579 printk(BIOS_INFO, "ME: HMRFPO LOCK message successful (%d)\n", ack);
Duncan Lauriec99681f2014-12-10 08:11:09 -0800580 return 0;
581}
582
583/* Send HMRFPO LOCK message to the ME, do not wait for response */
584static int mkhi_hmrfpo_lock_noack(void)
585{
586 struct mkhi_header mkhi = {
587 .group_id = MKHI_GROUP_ID_HMRFPO,
588 .command = MKHI_HMRFPO_LOCK_NOACK,
589 };
590
591 /* Send request, do not wait for response */
592 if (mei_sendrecv_mkhi(&mkhi, NULL, 0, NULL, 0) < 0) {
593 printk(BIOS_ERR, "ME: HMRFPO LOCK NOACK message failed\n");
594 return -1;
595 }
596
Angel Ponscac22172018-10-01 09:56:32 +0200597 printk(BIOS_INFO, "ME: HMRFPO LOCK NOACK message successful\n");
Duncan Lauriec99681f2014-12-10 08:11:09 -0800598 return 0;
599}
600
Elyes HAOUAS040aff22018-05-27 16:30:36 +0200601static void intel_me_finalize(struct device *dev)
Duncan Lauriec99681f2014-12-10 08:11:09 -0800602{
Elyes HAOUASb887adf2020-04-29 10:42:34 +0200603 u16 reg16;
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700604
605 /* S3 path will have hidden this device already */
Lee Leahy26b7cd02017-03-16 18:47:55 -0700606 if (!mei_base_address || mei_base_address == (u8 *) 0xfffffff0)
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700607 return;
608
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700609 /* Make sure IO is disabled */
Elyes HAOUASb887adf2020-04-29 10:42:34 +0200610 reg16 = pci_read_config16(dev, PCI_COMMAND);
611 reg16 &= ~(PCI_COMMAND_MASTER |
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700612 PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
Elyes HAOUASb887adf2020-04-29 10:42:34 +0200613 pci_write_config16(dev, PCI_COMMAND, reg16);
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700614
615 /* Hide the PCI device */
616 RCBA32_OR(FD2, PCH_DISABLE_MEI1);
Duncan Lauriec99681f2014-12-10 08:11:09 -0800617 RCBA32(FD2);
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700618}
619
620static int me_icc_set_clock_enables(u32 mask)
621{
622 struct icc_clock_enables_msg clk = {
623 .clock_enables = 0, /* Turn off specified clocks */
624 .clock_mask = mask,
625 .no_response = 1, /* Do not expect response */
626 };
627 struct icc_header icc = {
628 .api_version = ICC_API_VERSION_LYNXPOINT,
629 .icc_command = ICC_SET_CLOCK_ENABLES,
630 .length = sizeof(clk),
631 };
632
633 /* Send request and wait for response */
634 if (mei_sendrecv_icc(&icc, &clk, sizeof(clk), NULL, 0) < 0) {
635 printk(BIOS_ERR, "ME: ICC SET CLOCK ENABLES message failed\n");
636 return -1;
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700637 }
Lee Leahy8a9c7dc2017-03-17 10:43:25 -0700638 printk(BIOS_INFO, "ME: ICC SET CLOCK ENABLES 0x%08x\n", mask);
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700639 return 0;
640}
641
642/* Determine the path that we should take based on ME status */
Elyes HAOUAS040aff22018-05-27 16:30:36 +0200643static me_bios_path intel_me_path(struct device *dev)
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700644{
645 me_bios_path path = ME_DISABLE_BIOS_PATH;
646 struct me_hfs hfs;
647 struct me_hfs2 hfs2;
648
649 /* Check and dump status */
650 intel_me_status();
651
652 pci_read_dword_ptr(dev, &hfs, PCI_ME_HFS);
653 pci_read_dword_ptr(dev, &hfs2, PCI_ME_HFS2);
654
655 /* Check Current Working State */
656 switch (hfs.working_state) {
657 case ME_HFS_CWS_NORMAL:
658 path = ME_NORMAL_BIOS_PATH;
659 break;
660 case ME_HFS_CWS_REC:
661 path = ME_RECOVERY_BIOS_PATH;
662 break;
663 default:
664 path = ME_DISABLE_BIOS_PATH;
665 break;
666 }
667
668 /* Check Current Operation Mode */
669 switch (hfs.operation_mode) {
670 case ME_HFS_MODE_NORMAL:
671 break;
672 case ME_HFS_MODE_DEBUG:
673 case ME_HFS_MODE_DIS:
674 case ME_HFS_MODE_OVER_JMPR:
675 case ME_HFS_MODE_OVER_MEI:
676 default:
677 path = ME_DISABLE_BIOS_PATH;
678 break;
679 }
680
681 /* Check for any error code and valid firmware and MBP */
682 if (hfs.error_code || hfs.fpt_bad)
683 path = ME_ERROR_BIOS_PATH;
684
685 /* Check if the MBP is ready */
686 if (!hfs2.mbp_rdy) {
687 printk(BIOS_CRIT, "%s: mbp is not ready!\n",
Lee Leahy6ef51922017-03-17 10:56:08 -0700688 __func__);
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700689 path = ME_ERROR_BIOS_PATH;
690 }
691
Kyösti Mälkkibe5317f2019-11-06 12:07:21 +0200692 if (CONFIG(ELOG) && path != ME_NORMAL_BIOS_PATH) {
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700693 struct elog_event_data_me_extended data = {
694 .current_working_state = hfs.working_state,
695 .operation_state = hfs.operation_state,
696 .operation_mode = hfs.operation_mode,
697 .error_code = hfs.error_code,
698 .progress_code = hfs2.progress_code,
699 .current_pmevent = hfs2.current_pmevent,
700 .current_state = hfs2.current_state,
701 };
702 elog_add_event_byte(ELOG_TYPE_MANAGEMENT_ENGINE, path);
703 elog_add_event_raw(ELOG_TYPE_MANAGEMENT_ENGINE_EXT,
704 &data, sizeof(data));
705 }
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700706
707 return path;
708}
709
710/* Prepare ME for MEI messages */
Elyes HAOUAS040aff22018-05-27 16:30:36 +0200711static int intel_mei_setup(struct device *dev)
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700712{
713 struct resource *res;
714 struct mei_csr host;
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700715
716 /* Find the MMIO base for the ME interface */
717 res = find_resource(dev, PCI_BASE_ADDRESS_0);
718 if (!res || res->base == 0 || res->size == 0) {
719 printk(BIOS_DEBUG, "ME: MEI resource not present!\n");
720 return -1;
721 }
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800722 mei_base_address = res2mmio(res, 0, 0);
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700723
724 /* Ensure Memory and Bus Master bits are set */
Elyes HAOUASb887adf2020-04-29 10:42:34 +0200725 pci_or_config16(dev, PCI_COMMAND, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700726
727 /* Clean up status for next message */
728 read_host_csr(&host);
729 host.interrupt_generate = 1;
730 host.ready = 1;
731 host.reset = 0;
732 write_host_csr(&host);
733
734 return 0;
735}
736
737/* Read the Extend register hash of ME firmware */
Elyes HAOUAS040aff22018-05-27 16:30:36 +0200738static int intel_me_extend_valid(struct device *dev)
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700739{
740 struct me_heres status;
741 u32 extend[8] = {0};
742 int i, count = 0;
743
744 pci_read_dword_ptr(dev, &status, PCI_ME_HERES);
745 if (!status.extend_feature_present) {
746 printk(BIOS_ERR, "ME: Extend Feature not present\n");
747 return -1;
748 }
749
750 if (!status.extend_reg_valid) {
751 printk(BIOS_ERR, "ME: Extend Register not valid\n");
752 return -1;
753 }
754
755 switch (status.extend_reg_algorithm) {
756 case PCI_ME_EXT_SHA1:
757 count = 5;
758 printk(BIOS_DEBUG, "ME: Extend SHA-1: ");
759 break;
760 case PCI_ME_EXT_SHA256:
761 count = 8;
762 printk(BIOS_DEBUG, "ME: Extend SHA-256: ");
763 break;
764 default:
765 printk(BIOS_ERR, "ME: Extend Algorithm %d unknown\n",
766 status.extend_reg_algorithm);
767 return -1;
768 }
769
770 for (i = 0; i < count; ++i) {
771 extend[i] = pci_read_config32(dev, PCI_ME_HER(i));
772 printk(BIOS_DEBUG, "%08x", extend[i]);
773 }
774 printk(BIOS_DEBUG, "\n");
775
Julius Wernercd49cce2019-03-05 16:53:33 -0800776#if CONFIG(CHROMEOS)
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700777 /* Save hash in NVS for the OS to verify */
778 chromeos_set_me_hash(extend, count);
779#endif
780
781 return 0;
782}
783
Duncan Lauriec99681f2014-12-10 08:11:09 -0800784static void intel_me_print_mbp(me_bios_payload *mbp_data)
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700785{
Duncan Lauriec99681f2014-12-10 08:11:09 -0800786 me_print_fw_version(mbp_data->fw_version_name);
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700787
Kyösti Mälkkic86fc8e2019-11-06 06:32:27 +0200788 if (CONFIG(DEBUG_INTEL_ME))
789 me_print_fwcaps(mbp_data->fw_capabilities);
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700790
Duncan Lauriec99681f2014-12-10 08:11:09 -0800791 if (mbp_data->plat_time) {
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700792 printk(BIOS_DEBUG, "ME: Wake Event to ME Reset: %u ms\n",
Duncan Lauriec99681f2014-12-10 08:11:09 -0800793 mbp_data->plat_time->wake_event_mrst_time_ms);
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700794 printk(BIOS_DEBUG, "ME: ME Reset to Platform Reset: %u ms\n",
Duncan Lauriec99681f2014-12-10 08:11:09 -0800795 mbp_data->plat_time->mrst_pltrst_time_ms);
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700796 printk(BIOS_DEBUG, "ME: Platform Reset to CPU Reset: %u ms\n",
Duncan Lauriec99681f2014-12-10 08:11:09 -0800797 mbp_data->plat_time->pltrst_cpurst_time_ms);
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700798 }
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700799}
800
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700801static u32 me_to_host_words_pending(void)
802{
803 struct mei_csr me;
804 read_me_csr(&me);
805 if (!me.ready)
806 return 0;
807 return (me.buffer_write_ptr - me.buffer_read_ptr) &
808 (me.buffer_depth - 1);
809}
810
811struct mbp_payload {
812 mbp_header header;
813 u32 data[0];
814};
815
816/*
Duncan Lauriec99681f2014-12-10 08:11:09 -0800817 * Read and print ME MBP data
818 *
819 * Return -1 to indicate a problem (give up)
820 * Return 0 to indicate success (send LOCK+EOP)
821 * Return 1 to indicate success (send LOCK+EOP with NOACK)
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700822 */
Elyes HAOUAS040aff22018-05-27 16:30:36 +0200823static int intel_me_read_mbp(me_bios_payload *mbp_data, struct device *dev)
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700824{
825 mbp_header mbp_hdr;
826 u32 me2host_pending;
827 struct mei_csr host;
828 struct me_hfs2 hfs2;
829 struct mbp_payload *mbp;
830 int i;
Duncan Lauriec99681f2014-12-10 08:11:09 -0800831 int ret = 0;
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700832
833 pci_read_dword_ptr(dev, &hfs2, PCI_ME_HFS2);
834
835 if (!hfs2.mbp_rdy) {
836 printk(BIOS_ERR, "ME: MBP not ready\n");
Duncan Lauriec99681f2014-12-10 08:11:09 -0800837 intel_me_mbp_give_up(dev);
838 return -1;
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700839 }
840
841 me2host_pending = me_to_host_words_pending();
842 if (!me2host_pending) {
843 printk(BIOS_ERR, "ME: no mbp data!\n");
Duncan Lauriec99681f2014-12-10 08:11:09 -0800844 intel_me_mbp_give_up(dev);
845 return -1;
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700846 }
847
848 /* we know for sure that at least the header is there */
849 mei_read_dword_ptr(&mbp_hdr, MEI_ME_CB_RW);
850
851 if ((mbp_hdr.num_entries > (mbp_hdr.mbp_size / 2)) ||
852 (me2host_pending < mbp_hdr.mbp_size)) {
853 printk(BIOS_ERR, "ME: mbp of %d entries, total size %d words"
854 " buffer contains %d words\n",
855 mbp_hdr.num_entries, mbp_hdr.mbp_size,
856 me2host_pending);
Duncan Lauriec99681f2014-12-10 08:11:09 -0800857 intel_me_mbp_give_up(dev);
858 return -1;
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700859 }
860 mbp = malloc(mbp_hdr.mbp_size * sizeof(u32));
Duncan Lauriec99681f2014-12-10 08:11:09 -0800861 if (!mbp) {
862 intel_me_mbp_give_up(dev);
863 return -1;
864 }
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700865
866 mbp->header = mbp_hdr;
867 me2host_pending--;
868
869 i = 0;
870 while (i != me2host_pending) {
871 mei_read_dword_ptr(&mbp->data[i], MEI_ME_CB_RW);
872 i++;
873 }
874
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700875 read_host_csr(&host);
Duncan Lauriec99681f2014-12-10 08:11:09 -0800876
877 /* Check that read and write pointers are equal. */
878 if (host.buffer_read_ptr != host.buffer_write_ptr) {
879 printk(BIOS_INFO, "ME: MBP Read/Write pointer mismatch\n");
880 printk(BIOS_INFO, "ME: MBP Waiting for MBP cleared flag\n");
881
882 /* Tell ME that the host has finished reading the MBP. */
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700883 host.interrupt_generate = 1;
Duncan Lauriec99681f2014-12-10 08:11:09 -0800884 host.reset = 0;
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700885 write_host_csr(&host);
886
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700887 /* Wait for the mbp_cleared indicator. */
888 intel_me_mbp_clear(dev);
Duncan Lauriec99681f2014-12-10 08:11:09 -0800889 } else {
890 /* Indicate NOACK messages should be used. */
891 ret = 1;
892 }
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700893
894 /* Dump out the MBP contents. */
Kyösti Mälkkic86fc8e2019-11-06 06:32:27 +0200895 if (CONFIG(DEBUG_INTEL_ME)) {
896 printk(BIOS_INFO, "ME MBP: Header: items: %d, size dw: %d\n",
897 mbp->header.num_entries, mbp->header.mbp_size);
898 for (i = 0; i < mbp->header.mbp_size - 1; i++)
899 printk(BIOS_INFO, "ME MBP: %04x: 0x%08x\n", i, mbp->data[i]);
900 }
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700901
Lee Leahy26b7cd02017-03-16 18:47:55 -0700902#define ASSIGN_FIELD_PTR(field_, val_) \
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700903 { \
904 mbp_data->field_ = (typeof(mbp_data->field_))(void *)val_; \
905 break; \
906 }
907
908 /* Setup the pointers in the me_bios_payload structure. */
909 for (i = 0; i < mbp->header.mbp_size - 1;) {
910 mbp_item_header *item = (void *)&mbp->data[i];
911
Lee Leahy26b7cd02017-03-16 18:47:55 -0700912 switch (MBP_MAKE_IDENT(item->app_id, item->item_id)) {
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700913 case MBP_IDENT(KERNEL, FW_VER):
914 ASSIGN_FIELD_PTR(fw_version_name, &mbp->data[i+1]);
915
916 case MBP_IDENT(ICC, PROFILE):
917 ASSIGN_FIELD_PTR(icc_profile, &mbp->data[i+1]);
918
919 case MBP_IDENT(INTEL_AT, STATE):
920 ASSIGN_FIELD_PTR(at_state, &mbp->data[i+1]);
921
922 case MBP_IDENT(KERNEL, FW_CAP):
923 ASSIGN_FIELD_PTR(fw_capabilities, &mbp->data[i+1]);
924
925 case MBP_IDENT(KERNEL, ROM_BIST):
926 ASSIGN_FIELD_PTR(rom_bist_data, &mbp->data[i+1]);
927
928 case MBP_IDENT(KERNEL, PLAT_KEY):
929 ASSIGN_FIELD_PTR(platform_key, &mbp->data[i+1]);
930
931 case MBP_IDENT(KERNEL, FW_TYPE):
932 ASSIGN_FIELD_PTR(fw_plat_type, &mbp->data[i+1]);
933
934 case MBP_IDENT(KERNEL, MFS_FAILURE):
935 ASSIGN_FIELD_PTR(mfsintegrity, &mbp->data[i+1]);
936
937 case MBP_IDENT(KERNEL, PLAT_TIME):
938 ASSIGN_FIELD_PTR(plat_time, &mbp->data[i+1]);
939
940 case MBP_IDENT(NFC, SUPPORT_DATA):
941 ASSIGN_FIELD_PTR(nfc_data, &mbp->data[i+1]);
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700942 }
943 i += item->length;
944 }
945 #undef ASSIGN_FIELD_PTR
946
Patrick Georgib753eeb2016-10-18 19:46:33 +0200947 free(mbp);
Duncan Lauriec99681f2014-12-10 08:11:09 -0800948 return ret;
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700949}
Duncan Lauriec99681f2014-12-10 08:11:09 -0800950
951/* Check whether ME is present and do basic init */
Elyes HAOUAS040aff22018-05-27 16:30:36 +0200952static void intel_me_init(struct device *dev)
Duncan Lauriec99681f2014-12-10 08:11:09 -0800953{
Kyösti Mälkki8950cfb2019-07-13 22:16:25 +0300954 config_t *config = config_of(dev);
Duncan Lauriec99681f2014-12-10 08:11:09 -0800955 me_bios_path path = intel_me_path(dev);
956 me_bios_payload mbp_data;
957 int mbp_ret;
958 struct me_hfs hfs;
959 struct mei_csr csr;
960
961 /* Do initial setup and determine the BIOS path */
962 printk(BIOS_NOTICE, "ME: BIOS path: %s\n", me_bios_path_values[path]);
963
964 if (path == ME_NORMAL_BIOS_PATH) {
965 /* Validate the extend register */
966 intel_me_extend_valid(dev);
967}
968
969 memset(&mbp_data, 0, sizeof(mbp_data));
970
971 /*
972 * According to the ME9 BWG, BIOS is required to fetch MBP data in
973 * all boot flows except S3 Resume.
974 */
975
976 /* Prepare MEI MMIO interface */
977 if (intel_mei_setup(dev) < 0)
978 return;
979
980 /* Read ME MBP data */
981 mbp_ret = intel_me_read_mbp(&mbp_data, dev);
982 if (mbp_ret < 0)
983 return;
984 intel_me_print_mbp(&mbp_data);
985
986 /* Set clock enables according to devicetree */
Kyösti Mälkki8950cfb2019-07-13 22:16:25 +0300987 if (config->icc_clock_disable)
Duncan Lauriec99681f2014-12-10 08:11:09 -0800988 me_icc_set_clock_enables(config->icc_clock_disable);
989
990 /* Make sure ME is in a mode that expects EOP */
991 pci_read_dword_ptr(dev, &hfs, PCI_ME_HFS);
992
993 /* Abort and leave device alone if not normal mode */
994 if (hfs.fpt_bad ||
995 hfs.working_state != ME_HFS_CWS_NORMAL ||
996 hfs.operation_mode != ME_HFS_MODE_NORMAL)
997 return;
998
999 if (mbp_ret) {
1000 /*
1001 * MBP Cleared wait is skipped,
1002 * Do not expect ACK and reset when complete.
1003 */
1004
1005 /* Send HMRFPO Lock command, no response */
1006 mkhi_hmrfpo_lock_noack();
1007
1008 /* Send END OF POST command, no response */
1009 mkhi_end_of_post_noack();
1010
1011 /* Assert reset and interrupt */
1012 read_host_csr(&csr);
1013 csr.interrupt_generate = 1;
1014 csr.reset = 1;
1015 write_host_csr(&csr);
1016 } else {
1017 /*
1018 * MBP Cleared wait was not skipped
1019 */
1020
1021 /* Send HMRFPO LOCK command */
1022 mkhi_hmrfpo_lock();
1023
1024 /* Send EOP command so ME stops accepting other commands */
1025 mkhi_end_of_post();
1026 }
1027}
1028
Elyes HAOUAS040aff22018-05-27 16:30:36 +02001029static void intel_me_enable(struct device *dev)
Duncan Lauriec99681f2014-12-10 08:11:09 -08001030{
Duncan Lauriec99681f2014-12-10 08:11:09 -08001031 /* Avoid talking to the device in S3 path */
Kyösti Mälkki1ec23c92015-05-29 06:18:18 +03001032 if (acpi_is_wakeup_s3()) {
Duncan Lauriec99681f2014-12-10 08:11:09 -08001033 dev->enabled = 0;
1034 pch_disable_devfn(dev);
1035 }
Duncan Lauriec99681f2014-12-10 08:11:09 -08001036}
1037
1038static struct device_operations device_ops = {
1039 .read_resources = &pci_dev_read_resources,
1040 .set_resources = &pci_dev_set_resources,
1041 .enable_resources = &pci_dev_enable_resources,
1042 .enable = &intel_me_enable,
1043 .init = &intel_me_init,
1044 .final = &intel_me_finalize,
1045 .ops_pci = &broadwell_pci_ops,
1046};
1047
1048static const unsigned short pci_device_ids[] = {
1049 0x9c3a, /* Low Power */
1050 0x9cba, /* WildcatPoint */
1051 0
1052};
1053
1054static const struct pci_driver intel_me __pci_driver = {
1055 .ops = &device_ops,
1056 .vendor = PCI_VENDOR_ID_INTEL,
1057 .devices = pci_device_ids,
1058};