intel/skylake: Display ME firmware status before os boot

Display ME firmware status before os boot. Specifically this
patch reads out the ME hfsts1 and hfsts2 status registers that provide
information about overall ME health before device gets disabled.
This change reused most of the code from bdw me_status implementation.

BUG=chrome-os-partner:47384
BRANCH=glados
TEST=Builds and Boots on FAB4 SKU2/3. Can observe me status table

Change-Id: Ia511c4f336d33a6f3b49a344bfbaea6ed227ffeb
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Commit-Id: a9d0fb411c3921654f0fdcea2a3d4ee601987af2
Original-Change-Id: Ied7e2dcd9a1298a38dfe1eda9296b9ca8eccf6b1
Original-Credits-to: Duncan Laurie <dlaurie@chromium.org>
Original-Signed-off-by: Dhaval Sharma <dhaval.v.sharma@intel.com>
Original-Reviewed-on: https://chromium-review.googlesource.com/323260
Original-Commit-Ready: dhaval v sharma <dhaval.v.sharma@intel.com>
Original-Tested-by: dhaval v sharma <dhaval.v.sharma@intel.com>
Original-Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-on: https://review.coreboot.org/13573
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
This commit is contained in:
Dhaval Sharma 2016-01-18 17:28:20 +05:30 committed by Patrick Georgi
parent e2cea4f458
commit 9dca83c762
4 changed files with 450 additions and 0 deletions

View File

@ -41,6 +41,7 @@ ramstage-$(CONFIG_VBOOT_VERIFY_FIRMWARE) += fsp_reset.c
ramstage-y += gpio.c
ramstage-y += igd.c
ramstage-y += lpc.c
ramstage-y += me_status.c
ramstage-y += memmap.c
ramstage-y += monotonic_timer.c
ramstage-y += pch.c

View File

@ -24,6 +24,7 @@
#include <spi-generic.h>
#include <stdlib.h>
#include <soc/lpc.h>
#include <soc/me.h>
#include <soc/pci_devs.h>
#include <soc/pcr.h>
#include <soc/pm.h>
@ -120,6 +121,9 @@ static void pch_finalize_script(void)
pmsyncreg |= PMSYNC_LOCK;
write32(pmcbase + PMSYNC_TPR_CFG, pmsyncreg);
/* Display me status before we hide it */
intel_me_status();
/* we should disable Heci1 based on the devicetree policy */
config = dev->chip_info;
if (config->HeciEnabled == 0)

View File

@ -0,0 +1,170 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008-2009 coresystems GmbH
* Copyright (C) 2014 Google Inc.
* Copyright (C) 2016 Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _SKYLAKE_ME_H_
#define _SKYLAKE_ME_H_
/*
* Management Engine PCI registers
*/
#define PCI_ME_HFSTS1 0x40
#define ME_HFS_CWS_RESET 0
#define ME_HFS_CWS_INIT 1
#define ME_HFS_CWS_REC 2
#define ME_HFS_CWS_NORMAL 5
#define ME_HFS_CWS_WAIT 6
#define ME_HFS_CWS_TRANS 7
#define ME_HFS_CWS_INVALID 8
#define ME_HFS_STATE_PREBOOT 0
#define ME_HFS_STATE_M0_UMA 1
#define ME_HFS_STATE_M3 4
#define ME_HFS_STATE_M0 5
#define ME_HFS_STATE_BRINGUP 6
#define ME_HFS_STATE_ERROR 7
#define ME_HFS_ERROR_NONE 0
#define ME_HFS_ERROR_UNCAT 1
#define ME_HFS_ERROR_IMAGE 3
#define ME_HFS_ERROR_DEBUG 4
#define ME_HFS_MODE_NORMAL 0
#define ME_HFS_MODE_DEBUG 2
#define ME_HFS_MODE_DIS 3
#define ME_HFS_MODE_OVER_JMPR 4
#define ME_HFS_MODE_OVER_MEI 5
#define ME_HFS_BIOS_DRAM_ACK 1
#define ME_HFS_ACK_NO_DID 0
#define ME_HFS_ACK_RESET 1
#define ME_HFS_ACK_PWR_CYCLE 2
#define ME_HFS_ACK_S3 3
#define ME_HFS_ACK_S4 4
#define ME_HFS_ACK_S5 5
#define ME_HFS_ACK_GBL_RESET 6
#define ME_HFS_ACK_CONTINUE 7
struct me_hfs {
u32 working_state: 4;
u32 mfg_mode: 1;
u32 fpt_bad: 1;
u32 operation_state: 3;
u32 fw_init_complete: 1;
u32 ft_bup_ld_flr: 1;
u32 update_in_progress: 1;
u32 error_code: 4;
u32 operation_mode: 4;
u32 reserved: 4;
u32 boot_options_present: 1;
u32 ack_data: 3;
u32 bios_msg_ack: 4;
} __attribute__ ((packed));
#define PCI_ME_HFSTS2 0x48
/* Infrastructure Progress Values */
#define ME_HFS2_PHASE_ROM 0
#define ME_HFS2_PHASE_UKERNEL 2
#define ME_HFS2_PHASE_BUP 3
#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_CG_ENABLE 2
#define ME_HFS2_STATE_BUP_PM_HND_EN 3
#define ME_HFS2_STATE_BUP_FLOW_DET 4
#define ME_HFS2_STATE_BUP_PMC_PATCHING 5
#define ME_HFS2_STATE_BUP_GET_FLASH_VSCC 6
#define ME_HFS2_STATE_BUP_SET_FLASH_VSCC 7
#define ME_HFS2_STATE_BUP_VSCC_ERR 8
#define ME_HFS2_STATE_BUP_EFSS_INIT 9
#define ME_HFS2_STATE_BUP_CHECK_STRAP 0xa
#define ME_HFS2_STATE_BUP_PWR_OK_TIMEOUT 0xb
#define ME_HFS2_STATE_BUP_STRAP_DIS 0xc
#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_CPU_RESET_DID_TIMEOUT_MEM_MISSING 0x17
#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_CM0_CM3 7
#define ME_HFS2_PMEVENT_CM3_CM0 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_CMX_CMOFF 0xc
#define ME_HFS2_PMEVENT_CM0_CM0PG 0xd
#define ME_HFS2_PMEVENT_CM3_CM3PG 0xe
#define ME_HFS2_PMEVENT_CM0PG_CM0 0xf
struct me_hfs2 {
u32 reserved1: 3;
u32 invoke_mebx: 1;
u32 cpu_replaced_sts: 1;
u32 reserved2: 1;
u32 mfs_failure: 1;
u32 warm_reset_request: 1;
u32 cpu_replaced_valid: 1;
u32 low_power_state: 1;
u32 power_gating_ind: 1;
u32 reserved3: 1;
u32 fw_upd_forced_sb: 1;
u32 reserved4: 3;
u32 current_state: 8;
u32 current_pmevent: 4;
u32 progress_code: 4;
} __attribute__ ((packed));
void intel_me_status(void);
#endif

View File

@ -0,0 +1,275 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008-2009 coresystems GmbH
* Copyright (C) 2014 Google Inc.
* Copyright (C) 2016 Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <arch/io.h>
#include <console/console.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <stdlib.h>
#include <string.h>
#include <soc/pci_devs.h>
#include <soc/me.h>
#include <delay.h>
static inline void me_read_dword_ptr(void *ptr, int offset)
{
u32 dword = pci_read_config32(PCH_DEV_ME, offset);
memcpy(ptr, &dword, sizeof(dword));
}
/* HFSTS1[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",
[9] = "Unknown (9)",
[10] = "Unknown (10)",
[11] = "Unknown (11)",
[12] = "Unknown (12)",
[13] = "Unknown (13)",
[14] = "Unknown (14)",
[15] = "Unknown (15)",
};
/* HFSTS1[8:6] Current Operation State Values */
static const char *me_opstate_values[] = {
[ME_HFS_STATE_PREBOOT] = "Preboot",
[ME_HFS_STATE_M0_UMA] = "M0 with UMA",
[ME_HFS_STATE_M3] = "M3 without UMA",
[ME_HFS_STATE_M0] = "M0 without UMA",
[ME_HFS_STATE_BRINGUP] = "Bring up",
[ME_HFS_STATE_ERROR] = "M0 without UMA but with error"
};
/* HFSTS1[19:16] Current Operation Mode Values */
static const char *me_opmode_values[] = {
[ME_HFS_MODE_NORMAL] = "Normal",
[ME_HFS_MODE_DEBUG] = "Debug",
[ME_HFS_MODE_DIS] = "Soft Temporary Disable",
[ME_HFS_MODE_OVER_JMPR] = "Security Override via Jumper",
[ME_HFS_MODE_OVER_MEI] = "Security Override via MEI Message"
};
/* HFSTS1[15:12] Error Code Values */
static const char *me_error_values[] = {
[ME_HFS_ERROR_NONE] = "No Error",
[ME_HFS_ERROR_UNCAT] = "Uncategorized Failure",
[ME_HFS_ERROR_IMAGE] = "Image Failure",
[ME_HFS_ERROR_DEBUG] = "Debug Failure"
};
/* HFSTS2[31:28] ME Progress Code */
static const char *me_progress_values[] = {
[ME_HFS2_PHASE_ROM] = "ROM Phase",
[1] = "Unknown (1)",
[ME_HFS2_PHASE_UKERNEL] = "uKernel Phase",
[ME_HFS2_PHASE_BUP] = "BUP Phase",
[4] = "Unknown (4)",
[5] = "Unknown (5)",
[ME_HFS2_PHASE_HOST_COMM] = "Host Communication",
[7] = "Unknown (7)",
[8] = "Unknown (8)"
};
/* HFSTS2[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_CM0_CM3] =
"CM0->CM3",
[ME_HFS2_PMEVENT_CM3_CM0] =
"CM3->CM0",
[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_CMX_CMOFF] =
"Cx/Mx->Cx/Moff",
[ME_HFS2_PMEVENT_CM0_CM0PG] =
"CM0->CM0PG",
[ME_HFS2_PMEVENT_CM3_CM3PG] =
"CM3->CM3PG",
[ME_HFS2_PMEVENT_CM0PG_CM0] =
"CM0PG->CM0"
};
/* Progress Code 0 states */
static const char *me_progress_rom_values[] = {
[ME_HFS2_STATE_ROM_BEGIN] = "BEGIN",
[ME_HFS2_STATE_ROM_DISABLE] = "DISABLE"
};
/* 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_CG_ENABLE] =
"Enabling CG for cset",
[ME_HFS2_STATE_BUP_PM_HND_EN] =
"Enabling PM handshaking",
[ME_HFS2_STATE_BUP_FLOW_DET] =
"Flow determination start process",
[ME_HFS2_STATE_BUP_PMC_PATCHING] =
"PMC Patching process",
[ME_HFS2_STATE_BUP_GET_FLASH_VSCC] =
"Get VSCC params",
[ME_HFS2_STATE_BUP_SET_FLASH_VSCC] =
"Set VSCC params",
[ME_HFS2_STATE_BUP_VSCC_ERR] =
"Error reading/matching the VSCC table in the descriptor",
[ME_HFS2_STATE_BUP_EFSS_INIT] =
"Initialize EFFS",
[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_STRAP_DIS] =
"EFFS says ME disabled",
[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",
};
void intel_me_status(void)
{
struct me_hfs _hfs, *hfs = &_hfs;
struct me_hfs2 _hfs2, *hfs2 = &_hfs2;
me_read_dword_ptr(hfs, PCI_ME_HFSTS1);
me_read_dword_ptr(hfs2, PCI_ME_HFSTS2);
/* Check Current States */
printk(BIOS_DEBUG, "ME: FW Partition Table : %s\n",
hfs->fpt_bad ? "BAD" : "OK");
printk(BIOS_DEBUG, "ME: Bringup Loader Failure : %s\n",
hfs->ft_bup_ld_flr ? "YES" : "NO");
printk(BIOS_DEBUG, "ME: Firmware Init Complete : %s\n",
hfs->fw_init_complete ? "YES" : "NO");
printk(BIOS_DEBUG, "ME: Manufacturing Mode : %s\n",
hfs->mfg_mode ? "YES" : "NO");
printk(BIOS_DEBUG, "ME: Boot Options Present : %s\n",
hfs->boot_options_present ? "YES" : "NO");
printk(BIOS_DEBUG, "ME: Update In Progress : %s\n",
hfs->update_in_progress ? "YES" : "NO");
printk(BIOS_DEBUG, "ME: CPU Replaced : %s\n",
hfs2->cpu_replaced_sts ? "YES" : "NO");
printk(BIOS_DEBUG, "ME: CPU Replacement Valid : %s\n",
hfs2->cpu_replaced_valid ? "YES" : "NO");
printk(BIOS_DEBUG, "ME: Current Working State : %s\n",
me_cws_values[hfs->working_state]);
printk(BIOS_DEBUG, "ME: Current Operation State : %s\n",
me_opstate_values[hfs->operation_state]);
printk(BIOS_DEBUG, "ME: Current Operation Mode : %s\n",
me_opmode_values[hfs->operation_mode]);
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[hfs2->progress_code]);
printk(BIOS_DEBUG, "ME: Power Management Event : %s\n",
me_pmevent_values[hfs2->current_pmevent]);
printk(BIOS_DEBUG, "ME: Progress Phase State : ");
switch (hfs2->progress_code) {
case ME_HFS2_PHASE_ROM: /* ROM Phase */
printk(BIOS_DEBUG, "%s",
me_progress_rom_values[hfs2->current_state]);
break;
case ME_HFS2_PHASE_UKERNEL: /* uKernel Phase */
printk(BIOS_DEBUG, "0x%02x", hfs2->current_state);
break;
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[hfs2->current_state]);
else
printk(BIOS_DEBUG, "0x%02x", hfs2->current_state);
break;
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", hfs2->current_state);
break;
default:
printk(BIOS_DEBUG, "Unknown phase: 0x%02x state: 0x%02x",
hfs2->progress_code, hfs2->current_state);
}
printk(BIOS_DEBUG, "\n");
}