blob: 2e790fc2a5e90b8e69e441e29f43704803988b6d [file] [log] [blame]
Aaron Durbin76c37002012-10-30 09:03:43 -05001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2011 The Chromium OS Authors. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; version 2 of
9 * the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
19 * MA 02110-1301 USA
20 */
21
22/*
23 * This is a ramstage driver for the Intel Management Engine found in the
24 * 6-series chipset. It handles the required boot-time messages over the
25 * MMIO-based Management Engine Interface to tell the ME that the BIOS is
26 * finished with POST. Additional messages are defined for debug but are
27 * not used unless the console loglevel is high enough.
28 */
29
30#include <arch/acpi.h>
31#include <arch/hlt.h>
32#include <arch/io.h>
33#include <console/console.h>
34#include <device/pci_ids.h>
35#include <device/pci_def.h>
36#include <string.h>
37#include <delay.h>
38#include <elog.h>
39
40#ifdef __SMM__
41# include <arch/romcc_io.h>
Aaron Durbin76c37002012-10-30 09:03:43 -050042#else
43# include <device/device.h>
44# include <device/pci.h>
45#endif
46
47#include "me.h"
48#include "pch.h"
49
50#if CONFIG_CHROMEOS
51#include <vendorcode/google/chromeos/chromeos.h>
52#include <vendorcode/google/chromeos/gnvs.h>
53#endif
54
55#ifndef __SMM__
56/* Path that the BIOS should take based on ME state */
57static const char *me_bios_path_values[] = {
58 [ME_NORMAL_BIOS_PATH] = "Normal",
59 [ME_S3WAKE_BIOS_PATH] = "S3 Wake",
60 [ME_ERROR_BIOS_PATH] = "Error",
61 [ME_RECOVERY_BIOS_PATH] = "Recovery",
62 [ME_DISABLE_BIOS_PATH] = "Disable",
63 [ME_FIRMWARE_UPDATE_BIOS_PATH] = "Firmware Update",
64};
Aaron Durbin9aa031e2012-11-02 09:16:46 -050065static int intel_me_read_mbp(me_bios_payload *mbp_data, device_t dev);
Aaron Durbin76c37002012-10-30 09:03:43 -050066#endif
67
68/* MMIO base address for MEI interface */
69static u32 mei_base_address;
70
71#if CONFIG_DEBUG_INTEL_ME
72static void mei_dump(void *ptr, int dword, int offset, const char *type)
73{
74 struct mei_csr *csr;
75
76 printk(BIOS_SPEW, "%-9s[%02x] : ", type, offset);
77
78 switch (offset) {
79 case MEI_H_CSR:
80 case MEI_ME_CSR_HA:
81 csr = ptr;
82 if (!csr) {
83 printk(BIOS_SPEW, "ERROR: 0x%08x\n", dword);
84 break;
85 }
86 printk(BIOS_SPEW, "cbd=%u cbrp=%02u cbwp=%02u ready=%u "
87 "reset=%u ig=%u is=%u ie=%u\n", csr->buffer_depth,
88 csr->buffer_read_ptr, csr->buffer_write_ptr,
89 csr->ready, csr->reset, csr->interrupt_generate,
90 csr->interrupt_status, csr->interrupt_enable);
91 break;
92 case MEI_ME_CB_RW:
93 case MEI_H_CB_WW:
94 printk(BIOS_SPEW, "CB: 0x%08x\n", dword);
95 break;
96 default:
97 printk(BIOS_SPEW, "0x%08x\n", offset);
98 break;
99 }
100}
101#else
102# define mei_dump(ptr,dword,offset,type) do {} while (0)
103#endif
104
105/*
106 * ME/MEI access helpers using memcpy to avoid aliasing.
107 */
108
109static inline void mei_read_dword_ptr(void *ptr, int offset)
110{
111 u32 dword = read32(mei_base_address + offset);
112 memcpy(ptr, &dword, sizeof(dword));
113 mei_dump(ptr, dword, offset, "READ");
114}
115
116static inline void mei_write_dword_ptr(void *ptr, int offset)
117{
118 u32 dword = 0;
119 memcpy(&dword, ptr, sizeof(dword));
120 write32(mei_base_address + offset, dword);
121 mei_dump(ptr, dword, offset, "WRITE");
122}
123
124#ifndef __SMM__
125static inline void pci_read_dword_ptr(device_t dev, void *ptr, int offset)
126{
127 u32 dword = pci_read_config32(dev, offset);
128 memcpy(ptr, &dword, sizeof(dword));
129 mei_dump(ptr, dword, offset, "PCI READ");
130}
131#endif
132
133static inline void read_host_csr(struct mei_csr *csr)
134{
135 mei_read_dword_ptr(csr, MEI_H_CSR);
136}
137
138static inline void write_host_csr(struct mei_csr *csr)
139{
140 mei_write_dword_ptr(csr, MEI_H_CSR);
141}
142
143static inline void read_me_csr(struct mei_csr *csr)
144{
145 mei_read_dword_ptr(csr, MEI_ME_CSR_HA);
146}
147
148static inline void write_cb(u32 dword)
149{
150 write32(mei_base_address + MEI_H_CB_WW, dword);
151 mei_dump(NULL, dword, MEI_H_CB_WW, "WRITE");
152}
153
154static inline u32 read_cb(void)
155{
156 u32 dword = read32(mei_base_address + MEI_ME_CB_RW);
157 mei_dump(NULL, dword, MEI_ME_CB_RW, "READ");
158 return dword;
159}
160
161/* Wait for ME ready bit to be asserted */
162static int mei_wait_for_me_ready(void)
163{
164 struct mei_csr me;
165 unsigned try = ME_RETRY;
166
167 while (try--) {
168 read_me_csr(&me);
169 if (me.ready)
170 return 0;
171 udelay(ME_DELAY);
172 }
173
174 printk(BIOS_ERR, "ME: failed to become ready\n");
175 return -1;
176}
177
178static void mei_reset(void)
179{
180 struct mei_csr host;
181
182 if (mei_wait_for_me_ready() < 0)
183 return;
184
185 /* Reset host and ME circular buffers for next message */
186 read_host_csr(&host);
187 host.reset = 1;
188 host.interrupt_generate = 1;
189 write_host_csr(&host);
190
191 if (mei_wait_for_me_ready() < 0)
192 return;
193
194 /* Re-init and indicate host is ready */
195 read_host_csr(&host);
196 host.interrupt_generate = 1;
197 host.ready = 1;
198 host.reset = 0;
199 write_host_csr(&host);
200}
201
202static int mei_send_msg(struct mei_header *mei, struct mkhi_header *mkhi,
203 void *req_data)
204{
205 struct mei_csr host;
206 unsigned ndata, n;
207 u32 *data;
208
209 /* Number of dwords to write, ignoring MKHI */
210 ndata = mei->length >> 2;
211
212 /* Pad non-dword aligned request message length */
213 if (mei->length & 3)
214 ndata++;
215 if (!ndata) {
216 printk(BIOS_DEBUG, "ME: request does not include MKHI\n");
217 return -1;
218 }
219 ndata++; /* Add MEI header */
220
221 /*
222 * Make sure there is still room left in the circular buffer.
223 * Reset the buffer pointers if the requested message will not fit.
224 */
225 read_host_csr(&host);
226 if ((host.buffer_depth - host.buffer_write_ptr) < ndata) {
227 printk(BIOS_ERR, "ME: circular buffer full, resetting...\n");
228 mei_reset();
229 read_host_csr(&host);
230 }
231
232 /*
233 * This implementation does not handle splitting large messages
234 * across multiple transactions. Ensure the requested length
235 * will fit in the available circular buffer depth.
236 */
237 if ((host.buffer_depth - host.buffer_write_ptr) < ndata) {
238 printk(BIOS_ERR, "ME: message (%u) too large for buffer (%u)\n",
239 ndata + 2, host.buffer_depth);
240 return -1;
241 }
242
243 /* Write MEI header */
244 mei_write_dword_ptr(mei, MEI_H_CB_WW);
245 ndata--;
246
247 /* Write MKHI header */
248 mei_write_dword_ptr(mkhi, MEI_H_CB_WW);
249 ndata--;
250
251 /* Write message data */
252 data = req_data;
253 for (n = 0; n < ndata; ++n)
254 write_cb(*data++);
255
256 /* Generate interrupt to the ME */
257 read_host_csr(&host);
258 host.interrupt_generate = 1;
259 write_host_csr(&host);
260
261 /* Make sure ME is ready after sending request data */
262 return mei_wait_for_me_ready();
263}
264
265static int mei_recv_msg(struct mkhi_header *mkhi,
266 void *rsp_data, int rsp_bytes)
267{
268 struct mei_header mei_rsp;
269 struct mkhi_header mkhi_rsp;
270 struct mei_csr me, host;
271 unsigned ndata, n/*, me_data_len*/;
272 unsigned expected;
273 u32 *data;
274
275 /* Total number of dwords to read from circular buffer */
276 expected = (rsp_bytes + sizeof(mei_rsp) + sizeof(mkhi_rsp)) >> 2;
277 if (rsp_bytes & 3)
278 expected++;
279
280 /*
281 * The interrupt status bit does not appear to indicate that the
282 * message has actually been received. Instead we wait until the
283 * expected number of dwords are present in the circular buffer.
284 */
285 for (n = ME_RETRY; n; --n) {
286 read_me_csr(&me);
287 if ((me.buffer_write_ptr - me.buffer_read_ptr) >= expected)
288 break;
289 udelay(ME_DELAY);
290 }
291 if (!n) {
292 printk(BIOS_ERR, "ME: timeout waiting for data: expected "
293 "%u, available %u\n", expected,
294 me.buffer_write_ptr - me.buffer_read_ptr);
295 return -1;
296 }
297
298 /* Read and verify MEI response header from the ME */
299 mei_read_dword_ptr(&mei_rsp, MEI_ME_CB_RW);
300 if (!mei_rsp.is_complete) {
301 printk(BIOS_ERR, "ME: response is not complete\n");
302 return -1;
303 }
304
305 /* Handle non-dword responses and expect at least MKHI header */
306 ndata = mei_rsp.length >> 2;
307 if (mei_rsp.length & 3)
308 ndata++;
309 if (ndata != (expected - 1)) {
310 printk(BIOS_ERR, "ME: response is missing data %d != %d\n",
311 ndata, (expected - 1));
312 return -1;
313 }
314
315 /* Read and verify MKHI response header from the ME */
316 mei_read_dword_ptr(&mkhi_rsp, MEI_ME_CB_RW);
317 if (!mkhi_rsp.is_response ||
318 mkhi->group_id != mkhi_rsp.group_id ||
319 mkhi->command != mkhi_rsp.command) {
320 printk(BIOS_ERR, "ME: invalid response, group %u ?= %u,"
321 "command %u ?= %u, is_response %u\n", mkhi->group_id,
322 mkhi_rsp.group_id, mkhi->command, mkhi_rsp.command,
323 mkhi_rsp.is_response);
324 return -1;
325 }
326 ndata--; /* MKHI header has been read */
327
328 /* Make sure caller passed a buffer with enough space */
329 if (ndata != (rsp_bytes >> 2)) {
330 printk(BIOS_ERR, "ME: not enough room in response buffer: "
331 "%u != %u\n", ndata, rsp_bytes >> 2);
332 return -1;
333 }
334
335 /* Read response data from the circular buffer */
336 data = rsp_data;
337 for (n = 0; n < ndata; ++n)
338 *data++ = read_cb();
339
340 /* Tell the ME that we have consumed the response */
341 read_host_csr(&host);
342 host.interrupt_status = 1;
343 host.interrupt_generate = 1;
344 write_host_csr(&host);
345
346 return mei_wait_for_me_ready();
347}
348
349static inline int mei_sendrecv(struct mei_header *mei, struct mkhi_header *mkhi,
350 void *req_data, void *rsp_data, int rsp_bytes)
351{
352 if (mei_send_msg(mei, mkhi, req_data) < 0)
353 return -1;
354 if (mei_recv_msg(mkhi, rsp_data, rsp_bytes) < 0)
355 return -1;
356 return 0;
357}
358
359#if (CONFIG_DEFAULT_CONSOLE_LOGLEVEL >= BIOS_DEBUG) && !defined(__SMM__)
360static inline void print_cap(const char *name, int state)
361{
362 printk(BIOS_DEBUG, "ME Capability: %-41s : %sabled\n",
363 name, state ? " en" : "dis");
364}
365
366static void me_print_fw_version(mbp_fw_version_name *vers_name)
367{
Aaron Durbinbe985242012-12-12 12:40:33 -0600368 if (!vers_name) {
Aaron Durbin76c37002012-10-30 09:03:43 -0500369 printk(BIOS_ERR, "ME: mbp missing version report\n");
370 return;
371 }
372
373 printk(BIOS_DEBUG, "ME: found version %d.%d.%d.%d\n",
374 vers_name->major_version, vers_name->minor_version,
375 vers_name->hotfix_version, vers_name->build_version);
376}
377
378/* Get ME Firmware Capabilities */
Aaron Durbinbe985242012-12-12 12:40:33 -0600379static int mkhi_get_fwcaps(mbp_mefwcaps *cap)
Aaron Durbin76c37002012-10-30 09:03:43 -0500380{
381 u32 rule_id = 0;
382 struct me_fwcaps cap_msg;
383 struct mkhi_header mkhi = {
384 .group_id = MKHI_GROUP_ID_FWCAPS,
385 .command = MKHI_FWCAPS_GET_RULE,
386 };
387 struct mei_header mei = {
388 .is_complete = 1,
389 .host_address = MEI_HOST_ADDRESS,
390 .client_address = MEI_ADDRESS_MKHI,
391 .length = sizeof(mkhi) + sizeof(rule_id),
392 };
393
394 /* Send request and wait for response */
395 if (mei_sendrecv(&mei, &mkhi, &rule_id, &cap_msg, sizeof(cap_msg))
396 < 0) {
397 printk(BIOS_ERR, "ME: GET FWCAPS message failed\n");
398 return -1;
399 }
400 *cap = cap_msg.caps_sku;
401 return 0;
402}
403
404/* Get ME Firmware Capabilities */
Aaron Durbinbe985242012-12-12 12:40:33 -0600405static void me_print_fwcaps(mbp_mefwcaps *cap)
Aaron Durbin76c37002012-10-30 09:03:43 -0500406{
Aaron Durbinbe985242012-12-12 12:40:33 -0600407 mbp_mefwcaps local_caps;
408 if (!cap) {
409 cap = &local_caps;
Aaron Durbin76c37002012-10-30 09:03:43 -0500410 printk(BIOS_ERR, "ME: mbp missing fwcaps report\n");
411 if (mkhi_get_fwcaps(cap))
412 return;
413 }
414
415 print_cap("Full Network manageability", cap->full_net);
416 print_cap("Regular Network manageability", cap->std_net);
417 print_cap("Manageability", cap->manageability);
Aaron Durbin76c37002012-10-30 09:03:43 -0500418 print_cap("IntelR Anti-Theft (AT)", cap->intel_at);
419 print_cap("IntelR Capability Licensing Service (CLS)", cap->intel_cls);
420 print_cap("IntelR Power Sharing Technology (MPC)", cap->intel_mpc);
421 print_cap("ICC Over Clocking", cap->icc_over_clocking);
422 print_cap("Protected Audio Video Path (PAVP)", cap->pavp);
423 print_cap("IPV6", cap->ipv6);
424 print_cap("KVM Remote Control (KVM)", cap->kvm);
425 print_cap("Outbreak Containment Heuristic (OCH)", cap->och);
426 print_cap("Virtual LAN (VLAN)", cap->vlan);
427 print_cap("TLS", cap->tls);
428 print_cap("Wireless LAN (WLAN)", cap->wlan);
429}
430#endif
431
432#if CONFIG_CHROMEOS && 0 /* DISABLED */
433/* Tell ME to issue a global reset */
434static int mkhi_global_reset(void)
435{
436 struct me_global_reset reset = {
437 .request_origin = GLOBAL_RESET_BIOS_POST,
438 .reset_type = CBM_RR_GLOBAL_RESET,
439 };
440 struct mkhi_header mkhi = {
441 .group_id = MKHI_GROUP_ID_CBM,
442 .command = MKHI_GLOBAL_RESET,
443 };
444 struct mei_header mei = {
445 .is_complete = 1,
446 .length = sizeof(mkhi) + sizeof(reset),
447 .host_address = MEI_HOST_ADDRESS,
448 .client_address = MEI_ADDRESS_MKHI,
449 };
450
451 /* Send request and wait for response */
452 printk(BIOS_NOTICE, "ME: %s\n", __FUNCTION__);
453 if (mei_sendrecv(&mei, &mkhi, &reset, NULL, 0) < 0) {
454 /* No response means reset will happen shortly... */
455 hlt();
456 }
457
458 /* If the ME responded it rejected the reset request */
459 printk(BIOS_ERR, "ME: Global Reset failed\n");
460 return -1;
461}
462#endif
463
464#ifdef __SMM__
465
466/* Send END OF POST message to the ME */
467static int mkhi_end_of_post(void)
468{
469 struct mkhi_header mkhi = {
470 .group_id = MKHI_GROUP_ID_GEN,
471 .command = MKHI_END_OF_POST,
472 };
473 struct mei_header mei = {
474 .is_complete = 1,
475 .host_address = MEI_HOST_ADDRESS,
476 .client_address = MEI_ADDRESS_MKHI,
477 .length = sizeof(mkhi),
478 };
479
480 u32 eop_ack;
481
482 /* Send request and wait for response */
483 printk(BIOS_NOTICE, "ME: %s\n", __FUNCTION__);
484 if (mei_sendrecv(&mei, &mkhi, NULL, &eop_ack, sizeof(eop_ack)) < 0) {
485 printk(BIOS_ERR, "ME: END OF POST message failed\n");
486 return -1;
487 }
488
489 printk(BIOS_INFO, "ME: END OF POST message successful (%d)\n", eop_ack);
490 return 0;
491}
492
493void intel_me_finalize_smm(void)
494{
495 struct me_hfs hfs;
496 u32 reg32;
497
498 mei_base_address =
Aaron Durbin89f79a02012-10-31 23:05:25 -0500499 pci_read_config32(PCH_ME_DEV, PCI_BASE_ADDRESS_0) & ~0xf;
Aaron Durbin76c37002012-10-30 09:03:43 -0500500
501 /* S3 path will have hidden this device already */
502 if (!mei_base_address || mei_base_address == 0xfffffff0)
503 return;
504
505 /* Make sure ME is in a mode that expects EOP */
Aaron Durbin89f79a02012-10-31 23:05:25 -0500506 reg32 = pci_read_config32(PCH_ME_DEV, PCI_ME_HFS);
Aaron Durbin76c37002012-10-30 09:03:43 -0500507 memcpy(&hfs, &reg32, sizeof(u32));
508
509 /* Abort and leave device alone if not normal mode */
510 if (hfs.fpt_bad ||
511 hfs.working_state != ME_HFS_CWS_NORMAL ||
512 hfs.operation_mode != ME_HFS_MODE_NORMAL)
513 return;
514
515 /* Try to send EOP command so ME stops accepting other commands */
516 mkhi_end_of_post();
517
518 /* Make sure IO is disabled */
Aaron Durbin89f79a02012-10-31 23:05:25 -0500519 reg32 = pci_read_config32(PCH_ME_DEV, PCI_COMMAND);
Aaron Durbin76c37002012-10-30 09:03:43 -0500520 reg32 &= ~(PCI_COMMAND_MASTER |
521 PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
Aaron Durbin89f79a02012-10-31 23:05:25 -0500522 pci_write_config32(PCH_ME_DEV, PCI_COMMAND, reg32);
Aaron Durbin76c37002012-10-30 09:03:43 -0500523
524 /* Hide the PCI device */
525 RCBA32_OR(FD2, PCH_DISABLE_MEI1);
526}
527
528#else /* !__SMM__ */
529
530/* Determine the path that we should take based on ME status */
531static me_bios_path intel_me_path(device_t dev)
532{
533 me_bios_path path = ME_DISABLE_BIOS_PATH;
534 struct me_hfs hfs;
Aaron Durbin9aa031e2012-11-02 09:16:46 -0500535 struct me_hfs2 hfs2;
Aaron Durbin76c37002012-10-30 09:03:43 -0500536
537#if CONFIG_HAVE_ACPI_RESUME
538 /* S3 wake skips all MKHI messages */
539 if (acpi_slp_type == 3) {
540 return ME_S3WAKE_BIOS_PATH;
541 }
542#endif
543
544 pci_read_dword_ptr(dev, &hfs, PCI_ME_HFS);
Aaron Durbin9aa031e2012-11-02 09:16:46 -0500545 pci_read_dword_ptr(dev, &hfs2, PCI_ME_HFS2);
Aaron Durbin76c37002012-10-30 09:03:43 -0500546
547 /* Check and dump status */
Aaron Durbin9aa031e2012-11-02 09:16:46 -0500548 intel_me_status(&hfs, &hfs2);
Aaron Durbin76c37002012-10-30 09:03:43 -0500549
550 /* Check Current Working State */
551 switch (hfs.working_state) {
552 case ME_HFS_CWS_NORMAL:
553 path = ME_NORMAL_BIOS_PATH;
554 break;
555 case ME_HFS_CWS_REC:
556 path = ME_RECOVERY_BIOS_PATH;
557 break;
558 default:
559 path = ME_DISABLE_BIOS_PATH;
560 break;
561 }
562
563 /* Check Current Operation Mode */
564 switch (hfs.operation_mode) {
565 case ME_HFS_MODE_NORMAL:
566 break;
567 case ME_HFS_MODE_DEBUG:
568 case ME_HFS_MODE_DIS:
569 case ME_HFS_MODE_OVER_JMPR:
570 case ME_HFS_MODE_OVER_MEI:
571 default:
572 path = ME_DISABLE_BIOS_PATH;
573 break;
574 }
575
576 /* Check for any error code and valid firmware and MBP */
577 if (hfs.error_code || hfs.fpt_bad)
578 path = ME_ERROR_BIOS_PATH;
579
580 /* Check if the MBP is ready */
Aaron Durbin9aa031e2012-11-02 09:16:46 -0500581 if (!hfs2.mbp_rdy) {
Aaron Durbin76c37002012-10-30 09:03:43 -0500582 printk(BIOS_CRIT, "%s: mbp is not ready!\n",
583 __FUNCTION__);
584 path = ME_ERROR_BIOS_PATH;
585 }
586
587#if CONFIG_ELOG
588 if (path != ME_NORMAL_BIOS_PATH) {
589 struct elog_event_data_me_extended data = {
590 .current_working_state = hfs.working_state,
591 .operation_state = hfs.operation_state,
592 .operation_mode = hfs.operation_mode,
593 .error_code = hfs.error_code,
Aaron Durbin9aa031e2012-11-02 09:16:46 -0500594 .progress_code = hfs2.progress_code,
595 .current_pmevent = hfs2.current_pmevent,
596 .current_state = hfs2.current_state,
Aaron Durbin76c37002012-10-30 09:03:43 -0500597 };
598 elog_add_event_byte(ELOG_TYPE_MANAGEMENT_ENGINE, path);
599 elog_add_event_raw(ELOG_TYPE_MANAGEMENT_ENGINE_EXT,
600 &data, sizeof(data));
601 }
602#endif
603
604 return path;
605}
606
607/* Prepare ME for MEI messages */
608static int intel_mei_setup(device_t dev)
609{
610 struct resource *res;
611 struct mei_csr host;
612 u32 reg32;
613
614 /* Find the MMIO base for the ME interface */
615 res = find_resource(dev, PCI_BASE_ADDRESS_0);
616 if (!res || res->base == 0 || res->size == 0) {
617 printk(BIOS_DEBUG, "ME: MEI resource not present!\n");
618 return -1;
619 }
620 mei_base_address = res->base;
621
622 /* Ensure Memory and Bus Master bits are set */
623 reg32 = pci_read_config32(dev, PCI_COMMAND);
624 reg32 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
625 pci_write_config32(dev, PCI_COMMAND, reg32);
626
627 /* Clean up status for next message */
628 read_host_csr(&host);
629 host.interrupt_generate = 1;
630 host.ready = 1;
631 host.reset = 0;
632 write_host_csr(&host);
633
634 return 0;
635}
636
637/* Read the Extend register hash of ME firmware */
638static int intel_me_extend_valid(device_t dev)
639{
640 struct me_heres status;
641 u32 extend[8] = {0};
642 int i, count = 0;
643
644 pci_read_dword_ptr(dev, &status, PCI_ME_HERES);
645 if (!status.extend_feature_present) {
646 printk(BIOS_ERR, "ME: Extend Feature not present\n");
647 return -1;
648 }
649
650 if (!status.extend_reg_valid) {
651 printk(BIOS_ERR, "ME: Extend Register not valid\n");
652 return -1;
653 }
654
655 switch (status.extend_reg_algorithm) {
656 case PCI_ME_EXT_SHA1:
657 count = 5;
658 printk(BIOS_DEBUG, "ME: Extend SHA-1: ");
659 break;
660 case PCI_ME_EXT_SHA256:
661 count = 8;
662 printk(BIOS_DEBUG, "ME: Extend SHA-256: ");
663 break;
664 default:
665 printk(BIOS_ERR, "ME: Extend Algorithm %d unknown\n",
666 status.extend_reg_algorithm);
667 return -1;
668 }
669
670 for (i = 0; i < count; ++i) {
671 extend[i] = pci_read_config32(dev, PCI_ME_HER(i));
672 printk(BIOS_DEBUG, "%08x", extend[i]);
673 }
674 printk(BIOS_DEBUG, "\n");
675
676#if CONFIG_CHROMEOS
677 /* Save hash in NVS for the OS to verify */
678 chromeos_set_me_hash(extend, count);
679#endif
680
681 return 0;
682}
683
684/* Hide the ME virtual PCI devices */
685static void intel_me_hide(device_t dev)
686{
687 dev->enabled = 0;
688 pch_enable(dev);
689}
690
691/* Check whether ME is present and do basic init */
692static void intel_me_init(device_t dev)
693{
694 me_bios_path path = intel_me_path(dev);
695 me_bios_payload mbp_data;
696
697 /* Do initial setup and determine the BIOS path */
698 printk(BIOS_NOTICE, "ME: BIOS path: %s\n", me_bios_path_values[path]);
699
Aaron Durbin9aa031e2012-11-02 09:16:46 -0500700 if (path == ME_S3WAKE_BIOS_PATH) {
Aaron Durbin76c37002012-10-30 09:03:43 -0500701 intel_me_hide(dev);
Aaron Durbin9aa031e2012-11-02 09:16:46 -0500702 return;
703 } else if (path == ME_NORMAL_BIOS_PATH) {
Aaron Durbin76c37002012-10-30 09:03:43 -0500704 /* Validate the extend register */
Aaron Durbin9aa031e2012-11-02 09:16:46 -0500705 /* FIXME: force recovery mode on failure. */
706 intel_me_extend_valid(dev);
707 }
Aaron Durbin76c37002012-10-30 09:03:43 -0500708
Aaron Durbinbe985242012-12-12 12:40:33 -0600709 memset(&mbp_data, 0, sizeof(mbp_data));
710
Aaron Durbin9aa031e2012-11-02 09:16:46 -0500711 /*
712 * According to the ME9 BWG, BIOS is required to fetch MBP data in
713 * all boot flows except S3 Resume.
714 */
Aaron Durbin76c37002012-10-30 09:03:43 -0500715
Aaron Durbin9aa031e2012-11-02 09:16:46 -0500716 /* Prepare MEI MMIO interface */
717 if (intel_mei_setup(dev) < 0)
718 return;
Aaron Durbin76c37002012-10-30 09:03:43 -0500719
Aaron Durbin9aa031e2012-11-02 09:16:46 -0500720 if(intel_me_read_mbp(&mbp_data, dev))
721 return;
Aaron Durbin76c37002012-10-30 09:03:43 -0500722
723#if (CONFIG_DEFAULT_CONSOLE_LOGLEVEL >= BIOS_DEBUG)
Aaron Durbinbe985242012-12-12 12:40:33 -0600724 me_print_fw_version(mbp_data.fw_version_name);
725 me_print_fwcaps(mbp_data.fw_capabilities);
Aaron Durbin76c37002012-10-30 09:03:43 -0500726#endif
727
Aaron Durbin9aa031e2012-11-02 09:16:46 -0500728 /*
729 * Leave the ME unlocked. It will be locked via SMI command later.
730 */
Aaron Durbin76c37002012-10-30 09:03:43 -0500731}
732
733static void set_subsystem(device_t dev, unsigned vendor, unsigned device)
734{
735 if (!vendor || !device) {
736 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
737 pci_read_config32(dev, PCI_VENDOR_ID));
738 } else {
739 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
740 ((device & 0xffff) << 16) | (vendor & 0xffff));
741 }
742}
743
744static struct pci_operations pci_ops = {
745 .set_subsystem = set_subsystem,
746};
747
748static struct device_operations device_ops = {
749 .read_resources = pci_dev_read_resources,
750 .set_resources = pci_dev_set_resources,
751 .enable_resources = pci_dev_enable_resources,
752 .init = intel_me_init,
753 .scan_bus = scan_static_bus,
754 .ops_pci = &pci_ops,
755};
756
Duncan Laurie26e7dd72012-12-19 09:12:31 -0800757static const unsigned short pci_device_ids[] = {
758 0x8c3a, /* Mobile */
759 0x9c3a, /* Low Power */
760 0
761};
762
Aaron Durbin76c37002012-10-30 09:03:43 -0500763static const struct pci_driver intel_me __pci_driver = {
764 .ops = &device_ops,
765 .vendor = PCI_VENDOR_ID_INTEL,
Duncan Laurie26e7dd72012-12-19 09:12:31 -0800766 .devices= pci_device_ids,
Aaron Durbin76c37002012-10-30 09:03:43 -0500767};
768
769/******************************************************************************
770 * */
771static u32 me_to_host_words_pending(void)
772{
773 struct mei_csr me;
774 read_me_csr(&me);
775 if (!me.ready)
776 return 0;
777 return (me.buffer_write_ptr - me.buffer_read_ptr) &
778 (me.buffer_depth - 1);
779}
780
781#if 0
782/* This function is not yet being used, keep it in for the future. */
783static u32 host_to_me_words_room(void)
784{
785 struct mei_csr csr;
786
787 read_me_csr(&csr);
788 if (!csr.ready)
789 return 0;
790
791 read_host_csr(&csr);
792 return (csr.buffer_read_ptr - csr.buffer_write_ptr - 1) &
793 (csr.buffer_depth - 1);
794}
795#endif
Aaron Durbin9aa031e2012-11-02 09:16:46 -0500796
797/*
798 * mbp give up routine. This path is taken if hfs.mpb_rdy is 0 or the read
799 * state machine on the BIOS end doesn't match the ME's state machine.
800 */
801static void intel_me_mbp_give_up(device_t dev)
802{
803 u32 reg32;
804 struct mei_csr csr;
805
806 reg32 = PCI_ME_MBP_GIVE_UP;
Aaron Durbinb37d1fb2013-02-25 10:51:52 -0600807 pci_write_config32(dev, PCI_ME_H_GS2, reg32);
Aaron Durbin9aa031e2012-11-02 09:16:46 -0500808 read_host_csr(&csr);
809 csr.reset = 1;
810 csr.interrupt_generate = 1;
811 write_host_csr(&csr);
812}
813
Aaron Durbinbe985242012-12-12 12:40:33 -0600814struct mbp_payload {
815 mbp_header header;
816 u32 data[0];
817};
818
Aaron Durbin76c37002012-10-30 09:03:43 -0500819/*
820 * mbp seems to be following its own flow, let's retrieve it in a dedicated
821 * function.
822 */
Aaron Durbin9aa031e2012-11-02 09:16:46 -0500823static int intel_me_read_mbp(me_bios_payload *mbp_data, device_t dev)
Aaron Durbin76c37002012-10-30 09:03:43 -0500824{
825 mbp_header mbp_hdr;
Aaron Durbin76c37002012-10-30 09:03:43 -0500826 u32 me2host_pending;
Aaron Durbin76c37002012-10-30 09:03:43 -0500827 struct mei_csr host;
Aaron Durbin9aa031e2012-11-02 09:16:46 -0500828 struct me_hfs2 hfs2;
829 int count;
Aaron Durbinbe985242012-12-12 12:40:33 -0600830 struct mbp_payload *mbp;
831 int i;
Aaron Durbin9aa031e2012-11-02 09:16:46 -0500832
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");
837 goto mbp_failure;
838 }
Aaron Durbin76c37002012-10-30 09:03:43 -0500839
840 me2host_pending = me_to_host_words_pending();
841 if (!me2host_pending) {
842 printk(BIOS_ERR, "ME: no mbp data!\n");
Aaron Durbin9aa031e2012-11-02 09:16:46 -0500843 goto mbp_failure;
Aaron Durbin76c37002012-10-30 09:03:43 -0500844 }
845
846 /* we know for sure that at least the header is there */
847 mei_read_dword_ptr(&mbp_hdr, MEI_ME_CB_RW);
848
849 if ((mbp_hdr.num_entries > (mbp_hdr.mbp_size / 2)) ||
850 (me2host_pending < mbp_hdr.mbp_size)) {
851 printk(BIOS_ERR, "ME: mbp of %d entries, total size %d words"
852 " buffer contains %d words\n",
853 mbp_hdr.num_entries, mbp_hdr.mbp_size,
854 me2host_pending);
Aaron Durbin9aa031e2012-11-02 09:16:46 -0500855 goto mbp_failure;
Aaron Durbin76c37002012-10-30 09:03:43 -0500856 }
Aaron Durbinbe985242012-12-12 12:40:33 -0600857 mbp = malloc(mbp_hdr.mbp_size * sizeof(u32));
858 if (!mbp)
859 goto mbp_failure;
Aaron Durbin76c37002012-10-30 09:03:43 -0500860
Aaron Durbinbe985242012-12-12 12:40:33 -0600861 mbp->header = mbp_hdr;
Aaron Durbin76c37002012-10-30 09:03:43 -0500862 me2host_pending--;
Aaron Durbin76c37002012-10-30 09:03:43 -0500863
Aaron Durbinbe985242012-12-12 12:40:33 -0600864 i = 0;
865 while (i != me2host_pending) {
866 mei_read_dword_ptr(&mbp->data[i], MEI_ME_CB_RW);
867 i++;
Aaron Durbin76c37002012-10-30 09:03:43 -0500868 }
869
Aaron Durbinbe985242012-12-12 12:40:33 -0600870 /* Signal to the ME that the host has finished reading the MBP. */
Aaron Durbin76c37002012-10-30 09:03:43 -0500871 read_host_csr(&host);
872 host.interrupt_generate = 1;
873 write_host_csr(&host);
874
Aaron Durbinbe985242012-12-12 12:40:33 -0600875 /* Wait for the mbp_cleared indicator. */
Aaron Durbin9aa031e2012-11-02 09:16:46 -0500876 for (count = ME_RETRY; count > 0; --count) {
877 pci_read_dword_ptr(dev, &hfs2, PCI_ME_HFS2);
878 if (hfs2.mbp_cleared)
879 break;
880 udelay(ME_DELAY);
881 }
882
883 if (count == 0) {
884 printk(BIOS_WARNING, "ME: Timeout waiting for mbp_cleared\n");
885 intel_me_mbp_give_up(dev);
Aaron Durbin76c37002012-10-30 09:03:43 -0500886 }
887
Aaron Durbinbe985242012-12-12 12:40:33 -0600888 /* Dump out the MBP contents. */
889#if (CONFIG_DEFAULT_CONSOLE_LOGLEVEL >= BIOS_DEBUG)
890 printk(BIOS_INFO, "ME MBP: Header: items: %d, size dw: %d\n",
891 mbp->header.num_entries, mbp->header.mbp_size);
892 for (i = 0; i < mbp->header.mbp_size - 1; i++) {
893 printk(BIOS_INFO, "ME MBP: %04x: 0x%08x\n", i, mbp->data[i]);
894 }
895#endif
896
897 #define ASSIGN_FIELD_PTR(field_,val_) \
898 { \
899 mbp_data->field_ = (typeof(mbp_data->field_))(void *)val_; \
900 break; \
901 }
902 /* Setup the pointers in the me_bios_payload structure. */
903 for (i = 0; i < mbp->header.mbp_size - 1;) {
904 mbp_item_header *item = (void *)&mbp->data[i];
905
906 switch(MBP_MAKE_IDENT(item->app_id, item->item_id)) {
907 case MBP_IDENT(KERNEL, FW_VER):
908 ASSIGN_FIELD_PTR(fw_version_name, &mbp->data[i+1]);
909
910 case MBP_IDENT(ICC, PROFILE):
911 ASSIGN_FIELD_PTR(icc_profile, &mbp->data[i+1]);
912
913 case MBP_IDENT(INTEL_AT, STATE):
914 ASSIGN_FIELD_PTR(at_state, &mbp->data[i+1]);
915
916 case MBP_IDENT(KERNEL, FW_CAP):
917 ASSIGN_FIELD_PTR(fw_capabilities, &mbp->data[i+1]);
918
919 case MBP_IDENT(KERNEL, ROM_BIST):
920 ASSIGN_FIELD_PTR(rom_bist_data, &mbp->data[i+1]);
921
922 case MBP_IDENT(KERNEL, PLAT_KEY):
923 ASSIGN_FIELD_PTR(platform_key, &mbp->data[i+1]);
924
925 case MBP_IDENT(KERNEL, FW_TYPE):
926 ASSIGN_FIELD_PTR(fw_plat_type, &mbp->data[i+1]);
927
928 case MBP_IDENT(KERNEL, MFS_FAILURE):
929 ASSIGN_FIELD_PTR(mfsintegrity, &mbp->data[i+1]);
930
931 default:
932 printk(BIOS_ERR, "ME MBP: unknown item 0x%x @ dw offset 0x%x\n",
933 mbp->data[i], i);
934 break;
935 }
936 i += item->length;
937 }
938 #undef ASSIGN_FIELD_PTR
939
Aaron Durbin76c37002012-10-30 09:03:43 -0500940 return 0;
Aaron Durbin9aa031e2012-11-02 09:16:46 -0500941
942mbp_failure:
943 intel_me_mbp_give_up(dev);
944 return -1;
Aaron Durbin76c37002012-10-30 09:03:43 -0500945}
946
947#endif /* !__SMM__ */