diff --git a/src/soc/intel/broadwell/broadwell/me.h b/src/soc/intel/broadwell/broadwell/me.h index 08a5d425f0..ddecaf864d 100644 --- a/src/soc/intel/broadwell/broadwell/me.h +++ b/src/soc/intel/broadwell/broadwell/me.h @@ -17,8 +17,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef _INTEL_ME_H -#define _INTEL_ME_H +#ifndef _BROADWELL_ME_H_ +#define _BROADWELL_ME_H_ + +#include #define ME_RETRY 100000 /* 1 second */ #define ME_DELAY 10 /* 10 us */ @@ -27,7 +29,6 @@ * Management Engine PCI registers */ -#define PCI_CPU_DEVICE PCI_DEV(0,0,0) #define PCI_CPU_MEBASE_L 0x70 /* Set by MRC */ #define PCI_CPU_MEBASE_H 0x74 /* Set by MRC */ @@ -326,14 +327,6 @@ typedef enum { ME_FIRMWARE_UPDATE_BIOS_PATH, } me_bios_path; -/* Defined in me_status.c for both romstage and ramstage */ -void intel_me_status(struct me_hfs *hfs, struct me_hfs2 *hfs2); - -#ifdef __SMM__ -void intel_me_finalize_smm(void); -void intel_me8_finalize_smm(void); -#endif - /* * ME to BIOS Payload Datastructures and definitions. The ordering of the * structures follows the ordering in the ME9 BWG. @@ -496,4 +489,13 @@ struct me_fwcaps { u8 reserved[3]; } __attribute__ ((packed)); -#endif /* _INTEL_ME_H */ +void intel_me_finalize(void); + +#if (CONFIG_DEFAULT_CONSOLE_LOGLEVEL >= BIOS_DEBUG) +/* Defined in me_status.c for both romstage and ramstage */ +void intel_me_status(void); +#else +static inline void intel_me_status(void) { } +#endif + +#endif diff --git a/src/soc/intel/broadwell/me.c b/src/soc/intel/broadwell/me.c index 542ccc3e41..12de4a5883 100644 --- a/src/soc/intel/broadwell/me.c +++ b/src/soc/intel/broadwell/me.c @@ -19,7 +19,7 @@ /* * This is a ramstage driver for the Intel Management Engine found in the - * 6-series chipset. It handles the required boot-time messages over the + * southbridge. It handles the required boot-time messages over the * MMIO-based Management Engine Interface to tell the ME that the BIOS is * finished with POST. Additional messages are defined for debug but are * not used unless the console loglevel is high enough. @@ -36,16 +36,19 @@ #include #include #include - -#include "me.h" -#include "pch.h" +#include +#include +#include +#include +#include +#include +#include #if CONFIG_CHROMEOS #include #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", @@ -56,7 +59,6 @@ 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; @@ -475,7 +477,7 @@ void intel_me_mbp_clear(device_t dev) } } -#if (CONFIG_DEFAULT_CONSOLE_LOGLEVEL >= BIOS_DEBUG) && !defined(__SMM__) +#if (CONFIG_DEFAULT_CONSOLE_LOGLEVEL >= BIOS_DEBUG) static inline void print_cap(const char *name, int state) { printk(BIOS_DEBUG, "ME Capability: %-41s : %sabled\n", @@ -544,34 +546,6 @@ static void me_print_fwcaps(mbp_mefwcaps *cap) #endif #endif -#if CONFIG_CHROMEOS && 0 /* DISABLED */ -/* Tell ME to issue a global reset */ -static int mkhi_global_reset(void) -{ - struct me_global_reset reset = { - .request_origin = GLOBAL_RESET_BIOS_POST, - .reset_type = CBM_RR_GLOBAL_RESET, - }; - struct mkhi_header mkhi = { - .group_id = MKHI_GROUP_ID_CBM, - .command = MKHI_GLOBAL_RESET, - }; - - /* Send request and wait for response */ - printk(BIOS_NOTICE, "ME: %s\n", __FUNCTION__); - if (mei_sendrecv_mkhi(&mkhi, &reset, sizeof(reset), NULL, 0) < 0) { - /* No response means reset will happen shortly... */ - hlt(); - } - - /* If the ME responded it rejected the reset request */ - printk(BIOS_ERR, "ME: Global Reset failed\n"); - return -1; -} -#endif - -#ifdef __SMM__ - /* Send END OF POST message to the ME */ static int mkhi_end_of_post(void) { @@ -592,25 +566,23 @@ static int mkhi_end_of_post(void) return 0; } -void intel_me_finalize_smm(void) +void intel_me_finalize(void) { + device_t dev = PCH_DEV_ME; 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; #if CONFIG_ME_MBP_CLEAR_LATE /* Wait for ME MBP Cleared indicator */ - intel_me_mbp_clear(PCH_ME_DEV); + intel_me_mbp_clear(dev); #endif /* 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, ®32, sizeof(u32)); /* Abort and leave device alone if not normal mode */ @@ -623,17 +595,15 @@ void intel_me_finalize_smm(void) mkhi_end_of_post(); /* Make sure IO is disabled */ - reg32 = pci_read_config32(PCH_ME_DEV, PCI_COMMAND); + reg32 = pci_read_config32(dev, PCI_COMMAND); reg32 &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO); - pci_write_config32(PCH_ME_DEV, PCI_COMMAND, reg32); + pci_write_config32(dev, PCI_COMMAND, reg32); /* Hide the PCI device */ RCBA32_OR(FD2, PCH_DISABLE_MEI1); } -#else /* !__SMM__ */ - static int me_icc_set_clock_enables(u32 mask) { struct icc_clock_enables_msg clk = { @@ -665,12 +635,12 @@ static me_bios_path intel_me_path(device_t dev) struct me_hfs hfs; struct me_hfs2 hfs2; + /* Check and dump status */ + intel_me_status(); + pci_read_dword_ptr(dev, &hfs, PCI_ME_HFS); pci_read_dword_ptr(dev, &hfs2, PCI_ME_HFS2); - /* Check and dump status */ - intel_me_status(&hfs, &hfs2); - /* Check Current Working State */ switch (hfs.working_state) { case ME_HFS_CWS_NORMAL: @@ -808,7 +778,7 @@ static int intel_me_extend_valid(device_t dev) /* Check whether ME is present and do basic init */ static void intel_me_init(device_t dev) { - struct southbridge_intel_lynxpoint_config *config = dev->chip_info; + config_t *config = dev->chip_info; me_bios_path path = intel_me_path(dev); me_bios_payload mbp_data; @@ -918,22 +888,6 @@ static u32 me_to_host_words_pending(void) (me.buffer_depth - 1); } -#if 0 -/* This function is not yet being used, keep it in for the future. */ -static u32 host_to_me_words_room(void) -{ - struct mei_csr csr; - - read_me_csr(&csr); - if (!csr.ready) - return 0; - - read_host_csr(&csr); - return (csr.buffer_read_ptr - csr.buffer_write_ptr - 1) & - (csr.buffer_depth - 1); -} -#endif - struct mbp_payload { mbp_header header; u32 data[0]; @@ -1010,11 +964,12 @@ static int intel_me_read_mbp(me_bios_payload *mbp_data, device_t dev) #endif #endif - #define ASSIGN_FIELD_PTR(field_,val_) \ - { \ +#define ASSIGN_FIELD_PTR(field_,val_) \ + { \ mbp_data->field_ = (typeof(mbp_data->field_))(void *)val_; \ break; \ - } + } + /* Setup the pointers in the me_bios_payload structure. */ for (i = 0; i < mbp->header.mbp_size - 1;) { mbp_item_header *item = (void *)&mbp->data[i]; @@ -1065,5 +1020,3 @@ mbp_failure: intel_me_mbp_give_up(dev); return -1; } - -#endif /* !__SMM__ */ diff --git a/src/soc/intel/broadwell/me_status.c b/src/soc/intel/broadwell/me_status.c index 6b81da7b5b..476268f61a 100644 --- a/src/soc/intel/broadwell/me_status.c +++ b/src/soc/intel/broadwell/me_status.c @@ -17,20 +17,33 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include +#include #include -#include "me.h" +#include +#include +#include +#include +#include +#include -#if (CONFIG_DEFAULT_CONSOLE_LOGLEVEL >= BIOS_DEBUG) /* HFS1[3:0] Current Working State Values */ static const char *me_cws_values[] = { [ME_HFS_CWS_RESET] = "Reset", [ME_HFS_CWS_INIT] = "Initializing", [ME_HFS_CWS_REC] = "Recovery", + [3] = "Unknown (3)", + [4] = "Unknown (4)", [ME_HFS_CWS_NORMAL] = "Normal", [ME_HFS_CWS_WAIT] = "Platform Disable Wait", [ME_HFS_CWS_TRANS] = "OP State Transition", - [ME_HFS_CWS_INVALID] = "Invalid CPU Plugged In" + [ME_HFS_CWS_INVALID] = "Invalid CPU Plugged In", + [9] = "Unknown (9)", + [10] = "Unknown (10)", + [11] = "Unknown (11)", + [12] = "Unknown (12)", + [13] = "Unknown (13)", + [14] = "Unknown (14)", + [15] = "Unknown (15)", }; /* HFS1[8:6] Current Operation State Values */ @@ -73,19 +86,32 @@ static const char *me_progress_values[] = { /* HFS2[27:24] Power Management Event */ static const char *me_pmevent_values[] = { - [ME_HFS2_PMEVENT_CLEAN_MOFF_MX_WAKE] = "Clean Moff->Mx wake", - [ME_HFS2_PMEVENT_MOFF_MX_WAKE_ERROR] = "Moff->Mx wake after an error", - [ME_HFS2_PMEVENT_CLEAN_GLOBAL_RESET] = "Clean global reset", - [ME_HFS2_PMEVENT_CLEAN_GLOBAL_RESET_ERROR] = "Global reset after an error", - [ME_HFS2_PMEVENT_CLEAN_ME_RESET] = "Clean Intel ME reset", - [ME_HFS2_PMEVENT_ME_RESET_EXCEPTION] = "Intel ME reset due to exception", - [ME_HFS2_PMEVENT_PSEUDO_ME_RESET] = "Pseudo-global reset", - [ME_HFS2_PMEVENT_S0MO_SXM3] = "S0/M0->Sx/M3", - [ME_HFS2_PMEVENT_SXM3_S0M0] = "Sx/M3->S0/M0", - [ME_HFS2_PMEVENT_NON_PWR_CYCLE_RESET] = "Non-power cycle reset", - [ME_HFS2_PMEVENT_PWR_CYCLE_RESET_M3] = "Power cycle reset through M3", - [ME_HFS2_PMEVENT_PWR_CYCLE_RESET_MOFF] = "Power cycle reset through Moff", - [ME_HFS2_PMEVENT_SXMX_SXMOFF] = "Sx/Mx->Sx/Moff" + [ME_HFS2_PMEVENT_CLEAN_MOFF_MX_WAKE] = + "Clean Moff->Mx wake", + [ME_HFS2_PMEVENT_MOFF_MX_WAKE_ERROR] = + "Moff->Mx wake after an error", + [ME_HFS2_PMEVENT_CLEAN_GLOBAL_RESET] = + "Clean global reset", + [ME_HFS2_PMEVENT_CLEAN_GLOBAL_RESET_ERROR] = + "Global reset after an error", + [ME_HFS2_PMEVENT_CLEAN_ME_RESET] = + "Clean Intel ME reset", + [ME_HFS2_PMEVENT_ME_RESET_EXCEPTION] = + "Intel ME reset due to exception", + [ME_HFS2_PMEVENT_PSEUDO_ME_RESET] = + "Pseudo-global reset", + [ME_HFS2_PMEVENT_S0MO_SXM3] = + "S0/M0->Sx/M3", + [ME_HFS2_PMEVENT_SXM3_S0M0] = + "Sx/M3->S0/M0", + [ME_HFS2_PMEVENT_NON_PWR_CYCLE_RESET] = + "Non-power cycle reset", + [ME_HFS2_PMEVENT_PWR_CYCLE_RESET_M3] = + "Power cycle reset through M3", + [ME_HFS2_PMEVENT_PWR_CYCLE_RESET_MOFF] = + "Power cycle reset through Moff", + [ME_HFS2_PMEVENT_SXMX_SXMOFF] = + "Sx/Mx->Sx/Moff" }; /* Progress Code 0 states */ @@ -96,31 +122,56 @@ static const char *me_progress_rom_values[] = { /* Progress Code 1 states */ static const char *me_progress_bup_values[] = { - [ME_HFS2_STATE_BUP_INIT] = "Initialization starts", - [ME_HFS2_STATE_BUP_DIS_HOST_WAKE] = "Disable the host wake event", - [ME_HFS2_STATE_BUP_FLOW_DET] = "Flow determination start process", - [ME_HFS2_STATE_BUP_VSCC_ERR] = "Error reading/matching the VSCC table in the descriptor", - [ME_HFS2_STATE_BUP_CHECK_STRAP] = "Check to see if straps say ME DISABLED", - [ME_HFS2_STATE_BUP_PWR_OK_TIMEOUT] = "Timeout waiting for PWROK", - [ME_HFS2_STATE_BUP_MANUF_OVRD_STRAP] = "Possibly handle BUP manufacturing override strap", - [ME_HFS2_STATE_BUP_M3] = "Bringup in M3", - [ME_HFS2_STATE_BUP_M0] = "Bringup in M0", - [ME_HFS2_STATE_BUP_FLOW_DET_ERR] = "Flow detection error", - [ME_HFS2_STATE_BUP_M3_CLK_ERR] = "M3 clock switching error", - [ME_HFS2_STATE_BUP_CPU_RESET_DID_TIMEOUT_MEM_MISSING] = "Host error - CPU reset timeout, DID timeout, memory missing", - [ME_HFS2_STATE_BUP_M3_KERN_LOAD] = "M3 kernel load", - [ME_HFS2_STATE_BUP_T32_MISSING] = "T34 missing - cannot program ICC", - [ME_HFS2_STATE_BUP_WAIT_DID] = "Waiting for DID BIOS message", - [ME_HFS2_STATE_BUP_WAIT_DID_FAIL] = "Waiting for DID BIOS message failure", - [ME_HFS2_STATE_BUP_DID_NO_FAIL] = "DID reported no error", - [ME_HFS2_STATE_BUP_ENABLE_UMA] = "Enabling UMA", - [ME_HFS2_STATE_BUP_ENABLE_UMA_ERR] = "Enabling UMA error", - [ME_HFS2_STATE_BUP_SEND_DID_ACK] = "Sending DID Ack to BIOS", - [ME_HFS2_STATE_BUP_SEND_DID_ACK_ERR] = "Sending DID Ack to BIOS error", - [ME_HFS2_STATE_BUP_M0_CLK] = "Switching clocks in M0", - [ME_HFS2_STATE_BUP_M0_CLK_ERR] = "Switching clocks in M0 error", - [ME_HFS2_STATE_BUP_TEMP_DIS] = "ME in temp disable", - [ME_HFS2_STATE_BUP_M0_KERN_LOAD] = "M0 kernel load", + [ME_HFS2_STATE_BUP_INIT] = + "Initialization starts", + [ME_HFS2_STATE_BUP_DIS_HOST_WAKE] = + "Disable the host wake event", + [ME_HFS2_STATE_BUP_FLOW_DET] = + "Flow determination start process", + [ME_HFS2_STATE_BUP_VSCC_ERR] = + "Error reading/matching the VSCC table in the descriptor", + [ME_HFS2_STATE_BUP_CHECK_STRAP] = + "Check to see if straps say ME DISABLED", + [ME_HFS2_STATE_BUP_PWR_OK_TIMEOUT] = + "Timeout waiting for PWROK", + [ME_HFS2_STATE_BUP_MANUF_OVRD_STRAP] = + "Possibly handle BUP manufacturing override strap", + [ME_HFS2_STATE_BUP_M3] = + "Bringup in M3", + [ME_HFS2_STATE_BUP_M0] = + "Bringup in M0", + [ME_HFS2_STATE_BUP_FLOW_DET_ERR] = + "Flow detection error", + [ME_HFS2_STATE_BUP_M3_CLK_ERR] = + "M3 clock switching error", + [ME_HFS2_STATE_BUP_CPU_RESET_DID_TIMEOUT_MEM_MISSING] = + "Host error - CPU reset timeout, DID timeout, memory missing", + [ME_HFS2_STATE_BUP_M3_KERN_LOAD] = + "M3 kernel load", + [ME_HFS2_STATE_BUP_T32_MISSING] = + "T34 missing - cannot program ICC", + [ME_HFS2_STATE_BUP_WAIT_DID] = + "Waiting for DID BIOS message", + [ME_HFS2_STATE_BUP_WAIT_DID_FAIL] = + "Waiting for DID BIOS message failure", + [ME_HFS2_STATE_BUP_DID_NO_FAIL] = + "DID reported no error", + [ME_HFS2_STATE_BUP_ENABLE_UMA] = + "Enabling UMA", + [ME_HFS2_STATE_BUP_ENABLE_UMA_ERR] = + "Enabling UMA error", + [ME_HFS2_STATE_BUP_SEND_DID_ACK] = + "Sending DID Ack to BIOS", + [ME_HFS2_STATE_BUP_SEND_DID_ACK_ERR] = + "Sending DID Ack to BIOS error", + [ME_HFS2_STATE_BUP_M0_CLK] = + "Switching clocks in M0", + [ME_HFS2_STATE_BUP_M0_CLK_ERR] = + "Switching clocks in M0 error", + [ME_HFS2_STATE_BUP_TEMP_DIS] = + "ME in temp disable", + [ME_HFS2_STATE_BUP_M0_KERN_LOAD] = + "M0 kernel load", }; /* Progress Code 3 states */ @@ -135,17 +186,32 @@ static const char *me_progress_policy_values[] = { [ME_HFS2_STATE_POLICY_RCVD_HOST_WAKE] = "Received host wake", [ME_HFS2_STATE_POLICY_RCVD_AC_DC] = "Received AC<>DC switch", [ME_HFS2_STATE_POLICY_RCVD_DID] = "Received DRAM Init Done", - [ME_HFS2_STATE_POLICY_VSCC_NOT_FOUND] = "VSCC Data not found for flash device", - [ME_HFS2_STATE_POLICY_VSCC_INVALID] = "VSCC Table is not valid", - [ME_HFS2_STATE_POLICY_FPB_ERR] = "Flash Partition Boundary is outside address space", - [ME_HFS2_STATE_POLICY_DESCRIPTOR_ERR] = "ME cannot access the chipset descriptor region", - [ME_HFS2_STATE_POLICY_VSCC_NO_MATCH] = "Required VSCC values for flash parts do not match", + [ME_HFS2_STATE_POLICY_VSCC_NOT_FOUND] = + "VSCC Data not found for flash device", + [ME_HFS2_STATE_POLICY_VSCC_INVALID] = + "VSCC Table is not valid", + [ME_HFS2_STATE_POLICY_FPB_ERR] = + "Flash Partition Boundary is outside address space", + [ME_HFS2_STATE_POLICY_DESCRIPTOR_ERR] = + "ME cannot access the chipset descriptor region", + [ME_HFS2_STATE_POLICY_VSCC_NO_MATCH] = + "Required VSCC values for flash parts do not match", }; -#endif -void intel_me_status(struct me_hfs *hfs, struct me_hfs2 *hfs2) +static inline void me_read_dword_ptr(void *ptr, int offset) { -#if (CONFIG_DEFAULT_CONSOLE_LOGLEVEL >= BIOS_DEBUG) + u32 dword = pci_read_config32(PCH_DEV_ME, offset); + memcpy(ptr, &dword, sizeof(dword)); +} + +void intel_me_status(void) +{ + struct me_hfs _hfs, *hfs = &_hfs; + struct me_hfs2 _hfs2, *hfs2 = &_hfs2; + + me_read_dword_ptr(hfs, PCI_ME_HFS); + me_read_dword_ptr(hfs2, PCI_ME_HFS2); + /* Check Current States */ printk(BIOS_DEBUG, "ME: FW Partition Table : %s\n", hfs->fpt_bad ? "BAD" : "OK"); @@ -209,5 +275,4 @@ void intel_me_status(struct me_hfs *hfs, struct me_hfs2 *hfs2) hfs2->progress_code, hfs2->current_state); } printk(BIOS_DEBUG, "\n"); -#endif }