diff --git a/src/mainboard/google/slippy/smihandler.c b/src/mainboard/google/slippy/smihandler.c index 7b7dd69beb..428af5f5c5 100644 --- a/src/mainboard/google/slippy/smihandler.c +++ b/src/mainboard/google/slippy/smihandler.c @@ -133,6 +133,7 @@ int mainboard_smi_apmc(u8 apmc) return 0; } + intel_me_finalize_smm(); intel_pch_finalize_smm(); intel_northbridge_haswell_finalize_smm(); intel_cpu_haswell_finalize_smm(); diff --git a/src/mainboard/intel/baskingridge/mainboard_smi.c b/src/mainboard/intel/baskingridge/mainboard_smi.c index f24af67579..e543494b25 100644 --- a/src/mainboard/intel/baskingridge/mainboard_smi.c +++ b/src/mainboard/intel/baskingridge/mainboard_smi.c @@ -84,6 +84,7 @@ int mainboard_smi_apmc(u8 apmc) return 0; } + intel_me_finalize_smm(); intel_pch_finalize_smm(); intel_northbridge_haswell_finalize_smm(); intel_cpu_haswell_finalize_smm(); diff --git a/src/mainboard/intel/wtm2/mainboard_smi.c b/src/mainboard/intel/wtm2/mainboard_smi.c index bcc94d6f2b..3ffc68441d 100644 --- a/src/mainboard/intel/wtm2/mainboard_smi.c +++ b/src/mainboard/intel/wtm2/mainboard_smi.c @@ -60,6 +60,7 @@ int mainboard_smi_apmc(u8 apmc) return 0; } + intel_me_finalize_smm(); intel_pch_finalize_smm(); intel_northbridge_haswell_finalize_smm(); intel_cpu_haswell_finalize_smm(); diff --git a/src/southbridge/intel/lynxpoint/Makefile.inc b/src/southbridge/intel/lynxpoint/Makefile.inc index 92e1c0092e..1689132510 100644 --- a/src/southbridge/intel/lynxpoint/Makefile.inc +++ b/src/southbridge/intel/lynxpoint/Makefile.inc @@ -48,7 +48,7 @@ ramstage-y += spi.c smm-$(CONFIG_SPI_FLASH_SMM) += spi.c ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smi.c pmutil.c -smm-$(CONFIG_HAVE_SMI_HANDLER) += smihandler.c finalize.c pch.c +smm-$(CONFIG_HAVE_SMI_HANDLER) += smihandler.c me_9.x.c finalize.c pch.c smm-$(CONFIG_HAVE_SMI_HANDLER) += pmutil.c romstage-y += early_usb.c early_smbus.c early_me.c me_status.c early_pch.c diff --git a/src/southbridge/intel/lynxpoint/me_9.x.c b/src/southbridge/intel/lynxpoint/me_9.x.c index bde4e9d97a..01eb8447c6 100644 --- a/src/southbridge/intel/lynxpoint/me_9.x.c +++ b/src/southbridge/intel/lynxpoint/me_9.x.c @@ -47,6 +47,7 @@ #include #endif +#ifndef __SMM__ /* Path that the BIOS should take based on ME state */ static const char *me_bios_path_values[] = { [ME_NORMAL_BIOS_PATH] = "Normal", @@ -57,6 +58,7 @@ static const char *me_bios_path_values[] = { [ME_FIRMWARE_UPDATE_BIOS_PATH] = "Firmware Update", }; static int intel_me_read_mbp(me_bios_payload *mbp_data, device_t dev); +#endif /* MMIO base address for MEI interface */ static u32 mei_base_address; @@ -114,12 +116,14 @@ static inline void mei_write_dword_ptr(void *ptr, int offset) mei_dump(ptr, dword, offset, "WRITE"); } +#ifndef __SMM__ static inline void pci_read_dword_ptr(device_t dev, void *ptr, int offset) { u32 dword = pci_read_config32(dev, offset); memcpy(ptr, &dword, sizeof(dword)); mei_dump(ptr, dword, offset, "PCI READ"); } +#endif static inline void read_host_csr(struct mei_csr *csr) { @@ -347,7 +351,7 @@ static inline int mei_sendrecv(struct mei_header *mei, struct mkhi_header *mkhi, return 0; } -#if (CONFIG_DEFAULT_CONSOLE_LOGLEVEL >= BIOS_DEBUG) +#if (CONFIG_DEFAULT_CONSOLE_LOGLEVEL >= BIOS_DEBUG) && !defined(__SMM__) static inline void print_cap(const char *name, int state) { printk(BIOS_DEBUG, "ME Capability: %-41s : %sabled\n", @@ -452,6 +456,8 @@ static int mkhi_global_reset(void) } #endif +#ifdef __SMM__ + /* Send END OF POST message to the ME */ static int mkhi_end_of_post(void) { @@ -479,6 +485,43 @@ static int mkhi_end_of_post(void) return 0; } +void intel_me_finalize_smm(void) +{ + struct me_hfs hfs; + u32 reg32; + + mei_base_address = + pci_read_config32(PCH_ME_DEV, PCI_BASE_ADDRESS_0) & ~0xf; + + /* S3 path will have hidden this device already */ + if (!mei_base_address || mei_base_address == 0xfffffff0) + return; + + /* Make sure ME is in a mode that expects EOP */ + reg32 = pci_read_config32(PCH_ME_DEV, PCI_ME_HFS); + memcpy(&hfs, ®32, sizeof(u32)); + + /* Abort and leave device alone if not normal mode */ + if (hfs.fpt_bad || + hfs.working_state != ME_HFS_CWS_NORMAL || + hfs.operation_mode != ME_HFS_MODE_NORMAL) + return; + + /* Try to send EOP command so ME stops accepting other commands */ + mkhi_end_of_post(); + + /* Make sure IO is disabled */ + reg32 = pci_read_config32(PCH_ME_DEV, PCI_COMMAND); + reg32 &= ~(PCI_COMMAND_MASTER | + PCI_COMMAND_MEMORY | PCI_COMMAND_IO); + pci_write_config32(PCH_ME_DEV, PCI_COMMAND, reg32); + + /* Hide the PCI device */ + RCBA32_OR(FD2, PCH_DISABLE_MEI1); +} + +#else /* !__SMM__ */ + /* Determine the path that we should take based on ME status */ static me_bios_path intel_me_path(device_t dev) { @@ -636,12 +679,6 @@ static int intel_me_extend_valid(device_t dev) /* Hide the ME virtual PCI devices */ static void intel_me_hide(device_t dev) { - /* Make sure IO is disabled */ - u32 reg32 = pci_read_config32(dev, PCI_COMMAND); - reg32 &= ~(PCI_COMMAND_MASTER | - PCI_COMMAND_MEMORY | PCI_COMMAND_IO); - pci_write_config32(dev, PCI_COMMAND, reg32); - dev->enabled = 0; pch_enable(dev); } @@ -692,9 +729,9 @@ static void intel_me_init(device_t dev) } #endif - /* Lock down and hide Management Engine */ - mkhi_end_of_post(); - intel_me_hide(dev); + /* + * Leave the ME unlocked. It will be locked via SMI command later. + */ } static void set_subsystem(device_t dev, unsigned vendor, unsigned device) @@ -916,3 +953,5 @@ mbp_failure: intel_me_mbp_give_up(dev); return -1; } + +#endif /* !__SMM__ */