2 * This file is part of the coreboot project.
4 * Copyright (C) 2011 The Chromium OS Authors. All rights reserved.
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
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.
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,
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.
30 #include <arch/acpi.h>
33 #include <console/console.h>
34 #include <device/pci_ids.h>
35 #include <device/pci_def.h>
40 # include <arch/romcc_io.h>
41 # include <northbridge/intel/sandybridge/pcie_config.c>
43 # include <device/device.h>
44 # include <device/pci.h>
51 #include <vendorcode/google/chromeos/chromeos.h>
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",
64 static int intel_me_read_mbp(me_bios_payload *mbp_data);
67 /* MMIO base address for MEI interface */
68 static u32 mei_base_address;
70 #if CONFIG_DEBUG_INTEL_ME
71 static void mei_dump(void *ptr, int dword, int offset, const char *type)
75 printk(BIOS_SPEW, "%-9s[%02x] : ", type, offset);
82 printk(BIOS_SPEW, "ERROR: 0x%08x\n", dword);
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);
93 printk(BIOS_SPEW, "CB: 0x%08x\n", dword);
96 printk(BIOS_SPEW, "0x%08x\n", offset);
101 # define mei_dump(ptr,dword,offset,type) do {} while (0)
105 * ME/MEI access helpers using memcpy to avoid aliasing.
108 static inline void mei_read_dword_ptr(void *ptr, int offset)
110 u32 dword = read32(mei_base_address + offset);
111 memcpy(ptr, &dword, sizeof(dword));
112 mei_dump(ptr, dword, offset, "READ");
115 static inline void mei_write_dword_ptr(void *ptr, int offset)
118 memcpy(&dword, ptr, sizeof(dword));
119 write32(mei_base_address + offset, dword);
120 mei_dump(ptr, dword, offset, "WRITE");
124 static inline void pci_read_dword_ptr(device_t dev, void *ptr, int offset)
126 u32 dword = pci_read_config32(dev, offset);
127 memcpy(ptr, &dword, sizeof(dword));
128 mei_dump(ptr, dword, offset, "PCI READ");
132 static inline void read_host_csr(struct mei_csr *csr)
134 mei_read_dword_ptr(csr, MEI_H_CSR);
137 static inline void write_host_csr(struct mei_csr *csr)
139 mei_write_dword_ptr(csr, MEI_H_CSR);
142 static inline void read_me_csr(struct mei_csr *csr)
144 mei_read_dword_ptr(csr, MEI_ME_CSR_HA);
147 static inline void write_cb(u32 dword)
149 write32(mei_base_address + MEI_H_CB_WW, dword);
150 mei_dump(NULL, dword, MEI_H_CB_WW, "WRITE");
153 static inline u32 read_cb(void)
155 u32 dword = read32(mei_base_address + MEI_ME_CB_RW);
156 mei_dump(NULL, dword, MEI_ME_CB_RW, "READ");
160 /* Wait for ME ready bit to be asserted */
161 static int mei_wait_for_me_ready(void)
164 unsigned try = ME_RETRY;
173 printk(BIOS_ERR, "ME: failed to become ready\n");
177 static void mei_reset(void)
181 if (mei_wait_for_me_ready() < 0)
184 /* Reset host and ME circular buffers for next message */
185 read_host_csr(&host);
187 host.interrupt_generate = 1;
188 write_host_csr(&host);
190 if (mei_wait_for_me_ready() < 0)
193 /* Re-init and indicate host is ready */
194 read_host_csr(&host);
195 host.interrupt_generate = 1;
198 write_host_csr(&host);
201 static int mei_send_msg(struct mei_header *mei, struct mkhi_header *mkhi,
208 /* Number of dwords to write, ignoring MKHI */
209 ndata = mei->length >> 2;
211 /* Pad non-dword aligned request message length */
215 printk(BIOS_DEBUG, "ME: request does not include MKHI\n");
218 ndata++; /* Add MEI header */
221 * Make sure there is still room left in the circular buffer.
222 * Reset the buffer pointers if the requested message will not fit.
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");
228 read_host_csr(&host);
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.
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);
242 /* Write MEI header */
243 mei_write_dword_ptr(mei, MEI_H_CB_WW);
246 /* Write MKHI header */
247 mei_write_dword_ptr(mkhi, MEI_H_CB_WW);
250 /* Write message data */
252 for (n = 0; n < ndata; ++n)
255 /* Generate interrupt to the ME */
256 read_host_csr(&host);
257 host.interrupt_generate = 1;
258 write_host_csr(&host);
260 /* Make sure ME is ready after sending request data */
261 return mei_wait_for_me_ready();
264 static int mei_recv_msg(struct mkhi_header *mkhi,
265 void *rsp_data, int rsp_bytes)
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*/;
274 /* Total number of dwords to read from circular buffer */
275 expected = (rsp_bytes + sizeof(mei_rsp) + sizeof(mkhi_rsp)) >> 2;
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.
284 for (n = ME_RETRY; n; --n) {
286 if ((me.buffer_write_ptr - me.buffer_read_ptr) >= expected)
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);
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");
304 /* Handle non-dword responses and expect at least MKHI header */
305 ndata = mei_rsp.length >> 2;
306 if (mei_rsp.length & 3)
308 if (ndata != (expected - 1)) {
309 printk(BIOS_ERR, "ME: response is missing data %d != %d\n",
310 ndata, (expected - 1));
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);
325 ndata--; /* MKHI header has been read */
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);
334 /* Read response data from the circular buffer */
336 for (n = 0; n < ndata; ++n)
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);
345 return mei_wait_for_me_ready();
348 static inline int mei_sendrecv(struct mei_header *mei, struct mkhi_header *mkhi,
349 void *req_data, void *rsp_data, int rsp_bytes)
351 if (mei_send_msg(mei, mkhi, req_data) < 0)
353 if (mei_recv_msg(mkhi, rsp_data, rsp_bytes) < 0)
358 /* Send END OF POST message to the ME */
359 int mkhi_end_of_post(void)
361 struct mkhi_header mkhi = {
362 .group_id = MKHI_GROUP_ID_GEN,
363 .command = MKHI_END_OF_POST,
365 struct mei_header mei = {
367 .host_address = MEI_HOST_ADDRESS,
368 .client_address = MEI_ADDRESS_MKHI,
369 .length = sizeof(mkhi),
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");
381 printk(BIOS_INFO, "ME: END OF POST message successful (%d)\n", eop_ack);
385 #if (CONFIG_DEFAULT_CONSOLE_LOGLEVEL >= BIOS_DEBUG) && !defined(__SMM__)
386 static inline void print_cap(const char *name, int state)
388 printk(BIOS_DEBUG, "ME Capability: %-41s : %sabled\n",
389 name, state ? " en" : "dis");
392 static void me_print_fw_version(mbp_fw_version_name *vers_name)
394 if (!vers_name->major_version) {
395 printk(BIOS_ERR, "ME: mbp missing version report\n");
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);
404 /* Get ME Firmware Capabilities */
405 static int mkhi_get_fwcaps(mefwcaps_sku *cap)
408 struct me_fwcaps cap_msg;
409 struct mkhi_header mkhi = {
410 .group_id = MKHI_GROUP_ID_FWCAPS,
411 .command = MKHI_FWCAPS_GET_RULE,
413 struct mei_header mei = {
415 .host_address = MEI_HOST_ADDRESS,
416 .client_address = MEI_ADDRESS_MKHI,
417 .length = sizeof(mkhi) + sizeof(rule_id),
420 /* Send request and wait for response */
421 if (mei_sendrecv(&mei, &mkhi, &rule_id, &cap_msg, sizeof(cap_msg))
423 printk(BIOS_ERR, "ME: GET FWCAPS message failed\n");
426 *cap = cap_msg.caps_sku;
430 /* Get ME Firmware Capabilities */
431 static void me_print_fwcaps(mbp_fw_caps *caps_section)
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))
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);
459 /* Tell ME to issue a global reset */
460 int mkhi_global_reset(void)
462 struct me_global_reset reset = {
463 .request_origin = GLOBAL_RESET_BIOS_POST,
464 .reset_type = CBM_RR_GLOBAL_RESET,
466 struct mkhi_header mkhi = {
467 .group_id = MKHI_GROUP_ID_CBM,
468 .command = MKHI_GLOBAL_RESET,
470 struct mei_header mei = {
472 .length = sizeof(mkhi) + sizeof(reset),
473 .host_address = MEI_HOST_ADDRESS,
474 .client_address = MEI_ADDRESS_MKHI,
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... */
484 /* If the ME responded it rejected the reset request */
485 printk(BIOS_ERR, "ME: Global Reset failed\n");
491 void intel_me_finalize_smm(void)
497 pcie_read_config32(PCH_ME_DEV, PCI_BASE_ADDRESS_0) & ~0xf;
499 /* S3 path will have hidden this device already */
500 if (!mei_base_address || mei_base_address == 0xfffffff0)
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, ®32, sizeof(u32));
507 /* Abort and leave device alone if not normal mode */
509 hfs.working_state != ME_HFS_CWS_NORMAL ||
510 hfs.operation_mode != ME_HFS_MODE_NORMAL)
513 /* Try to send EOP command so ME stops accepting other commands */
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);
522 /* Hide the PCI device */
523 RCBA32_OR(FD2, PCH_DISABLE_MEI1);
528 /* Determine the path that we should take based on ME status */
529 static me_bios_path intel_me_path(device_t dev)
531 me_bios_path path = ME_DISABLE_BIOS_PATH;
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;
542 pci_read_dword_ptr(dev, &hfs, PCI_ME_HFS);
543 pci_read_dword_ptr(dev, &gmes, PCI_ME_GMES);
545 /* Check and dump status */
546 intel_me_status(&hfs, &gmes);
548 /* Check for valid firmware */
550 return ME_ERROR_BIOS_PATH;
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 */
558 printk(BIOS_CRIT, "%s: mbp is not ready!\n",
560 return ME_ERROR_BIOS_PATH;
564 path = ME_RECOVERY_BIOS_PATH;
567 path = ME_DISABLE_BIOS_PATH;
571 /* Check Current Operation Mode */
572 switch (hfs.operation_mode) {
573 case ME_HFS_MODE_NORMAL:
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:
580 path = ME_DISABLE_BIOS_PATH;
584 /* Check for any error code */
586 path = ME_ERROR_BIOS_PATH;
591 /* Prepare ME for MEI messages */
592 static int intel_mei_setup(device_t dev)
594 struct resource *res;
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");
604 mei_base_address = res->base;
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);
611 /* Clean up status for next message */
612 read_host_csr(&host);
613 host.interrupt_generate = 1;
616 write_host_csr(&host);
621 /* Read the Extend register hash of ME firmware */
622 static int intel_me_extend_valid(device_t dev)
624 struct me_heres status;
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");
634 if (!status.extend_reg_valid) {
635 printk(BIOS_ERR, "ME: Extend Register not valid\n");
639 switch (status.extend_reg_algorithm) {
640 case PCI_ME_EXT_SHA1:
642 printk(BIOS_DEBUG, "ME: Extend SHA-1: ");
644 case PCI_ME_EXT_SHA256:
646 printk(BIOS_DEBUG, "ME: Extend SHA-256: ");
649 printk(BIOS_ERR, "ME: Extend Algorithm %d unknown\n",
650 status.extend_reg_algorithm);
655 * TODO(dlaurie) Verify the hash against a saved good value.
658 for (i = 0; i < count; ++i) {
659 extend = pci_read_config32(dev, PCI_ME_HER(i));
660 printk(BIOS_DEBUG, "%08x", extend);
662 printk(BIOS_DEBUG, "\n");
667 /* Hide the ME virtual PCI devices */
668 static void intel_me_hide(device_t dev)
674 /* Check whether ME is present and do basic init */
675 static void intel_me_init(device_t dev)
677 me_bios_path path = intel_me_path(dev);
678 me_bios_payload mbp_data;
680 /* Do initial setup and determine the BIOS path */
681 printk(BIOS_NOTICE, "ME: BIOS path: %s\n", me_bios_path_values[path]);
684 case ME_S3WAKE_BIOS_PATH:
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 */
693 /* Prepare MEI MMIO interface */
694 if (intel_mei_setup(dev) < 0)
697 if(intel_me_read_mbp(&mbp_data))
700 #if CONFIG_CHROMEOS && 0 /* DISABLED */
702 * Unlock ME in recovery mode.
704 if (recovery_mode_enabled()) {
705 /* Unlock ME flash region */
706 mkhi_hmrfpo_enable();
708 /* Issue global reset */
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);
718 /* Tell ME that BIOS is done */
720 /* Hide the virtual PCI device */
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:
729 * TODO(dlaurie) Force recovery mode if ME is unhappy?
735 static void set_subsystem(device_t dev, unsigned vendor, unsigned device)
737 if (!vendor || !device) {
738 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
739 pci_read_config32(dev, PCI_VENDOR_ID));
741 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
742 ((device & 0xffff) << 16) | (vendor & 0xffff));
746 static struct pci_operations pci_ops = {
747 .set_subsystem = set_subsystem,
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,
759 static const struct pci_driver intel_me __pci_driver = {
761 .vendor = PCI_VENDOR_ID_INTEL,
765 /******************************************************************************
767 static u32 me_to_host_words_pending(void)
773 return (me.buffer_write_ptr - me.buffer_read_ptr) &
774 (me.buffer_depth - 1);
778 /* This function is not yet being used, keep it in for the future. */
779 static u32 host_to_me_words_room(void)
788 return (csr.buffer_read_ptr - csr.buffer_write_ptr - 1) &
789 (csr.buffer_depth - 1);
793 * mbp seems to be following its own flow, let's retrieve it in a dedicated
796 static int intel_me_read_mbp(me_bios_payload *mbp_data)
799 mbp_item_header mbp_item_hdr;
804 me2host_pending = me_to_host_words_pending();
805 if (!me2host_pending) {
806 printk(BIOS_ERR, "ME: no mbp data!\n");
810 /* we know for sure that at least the header is there */
811 mei_read_dword_ptr(&mbp_hdr, MEI_ME_CB_RW);
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,
823 memset(mbp_data, 0, sizeof(*mbp_data));
825 while (mbp_hdr.num_entries--) {
827 u32 copy_size, buffer_room;
830 if (!me2host_pending) {
831 printk(BIOS_ERR, "ME: no mbp data %d entries to go!\n",
832 mbp_hdr.num_entries + 1);
836 mei_read_dword_ptr(&mbp_item_hdr, MEI_ME_CB_RW);
838 if (mbp_item_hdr.length > me2host_pending) {
839 printk(BIOS_ERR, "ME: insufficient mbp data %d "
841 mbp_hdr.num_entries + 1);
845 me2host_pending -= mbp_item_hdr.length;
847 mbp_item_id = (((u32)mbp_item_hdr.item_id) << 8) +
850 copy_size = mbp_item_hdr.length - 1;
852 #define SET_UP_COPY(field) { copy_addr = (u32 *)&mbp_data->field; \
853 buffer_room = sizeof(mbp_data->field) / sizeof(u32); \
858 printk(BIOS_INFO, "ME: MBP item header %8.8x\n", *((u32*)p));
860 switch(mbp_item_id) {
862 SET_UP_COPY(fw_version_name);
865 SET_UP_COPY(icc_profile);
868 SET_UP_COPY(at_state);
871 mbp_data->fw_caps_sku.available = 1;
872 SET_UP_COPY(fw_caps_sku.fw_capabilities);
875 SET_UP_COPY(rom_bist_data);
878 SET_UP_COPY(platform_key);
881 mbp_data->fw_plat_type.available = 1;
882 SET_UP_COPY(fw_plat_type.rule_data);
885 SET_UP_COPY(mfsintegrity);
888 printk(BIOS_ERR, "ME: unknown mbp item id 0x%x!!!\n",
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);
900 *copy_addr++ = read_cb();
903 read_host_csr(&host);
904 host.interrupt_generate = 1;
905 write_host_csr(&host);
909 while(host.interrupt_generate) {
910 read_host_csr(&host);
913 printk(BIOS_SPEW, "ME: mbp read OK after %d cycles\n", cntr);
919 #endif /* !__SMM__ */