sb/intel/lynxpoint: Finalize ME in ramstage

Performing ME finalization in SMM does not seem to be required.

Tested on Asrock B85M Pro4, ME still gets finalized successfully.

Change-Id: I9fde40a54f3fb8da2fba46c531443fdd2e067077
Signed-off-by: Angel Pons <th3fanbus@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/51036
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Nico Huber <nico.h@gmx.de>
This commit is contained in:
Angel Pons 2021-02-23 14:19:28 +01:00 committed by Nico Huber
parent d32b51466e
commit 10274d83fc
4 changed files with 15 additions and 47 deletions

View File

@ -30,7 +30,7 @@ ramstage-y += acpi.c
ramstage-$(CONFIG_ELOG) += elog.c ramstage-$(CONFIG_ELOG) += elog.c
ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smi.c pmutil.c ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smi.c pmutil.c
smm-y += smihandler.c me.c pch.c smm-y += smihandler.c pch.c
smm-y += pmutil.c usb_ehci.c usb_xhci.c smm-y += pmutil.c usb_ehci.c usb_xhci.c
bootblock-y += early_pch.c bootblock-y += early_pch.c

View File

@ -28,7 +28,7 @@
#include <vendorcode/google/chromeos/chromeos.h> #include <vendorcode/google/chromeos/chromeos.h>
/* Path that the BIOS should take based on ME state */ /* Path that the BIOS should take based on ME state */
static const char *const me_bios_path_values[] __unused = { static const char *const me_bios_path_values[] = {
[ME_NORMAL_BIOS_PATH] = "Normal", [ME_NORMAL_BIOS_PATH] = "Normal",
[ME_S3WAKE_BIOS_PATH] = "S3 Wake", [ME_S3WAKE_BIOS_PATH] = "S3 Wake",
[ME_ERROR_BIOS_PATH] = "Error", [ME_ERROR_BIOS_PATH] = "Error",
@ -40,11 +40,6 @@ static int intel_me_read_mbp(me_bios_payload *mbp_data, struct device *dev);
/* MMIO base address for MEI interface */ /* MMIO base address for MEI interface */
static u8 *mei_base_address; static u8 *mei_base_address;
#ifdef __SIMPLE_DEVICE__
void intel_me_mbp_clear(pci_devfn_t dev);
#else
void intel_me_mbp_clear(struct device *dev);
#endif
static void mei_dump(void *ptr, int dword, int offset, const char *type) static void mei_dump(void *ptr, int dword, int offset, const char *type)
{ {
@ -98,11 +93,7 @@ static inline void mei_write_dword_ptr(void *ptr, int offset)
mei_dump(ptr, dword, offset, "WRITE"); mei_dump(ptr, dword, offset, "WRITE");
} }
#ifdef __SIMPLE_DEVICE__
static inline void pci_read_dword_ptr(pci_devfn_t dev, void *ptr, int offset)
#else
static inline void pci_read_dword_ptr(struct device *dev, void *ptr, int offset) static inline void pci_read_dword_ptr(struct device *dev, void *ptr, int offset)
#endif
{ {
u32 dword = pci_read_config32(dev, offset); u32 dword = pci_read_config32(dev, offset);
memcpy(ptr, &dword, sizeof(dword)); memcpy(ptr, &dword, sizeof(dword));
@ -401,11 +392,7 @@ static inline int mei_sendrecv_mkhi(struct mkhi_header *mkhi,
* mbp give up routine. This path is taken if hfs.mpb_rdy is 0 or the read * mbp give up routine. This path is taken if hfs.mpb_rdy is 0 or the read
* state machine on the BIOS end doesn't match the ME's state machine. * state machine on the BIOS end doesn't match the ME's state machine.
*/ */
#ifdef __SIMPLE_DEVICE__
static void intel_me_mbp_give_up(pci_devfn_t dev)
#else
static void intel_me_mbp_give_up(struct device *dev) static void intel_me_mbp_give_up(struct device *dev)
#endif
{ {
struct mei_csr csr; struct mei_csr csr;
@ -421,11 +408,7 @@ static void intel_me_mbp_give_up(struct device *dev)
* mbp clear routine. This will wait for the ME to indicate that * mbp clear routine. This will wait for the ME to indicate that
* the MBP has been read and cleared. * the MBP has been read and cleared.
*/ */
#ifdef __SIMPLE_DEVICE__ static void intel_me_mbp_clear(struct device *dev)
void intel_me_mbp_clear(pci_devfn_t dev)
#else
void intel_me_mbp_clear(struct device *dev)
#endif
{ {
int count; int count;
struct me_hfs2 hfs2; struct me_hfs2 hfs2;
@ -446,7 +429,7 @@ void intel_me_mbp_clear(struct device *dev)
} }
} }
static void __unused me_print_fw_version(mbp_fw_version_name *vers_name) static void me_print_fw_version(mbp_fw_version_name *vers_name)
{ {
if (!vers_name) { if (!vers_name) {
printk(BIOS_ERR, "ME: mbp missing version report\n"); printk(BIOS_ERR, "ME: mbp missing version report\n");
@ -485,7 +468,7 @@ static int mkhi_get_fwcaps(mbp_mefwcaps *cap)
} }
/* Get ME Firmware Capabilities */ /* Get ME Firmware Capabilities */
static void __unused me_print_fwcaps(mbp_mefwcaps *cap) static void me_print_fwcaps(mbp_mefwcaps *cap)
{ {
mbp_mefwcaps local_caps; mbp_mefwcaps local_caps;
if (!cap) { if (!cap) {
@ -512,7 +495,7 @@ static void __unused me_print_fwcaps(mbp_mefwcaps *cap)
} }
/* Send END OF POST message to the ME */ /* Send END OF POST message to the ME */
static int __unused mkhi_end_of_post(void) static int mkhi_end_of_post(void)
{ {
struct mkhi_header mkhi = { struct mkhi_header mkhi = {
.group_id = MKHI_GROUP_ID_GEN, .group_id = MKHI_GROUP_ID_GEN,
@ -531,14 +514,12 @@ static int __unused mkhi_end_of_post(void)
return 0; return 0;
} }
#ifdef __SIMPLE_DEVICE__ void intel_me_finalize(struct device *dev)
void intel_me_finalize_smm(void)
{ {
struct me_hfs hfs; struct me_hfs hfs;
u32 reg32; u32 reg32;
reg32 = pci_read_config32(PCH_ME_DEV, PCI_BASE_ADDRESS_0); reg32 = pci_read_config32(dev, PCI_BASE_ADDRESS_0);
mei_base_address = (u8 *)(uintptr_t)(reg32 & ~PCI_BASE_ADDRESS_MEM_ATTR_MASK); mei_base_address = (u8 *)(uintptr_t)(reg32 & ~PCI_BASE_ADDRESS_MEM_ATTR_MASK);
/* S3 path will have hidden this device already */ /* S3 path will have hidden this device already */
@ -546,10 +527,10 @@ void intel_me_finalize_smm(void)
return; return;
/* Wait for ME MBP Cleared indicator */ /* Wait for ME MBP Cleared indicator */
intel_me_mbp_clear(PCH_ME_DEV); intel_me_mbp_clear(dev);
/* Make sure ME is in a mode that expects EOP */ /* Make sure ME is in a mode that expects EOP */
reg32 = pci_read_config32(PCH_ME_DEV, PCI_ME_HFS); reg32 = pci_read_config32(dev, PCI_ME_HFS);
memcpy(&hfs, &reg32, sizeof(u32)); memcpy(&hfs, &reg32, sizeof(u32));
/* Abort and leave device alone if not normal mode */ /* Abort and leave device alone if not normal mode */
@ -562,15 +543,13 @@ void intel_me_finalize_smm(void)
mkhi_end_of_post(); mkhi_end_of_post();
/* Make sure IO is disabled */ /* Make sure IO is disabled */
pci_and_config16(PCH_ME_DEV, PCI_COMMAND, pci_and_config16(dev, PCI_COMMAND,
~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO)); ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO));
/* Hide the PCI device */ /* Hide the PCI device */
RCBA32_OR(FD2, PCH_DISABLE_MEI1); RCBA32_OR(FD2, PCH_DISABLE_MEI1);
} }
#else /* !__SIMPLE_DEVICE__ */
static inline int mei_sendrecv_icc(struct icc_header *icc, static inline int mei_sendrecv_icc(struct icc_header *icc,
void *req_data, int req_bytes, void *req_data, int req_bytes,
void *rsp_data, int rsp_bytes) void *rsp_data, int rsp_bytes)
@ -809,7 +788,7 @@ static void intel_me_init(struct device *dev)
me_icc_set_clock_enables(config->icc_clock_disable); me_icc_set_clock_enables(config->icc_clock_disable);
/* /*
* Leave the ME unlocked. It will be locked via SMI command later. * Leave the ME unlocked. It will be locked later.
*/ */
} }
@ -828,6 +807,7 @@ static struct device_operations device_ops = {
.enable_resources = pci_dev_enable_resources, .enable_resources = pci_dev_enable_resources,
.enable = intel_me_enable, .enable = intel_me_enable,
.init = intel_me_init, .init = intel_me_init,
.final = intel_me_finalize,
.ops_pci = &pci_dev_ops_pci, .ops_pci = &pci_dev_ops_pci,
}; };
@ -843,8 +823,6 @@ static const struct pci_driver intel_me __pci_driver = {
.devices = pci_device_ids, .devices = pci_device_ids,
}; };
#endif /* !__SIMPLE_DEVICE__ */
/****************************************************************************** /******************************************************************************
* */ * */
static u32 me_to_host_words_pending(void) static u32 me_to_host_words_pending(void)
@ -866,7 +844,7 @@ struct mbp_payload {
* mbp seems to be following its own flow, let's retrieve it in a dedicated * mbp seems to be following its own flow, let's retrieve it in a dedicated
* function. * function.
*/ */
static int __unused intel_me_read_mbp(me_bios_payload *mbp_data, struct device *dev) static int intel_me_read_mbp(me_bios_payload *mbp_data, struct device *dev)
{ {
mbp_header mbp_hdr; mbp_header mbp_hdr;
u32 me2host_pending; u32 me2host_pending;
@ -875,11 +853,7 @@ static int __unused intel_me_read_mbp(me_bios_payload *mbp_data, struct device *
struct mbp_payload *mbp; struct mbp_payload *mbp;
int i; int i;
#ifdef __SIMPLE_DEVICE__
pci_read_dword_ptr(PCI_BDF(dev), &hfs2, PCI_ME_HFS2);
#else
pci_read_dword_ptr(dev, &hfs2, PCI_ME_HFS2); pci_read_dword_ptr(dev, &hfs2, PCI_ME_HFS2);
#endif
if (!hfs2.mbp_rdy) { if (!hfs2.mbp_rdy) {
printk(BIOS_ERR, "ME: MBP not ready\n"); printk(BIOS_ERR, "ME: MBP not ready\n");
@ -984,10 +958,6 @@ static int __unused intel_me_read_mbp(me_bios_payload *mbp_data, struct device *
return 0; return 0;
mbp_failure: mbp_failure:
#ifdef __SIMPLE_DEVICE__
intel_me_mbp_give_up(PCI_BDF(dev));
#else
intel_me_mbp_give_up(dev); intel_me_mbp_give_up(dev);
#endif
return -1; return -1;
} }

View File

@ -317,8 +317,7 @@ int intel_early_me_init(void);
int intel_early_me_uma_size(void); int intel_early_me_uma_size(void);
int intel_early_me_init_done(u8 status); int intel_early_me_init_done(u8 status);
void intel_me_finalize_smm(void); void intel_me_finalize(struct device *dev);
void intel_me8_finalize_smm(void);
/* /*
* ME to BIOS Payload Datastructures and definitions. The ordering of the * ME to BIOS Payload Datastructures and definitions. The ordering of the

View File

@ -272,7 +272,6 @@ static void southbridge_smi_apmc(void)
return; return;
} }
intel_me_finalize_smm();
intel_pch_finalize_smm(); intel_pch_finalize_smm();
intel_northbridge_haswell_finalize_smm(); intel_northbridge_haswell_finalize_smm();
intel_cpu_haswell_finalize_smm(); intel_cpu_haswell_finalize_smm();