Add support for Intel Panther Point PCH
[coreboot.git] / src / southbridge / intel / bd82x6x / me_8.x.c
1 /*
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
39 #ifdef __SMM__
40 # include <arch/romcc_io.h>
41 # include <northbridge/intel/sandybridge/pcie_config.c>
42 #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 #endif
53
54 #ifndef __SMM__
55 /* Path that the BIOS should take based on ME state */
56 static const char *me_bios_path_values[] = {
57         [ME_NORMAL_BIOS_PATH]           = "Normal",
58         [ME_S3WAKE_BIOS_PATH]           = "S3 Wake",
59         [ME_ERROR_BIOS_PATH]            = "Error",
60         [ME_RECOVERY_BIOS_PATH]         = "Recovery",
61         [ME_DISABLE_BIOS_PATH]          = "Disable",
62         [ME_FIRMWARE_UPDATE_BIOS_PATH]  = "Firmware Update",
63 };
64 static int intel_me_read_mbp(me_bios_payload *mbp_data);
65 #endif
66
67 /* MMIO base address for MEI interface */
68 static u32 mei_base_address;
69
70 #if CONFIG_DEBUG_INTEL_ME
71 static void mei_dump(void *ptr, int dword, int offset, const char *type)
72 {
73         struct mei_csr *csr;
74
75         printk(BIOS_SPEW, "%-9s[%02x] : ", type, offset);
76
77         switch (offset) {
78         case MEI_H_CSR:
79         case MEI_ME_CSR_HA:
80                 csr = ptr;
81                 if (!csr) {
82                         printk(BIOS_SPEW, "ERROR: 0x%08x\n", dword);
83                         break;
84                 }
85                 printk(BIOS_SPEW, "cbd=%u cbrp=%02u cbwp=%02u ready=%u "
86                        "reset=%u ig=%u is=%u ie=%u\n", csr->buffer_depth,
87                        csr->buffer_read_ptr, csr->buffer_write_ptr,
88                        csr->ready, csr->reset, csr->interrupt_generate,
89                        csr->interrupt_status, csr->interrupt_enable);
90                 break;
91         case MEI_ME_CB_RW:
92         case MEI_H_CB_WW:
93                 printk(BIOS_SPEW, "CB: 0x%08x\n", dword);
94                 break;
95         default:
96                 printk(BIOS_SPEW, "0x%08x\n", offset);
97                 break;
98         }
99 }
100 #else
101 # define mei_dump(ptr,dword,offset,type) do {} while (0)
102 #endif
103
104 /*
105  * ME/MEI access helpers using memcpy to avoid aliasing.
106  */
107
108 static inline void mei_read_dword_ptr(void *ptr, int offset)
109 {
110         u32 dword = read32(mei_base_address + offset);
111         memcpy(ptr, &dword, sizeof(dword));
112         mei_dump(ptr, dword, offset, "READ");
113 }
114
115 static inline void mei_write_dword_ptr(void *ptr, int offset)
116 {
117         u32 dword = 0;
118         memcpy(&dword, ptr, sizeof(dword));
119         write32(mei_base_address + offset, dword);
120         mei_dump(ptr, dword, offset, "WRITE");
121 }
122
123 #ifndef __SMM__
124 static inline void pci_read_dword_ptr(device_t dev, void *ptr, int offset)
125 {
126         u32 dword = pci_read_config32(dev, offset);
127         memcpy(ptr, &dword, sizeof(dword));
128         mei_dump(ptr, dword, offset, "PCI READ");
129 }
130 #endif
131
132 static inline void read_host_csr(struct mei_csr *csr)
133 {
134         mei_read_dword_ptr(csr, MEI_H_CSR);
135 }
136
137 static inline void write_host_csr(struct mei_csr *csr)
138 {
139         mei_write_dword_ptr(csr, MEI_H_CSR);
140 }
141
142 static inline void read_me_csr(struct mei_csr *csr)
143 {
144         mei_read_dword_ptr(csr, MEI_ME_CSR_HA);
145 }
146
147 static inline void write_cb(u32 dword)
148 {
149         write32(mei_base_address + MEI_H_CB_WW, dword);
150         mei_dump(NULL, dword, MEI_H_CB_WW, "WRITE");
151 }
152
153 static inline u32 read_cb(void)
154 {
155         u32 dword = read32(mei_base_address + MEI_ME_CB_RW);
156         mei_dump(NULL, dword, MEI_ME_CB_RW, "READ");
157         return dword;
158 }
159
160 /* Wait for ME ready bit to be asserted */
161 static int mei_wait_for_me_ready(void)
162 {
163         struct mei_csr me;
164         unsigned try = ME_RETRY;
165
166         while (try--) {
167                 read_me_csr(&me);
168                 if (me.ready)
169                         return 0;
170                 udelay(ME_DELAY);
171         }
172
173         printk(BIOS_ERR, "ME: failed to become ready\n");
174         return -1;
175 }
176
177 static void mei_reset(void)
178 {
179         struct mei_csr host;
180
181         if (mei_wait_for_me_ready() < 0)
182                 return;
183
184         /* Reset host and ME circular buffers for next message */
185         read_host_csr(&host);
186         host.reset = 1;
187         host.interrupt_generate = 1;
188         write_host_csr(&host);
189
190         if (mei_wait_for_me_ready() < 0)
191                 return;
192
193         /* Re-init and indicate host is ready */
194         read_host_csr(&host);
195         host.interrupt_generate = 1;
196         host.ready = 1;
197         host.reset = 0;
198         write_host_csr(&host);
199 }
200
201 static int mei_send_msg(struct mei_header *mei, struct mkhi_header *mkhi,
202                         void *req_data)
203 {
204         struct mei_csr host;
205         unsigned ndata, n;
206         u32 *data;
207
208         /* Number of dwords to write, ignoring MKHI */
209         ndata = mei->length >> 2;
210
211         /* Pad non-dword aligned request message length */
212         if (mei->length & 3)
213                 ndata++;
214         if (!ndata) {
215                 printk(BIOS_DEBUG, "ME: request does not include MKHI\n");
216                 return -1;
217         }
218         ndata++; /* Add MEI header */
219
220         /*
221          * Make sure there is still room left in the circular buffer.
222          * Reset the buffer pointers if the requested message will not fit.
223          */
224         read_host_csr(&host);
225         if ((host.buffer_depth - host.buffer_write_ptr) < ndata) {
226                 printk(BIOS_ERR, "ME: circular buffer full, resetting...\n");
227                 mei_reset();
228                 read_host_csr(&host);
229         }
230
231         /*
232          * This implementation does not handle splitting large messages
233          * across multiple transactions.  Ensure the requested length
234          * will fit in the available circular buffer depth.
235          */
236         if ((host.buffer_depth - host.buffer_write_ptr) < ndata) {
237                 printk(BIOS_ERR, "ME: message (%u) too large for buffer (%u)\n",
238                        ndata + 2, host.buffer_depth);
239                 return -1;
240         }
241
242         /* Write MEI header */
243         mei_write_dword_ptr(mei, MEI_H_CB_WW);
244         ndata--;
245
246         /* Write MKHI header */
247         mei_write_dword_ptr(mkhi, MEI_H_CB_WW);
248         ndata--;
249
250         /* Write message data */
251         data = req_data;
252         for (n = 0; n < ndata; ++n)
253                 write_cb(*data++);
254
255         /* Generate interrupt to the ME */
256         read_host_csr(&host);
257         host.interrupt_generate = 1;
258         write_host_csr(&host);
259
260         /* Make sure ME is ready after sending request data */
261         return mei_wait_for_me_ready();
262 }
263
264 static int mei_recv_msg(struct mkhi_header *mkhi,
265                         void *rsp_data, int rsp_bytes)
266 {
267         struct mei_header mei_rsp;
268         struct mkhi_header mkhi_rsp;
269         struct mei_csr me, host;
270         unsigned ndata, n/*, me_data_len*/;
271         unsigned expected;
272         u32 *data;
273
274         /* Total number of dwords to read from circular buffer */
275         expected = (rsp_bytes + sizeof(mei_rsp) + sizeof(mkhi_rsp)) >> 2;
276         if (rsp_bytes & 3)
277                 expected++;
278
279         /*
280          * The interrupt status bit does not appear to indicate that the
281          * message has actually been received.  Instead we wait until the
282          * expected number of dwords are present in the circular buffer.
283          */
284         for (n = ME_RETRY; n; --n) {
285                 read_me_csr(&me);
286                 if ((me.buffer_write_ptr - me.buffer_read_ptr) >= expected)
287                         break;
288                 udelay(ME_DELAY);
289         }
290         if (!n) {
291                 printk(BIOS_ERR, "ME: timeout waiting for data: expected "
292                        "%u, available %u\n", expected,
293                        me.buffer_write_ptr - me.buffer_read_ptr);
294                 return -1;
295         }
296
297         /* Read and verify MEI response header from the ME */
298         mei_read_dword_ptr(&mei_rsp, MEI_ME_CB_RW);
299         if (!mei_rsp.is_complete) {
300                 printk(BIOS_ERR, "ME: response is not complete\n");
301                 return -1;
302         }
303
304         /* Handle non-dword responses and expect at least MKHI header */
305         ndata = mei_rsp.length >> 2;
306         if (mei_rsp.length & 3)
307                 ndata++;
308         if (ndata != (expected - 1)) {
309                 printk(BIOS_ERR, "ME: response is missing data %d != %d\n",
310                        ndata, (expected - 1));
311                 return -1;
312         }
313
314         /* Read and verify MKHI response header from the ME */
315         mei_read_dword_ptr(&mkhi_rsp, MEI_ME_CB_RW);
316         if (!mkhi_rsp.is_response ||
317             mkhi->group_id != mkhi_rsp.group_id ||
318             mkhi->command != mkhi_rsp.command) {
319                 printk(BIOS_ERR, "ME: invalid response, group %u ?= %u,"
320                        "command %u ?= %u, is_response %u\n", mkhi->group_id,
321                        mkhi_rsp.group_id, mkhi->command, mkhi_rsp.command,
322                        mkhi_rsp.is_response);
323                 return -1;
324         }
325         ndata--; /* MKHI header has been read */
326
327         /* Make sure caller passed a buffer with enough space */
328         if (ndata != (rsp_bytes >> 2)) {
329                 printk(BIOS_ERR, "ME: not enough room in response buffer: "
330                        "%u != %u\n", ndata, rsp_bytes >> 2);
331                 return -1;
332         }
333
334         /* Read response data from the circular buffer */
335         data = rsp_data;
336         for (n = 0; n < ndata; ++n)
337                 *data++ = read_cb();
338
339         /* Tell the ME that we have consumed the response */
340         read_host_csr(&host);
341         host.interrupt_status = 1;
342         host.interrupt_generate = 1;
343         write_host_csr(&host);
344
345         return mei_wait_for_me_ready();
346 }
347
348 static inline int mei_sendrecv(struct mei_header *mei, struct mkhi_header *mkhi,
349                                void *req_data, void *rsp_data, int rsp_bytes)
350 {
351         if (mei_send_msg(mei, mkhi, req_data) < 0)
352                 return -1;
353         if (mei_recv_msg(mkhi, rsp_data, rsp_bytes) < 0)
354                 return -1;
355         return 0;
356 }
357
358 /* Send END OF POST message to the ME */
359 int mkhi_end_of_post(void)
360 {
361         struct mkhi_header mkhi = {
362                 .group_id       = MKHI_GROUP_ID_GEN,
363                 .command        = MKHI_END_OF_POST,
364         };
365         struct mei_header mei = {
366                 .is_complete    = 1,
367                 .host_address   = MEI_HOST_ADDRESS,
368                 .client_address = MEI_ADDRESS_MKHI,
369                 .length         = sizeof(mkhi),
370         };
371
372         u32 eop_ack;
373
374         /* Send request and wait for response */
375         printk(BIOS_NOTICE, "ME: %s\n", __FUNCTION__);
376         if (mei_sendrecv(&mei, &mkhi, NULL, &eop_ack, sizeof(eop_ack)) < 0) {
377                 printk(BIOS_ERR, "ME: END OF POST message failed\n");
378                 return -1;
379         }
380
381         printk(BIOS_INFO, "ME: END OF POST message successful (%d)\n", eop_ack);
382         return 0;
383 }
384
385 #if (CONFIG_DEFAULT_CONSOLE_LOGLEVEL >= BIOS_DEBUG) && !defined(__SMM__)
386 static inline void print_cap(const char *name, int state)
387 {
388         printk(BIOS_DEBUG, "ME Capability: %-41s : %sabled\n",
389                name, state ? " en" : "dis");
390 }
391
392 static void me_print_fw_version(mbp_fw_version_name *vers_name)
393 {
394         if (!vers_name->major_version) {
395                 printk(BIOS_ERR, "ME: mbp missing version report\n");
396                 return;
397         }
398
399         printk(BIOS_DEBUG, "ME: found version %d.%d.%d.%d\n",
400                vers_name->major_version, vers_name->minor_version,
401                vers_name->hotfix_version, vers_name->build_version);
402 }
403
404 /* Get ME Firmware Capabilities */
405 static int mkhi_get_fwcaps(mefwcaps_sku *cap)
406 {
407         u32 rule_id = 0;
408         struct me_fwcaps cap_msg;
409         struct mkhi_header mkhi = {
410                 .group_id       = MKHI_GROUP_ID_FWCAPS,
411                 .command        = MKHI_FWCAPS_GET_RULE,
412         };
413         struct mei_header mei = {
414                 .is_complete    = 1,
415                 .host_address   = MEI_HOST_ADDRESS,
416                 .client_address = MEI_ADDRESS_MKHI,
417                 .length         = sizeof(mkhi) + sizeof(rule_id),
418         };
419
420         /* Send request and wait for response */
421         if (mei_sendrecv(&mei, &mkhi, &rule_id, &cap_msg, sizeof(cap_msg))
422             < 0) {
423                 printk(BIOS_ERR, "ME: GET FWCAPS message failed\n");
424                 return -1;
425         }
426         *cap = cap_msg.caps_sku;
427         return 0;
428 }
429
430 /* Get ME Firmware Capabilities */
431 static void me_print_fwcaps(mbp_fw_caps *caps_section)
432 {
433         mefwcaps_sku *cap = &caps_section->fw_capabilities;
434         if (!caps_section->available) {
435                 printk(BIOS_ERR, "ME: mbp missing fwcaps report\n");
436                 if (mkhi_get_fwcaps(cap))
437                         return;
438         }
439
440         print_cap("Full Network manageability", cap->full_net);
441         print_cap("Regular Network manageability", cap->std_net);
442         print_cap("Manageability", cap->manageability);
443         print_cap("Small business technology", cap->small_business);
444         print_cap("Level III manageability", cap->l3manageability);
445         print_cap("IntelR Anti-Theft (AT)", cap->intel_at);
446         print_cap("IntelR Capability Licensing Service (CLS)", cap->intel_cls);
447         print_cap("IntelR Power Sharing Technology (MPC)", cap->intel_mpc);
448         print_cap("ICC Over Clocking", cap->icc_over_clocking);
449         print_cap("Protected Audio Video Path (PAVP)", cap->pavp);
450         print_cap("IPV6", cap->ipv6);
451         print_cap("KVM Remote Control (KVM)", cap->kvm);
452         print_cap("Outbreak Containment Heuristic (OCH)", cap->och);
453         print_cap("Virtual LAN (VLAN)", cap->vlan);
454         print_cap("TLS", cap->tls);
455         print_cap("Wireless LAN (WLAN)", cap->wlan);
456 }
457 #endif
458
459 /* Tell ME to issue a global reset */
460 int mkhi_global_reset(void)
461 {
462         struct me_global_reset reset = {
463                 .request_origin = GLOBAL_RESET_BIOS_POST,
464                 .reset_type     = CBM_RR_GLOBAL_RESET,
465         };
466         struct mkhi_header mkhi = {
467                 .group_id       = MKHI_GROUP_ID_CBM,
468                 .command        = MKHI_GLOBAL_RESET,
469         };
470         struct mei_header mei = {
471                 .is_complete    = 1,
472                 .length         = sizeof(mkhi) + sizeof(reset),
473                 .host_address   = MEI_HOST_ADDRESS,
474                 .client_address = MEI_ADDRESS_MKHI,
475         };
476
477         /* Send request and wait for response */
478         printk(BIOS_NOTICE, "ME: %s\n", __FUNCTION__);
479         if (mei_sendrecv(&mei, &mkhi, &reset, NULL, 0) < 0) {
480                 /* No response means reset will happen shortly... */
481                 hlt();
482         }
483
484         /* If the ME responded it rejected the reset request */
485         printk(BIOS_ERR, "ME: Global Reset failed\n");
486         return -1;
487 }
488
489 #ifdef __SMM__
490
491 void intel_me_finalize_smm(void)
492 {
493         struct me_hfs hfs;
494         u32 reg32;
495
496         mei_base_address =
497                 pcie_read_config32(PCH_ME_DEV, PCI_BASE_ADDRESS_0) & ~0xf;
498
499         /* S3 path will have hidden this device already */
500         if (!mei_base_address || mei_base_address == 0xfffffff0)
501                 return;
502
503         /* Make sure ME is in a mode that expects EOP */
504         reg32 = pcie_read_config32(PCH_ME_DEV, PCI_ME_HFS);
505         memcpy(&hfs, &reg32, sizeof(u32));
506
507         /* Abort and leave device alone if not normal mode */
508         if (hfs.fpt_bad ||
509             hfs.working_state != ME_HFS_CWS_NORMAL ||
510             hfs.operation_mode != ME_HFS_MODE_NORMAL)
511                 return;
512
513         /* Try to send EOP command so ME stops accepting other commands */
514         mkhi_end_of_post();
515
516         /* Make sure IO is disabled */
517         reg32 = pcie_read_config32(PCH_ME_DEV, PCI_COMMAND);
518         reg32 &= ~(PCI_COMMAND_MASTER |
519                    PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
520         pcie_write_config32(PCH_ME_DEV, PCI_COMMAND, reg32);
521
522         /* Hide the PCI device */
523         RCBA32_OR(FD2, PCH_DISABLE_MEI1);
524 }
525
526 #else /* !__SMM__ */
527
528 /* Determine the path that we should take based on ME status */
529 static me_bios_path intel_me_path(device_t dev)
530 {
531         me_bios_path path = ME_DISABLE_BIOS_PATH;
532         struct me_hfs hfs;
533         struct me_gmes gmes;
534
535 #if CONFIG_HAVE_ACPI_RESUME
536         /* S3 wake skips all MKHI messages */
537         if (acpi_slp_type == 3) {
538                 return ME_S3WAKE_BIOS_PATH;
539         }
540 #endif
541
542         pci_read_dword_ptr(dev, &hfs, PCI_ME_HFS);
543         pci_read_dword_ptr(dev, &gmes, PCI_ME_GMES);
544
545         /* Check and dump status */
546         intel_me_status(&hfs, &gmes);
547
548         /* Check for valid firmware */
549         if (hfs.fpt_bad)
550                 return ME_ERROR_BIOS_PATH;
551
552         /* Check Current Working State */
553         switch (hfs.working_state) {
554         case ME_HFS_CWS_NORMAL:
555                 path = ME_NORMAL_BIOS_PATH;
556                 /* check if the MBP is ready */
557                 if (!gmes.mbp_rdy) {
558                         printk(BIOS_CRIT, "%s: mbp is not ready!\n",
559                                __FUNCTION__);
560                         return ME_ERROR_BIOS_PATH;
561                 }
562                 break;
563         case ME_HFS_CWS_REC:
564                 path = ME_RECOVERY_BIOS_PATH;
565                 break;
566         default:
567                 path = ME_DISABLE_BIOS_PATH;
568                 break;
569         }
570
571         /* Check Current Operation Mode */
572         switch (hfs.operation_mode) {
573         case ME_HFS_MODE_NORMAL:
574                 break;
575         case ME_HFS_MODE_DEBUG:
576         case ME_HFS_MODE_DIS:
577         case ME_HFS_MODE_OVER_JMPR:
578         case ME_HFS_MODE_OVER_MEI:
579         default:
580                 path = ME_DISABLE_BIOS_PATH;
581                 break;
582         }
583
584         /* Check for any error code */
585         if (hfs.error_code)
586                 path = ME_ERROR_BIOS_PATH;
587
588         return path;
589 }
590
591 /* Prepare ME for MEI messages */
592 static int intel_mei_setup(device_t dev)
593 {
594         struct resource *res;
595         struct mei_csr host;
596         u32 reg32;
597
598         /* Find the MMIO base for the ME interface */
599         res = find_resource(dev, PCI_BASE_ADDRESS_0);
600         if (!res || res->base == 0 || res->size == 0) {
601                 printk(BIOS_DEBUG, "ME: MEI resource not present!\n");
602                 return -1;
603         }
604         mei_base_address = res->base;
605
606         /* Ensure Memory and Bus Master bits are set */
607         reg32 = pci_read_config32(dev, PCI_COMMAND);
608         reg32 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
609         pci_write_config32(dev, PCI_COMMAND, reg32);
610
611         /* Clean up status for next message */
612         read_host_csr(&host);
613         host.interrupt_generate = 1;
614         host.ready = 1;
615         host.reset = 0;
616         write_host_csr(&host);
617
618         return 0;
619 }
620
621 /* Read the Extend register hash of ME firmware */
622 static int intel_me_extend_valid(device_t dev)
623 {
624         struct me_heres status;
625         u32 extend;
626         int i, count = 0;
627
628         pci_read_dword_ptr(dev, &status, PCI_ME_HERES);
629         if (!status.extend_feature_present) {
630                 printk(BIOS_ERR, "ME: Extend Feature not present\n");
631                 return -1;
632         }
633
634         if (!status.extend_reg_valid) {
635                 printk(BIOS_ERR, "ME: Extend Register not valid\n");
636                 return -1;
637         }
638
639         switch (status.extend_reg_algorithm) {
640         case PCI_ME_EXT_SHA1:
641                 count = 5;
642                 printk(BIOS_DEBUG, "ME: Extend SHA-1: ");
643                 break;
644         case PCI_ME_EXT_SHA256:
645                 count = 8;
646                 printk(BIOS_DEBUG, "ME: Extend SHA-256: ");
647                 break;
648         default:
649                 printk(BIOS_ERR, "ME: Extend Algorithm %d unknown\n",
650                        status.extend_reg_algorithm);
651                 return -1;
652         }
653
654         /*
655          * TODO(dlaurie) Verify the hash against a saved good value.
656          */
657
658         for (i = 0; i < count; ++i) {
659                 extend = pci_read_config32(dev, PCI_ME_HER(i));
660                 printk(BIOS_DEBUG, "%08x", extend);
661         }
662         printk(BIOS_DEBUG, "\n");
663
664         return 0;
665 }
666
667 /* Hide the ME virtual PCI devices */
668 static void intel_me_hide(device_t dev)
669 {
670         dev->enabled = 0;
671         pch_enable(dev);
672 }
673
674 /* Check whether ME is present and do basic init */
675 static void intel_me_init(device_t dev)
676 {
677         me_bios_path path = intel_me_path(dev);
678         me_bios_payload mbp_data;
679
680         /* Do initial setup and determine the BIOS path */
681         printk(BIOS_NOTICE, "ME: BIOS path: %s\n", me_bios_path_values[path]);
682
683         switch (path) {
684         case ME_S3WAKE_BIOS_PATH:
685                 intel_me_hide(dev);
686                 break;
687
688         case ME_NORMAL_BIOS_PATH:
689                 /* Validate the extend register */
690                 if (intel_me_extend_valid(dev) < 0)
691                         break; /* TODO: force recovery mode */
692
693                 /* Prepare MEI MMIO interface */
694                 if (intel_mei_setup(dev) < 0)
695                         break;
696
697                 if(intel_me_read_mbp(&mbp_data))
698                         break;
699
700 #if CONFIG_CHROMEOS && 0 /* DISABLED */
701                 /*
702                  * Unlock ME in recovery mode.
703                  */
704                 if (recovery_mode_enabled()) {
705                         /* Unlock ME flash region */
706                         mkhi_hmrfpo_enable();
707
708                         /* Issue global reset */
709                         mkhi_global_reset();
710                         return;
711                 }
712 #endif
713
714 #if (CONFIG_DEFAULT_CONSOLE_LOGLEVEL >= BIOS_DEBUG)
715                 me_print_fw_version(&mbp_data.fw_version_name);
716                 me_print_fwcaps(&mbp_data.fw_caps_sku);
717 #endif
718                 /* Tell ME that BIOS is done */
719                 mkhi_end_of_post();
720                 /* Hide the virtual PCI device */
721                 intel_me_hide(dev);
722                 break;
723
724         case ME_ERROR_BIOS_PATH:
725         case ME_RECOVERY_BIOS_PATH:
726         case ME_DISABLE_BIOS_PATH:
727         case ME_FIRMWARE_UPDATE_BIOS_PATH:
728                 /*
729                  * TODO(dlaurie) Force recovery mode if ME is unhappy?
730                  */
731                 break;
732         }
733 }
734
735 static void set_subsystem(device_t dev, unsigned vendor, unsigned device)
736 {
737         if (!vendor || !device) {
738                 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
739                            pci_read_config32(dev, PCI_VENDOR_ID));
740         } else {
741                 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
742                            ((device & 0xffff) << 16) | (vendor & 0xffff));
743         }
744 }
745
746 static struct pci_operations pci_ops = {
747         .set_subsystem = set_subsystem,
748 };
749
750 static struct device_operations device_ops = {
751         .read_resources         = pci_dev_read_resources,
752         .set_resources          = pci_dev_set_resources,
753         .enable_resources       = pci_dev_enable_resources,
754         .init                   = intel_me_init,
755         .scan_bus               = scan_static_bus,
756         .ops_pci                = &pci_ops,
757 };
758
759 static const struct pci_driver intel_me __pci_driver = {
760         .ops    = &device_ops,
761         .vendor = PCI_VENDOR_ID_INTEL,
762         .device = 0x1e3a,
763 };
764
765 /******************************************************************************
766  *                                                                           */
767 static u32 me_to_host_words_pending(void)
768 {
769         struct mei_csr me;
770         read_me_csr(&me);
771         if (!me.ready)
772                 return 0;
773         return (me.buffer_write_ptr - me.buffer_read_ptr) &
774                 (me.buffer_depth - 1);
775 }
776
777 #if 0
778 /* This function is not yet being used, keep it in for the future. */
779 static u32 host_to_me_words_room(void)
780 {
781         struct mei_csr csr;
782
783         read_me_csr(&csr);
784         if (!csr.ready)
785                 return 0;
786
787         read_host_csr(&csr);
788         return (csr.buffer_read_ptr - csr.buffer_write_ptr - 1) &
789                 (csr.buffer_depth - 1);
790 }
791 #endif
792 /*
793  * mbp seems to be following its own flow, let's retrieve it in a dedicated
794  * function.
795  */
796 static int intel_me_read_mbp(me_bios_payload *mbp_data)
797 {
798         mbp_header mbp_hdr;
799         mbp_item_header mbp_item_hdr;
800         u32 me2host_pending;
801         u32 mbp_item_id;
802         struct mei_csr host;
803
804         me2host_pending = me_to_host_words_pending();
805         if (!me2host_pending) {
806                 printk(BIOS_ERR, "ME: no mbp data!\n");
807                 return -1;
808         }
809
810         /* we know for sure that at least the header is there */
811         mei_read_dword_ptr(&mbp_hdr, MEI_ME_CB_RW);
812
813         if ((mbp_hdr.num_entries > (mbp_hdr.mbp_size / 2)) ||
814             (me2host_pending < mbp_hdr.mbp_size)) {
815                 printk(BIOS_ERR, "ME: mbp of %d entries, total size %d words"
816                        " buffer contains %d words\n",
817                        mbp_hdr.num_entries, mbp_hdr.mbp_size,
818                        me2host_pending);
819                 return -1;
820         }
821
822         me2host_pending--;
823         memset(mbp_data, 0, sizeof(*mbp_data));
824
825         while (mbp_hdr.num_entries--) {
826                 u32* copy_addr;
827                 u32 copy_size, buffer_room;
828                 void *p;
829
830                 if (!me2host_pending) {
831                         printk(BIOS_ERR, "ME: no mbp data %d entries to go!\n",
832                                mbp_hdr.num_entries + 1);
833                         return -1;
834                 }
835
836                 mei_read_dword_ptr(&mbp_item_hdr, MEI_ME_CB_RW);
837
838                 if (mbp_item_hdr.length > me2host_pending) {
839                         printk(BIOS_ERR, "ME: insufficient mbp data %d "
840                                "entries to go!\n",
841                                mbp_hdr.num_entries + 1);
842                         return -1;
843                 }
844
845                 me2host_pending -= mbp_item_hdr.length;
846
847                 mbp_item_id = (((u32)mbp_item_hdr.item_id) << 8) +
848                         mbp_item_hdr.app_id;
849
850                 copy_size = mbp_item_hdr.length - 1;
851
852 #define SET_UP_COPY(field) { copy_addr = (u32 *)&mbp_data->field;            \
853                         buffer_room = sizeof(mbp_data->field) / sizeof(u32); \
854                         break;                                               \
855                 }
856
857                 p = &mbp_item_hdr;
858                 printk(BIOS_INFO, "ME: MBP item header %8.8x\n", *((u32*)p));
859
860                 switch(mbp_item_id) {
861                 case 0x101:
862                         SET_UP_COPY(fw_version_name);
863
864                 case 0x102:
865                         SET_UP_COPY(icc_profile);
866
867                 case 0x103:
868                         SET_UP_COPY(at_state);
869
870                 case 0x201:
871                         mbp_data->fw_caps_sku.available = 1;
872                         SET_UP_COPY(fw_caps_sku.fw_capabilities);
873
874                 case 0x301:
875                         SET_UP_COPY(rom_bist_data);
876
877                 case 0x401:
878                         SET_UP_COPY(platform_key);
879
880                 case 0x501:
881                         mbp_data->fw_plat_type.available = 1;
882                         SET_UP_COPY(fw_plat_type.rule_data);
883
884                 case 0x601:
885                         SET_UP_COPY(mfsintegrity);
886
887                 default:
888                         printk(BIOS_ERR, "ME: unknown mbp item id 0x%x!!!\n",
889                                mbp_item_id);
890                         return -1;
891                 }
892
893                 if (buffer_room != copy_size) {
894                         printk(BIOS_ERR, "ME: buffer room %d != %d copy size"
895                                " for item  0x%x!!!\n",
896                                buffer_room, copy_size, mbp_item_id);
897                         return -1;
898                 }
899                 while(copy_size--)
900                         *copy_addr++ = read_cb();
901         }
902
903         read_host_csr(&host);
904         host.interrupt_generate = 1;
905         write_host_csr(&host);
906
907         {
908                 int cntr = 0;
909                 while(host.interrupt_generate) {
910                         read_host_csr(&host);
911                         cntr++;
912                 }
913                 printk(BIOS_SPEW, "ME: mbp read OK after %d cycles\n", cntr);
914         }
915
916         return 0;
917 }
918
919 #endif /* !__SMM__ */