blob: dd5e5b870ca168ad328d604cf2b2545438ca8417 [file] [log] [blame]
Duncan Lauriec88c54c2014-04-30 16:36:13 -07001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2014 Google Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
Duncan Lauriec88c54c2014-04-30 16:36:13 -070014 */
15
16/*
17 * This is a ramstage driver for the Intel Management Engine found in the
18 * southbridge. It handles the required boot-time messages over the
19 * MMIO-based Management Engine Interface to tell the ME that the BIOS is
20 * finished with POST. Additional messages are defined for debug but are
21 * not used unless the console loglevel is high enough.
22 */
23
24#include <arch/acpi.h>
Kyösti Mälkki13f66502019-03-03 08:01:05 +020025#include <device/mmio.h>
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +020026#include <device/pci_ops.h>
Duncan Lauriec88c54c2014-04-30 16:36:13 -070027#include <console/console.h>
28#include <device/device.h>
29#include <device/pci.h>
30#include <device/pci_ids.h>
31#include <device/pci_def.h>
32#include <string.h>
33#include <delay.h>
34#include <elog.h>
Julius Werner4ee4bd52014-10-20 13:46:39 -070035#include <soc/me.h>
36#include <soc/lpc.h>
37#include <soc/pch.h>
38#include <soc/pci_devs.h>
39#include <soc/ramstage.h>
40#include <soc/rcba.h>
41#include <soc/intel/broadwell/chip.h>
Duncan Lauriec88c54c2014-04-30 16:36:13 -070042
Julius Wernercd49cce2019-03-05 16:53:33 -080043#if CONFIG(CHROMEOS)
Duncan Lauriec88c54c2014-04-30 16:36:13 -070044#include <vendorcode/google/chromeos/chromeos.h>
45#include <vendorcode/google/chromeos/gnvs.h>
46#endif
47
48/* Path that the BIOS should take based on ME state */
49static const char *me_bios_path_values[] = {
50 [ME_NORMAL_BIOS_PATH] = "Normal",
51 [ME_S3WAKE_BIOS_PATH] = "S3 Wake",
52 [ME_ERROR_BIOS_PATH] = "Error",
53 [ME_RECOVERY_BIOS_PATH] = "Recovery",
54 [ME_DISABLE_BIOS_PATH] = "Disable",
55 [ME_FIRMWARE_UPDATE_BIOS_PATH] = "Firmware Update",
56};
Duncan Lauriec88c54c2014-04-30 16:36:13 -070057
58/* MMIO base address for MEI interface */
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080059static u8 *mei_base_address;
Duncan Lauriec88c54c2014-04-30 16:36:13 -070060
Julius Wernercd49cce2019-03-05 16:53:33 -080061#if CONFIG(DEBUG_INTEL_ME)
Duncan Lauriec88c54c2014-04-30 16:36:13 -070062static void mei_dump(void *ptr, int dword, int offset, const char *type)
63{
64 struct mei_csr *csr;
65
66 printk(BIOS_SPEW, "%-9s[%02x] : ", type, offset);
67
68 switch (offset) {
69 case MEI_H_CSR:
70 case MEI_ME_CSR_HA:
71 csr = ptr;
72 if (!csr) {
73 printk(BIOS_SPEW, "ERROR: 0x%08x\n", dword);
74 break;
75 }
76 printk(BIOS_SPEW, "cbd=%u cbrp=%02u cbwp=%02u ready=%u "
77 "reset=%u ig=%u is=%u ie=%u\n", csr->buffer_depth,
78 csr->buffer_read_ptr, csr->buffer_write_ptr,
79 csr->ready, csr->reset, csr->interrupt_generate,
80 csr->interrupt_status, csr->interrupt_enable);
81 break;
82 case MEI_ME_CB_RW:
83 case MEI_H_CB_WW:
84 printk(BIOS_SPEW, "CB: 0x%08x\n", dword);
85 break;
86 default:
87 printk(BIOS_SPEW, "0x%08x\n", offset);
88 break;
89 }
90}
91#else
Lee Leahy26b7cd02017-03-16 18:47:55 -070092# define mei_dump(ptr, dword, offset, type) do {} while (0)
Duncan Lauriec88c54c2014-04-30 16:36:13 -070093#endif
94
95/*
96 * ME/MEI access helpers using memcpy to avoid aliasing.
97 */
98
99static inline void mei_read_dword_ptr(void *ptr, int offset)
100{
101 u32 dword = read32(mei_base_address + offset);
102 memcpy(ptr, &dword, sizeof(dword));
103 mei_dump(ptr, dword, offset, "READ");
104}
105
106static inline void mei_write_dword_ptr(void *ptr, int offset)
107{
108 u32 dword = 0;
109 memcpy(&dword, ptr, sizeof(dword));
110 write32(mei_base_address + offset, dword);
111 mei_dump(ptr, dword, offset, "WRITE");
112}
113
Elyes HAOUAS040aff22018-05-27 16:30:36 +0200114static inline void pci_read_dword_ptr(struct device *dev, void *ptr, int offset)
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700115{
116 u32 dword = pci_read_config32(dev, offset);
117 memcpy(ptr, &dword, sizeof(dword));
118 mei_dump(ptr, dword, offset, "PCI READ");
119}
120
121static inline void read_host_csr(struct mei_csr *csr)
122{
123 mei_read_dword_ptr(csr, MEI_H_CSR);
124}
125
126static inline void write_host_csr(struct mei_csr *csr)
127{
128 mei_write_dword_ptr(csr, MEI_H_CSR);
129}
130
131static inline void read_me_csr(struct mei_csr *csr)
132{
133 mei_read_dword_ptr(csr, MEI_ME_CSR_HA);
134}
135
136static inline void write_cb(u32 dword)
137{
138 write32(mei_base_address + MEI_H_CB_WW, dword);
139 mei_dump(NULL, dword, MEI_H_CB_WW, "WRITE");
140}
141
142static inline u32 read_cb(void)
143{
144 u32 dword = read32(mei_base_address + MEI_ME_CB_RW);
145 mei_dump(NULL, dword, MEI_ME_CB_RW, "READ");
146 return dword;
147}
148
149/* Wait for ME ready bit to be asserted */
150static int mei_wait_for_me_ready(void)
151{
152 struct mei_csr me;
Lee Leahy23602df2017-03-16 19:00:37 -0700153 unsigned int try = ME_RETRY;
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700154
155 while (try--) {
156 read_me_csr(&me);
157 if (me.ready)
158 return 0;
159 udelay(ME_DELAY);
160 }
161
162 printk(BIOS_ERR, "ME: failed to become ready\n");
163 return -1;
164}
165
166static void mei_reset(void)
167{
168 struct mei_csr host;
169
170 if (mei_wait_for_me_ready() < 0)
171 return;
172
173 /* Reset host and ME circular buffers for next message */
174 read_host_csr(&host);
175 host.reset = 1;
176 host.interrupt_generate = 1;
177 write_host_csr(&host);
178
179 if (mei_wait_for_me_ready() < 0)
180 return;
181
182 /* Re-init and indicate host is ready */
183 read_host_csr(&host);
184 host.interrupt_generate = 1;
185 host.ready = 1;
186 host.reset = 0;
187 write_host_csr(&host);
188}
189
190static int mei_send_packet(struct mei_header *mei, void *req_data)
191{
192 struct mei_csr host;
Lee Leahy23602df2017-03-16 19:00:37 -0700193 unsigned int ndata, n;
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700194 u32 *data;
195
196 /* Number of dwords to write */
197 ndata = mei->length >> 2;
198
199 /* Pad non-dword aligned request message length */
200 if (mei->length & 3)
201 ndata++;
202 if (!ndata) {
203 printk(BIOS_DEBUG, "ME: request has no data\n");
204 return -1;
205 }
206 ndata++; /* Add MEI header */
207
208 /*
209 * Make sure there is still room left in the circular buffer.
210 * Reset the buffer pointers if the requested message will not fit.
211 */
212 read_host_csr(&host);
213 if ((host.buffer_depth - host.buffer_write_ptr) < ndata) {
214 printk(BIOS_ERR, "ME: circular buffer full, resetting...\n");
215 mei_reset();
216 read_host_csr(&host);
217 }
218
219 /* Ensure the requested length will fit in the circular buffer. */
220 if ((host.buffer_depth - host.buffer_write_ptr) < ndata) {
221 printk(BIOS_ERR, "ME: message (%u) too large for buffer (%u)\n",
222 ndata + 2, host.buffer_depth);
223 return -1;
224 }
225
226 /* Write MEI header */
227 mei_write_dword_ptr(mei, MEI_H_CB_WW);
228 ndata--;
229
230 /* Write message data */
231 data = req_data;
232 for (n = 0; n < ndata; ++n)
233 write_cb(*data++);
234
235 /* Generate interrupt to the ME */
236 read_host_csr(&host);
237 host.interrupt_generate = 1;
238 write_host_csr(&host);
239
240 /* Make sure ME is ready after sending request data */
241 return mei_wait_for_me_ready();
242}
243
244static int mei_send_data(u8 me_address, u8 host_address,
245 void *req_data, int req_bytes)
246{
247 struct mei_header header = {
248 .client_address = me_address,
249 .host_address = host_address,
250 };
251 struct mei_csr host;
252 int current = 0;
253 u8 *req_ptr = req_data;
254
255 while (!header.is_complete) {
256 int remain = req_bytes - current;
257 int buf_len;
258
259 read_host_csr(&host);
260 buf_len = host.buffer_depth - host.buffer_write_ptr;
261
262 if (buf_len > remain) {
263 /* Send all remaining data as final message */
264 header.length = req_bytes - current;
265 header.is_complete = 1;
266 } else {
267 /* Send as much data as the buffer can hold */
268 header.length = buf_len;
269 }
270
271 mei_send_packet(&header, req_ptr);
272
273 req_ptr += header.length;
274 current += header.length;
275 }
276
277 return 0;
278}
279
280static int mei_send_header(u8 me_address, u8 host_address,
281 void *header, int header_len, int complete)
282{
283 struct mei_header mei = {
284 .client_address = me_address,
285 .host_address = host_address,
286 .length = header_len,
287 .is_complete = complete,
288 };
289 return mei_send_packet(&mei, header);
290}
291
292static int mei_recv_msg(void *header, int header_bytes,
293 void *rsp_data, int rsp_bytes)
294{
295 struct mei_header mei_rsp;
296 struct mei_csr me, host;
Lee Leahy23602df2017-03-16 19:00:37 -0700297 unsigned int ndata, n;
298 unsigned int expected;
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700299 u32 *data;
300
301 /* Total number of dwords to read from circular buffer */
302 expected = (rsp_bytes + sizeof(mei_rsp) + header_bytes) >> 2;
303 if (rsp_bytes & 3)
304 expected++;
305
306 if (mei_wait_for_me_ready() < 0)
307 return -1;
308
309 /*
310 * The interrupt status bit does not appear to indicate that the
311 * message has actually been received. Instead we wait until the
312 * expected number of dwords are present in the circular buffer.
313 */
314 for (n = ME_RETRY; n; --n) {
315 read_me_csr(&me);
316 if ((me.buffer_write_ptr - me.buffer_read_ptr) >= expected)
317 break;
318 udelay(ME_DELAY);
319 }
320 if (!n) {
321 printk(BIOS_ERR, "ME: timeout waiting for data: expected "
322 "%u, available %u\n", expected,
323 me.buffer_write_ptr - me.buffer_read_ptr);
324 return -1;
325 }
326
327 /* Read and verify MEI response header from the ME */
328 mei_read_dword_ptr(&mei_rsp, MEI_ME_CB_RW);
329 if (!mei_rsp.is_complete) {
330 printk(BIOS_ERR, "ME: response is not complete\n");
331 return -1;
332 }
333
334 /* Handle non-dword responses and expect at least the header */
335 ndata = mei_rsp.length >> 2;
336 if (mei_rsp.length & 3)
337 ndata++;
338 if (ndata != (expected - 1)) {
339 printk(BIOS_ERR, "ME: response is missing data %d != %d\n",
340 ndata, (expected - 1));
341 return -1;
342 }
343
344 /* Read response header from the ME */
345 data = header;
346 for (n = 0; n < (header_bytes >> 2); ++n)
347 *data++ = read_cb();
348 ndata -= header_bytes >> 2;
349
350 /* Make sure caller passed a buffer with enough space */
351 if (ndata != (rsp_bytes >> 2)) {
352 printk(BIOS_ERR, "ME: not enough room in response buffer: "
353 "%u != %u\n", ndata, rsp_bytes >> 2);
354 return -1;
355 }
356
357 /* Read response data from the circular buffer */
358 data = rsp_data;
359 for (n = 0; n < ndata; ++n)
360 *data++ = read_cb();
361
362 /* Tell the ME that we have consumed the response */
363 read_host_csr(&host);
364 host.interrupt_status = 1;
365 host.interrupt_generate = 1;
366 write_host_csr(&host);
367
368 return mei_wait_for_me_ready();
369}
370
371static inline int mei_sendrecv_mkhi(struct mkhi_header *mkhi,
372 void *req_data, int req_bytes,
373 void *rsp_data, int rsp_bytes)
374{
375 struct mkhi_header mkhi_rsp;
376
377 /* Send header */
378 if (mei_send_header(MEI_ADDRESS_MKHI, MEI_HOST_ADDRESS,
379 mkhi, sizeof(*mkhi), req_bytes ? 0 : 1) < 0)
380 return -1;
381
382 /* Send data if available */
383 if (req_bytes && mei_send_data(MEI_ADDRESS_MKHI, MEI_HOST_ADDRESS,
384 req_data, req_bytes) < 0)
385 return -1;
386
387 /* Return now if no response expected */
388 if (!rsp_bytes)
389 return 0;
390
391 /* Read header and data */
392 if (mei_recv_msg(&mkhi_rsp, sizeof(mkhi_rsp),
393 rsp_data, rsp_bytes) < 0)
394 return -1;
395
396 if (!mkhi_rsp.is_response ||
397 mkhi->group_id != mkhi_rsp.group_id ||
398 mkhi->command != mkhi_rsp.command) {
399 printk(BIOS_ERR, "ME: invalid response, group %u ?= %u,"
400 "command %u ?= %u, is_response %u\n", mkhi->group_id,
401 mkhi_rsp.group_id, mkhi->command, mkhi_rsp.command,
402 mkhi_rsp.is_response);
403 return -1;
404 }
405
406 return 0;
407}
408
409static inline int mei_sendrecv_icc(struct icc_header *icc,
410 void *req_data, int req_bytes,
411 void *rsp_data, int rsp_bytes)
412{
413 struct icc_header icc_rsp;
414
415 /* Send header */
416 if (mei_send_header(MEI_ADDRESS_ICC, MEI_HOST_ADDRESS,
417 icc, sizeof(*icc), req_bytes ? 0 : 1) < 0)
418 return -1;
419
420 /* Send data if available */
421 if (req_bytes && mei_send_data(MEI_ADDRESS_ICC, MEI_HOST_ADDRESS,
422 req_data, req_bytes) < 0)
423 return -1;
424
425 /* Read header and data, if needed */
426 if (rsp_bytes && mei_recv_msg(&icc_rsp, sizeof(icc_rsp),
427 rsp_data, rsp_bytes) < 0)
428 return -1;
429
430 return 0;
431}
432
433/*
434 * mbp give up routine. This path is taken if hfs.mpb_rdy is 0 or the read
435 * state machine on the BIOS end doesn't match the ME's state machine.
436 */
Elyes HAOUAS040aff22018-05-27 16:30:36 +0200437static void intel_me_mbp_give_up(struct device *dev)
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700438{
439 struct mei_csr csr;
440
441 pci_write_config32(dev, PCI_ME_H_GS2, PCI_ME_MBP_GIVE_UP);
442
443 read_host_csr(&csr);
444 csr.reset = 1;
445 csr.interrupt_generate = 1;
446 write_host_csr(&csr);
447}
448
449/*
450 * mbp clear routine. This will wait for the ME to indicate that
451 * the MBP has been read and cleared.
452 */
Elyes HAOUAS040aff22018-05-27 16:30:36 +0200453static void intel_me_mbp_clear(struct device *dev)
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700454{
455 int count;
456 struct me_hfs2 hfs2;
457
458 /* Wait for the mbp_cleared indicator */
459 for (count = ME_RETRY; count > 0; --count) {
460 pci_read_dword_ptr(dev, &hfs2, PCI_ME_HFS2);
461 if (hfs2.mbp_cleared)
462 break;
463 udelay(ME_DELAY);
464 }
465
466 if (count == 0) {
467 printk(BIOS_WARNING, "ME: Timeout waiting for mbp_cleared\n");
468 intel_me_mbp_give_up(dev);
469 } else {
470 printk(BIOS_INFO, "ME: MBP cleared\n");
471 }
472}
473
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700474static void me_print_fw_version(mbp_fw_version_name *vers_name)
475{
476 if (!vers_name) {
477 printk(BIOS_ERR, "ME: mbp missing version report\n");
478 return;
479 }
480
481 printk(BIOS_DEBUG, "ME: found version %d.%d.%d.%d\n",
482 vers_name->major_version, vers_name->minor_version,
483 vers_name->hotfix_version, vers_name->build_version);
484}
485
Julius Wernercd49cce2019-03-05 16:53:33 -0800486#if CONFIG(DEBUG_INTEL_ME)
Edward O'Callaghan8cc5dc12015-01-07 15:50:43 +1100487static inline void print_cap(const char *name, int state)
488{
489 printk(BIOS_DEBUG, "ME Capability: %-41s : %sabled\n",
490 name, state ? " en" : "dis");
491}
492
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700493/* Get ME Firmware Capabilities */
494static int mkhi_get_fwcaps(mbp_mefwcaps *cap)
495{
496 u32 rule_id = 0;
497 struct me_fwcaps cap_msg;
498 struct mkhi_header mkhi = {
499 .group_id = MKHI_GROUP_ID_FWCAPS,
500 .command = MKHI_FWCAPS_GET_RULE,
501 };
502
503 /* Send request and wait for response */
504 if (mei_sendrecv_mkhi(&mkhi, &rule_id, sizeof(u32),
505 &cap_msg, sizeof(cap_msg)) < 0) {
506 printk(BIOS_ERR, "ME: GET FWCAPS message failed\n");
507 return -1;
Lee Leahy26b7cd02017-03-16 18:47:55 -0700508 }
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700509 *cap = cap_msg.caps_sku;
510 return 0;
511}
512
513/* Get ME Firmware Capabilities */
514static void me_print_fwcaps(mbp_mefwcaps *cap)
515{
516 mbp_mefwcaps local_caps;
517 if (!cap) {
518 cap = &local_caps;
519 printk(BIOS_ERR, "ME: mbp missing fwcaps report\n");
520 if (mkhi_get_fwcaps(cap))
521 return;
522 }
523
524 print_cap("Full Network manageability", cap->full_net);
525 print_cap("Regular Network manageability", cap->std_net);
526 print_cap("Manageability", cap->manageability);
527 print_cap("IntelR Anti-Theft (AT)", cap->intel_at);
528 print_cap("IntelR Capability Licensing Service (CLS)", cap->intel_cls);
529 print_cap("IntelR Power Sharing Technology (MPC)", cap->intel_mpc);
530 print_cap("ICC Over Clocking", cap->icc_over_clocking);
Edward O'Callaghan8cc5dc12015-01-07 15:50:43 +1100531 print_cap("Protected Audio Video Path (PAVP)", cap->pavp);
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700532 print_cap("IPV6", cap->ipv6);
533 print_cap("KVM Remote Control (KVM)", cap->kvm);
534 print_cap("Outbreak Containment Heuristic (OCH)", cap->och);
535 print_cap("Virtual LAN (VLAN)", cap->vlan);
536 print_cap("TLS", cap->tls);
537 print_cap("Wireless LAN (WLAN)", cap->wlan);
538}
539#endif
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700540
541/* Send END OF POST message to the ME */
542static int mkhi_end_of_post(void)
543{
544 struct mkhi_header mkhi = {
545 .group_id = MKHI_GROUP_ID_GEN,
546 .command = MKHI_END_OF_POST,
547 };
548 u32 eop_ack;
549
550 /* Send request and wait for response */
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700551 if (mei_sendrecv_mkhi(&mkhi, NULL, 0, &eop_ack, sizeof(eop_ack)) < 0) {
552 printk(BIOS_ERR, "ME: END OF POST message failed\n");
553 return -1;
554 }
555
556 printk(BIOS_INFO, "ME: END OF POST message successful (%d)\n", eop_ack);
557 return 0;
558}
559
Duncan Lauriec99681f2014-12-10 08:11:09 -0800560/* Send END OF POST message to the ME */
561static int mkhi_end_of_post_noack(void)
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700562{
Duncan Lauriec99681f2014-12-10 08:11:09 -0800563 struct mkhi_header mkhi = {
564 .group_id = MKHI_GROUP_ID_GEN,
565 .command = MKHI_END_OF_POST_NOACK,
566 };
567
568 /* Send request, do not wait for response */
569 if (mei_sendrecv_mkhi(&mkhi, NULL, 0, NULL, 0) < 0) {
570 printk(BIOS_ERR, "ME: END OF POST NOACK message failed\n");
571 return -1;
572 }
573
574 printk(BIOS_INFO, "ME: END OF POST NOACK message successful\n");
575 return 0;
576}
577
578/* Send HMRFPO LOCK message to the ME */
579static int mkhi_hmrfpo_lock(void)
580{
581 struct mkhi_header mkhi = {
582 .group_id = MKHI_GROUP_ID_HMRFPO,
583 .command = MKHI_HMRFPO_LOCK,
584 };
585 u32 ack;
586
587 /* Send request and wait for response */
588 if (mei_sendrecv_mkhi(&mkhi, NULL, 0, &ack, sizeof(ack)) < 0) {
589 printk(BIOS_ERR, "ME: HMRFPO LOCK message failed\n");
590 return -1;
591 }
592
Angel Ponscac22172018-10-01 09:56:32 +0200593 printk(BIOS_INFO, "ME: HMRFPO LOCK message successful (%d)\n", ack);
Duncan Lauriec99681f2014-12-10 08:11:09 -0800594 return 0;
595}
596
597/* Send HMRFPO LOCK message to the ME, do not wait for response */
598static int mkhi_hmrfpo_lock_noack(void)
599{
600 struct mkhi_header mkhi = {
601 .group_id = MKHI_GROUP_ID_HMRFPO,
602 .command = MKHI_HMRFPO_LOCK_NOACK,
603 };
604
605 /* Send request, do not wait for response */
606 if (mei_sendrecv_mkhi(&mkhi, NULL, 0, NULL, 0) < 0) {
607 printk(BIOS_ERR, "ME: HMRFPO LOCK NOACK message failed\n");
608 return -1;
609 }
610
Angel Ponscac22172018-10-01 09:56:32 +0200611 printk(BIOS_INFO, "ME: HMRFPO LOCK NOACK message successful\n");
Duncan Lauriec99681f2014-12-10 08:11:09 -0800612 return 0;
613}
614
Elyes HAOUAS040aff22018-05-27 16:30:36 +0200615static void intel_me_finalize(struct device *dev)
Duncan Lauriec99681f2014-12-10 08:11:09 -0800616{
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700617 u32 reg32;
618
619 /* S3 path will have hidden this device already */
Lee Leahy26b7cd02017-03-16 18:47:55 -0700620 if (!mei_base_address || mei_base_address == (u8 *) 0xfffffff0)
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700621 return;
622
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700623 /* Make sure IO is disabled */
624 reg32 = pci_read_config32(dev, PCI_COMMAND);
625 reg32 &= ~(PCI_COMMAND_MASTER |
626 PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
627 pci_write_config32(dev, PCI_COMMAND, reg32);
628
629 /* Hide the PCI device */
630 RCBA32_OR(FD2, PCH_DISABLE_MEI1);
Duncan Lauriec99681f2014-12-10 08:11:09 -0800631 RCBA32(FD2);
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700632}
633
634static int me_icc_set_clock_enables(u32 mask)
635{
636 struct icc_clock_enables_msg clk = {
637 .clock_enables = 0, /* Turn off specified clocks */
638 .clock_mask = mask,
639 .no_response = 1, /* Do not expect response */
640 };
641 struct icc_header icc = {
642 .api_version = ICC_API_VERSION_LYNXPOINT,
643 .icc_command = ICC_SET_CLOCK_ENABLES,
644 .length = sizeof(clk),
645 };
646
647 /* Send request and wait for response */
648 if (mei_sendrecv_icc(&icc, &clk, sizeof(clk), NULL, 0) < 0) {
649 printk(BIOS_ERR, "ME: ICC SET CLOCK ENABLES message failed\n");
650 return -1;
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700651 }
Lee Leahy8a9c7dc2017-03-17 10:43:25 -0700652 printk(BIOS_INFO, "ME: ICC SET CLOCK ENABLES 0x%08x\n", mask);
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700653 return 0;
654}
655
656/* Determine the path that we should take based on ME status */
Elyes HAOUAS040aff22018-05-27 16:30:36 +0200657static me_bios_path intel_me_path(struct device *dev)
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700658{
659 me_bios_path path = ME_DISABLE_BIOS_PATH;
660 struct me_hfs hfs;
661 struct me_hfs2 hfs2;
662
663 /* Check and dump status */
664 intel_me_status();
665
666 pci_read_dword_ptr(dev, &hfs, PCI_ME_HFS);
667 pci_read_dword_ptr(dev, &hfs2, PCI_ME_HFS2);
668
669 /* Check Current Working State */
670 switch (hfs.working_state) {
671 case ME_HFS_CWS_NORMAL:
672 path = ME_NORMAL_BIOS_PATH;
673 break;
674 case ME_HFS_CWS_REC:
675 path = ME_RECOVERY_BIOS_PATH;
676 break;
677 default:
678 path = ME_DISABLE_BIOS_PATH;
679 break;
680 }
681
682 /* Check Current Operation Mode */
683 switch (hfs.operation_mode) {
684 case ME_HFS_MODE_NORMAL:
685 break;
686 case ME_HFS_MODE_DEBUG:
687 case ME_HFS_MODE_DIS:
688 case ME_HFS_MODE_OVER_JMPR:
689 case ME_HFS_MODE_OVER_MEI:
690 default:
691 path = ME_DISABLE_BIOS_PATH;
692 break;
693 }
694
695 /* Check for any error code and valid firmware and MBP */
696 if (hfs.error_code || hfs.fpt_bad)
697 path = ME_ERROR_BIOS_PATH;
698
699 /* Check if the MBP is ready */
700 if (!hfs2.mbp_rdy) {
701 printk(BIOS_CRIT, "%s: mbp is not ready!\n",
Lee Leahy6ef51922017-03-17 10:56:08 -0700702 __func__);
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700703 path = ME_ERROR_BIOS_PATH;
704 }
705
Julius Wernercd49cce2019-03-05 16:53:33 -0800706#if CONFIG(ELOG)
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700707 if (path != ME_NORMAL_BIOS_PATH) {
708 struct elog_event_data_me_extended data = {
709 .current_working_state = hfs.working_state,
710 .operation_state = hfs.operation_state,
711 .operation_mode = hfs.operation_mode,
712 .error_code = hfs.error_code,
713 .progress_code = hfs2.progress_code,
714 .current_pmevent = hfs2.current_pmevent,
715 .current_state = hfs2.current_state,
716 };
717 elog_add_event_byte(ELOG_TYPE_MANAGEMENT_ENGINE, path);
718 elog_add_event_raw(ELOG_TYPE_MANAGEMENT_ENGINE_EXT,
719 &data, sizeof(data));
720 }
721#endif
722
723 return path;
724}
725
726/* Prepare ME for MEI messages */
Elyes HAOUAS040aff22018-05-27 16:30:36 +0200727static int intel_mei_setup(struct device *dev)
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700728{
729 struct resource *res;
730 struct mei_csr host;
731 u32 reg32;
732
733 /* Find the MMIO base for the ME interface */
734 res = find_resource(dev, PCI_BASE_ADDRESS_0);
735 if (!res || res->base == 0 || res->size == 0) {
736 printk(BIOS_DEBUG, "ME: MEI resource not present!\n");
737 return -1;
738 }
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800739 mei_base_address = res2mmio(res, 0, 0);
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700740
741 /* Ensure Memory and Bus Master bits are set */
742 reg32 = pci_read_config32(dev, PCI_COMMAND);
743 reg32 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
744 pci_write_config32(dev, PCI_COMMAND, reg32);
745
746 /* Clean up status for next message */
747 read_host_csr(&host);
748 host.interrupt_generate = 1;
749 host.ready = 1;
750 host.reset = 0;
751 write_host_csr(&host);
752
753 return 0;
754}
755
756/* Read the Extend register hash of ME firmware */
Elyes HAOUAS040aff22018-05-27 16:30:36 +0200757static int intel_me_extend_valid(struct device *dev)
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700758{
759 struct me_heres status;
760 u32 extend[8] = {0};
761 int i, count = 0;
762
763 pci_read_dword_ptr(dev, &status, PCI_ME_HERES);
764 if (!status.extend_feature_present) {
765 printk(BIOS_ERR, "ME: Extend Feature not present\n");
766 return -1;
767 }
768
769 if (!status.extend_reg_valid) {
770 printk(BIOS_ERR, "ME: Extend Register not valid\n");
771 return -1;
772 }
773
774 switch (status.extend_reg_algorithm) {
775 case PCI_ME_EXT_SHA1:
776 count = 5;
777 printk(BIOS_DEBUG, "ME: Extend SHA-1: ");
778 break;
779 case PCI_ME_EXT_SHA256:
780 count = 8;
781 printk(BIOS_DEBUG, "ME: Extend SHA-256: ");
782 break;
783 default:
784 printk(BIOS_ERR, "ME: Extend Algorithm %d unknown\n",
785 status.extend_reg_algorithm);
786 return -1;
787 }
788
789 for (i = 0; i < count; ++i) {
790 extend[i] = pci_read_config32(dev, PCI_ME_HER(i));
791 printk(BIOS_DEBUG, "%08x", extend[i]);
792 }
793 printk(BIOS_DEBUG, "\n");
794
Julius Wernercd49cce2019-03-05 16:53:33 -0800795#if CONFIG(CHROMEOS)
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700796 /* Save hash in NVS for the OS to verify */
797 chromeos_set_me_hash(extend, count);
798#endif
799
800 return 0;
801}
802
Duncan Lauriec99681f2014-12-10 08:11:09 -0800803static void intel_me_print_mbp(me_bios_payload *mbp_data)
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700804{
Duncan Lauriec99681f2014-12-10 08:11:09 -0800805 me_print_fw_version(mbp_data->fw_version_name);
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700806
Julius Wernercd49cce2019-03-05 16:53:33 -0800807#if CONFIG(DEBUG_INTEL_ME)
Duncan Lauriec99681f2014-12-10 08:11:09 -0800808 me_print_fwcaps(mbp_data->fw_capabilities);
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700809#endif
810
Duncan Lauriec99681f2014-12-10 08:11:09 -0800811 if (mbp_data->plat_time) {
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700812 printk(BIOS_DEBUG, "ME: Wake Event to ME Reset: %u ms\n",
Duncan Lauriec99681f2014-12-10 08:11:09 -0800813 mbp_data->plat_time->wake_event_mrst_time_ms);
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700814 printk(BIOS_DEBUG, "ME: ME Reset to Platform Reset: %u ms\n",
Duncan Lauriec99681f2014-12-10 08:11:09 -0800815 mbp_data->plat_time->mrst_pltrst_time_ms);
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700816 printk(BIOS_DEBUG, "ME: Platform Reset to CPU Reset: %u ms\n",
Duncan Lauriec99681f2014-12-10 08:11:09 -0800817 mbp_data->plat_time->pltrst_cpurst_time_ms);
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700818 }
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700819}
820
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700821static u32 me_to_host_words_pending(void)
822{
823 struct mei_csr me;
824 read_me_csr(&me);
825 if (!me.ready)
826 return 0;
827 return (me.buffer_write_ptr - me.buffer_read_ptr) &
828 (me.buffer_depth - 1);
829}
830
831struct mbp_payload {
832 mbp_header header;
833 u32 data[0];
834};
835
836/*
Duncan Lauriec99681f2014-12-10 08:11:09 -0800837 * Read and print ME MBP data
838 *
839 * Return -1 to indicate a problem (give up)
840 * Return 0 to indicate success (send LOCK+EOP)
841 * Return 1 to indicate success (send LOCK+EOP with NOACK)
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700842 */
Elyes HAOUAS040aff22018-05-27 16:30:36 +0200843static int intel_me_read_mbp(me_bios_payload *mbp_data, struct device *dev)
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700844{
845 mbp_header mbp_hdr;
846 u32 me2host_pending;
847 struct mei_csr host;
848 struct me_hfs2 hfs2;
849 struct mbp_payload *mbp;
850 int i;
Duncan Lauriec99681f2014-12-10 08:11:09 -0800851 int ret = 0;
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700852
853 pci_read_dword_ptr(dev, &hfs2, PCI_ME_HFS2);
854
855 if (!hfs2.mbp_rdy) {
856 printk(BIOS_ERR, "ME: MBP not ready\n");
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
861 me2host_pending = me_to_host_words_pending();
862 if (!me2host_pending) {
863 printk(BIOS_ERR, "ME: no mbp data!\n");
Duncan Lauriec99681f2014-12-10 08:11:09 -0800864 intel_me_mbp_give_up(dev);
865 return -1;
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700866 }
867
868 /* we know for sure that at least the header is there */
869 mei_read_dword_ptr(&mbp_hdr, MEI_ME_CB_RW);
870
871 if ((mbp_hdr.num_entries > (mbp_hdr.mbp_size / 2)) ||
872 (me2host_pending < mbp_hdr.mbp_size)) {
873 printk(BIOS_ERR, "ME: mbp of %d entries, total size %d words"
874 " buffer contains %d words\n",
875 mbp_hdr.num_entries, mbp_hdr.mbp_size,
876 me2host_pending);
Duncan Lauriec99681f2014-12-10 08:11:09 -0800877 intel_me_mbp_give_up(dev);
878 return -1;
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700879 }
880 mbp = malloc(mbp_hdr.mbp_size * sizeof(u32));
Duncan Lauriec99681f2014-12-10 08:11:09 -0800881 if (!mbp) {
882 intel_me_mbp_give_up(dev);
883 return -1;
884 }
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700885
886 mbp->header = mbp_hdr;
887 me2host_pending--;
888
889 i = 0;
890 while (i != me2host_pending) {
891 mei_read_dword_ptr(&mbp->data[i], MEI_ME_CB_RW);
892 i++;
893 }
894
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700895 read_host_csr(&host);
Duncan Lauriec99681f2014-12-10 08:11:09 -0800896
897 /* Check that read and write pointers are equal. */
898 if (host.buffer_read_ptr != host.buffer_write_ptr) {
899 printk(BIOS_INFO, "ME: MBP Read/Write pointer mismatch\n");
900 printk(BIOS_INFO, "ME: MBP Waiting for MBP cleared flag\n");
901
902 /* Tell ME that the host has finished reading the MBP. */
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700903 host.interrupt_generate = 1;
Duncan Lauriec99681f2014-12-10 08:11:09 -0800904 host.reset = 0;
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700905 write_host_csr(&host);
906
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700907 /* Wait for the mbp_cleared indicator. */
908 intel_me_mbp_clear(dev);
Duncan Lauriec99681f2014-12-10 08:11:09 -0800909 } else {
910 /* Indicate NOACK messages should be used. */
911 ret = 1;
912 }
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700913
914 /* Dump out the MBP contents. */
Julius Wernercd49cce2019-03-05 16:53:33 -0800915#if CONFIG(DEBUG_INTEL_ME)
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700916 printk(BIOS_INFO, "ME MBP: Header: items: %d, size dw: %d\n",
917 mbp->header.num_entries, mbp->header.mbp_size);
Lee Leahy8a9c7dc2017-03-17 10:43:25 -0700918 for (i = 0; i < mbp->header.mbp_size - 1; i++)
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700919 printk(BIOS_INFO, "ME MBP: %04x: 0x%08x\n", i, mbp->data[i]);
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700920#endif
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700921
Lee Leahy26b7cd02017-03-16 18:47:55 -0700922#define ASSIGN_FIELD_PTR(field_, val_) \
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700923 { \
924 mbp_data->field_ = (typeof(mbp_data->field_))(void *)val_; \
925 break; \
926 }
927
928 /* Setup the pointers in the me_bios_payload structure. */
929 for (i = 0; i < mbp->header.mbp_size - 1;) {
930 mbp_item_header *item = (void *)&mbp->data[i];
931
Lee Leahy26b7cd02017-03-16 18:47:55 -0700932 switch (MBP_MAKE_IDENT(item->app_id, item->item_id)) {
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700933 case MBP_IDENT(KERNEL, FW_VER):
934 ASSIGN_FIELD_PTR(fw_version_name, &mbp->data[i+1]);
935
936 case MBP_IDENT(ICC, PROFILE):
937 ASSIGN_FIELD_PTR(icc_profile, &mbp->data[i+1]);
938
939 case MBP_IDENT(INTEL_AT, STATE):
940 ASSIGN_FIELD_PTR(at_state, &mbp->data[i+1]);
941
942 case MBP_IDENT(KERNEL, FW_CAP):
943 ASSIGN_FIELD_PTR(fw_capabilities, &mbp->data[i+1]);
944
945 case MBP_IDENT(KERNEL, ROM_BIST):
946 ASSIGN_FIELD_PTR(rom_bist_data, &mbp->data[i+1]);
947
948 case MBP_IDENT(KERNEL, PLAT_KEY):
949 ASSIGN_FIELD_PTR(platform_key, &mbp->data[i+1]);
950
951 case MBP_IDENT(KERNEL, FW_TYPE):
952 ASSIGN_FIELD_PTR(fw_plat_type, &mbp->data[i+1]);
953
954 case MBP_IDENT(KERNEL, MFS_FAILURE):
955 ASSIGN_FIELD_PTR(mfsintegrity, &mbp->data[i+1]);
956
957 case MBP_IDENT(KERNEL, PLAT_TIME):
958 ASSIGN_FIELD_PTR(plat_time, &mbp->data[i+1]);
959
960 case MBP_IDENT(NFC, SUPPORT_DATA):
961 ASSIGN_FIELD_PTR(nfc_data, &mbp->data[i+1]);
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700962 }
963 i += item->length;
964 }
965 #undef ASSIGN_FIELD_PTR
966
Patrick Georgib753eeb2016-10-18 19:46:33 +0200967 free(mbp);
Duncan Lauriec99681f2014-12-10 08:11:09 -0800968 return ret;
Duncan Lauriec88c54c2014-04-30 16:36:13 -0700969}
Duncan Lauriec99681f2014-12-10 08:11:09 -0800970
971/* Check whether ME is present and do basic init */
Elyes HAOUAS040aff22018-05-27 16:30:36 +0200972static void intel_me_init(struct device *dev)
Duncan Lauriec99681f2014-12-10 08:11:09 -0800973{
974 config_t *config = dev->chip_info;
975 me_bios_path path = intel_me_path(dev);
976 me_bios_payload mbp_data;
977 int mbp_ret;
978 struct me_hfs hfs;
979 struct mei_csr csr;
980
981 /* Do initial setup and determine the BIOS path */
982 printk(BIOS_NOTICE, "ME: BIOS path: %s\n", me_bios_path_values[path]);
983
984 if (path == ME_NORMAL_BIOS_PATH) {
985 /* Validate the extend register */
986 intel_me_extend_valid(dev);
987}
988
989 memset(&mbp_data, 0, sizeof(mbp_data));
990
991 /*
992 * According to the ME9 BWG, BIOS is required to fetch MBP data in
993 * all boot flows except S3 Resume.
994 */
995
996 /* Prepare MEI MMIO interface */
997 if (intel_mei_setup(dev) < 0)
998 return;
999
1000 /* Read ME MBP data */
1001 mbp_ret = intel_me_read_mbp(&mbp_data, dev);
1002 if (mbp_ret < 0)
1003 return;
1004 intel_me_print_mbp(&mbp_data);
1005
1006 /* Set clock enables according to devicetree */
1007 if (config && config->icc_clock_disable)
1008 me_icc_set_clock_enables(config->icc_clock_disable);
1009
1010 /* Make sure ME is in a mode that expects EOP */
1011 pci_read_dword_ptr(dev, &hfs, PCI_ME_HFS);
1012
1013 /* Abort and leave device alone if not normal mode */
1014 if (hfs.fpt_bad ||
1015 hfs.working_state != ME_HFS_CWS_NORMAL ||
1016 hfs.operation_mode != ME_HFS_MODE_NORMAL)
1017 return;
1018
1019 if (mbp_ret) {
1020 /*
1021 * MBP Cleared wait is skipped,
1022 * Do not expect ACK and reset when complete.
1023 */
1024
1025 /* Send HMRFPO Lock command, no response */
1026 mkhi_hmrfpo_lock_noack();
1027
1028 /* Send END OF POST command, no response */
1029 mkhi_end_of_post_noack();
1030
1031 /* Assert reset and interrupt */
1032 read_host_csr(&csr);
1033 csr.interrupt_generate = 1;
1034 csr.reset = 1;
1035 write_host_csr(&csr);
1036 } else {
1037 /*
1038 * MBP Cleared wait was not skipped
1039 */
1040
1041 /* Send HMRFPO LOCK command */
1042 mkhi_hmrfpo_lock();
1043
1044 /* Send EOP command so ME stops accepting other commands */
1045 mkhi_end_of_post();
1046 }
1047}
1048
Elyes HAOUAS040aff22018-05-27 16:30:36 +02001049static void intel_me_enable(struct device *dev)
Duncan Lauriec99681f2014-12-10 08:11:09 -08001050{
Duncan Lauriec99681f2014-12-10 08:11:09 -08001051 /* Avoid talking to the device in S3 path */
Kyösti Mälkki1ec23c92015-05-29 06:18:18 +03001052 if (acpi_is_wakeup_s3()) {
Duncan Lauriec99681f2014-12-10 08:11:09 -08001053 dev->enabled = 0;
1054 pch_disable_devfn(dev);
1055 }
Duncan Lauriec99681f2014-12-10 08:11:09 -08001056}
1057
1058static struct device_operations device_ops = {
1059 .read_resources = &pci_dev_read_resources,
1060 .set_resources = &pci_dev_set_resources,
1061 .enable_resources = &pci_dev_enable_resources,
1062 .enable = &intel_me_enable,
1063 .init = &intel_me_init,
1064 .final = &intel_me_finalize,
1065 .ops_pci = &broadwell_pci_ops,
1066};
1067
1068static const unsigned short pci_device_ids[] = {
1069 0x9c3a, /* Low Power */
1070 0x9cba, /* WildcatPoint */
1071 0
1072};
1073
1074static const struct pci_driver intel_me __pci_driver = {
1075 .ops = &device_ops,
1076 .vendor = PCI_VENDOR_ID_INTEL,
1077 .devices = pci_device_ids,
1078};