From 9aa031e47157e37e8f3cd80cbc80215e2843eaa9 Mon Sep 17 00:00:00 2001 From: Aaron Durbin Date: Fri, 2 Nov 2012 09:16:46 -0500 Subject: [PATCH] lynxpoint: Management Engine Updates The ME9 requirements have added some registers and changed some of the MBP state machine. Implement the changes found so far in the ME9 BWG. There were a couple of reigster renames, but the majority of th churn in the me.h header file is just introducing the data structures in the same order as the ME9 BWG. Change-Id: I51b0bb6620eff4979674ea99992ddab65a8abc18 Signed-Off-by: Aaron Durbin Reviewed-on: http://review.coreboot.org/2620 Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich --- src/southbridge/intel/lynxpoint/early_me.c | 18 +- src/southbridge/intel/lynxpoint/me.h | 262 ++++++++++++++------ src/southbridge/intel/lynxpoint/me_9.x.c | 167 +++++++------ src/southbridge/intel/lynxpoint/me_status.c | 167 ++++++------- 4 files changed, 369 insertions(+), 245 deletions(-) diff --git a/src/southbridge/intel/lynxpoint/early_me.c b/src/southbridge/intel/lynxpoint/early_me.c index 5b266cc10c..1eb30a1ff7 100644 --- a/src/southbridge/intel/lynxpoint/early_me.c +++ b/src/southbridge/intel/lynxpoint/early_me.c @@ -56,12 +56,12 @@ static inline void pci_write_dword_ptr(void *ptr, int offset) void intel_early_me_status(void) { struct me_hfs hfs; - struct me_gmes gmes; + struct me_hfs2 hfs2; pci_read_dword_ptr(&hfs, PCI_ME_HFS); - pci_read_dword_ptr(&gmes, PCI_ME_GMES); + pci_read_dword_ptr(&hfs2, PCI_ME_HFS2); - intel_me_status(&hfs, &gmes); + intel_me_status(&hfs, &hfs2); } int intel_early_me_init(void) @@ -73,6 +73,7 @@ int intel_early_me_init(void) printk(BIOS_INFO, "Intel ME early init\n"); /* Wait for ME UMA SIZE VALID bit to be set */ + /* FIXME: ME9 BGW indicates a 5 sec poll timeout. */ for (count = ME_RETRY; count > 0; --count) { pci_read_dword_ptr(&uma, PCI_ME_UMA); if (uma.valid) @@ -147,6 +148,13 @@ int intel_early_me_init_done(u8 status) pci_write_dword_ptr(&did, PCI_ME_H_GS); + /* + * The ME firmware does not respond with an ACK when NOMEM or ERROR + * are sent. + */ + if (status == ME_INIT_STATUS_NOMEM || status == ME_INIT_STATUS_ERROR) + return 0; + /* Must wait for ME acknowledgement */ for (count = ME_RETRY; count > 0; --count) { pci_read_dword_ptr(&hfs, PCI_ME_HFS); @@ -195,7 +203,9 @@ int intel_early_me_init_done(u8 status) /* Perform the requested reset */ if (reset) { outb(reset, 0xcf9); - hlt(); + while (1) { + hlt(); + } } return -1; } diff --git a/src/southbridge/intel/lynxpoint/me.h b/src/southbridge/intel/lynxpoint/me.h index aaeb24d65d..57c4f2409b 100644 --- a/src/southbridge/intel/lynxpoint/me.h +++ b/src/southbridge/intel/lynxpoint/me.h @@ -97,40 +97,111 @@ struct me_uma { #define ME_INIT_STATUS_SUCCESS 0 #define ME_INIT_STATUS_NOMEM 1 #define ME_INIT_STATUS_ERROR 2 +#define ME_INIT_STATUS_SUCCESS_OTHER 3 /* SEE ME9 BWG */ struct me_did { u32 uma_base: 16; - u32 reserved: 8; + u32 reserved: 7; + u32 rapid_start: 1; u32 status: 4; u32 init_done: 4; } __attribute__ ((packed)); -#define PCI_ME_GMES 0x48 -#define ME_GMES_PHASE_ROM 0 -#define ME_GMES_PHASE_BUP 1 -#define ME_GMES_PHASE_UKERNEL 2 -#define ME_GMES_PHASE_POLICY 3 -#define ME_GMES_PHASE_MODULE 4 -#define ME_GMES_PHASE_UNKNOWN 5 -#define ME_GMES_PHASE_HOST 6 +/* + * Apparently the GMES register is renamed to HFS2 (or HFSTS2 according + * to ME9 BWG). Sadly the PCH EDS and the ME BWG do not match on nomenclature. + */ +#define PCI_ME_HFS2 0x48 +/* Infrastructure Progress Values */ +#define ME_HFS2_PHASE_ROM 0 +#define ME_HFS2_PHASE_BUP 1 +#define ME_HFS2_PHASE_UKERNEL 2 +#define ME_HFS2_PHASE_POLICY 3 +#define ME_HFS2_PHASE_MODULE_LOAD 4 +#define ME_HFS2_PHASE_UNKNOWN 5 +#define ME_HFS2_PHASE_HOST_COMM 6 +/* Current State - Based on Infra Progress values. */ +/* ROM State */ +#define ME_HFS2_STATE_ROM_BEGIN 0 +#define ME_HFS2_STATE_ROM_DISABLE 6 +/* BUP State */ +#define ME_HFS2_STATE_BUP_INIT 0 +#define ME_HFS2_STATE_BUP_DIS_HOST_WAKE 1 +#define ME_HFS2_STATE_BUP_FLOW_DET 4 +#define ME_HFS2_STATE_BUP_VSCC_ERR 8 +#define ME_HFS2_STATE_BUP_CHECK_STRAP 0xa +#define ME_HFS2_STATE_BUP_PWR_OK_TIMEOUT 0xb +#define ME_HFS2_STATE_BUP_MANUF_OVRD_STRAP 0xd +#define ME_HFS2_STATE_BUP_M3 0x11 +#define ME_HFS2_STATE_BUP_M0 0x12 +#define ME_HFS2_STATE_BUP_FLOW_DET_ERR 0x13 +#define ME_HFS2_STATE_BUP_M3_CLK_ERR 0x15 +#define ME_HFS2_STATE_BUP_M3_KERN_LOAD 0x18 +#define ME_HFS2_STATE_BUP_T32_MISSING 0x1c +#define ME_HFS2_STATE_BUP_WAIT_DID 0x1f +#define ME_HFS2_STATE_BUP_WAIT_DID_FAIL 0x20 +#define ME_HFS2_STATE_BUP_DID_NO_FAIL 0x21 +#define ME_HFS2_STATE_BUP_ENABLE_UMA 0x22 +#define ME_HFS2_STATE_BUP_ENABLE_UMA_ERR 0x23 +#define ME_HFS2_STATE_BUP_SEND_DID_ACK 0x24 +#define ME_HFS2_STATE_BUP_SEND_DID_ACK_ERR 0x25 +#define ME_HFS2_STATE_BUP_M0_CLK 0x26 +#define ME_HFS2_STATE_BUP_M0_CLK_ERR 0x27 +#define ME_HFS2_STATE_BUP_TEMP_DIS 0x28 +#define ME_HFS2_STATE_BUP_M0_KERN_LOAD 0x32 +/* Policy Module State */ +#define ME_HFS2_STATE_POLICY_ENTRY 0 +#define ME_HFS2_STATE_POLICY_RCVD_S3 3 +#define ME_HFS2_STATE_POLICY_RCVD_S4 4 +#define ME_HFS2_STATE_POLICY_RCVD_S5 5 +#define ME_HFS2_STATE_POLICY_RCVD_UPD 6 +#define ME_HFS2_STATE_POLICY_RCVD_PCR 7 +#define ME_HFS2_STATE_POLICY_RCVD_NPCR 8 +#define ME_HFS2_STATE_POLICY_RCVD_HOST_WAKE 9 +#define ME_HFS2_STATE_POLICY_RCVD_AC_DC 0xa +#define ME_HFS2_STATE_POLICY_RCVD_DID 0xb +#define ME_HFS2_STATE_POLICY_VSCC_NOT_FOUND 0xc +#define ME_HFS2_STATE_POLICY_VSCC_INVALID 0xd +#define ME_HFS2_STATE_POLICY_FPB_ERR 0xe +#define ME_HFS2_STATE_POLICY_DESCRIPTOR_ERR 0xf +#define ME_HFS2_STATE_POLICY_VSCC_NO_MATCH 0x10 +/* Current PM Event Values */ +#define ME_HFS2_PMEVENT_CLEAN_MOFF_MX_WAKE 0 +#define ME_HFS2_PMEVENT_MOFF_MX_WAKE_ERROR 1 +#define ME_HFS2_PMEVENT_CLEAN_GLOBAL_RESET 2 +#define ME_HFS2_PMEVENT_CLEAN_GLOBAL_RESET_ERROR 3 +#define ME_HFS2_PMEVENT_CLEAN_ME_RESET 4 +#define ME_HFS2_PMEVENT_ME_RESET_EXCEPTION 5 +#define ME_HFS2_PMEVENT_PSEUDO_ME_RESET 6 +#define ME_HFS2_PMEVENT_S0MO_SXM3 7 +#define ME_HFS2_PMEVENT_SXM3_S0M0 8 +#define ME_HFS2_PMEVENT_NON_PWR_CYCLE_RESET 9 +#define ME_HFS2_PMEVENT_PWR_CYCLE_RESET_M3 0xa +#define ME_HFS2_PMEVENT_PWR_CYCLE_RESET_MOFF 0xb +#define ME_HFS2_PMEVENT_SXMX_SXMOFF 0xc -struct me_gmes { - u32 bist_in_prog : 1; - u32 icc_prog_sts : 2; - u32 invoke_mebx : 1; - u32 cpu_replaced_sts : 1; - u32 mbp_rdy : 1; - u32 mfs_failure : 1; - u32 warm_rst_req_for_df : 1; - u32 cpu_replaced_valid : 1; - u32 reserved_1 : 2; - u32 fw_upd_ipu : 1; - u32 reserved_2 : 4; +struct me_hfs2 { + u32 bist_in_progress: 1; + u32 reserved1: 2; + u32 invoke_mebx: 1; + u32 cpu_replaced_sts: 1; + u32 mbp_rdy: 1; + u32 mfs_failure: 1; + u32 warm_reset_request: 1; + u32 cpu_replaced_valid: 1; + u32 reserved2: 4; + u32 mbp_cleared: 1; + u32 reserved3: 2; u32 current_state: 8; u32 current_pmevent: 4; u32 progress_code: 4; } __attribute__ ((packed)); +#define PCI_ME_H_GS2 0x70 +#define PCI_ME_MBP_GIVE_UP 0x01 + +#define PCI_ME_H_GS3 0x74 + #define PCI_ME_HERES 0xbc #define PCI_ME_EXT_SHA1 0x00 #define PCI_ME_EXT_SHA256 0x02 @@ -241,7 +312,7 @@ typedef enum { } me_bios_path; /* Defined in me_status.c for both romstage and ramstage */ -void intel_me_status(struct me_hfs *hfs, struct me_gmes *gmes); +void intel_me_status(struct me_hfs *hfs, struct me_hfs2 *hfs2); #ifdef __PRE_RAM__ void intel_early_me_status(void); @@ -254,6 +325,47 @@ int intel_early_me_init_done(u8 status); 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. + */ + +#define MBP_APPID_KERNEL 1 +#define MBP_APPID_INTEL_AT 3 +#define MBP_APPID_HWA 4 +#define MBP_APPID_ICC 5 +/* Kernel items: */ +#define MBP_KERNEL_FW_VER_ITEM 1 +#define MBP_KERNEL_FW_CAP_ITEM 2 +#define MBP_KERNEL_ROM_BIST_ITEM 3 +#define MBP_KERNEL_PLAT_KEY_ITEM 4 +#define MBP_KERNEL_FW_TYPE_ITEM 5 +#define MBP_KERNEL_MFS_FAILURE_ITEM 6 +/* Intel AT items: */ +#define MBP_INTEL_AT_STATE_ITEM 1 +/* ICC Items: */ +#define MBP_ICC_PROFILE_ITEM 1 +/* HWA Items: */ +#define MBP_HWA_REQUEST_ITEM 1 + +#define MBP_MAKE_IDENT(appid, item) ((appid << 8) | item) +#define MBP_IDENT(appid, item) \ + MBP_MAKE_IDENT(MBP_APPID_##appid, MBP_##appid##_##item##_ITEM) + +typedef struct { + u32 mbp_size : 8; + u32 num_entries : 8; + u32 rsvd : 16; +} __attribute__ ((packed)) mbp_header; + +typedef struct { + u32 app_id : 8; + u32 item_id : 8; + u32 length : 8; + u32 rsvd : 8; +} __attribute__ ((packed)) mbp_item_header; + typedef struct { u32 major_version : 16; u32 minor_version : 16; @@ -261,20 +373,11 @@ typedef struct { u32 build_version : 16; } __attribute__ ((packed)) mbp_fw_version_name; -typedef struct { - u8 num_icc_profiles; - u8 icc_profile_soft_strap; - u8 icc_profile_index; - u8 reserved; - u32 register_lock_mask[3]; -} __attribute__ ((packed)) mbp_icc_profile; - typedef struct { u32 full_net : 1; u32 std_net : 1; u32 manageability : 1; - u32 small_business : 1; - u32 l3manageability : 1; + u32 reserved_2 : 2; u32 intel_at : 1; u32 intel_cls : 1; u32 reserved : 3; @@ -292,33 +395,6 @@ typedef struct { u32 reserved_5 : 8; } __attribute__ ((packed)) mefwcaps_sku; -typedef struct { - u16 lock_state : 1; - u16 authenticate_module : 1; - u16 s3authentication : 1; - u16 flash_wear_out : 1; - u16 flash_variable_security : 1; - u16 wwan3gpresent : 1; - u16 wwan3goob : 1; - u16 reserved : 9; -} __attribute__ ((packed)) tdt_state_flag; - -typedef struct { - u8 state; - u8 last_theft_trigger; - tdt_state_flag flags; -} __attribute__ ((packed)) tdt_state_info; - -typedef struct { - u32 platform_target_usage_type : 4; - u32 platform_target_market_type : 2; - u32 super_sku : 1; - u32 reserved : 1; - u32 intel_me_fw_image_type : 4; - u32 platform_brand : 4; - u32 reserved_1 : 16; -} __attribute__ ((packed)) platform_type_rule_data; - typedef struct { mefwcaps_sku fw_capabilities; u8 available; @@ -335,33 +411,57 @@ typedef struct { } mbp_platform_key; typedef struct { - platform_type_rule_data rule_data; - u8 available; + u32 mobile: 1; + u32 desktop: 1; + u32 server: 1; + u32 workstation: 1; + u32 corporate: 1; + u32 consumer: 1; + u32 regular_super_sku: 1; + u32 rsvd: 1; + u32 image_type: 4; + u32 brand: 4; + u32 rsvd1: 16; +} __attribute__ ((packed)) mbp_me_firmware_type; + +typedef struct { + mbp_me_firmware_type rule_data; + u8 available; } mbp_plat_type; typedef struct { - mbp_fw_version_name fw_version_name; - mbp_fw_caps fw_caps_sku; - mbp_rom_bist_data rom_bist_data; - mbp_platform_key platform_key; - mbp_plat_type fw_plat_type; - mbp_icc_profile icc_profile; - tdt_state_info at_state; - u32 mfsintegrity; -} me_bios_payload; - -typedef struct { - u32 mbp_size : 8; - u32 num_entries : 8; - u32 rsvd : 16; -} __attribute__ ((packed)) mbp_header; + u8 num_icc_profiles; + u8 icc_profile_soft_strap; + u8 icc_profile_index; + u8 reserved; + u32 register_lock_mask[3]; +} __attribute__ ((packed)) mbp_icc_profile; typedef struct { - u32 app_id : 8; - u32 item_id : 8; - u32 length : 8; - u32 rsvd : 8; -} __attribute__ ((packed)) mbp_item_header; + u16 lock_state : 1; + u16 authenticate_module : 1; + u16 s3authentication : 1; + u16 flash_wear_out : 1; + u16 flash_variable_security : 1; + u16 reserved : 11; +} __attribute__ ((packed)) tdt_state_flag; + +typedef struct { + u8 state; + u8 last_theft_trigger; + tdt_state_flag flags; +} __attribute__ ((packed)) tdt_state_info; + +typedef struct { + mbp_fw_version_name fw_version_name; + mbp_fw_caps fw_caps_sku; + mbp_rom_bist_data rom_bist_data; + mbp_platform_key platform_key; + mbp_plat_type fw_plat_type; + mbp_icc_profile icc_profile; + tdt_state_info at_state; + u32 mfsintegrity; +} me_bios_payload; struct me_fwcaps { u32 id; diff --git a/src/southbridge/intel/lynxpoint/me_9.x.c b/src/southbridge/intel/lynxpoint/me_9.x.c index e691cf340e..facfc37645 100644 --- a/src/southbridge/intel/lynxpoint/me_9.x.c +++ b/src/southbridge/intel/lynxpoint/me_9.x.c @@ -63,7 +63,7 @@ static const char *me_bios_path_values[] = { [ME_DISABLE_BIOS_PATH] = "Disable", [ME_FIRMWARE_UPDATE_BIOS_PATH] = "Firmware Update", }; -static int intel_me_read_mbp(me_bios_payload *mbp_data); +static int intel_me_read_mbp(me_bios_payload *mbp_data, device_t dev); #endif /* MMIO base address for MEI interface */ @@ -415,8 +415,6 @@ static void me_print_fwcaps(mbp_fw_caps *caps_section) print_cap("Full Network manageability", cap->full_net); print_cap("Regular Network manageability", cap->std_net); print_cap("Manageability", cap->manageability); - print_cap("Small business technology", cap->small_business); - print_cap("Level III manageability", cap->l3manageability); print_cap("IntelR Anti-Theft (AT)", cap->intel_at); print_cap("IntelR Capability Licensing Service (CLS)", cap->intel_cls); print_cap("IntelR Power Sharing Technology (MPC)", cap->intel_mpc); @@ -534,7 +532,7 @@ static me_bios_path intel_me_path(device_t dev) { me_bios_path path = ME_DISABLE_BIOS_PATH; struct me_hfs hfs; - struct me_gmes gmes; + struct me_hfs2 hfs2; #if CONFIG_HAVE_ACPI_RESUME /* S3 wake skips all MKHI messages */ @@ -544,10 +542,10 @@ static me_bios_path intel_me_path(device_t dev) #endif pci_read_dword_ptr(dev, &hfs, PCI_ME_HFS); - pci_read_dword_ptr(dev, &gmes, PCI_ME_GMES); + pci_read_dword_ptr(dev, &hfs2, PCI_ME_HFS2); /* Check and dump status */ - intel_me_status(&hfs, &gmes); + intel_me_status(&hfs, &hfs2); /* Check Current Working State */ switch (hfs.working_state) { @@ -580,7 +578,7 @@ static me_bios_path intel_me_path(device_t dev) path = ME_ERROR_BIOS_PATH; /* Check if the MBP is ready */ - if (!gmes.mbp_rdy) { + if (!hfs2.mbp_rdy) { printk(BIOS_CRIT, "%s: mbp is not ready!\n", __FUNCTION__); path = ME_ERROR_BIOS_PATH; @@ -593,9 +591,9 @@ static me_bios_path intel_me_path(device_t dev) .operation_state = hfs.operation_state, .operation_mode = hfs.operation_mode, .error_code = hfs.error_code, - .progress_code = gmes.progress_code, - .current_pmevent = gmes.current_pmevent, - .current_state = gmes.current_state, + .progress_code = hfs2.progress_code, + .current_pmevent = hfs2.current_pmevent, + .current_state = hfs2.current_state, }; elog_add_event_byte(ELOG_TYPE_MANAGEMENT_ENGINE, path); elog_add_event_raw(ELOG_TYPE_MANAGEMENT_ENGINE_EXT, @@ -699,54 +697,35 @@ static void intel_me_init(device_t dev) /* Do initial setup and determine the BIOS path */ printk(BIOS_NOTICE, "ME: BIOS path: %s\n", me_bios_path_values[path]); - switch (path) { - case ME_S3WAKE_BIOS_PATH: + if (path == ME_S3WAKE_BIOS_PATH) { intel_me_hide(dev); - break; - - case ME_NORMAL_BIOS_PATH: + return; + } else if (path == ME_NORMAL_BIOS_PATH) { /* Validate the extend register */ - if (intel_me_extend_valid(dev) < 0) - break; /* TODO: force recovery mode */ + /* FIXME: force recovery mode on failure. */ + intel_me_extend_valid(dev); + } - /* Prepare MEI MMIO interface */ - if (intel_mei_setup(dev) < 0) - break; + /* + * According to the ME9 BWG, BIOS is required to fetch MBP data in + * all boot flows except S3 Resume. + */ - if(intel_me_read_mbp(&mbp_data)) - break; + /* Prepare MEI MMIO interface */ + if (intel_mei_setup(dev) < 0) + return; -#if CONFIG_CHROMEOS && 0 /* DISABLED */ - /* - * Unlock ME in recovery mode. - */ - if (recovery_mode_enabled()) { - /* Unlock ME flash region */ - mkhi_hmrfpo_enable(); - - /* Issue global reset */ - mkhi_global_reset(); - return; - } -#endif + if(intel_me_read_mbp(&mbp_data, dev)) + return; #if (CONFIG_DEFAULT_CONSOLE_LOGLEVEL >= BIOS_DEBUG) - me_print_fw_version(&mbp_data.fw_version_name); - me_print_fwcaps(&mbp_data.fw_caps_sku); + me_print_fw_version(&mbp_data.fw_version_name); + me_print_fwcaps(&mbp_data.fw_caps_sku); #endif - /* - * Leave the ME unlocked in this path. - * It will be locked via SMI command later. - */ - break; - - case ME_ERROR_BIOS_PATH: - case ME_RECOVERY_BIOS_PATH: - case ME_DISABLE_BIOS_PATH: - case ME_FIRMWARE_UPDATE_BIOS_PATH: - break; - } + /* + * Leave the ME unlocked. It will be locked via SMI command later. + */ } static void set_subsystem(device_t dev, unsigned vendor, unsigned device) @@ -806,22 +785,49 @@ static u32 host_to_me_words_room(void) (csr.buffer_depth - 1); } #endif + +/* + * 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. + */ +static void intel_me_mbp_give_up(device_t dev) +{ + u32 reg32; + struct mei_csr csr; + + reg32 = PCI_ME_MBP_GIVE_UP; + pci_write_config32(dev, PCI_ME_H_GS3, reg32); + read_host_csr(&csr); + csr.reset = 1; + csr.interrupt_generate = 1; + write_host_csr(&csr); +} + /* * mbp seems to be following its own flow, let's retrieve it in a dedicated * function. */ -static int intel_me_read_mbp(me_bios_payload *mbp_data) +static int intel_me_read_mbp(me_bios_payload *mbp_data, device_t dev) { mbp_header mbp_hdr; mbp_item_header mbp_item_hdr; u32 me2host_pending; - u32 mbp_item_id; + u32 mbp_ident; struct mei_csr host; + struct me_hfs2 hfs2; + int count; + + pci_read_dword_ptr(dev, &hfs2, PCI_ME_HFS2); + + if (!hfs2.mbp_rdy) { + printk(BIOS_ERR, "ME: MBP not ready\n"); + goto mbp_failure; + } me2host_pending = me_to_host_words_pending(); if (!me2host_pending) { printk(BIOS_ERR, "ME: no mbp data!\n"); - return -1; + goto mbp_failure; } /* we know for sure that at least the header is there */ @@ -833,7 +839,7 @@ static int intel_me_read_mbp(me_bios_payload *mbp_data) " buffer contains %d words\n", mbp_hdr.num_entries, mbp_hdr.mbp_size, me2host_pending); - return -1; + goto mbp_failure; } me2host_pending--; @@ -847,7 +853,7 @@ static int intel_me_read_mbp(me_bios_payload *mbp_data) if (!me2host_pending) { printk(BIOS_ERR, "ME: no mbp data %d entries to go!\n", mbp_hdr.num_entries + 1); - return -1; + goto mbp_failure; } mei_read_dword_ptr(&mbp_item_hdr, MEI_ME_CB_RW); @@ -856,13 +862,13 @@ static int intel_me_read_mbp(me_bios_payload *mbp_data) printk(BIOS_ERR, "ME: insufficient mbp data %d " "entries to go!\n", mbp_hdr.num_entries + 1); - return -1; + goto mbp_failure; } me2host_pending -= mbp_item_hdr.length; - mbp_item_id = (((u32)mbp_item_hdr.item_id) << 8) + - mbp_item_hdr.app_id; + mbp_ident = MBP_MAKE_IDENT(mbp_item_hdr.app_id, + mbp_item_hdr.item_id); copy_size = mbp_item_hdr.length - 1; @@ -874,44 +880,44 @@ static int intel_me_read_mbp(me_bios_payload *mbp_data) p = &mbp_item_hdr; printk(BIOS_INFO, "ME: MBP item header %8.8x\n", *((u32*)p)); - switch(mbp_item_id) { - case 0x101: + switch(mbp_ident) { + case MBP_IDENT(KERNEL, FW_VER): SET_UP_COPY(fw_version_name); - case 0x102: + case MBP_IDENT(ICC, PROFILE): SET_UP_COPY(icc_profile); - case 0x103: + case MBP_IDENT(INTEL_AT, STATE): SET_UP_COPY(at_state); - case 0x201: + case MBP_IDENT(KERNEL, FW_CAP): mbp_data->fw_caps_sku.available = 1; SET_UP_COPY(fw_caps_sku.fw_capabilities); - case 0x301: + case MBP_IDENT(KERNEL, ROM_BIST): SET_UP_COPY(rom_bist_data); - case 0x401: + case MBP_IDENT(KERNEL, PLAT_KEY): SET_UP_COPY(platform_key); - case 0x501: + case MBP_IDENT(KERNEL, FW_TYPE): mbp_data->fw_plat_type.available = 1; SET_UP_COPY(fw_plat_type.rule_data); - case 0x601: + case MBP_IDENT(KERNEL, MFS_FAILURE): SET_UP_COPY(mfsintegrity); default: printk(BIOS_ERR, "ME: unknown mbp item id 0x%x!!!\n", - mbp_item_id); - return -1; + mbp_ident); + goto mbp_failure; } if (buffer_room != copy_size) { printk(BIOS_ERR, "ME: buffer room %d != %d copy size" " for item 0x%x!!!\n", - buffer_room, copy_size, mbp_item_id); - return -1; + buffer_room, copy_size, mbp_ident); + goto mbp_failure; } while(copy_size--) *copy_addr++ = read_cb(); @@ -921,16 +927,23 @@ static int intel_me_read_mbp(me_bios_payload *mbp_data) host.interrupt_generate = 1; write_host_csr(&host); - { - int cntr = 0; - while(host.interrupt_generate) { - read_host_csr(&host); - cntr++; - } - printk(BIOS_SPEW, "ME: mbp read OK after %d cycles\n", cntr); + for (count = ME_RETRY; count > 0; --count) { + pci_read_dword_ptr(dev, &hfs2, PCI_ME_HFS2); + if (hfs2.mbp_cleared) + break; + udelay(ME_DELAY); + } + + if (count == 0) { + printk(BIOS_WARNING, "ME: Timeout waiting for mbp_cleared\n"); + intel_me_mbp_give_up(dev); } return 0; + +mbp_failure: + intel_me_mbp_give_up(dev); + return -1; } #endif /* !__SMM__ */ diff --git a/src/southbridge/intel/lynxpoint/me_status.c b/src/southbridge/intel/lynxpoint/me_status.c index b2f38d635f..1feaf7d4f0 100644 --- a/src/southbridge/intel/lynxpoint/me_status.c +++ b/src/southbridge/intel/lynxpoint/me_status.c @@ -62,89 +62,89 @@ static const char *me_error_values[] = { [ME_HFS_ERROR_DEBUG] = "Debug Failure" }; -/* GMES[31:28] ME Progress Code */ +/* HFS2[31:28] ME Progress Code */ static const char *me_progress_values[] = { - [ME_GMES_PHASE_ROM] = "ROM Phase", - [ME_GMES_PHASE_BUP] = "BUP Phase", - [ME_GMES_PHASE_UKERNEL] = "uKernel Phase", - [ME_GMES_PHASE_POLICY] = "Policy Module", - [ME_GMES_PHASE_MODULE] = "Module Loading", - [ME_GMES_PHASE_UNKNOWN] = "Unknown", - [ME_GMES_PHASE_HOST] = "Host Communication" + [ME_HFS2_PHASE_ROM] = "ROM Phase", + [ME_HFS2_PHASE_BUP] = "BUP Phase", + [ME_HFS2_PHASE_UKERNEL] = "uKernel Phase", + [ME_HFS2_PHASE_POLICY] = "Policy Module", + [ME_HFS2_PHASE_MODULE_LOAD] = "Module Loading", + [ME_HFS2_PHASE_UNKNOWN] = "Unknown", + [ME_HFS2_PHASE_HOST_COMM] = "Host Communication" }; -/* GMES[27:24] Power Management Event */ +/* HFS2[27:24] Power Management Event */ static const char *me_pmevent_values[] = { - [0x00] = "Clean Moff->Mx wake", - [0x01] = "Moff->Mx wake after an error", - [0x02] = "Clean global reset", - [0x03] = "Global reset after an error", - [0x04] = "Clean Intel ME reset", - [0x05] = "Intel ME reset due to exception", - [0x06] = "Pseudo-global reset", - [0x07] = "S0/M0->Sx/M3", - [0x08] = "Sx/M3->S0/M0", - [0x09] = "Non-power cycle reset", - [0x0a] = "Power cycle reset through M3", - [0x0b] = "Power cycle reset through Moff", - [0x0c] = "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 */ static const char *me_progress_rom_values[] = { - [0x00] = "BEGIN", - [0x06] = "DISABLE" + [ME_HFS2_STATE_ROM_BEGIN] = "BEGIN", + [ME_HFS2_STATE_ROM_DISABLE] = "DISABLE" }; /* Progress Code 1 states */ static const char *me_progress_bup_values[] = { - [0x00] = "Initialization starts", - [0x01] = "Disable the host wake event", - [0x04] = "Flow determination start process", - [0x08] = "Error reading/matching the VSCC table in the descriptor", - [0x0a] = "Check to see if straps say ME DISABLED", - [0x0b] = "Timeout waiting for PWROK", - [0x0d] = "Possibly handle BUP manufacturing override strap", - [0x11] = "Bringup in M3", - [0x12] = "Bringup in M0", - [0x13] = "Flow detection error", - [0x15] = "M3 clock switching error", - [0x18] = "M3 kernel load", - [0x1c] = "T34 missing - cannot program ICC", - [0x1f] = "Waiting for DID BIOS message", - [0x20] = "Waiting for DID BIOS message failure", - [0x21] = "DID reported an error", - [0x22] = "Enabling UMA", - [0x23] = "Enabling UMA error", - [0x24] = "Sending DID Ack to BIOS", - [0x25] = "Sending DID Ack to BIOS error", - [0x26] = "Switching clocks in M0", - [0x27] = "Switching clocks in M0 error", - [0x28] = "ME in temp disable", - [0x32] = "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_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 */ static const char *me_progress_policy_values[] = { - [0x00] = "Entery into Policy Module", - [0x03] = "Received S3 entry", - [0x04] = "Received S4 entry", - [0x05] = "Received S5 entry", - [0x06] = "Received UPD entry", - [0x07] = "Received PCR entry", - [0x08] = "Received NPCR entry", - [0x09] = "Received host wake", - [0x0a] = "Received AC<>DC switch", - [0x0b] = "Received DRAM Init Done", - [0x0c] = "VSCC Data not found for flash device", - [0x0d] = "VSCC Table is not valid", - [0x0e] = "Flash Partition Boundary is outside address space", - [0x0f] = "ME cannot access the chipset descriptor region", - [0x10] = "Required VSCC values for flash parts do not match", + [ME_HFS2_STATE_POLICY_ENTRY] = "Entery into Policy Module", + [ME_HFS2_STATE_POLICY_RCVD_S3] = "Received S3 entry", + [ME_HFS2_STATE_POLICY_RCVD_S4] = "Received S4 entry", + [ME_HFS2_STATE_POLICY_RCVD_S5] = "Received S5 entry", + [ME_HFS2_STATE_POLICY_RCVD_UPD] = "Received UPD entry", + [ME_HFS2_STATE_POLICY_RCVD_PCR] = "Received PCR entry", + [ME_HFS2_STATE_POLICY_RCVD_NPCR] = "Received NPCR entry", + [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", }; #endif -void intel_me_status(struct me_hfs *hfs, struct me_gmes *gmes) +void intel_me_status(struct me_hfs *hfs, struct me_hfs2 *hfs2) { #if (CONFIG_DEFAULT_CONSOLE_LOGLEVEL >= BIOS_DEBUG) /* Check Current States */ @@ -169,44 +169,45 @@ void intel_me_status(struct me_hfs *hfs, struct me_gmes *gmes) printk(BIOS_DEBUG, "ME: Error Code : %s\n", me_error_values[hfs->error_code]); printk(BIOS_DEBUG, "ME: Progress Phase : %s\n", - me_progress_values[gmes->progress_code]); + me_progress_values[hfs2->progress_code]); printk(BIOS_DEBUG, "ME: Power Management Event : %s\n", - me_pmevent_values[gmes->current_pmevent]); + me_pmevent_values[hfs2->current_pmevent]); printk(BIOS_DEBUG, "ME: Progress Phase State : "); - switch (gmes->progress_code) { - case ME_GMES_PHASE_ROM: /* ROM Phase */ + switch (hfs2->progress_code) { + case ME_HFS2_PHASE_ROM: /* ROM Phase */ printk(BIOS_DEBUG, "%s", - me_progress_rom_values[gmes->current_state]); + me_progress_rom_values[hfs2->current_state]); break; - case ME_GMES_PHASE_BUP: /* Bringup Phase */ - if (gmes->current_state < ARRAY_SIZE(me_progress_bup_values) - && me_progress_bup_values[gmes->current_state]) + case ME_HFS2_PHASE_BUP: /* Bringup Phase */ + if (hfs2->current_state < ARRAY_SIZE(me_progress_bup_values) + && me_progress_bup_values[hfs2->current_state]) printk(BIOS_DEBUG, "%s", - me_progress_bup_values[gmes->current_state]); + me_progress_bup_values[hfs2->current_state]); else - printk(BIOS_DEBUG, "0x%02x", gmes->current_state); + printk(BIOS_DEBUG, "0x%02x", hfs2->current_state); break; - case ME_GMES_PHASE_POLICY: /* Policy Module Phase */ - if (gmes->current_state < ARRAY_SIZE(me_progress_policy_values) - && me_progress_policy_values[gmes->current_state]) + case ME_HFS2_PHASE_POLICY: /* Policy Module Phase */ + if (hfs2->current_state < ARRAY_SIZE(me_progress_policy_values) + && me_progress_policy_values[hfs2->current_state]) printk(BIOS_DEBUG, "%s", - me_progress_policy_values[gmes->current_state]); + me_progress_policy_values[hfs2->current_state]); else - printk(BIOS_DEBUG, "0x%02x", gmes->current_state); + printk(BIOS_DEBUG, "0x%02x", hfs2->current_state); break; - case ME_GMES_PHASE_HOST: /* Host Communication Phase */ - if (!gmes->current_state) + case ME_HFS2_PHASE_HOST_COMM: /* Host Communication Phase */ + if (!hfs2->current_state) printk(BIOS_DEBUG, "Host communication established"); else - printk(BIOS_DEBUG, "0x%02x", gmes->current_state); + printk(BIOS_DEBUG, "0x%02x", hfs2->current_state); break; default: - printk(BIOS_DEBUG, "Unknown 0x%02x", gmes->current_state); + printk(BIOS_DEBUG, "Unknown phase: 0x%02x sate: 0x%02x", + hfs2->progress_code, hfs2->current_state); } printk(BIOS_DEBUG, "\n"); #endif