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