src/soc/intel/common/block/cse: Make hfsts1 common & add helper functions

Host FW status 1 (FWSTS1/HFSTS1) register definition is common across SoCs,
hence move it to common. Also add below helper function,

* wait_cse_sec_override_mode() - Polls ME status for "HECI_OP_MODE_SEC_OVERRIDE".
  It's a special CSE mode, the mode ensures CSE does not trigger any
  spi cycles to CSE region.

* set_host_ready() - Clears reset state from host CSR.

TEST=Verified CSE recover mode on CML RVP & Hatch board

Change-Id: Id5c12b7abdb27c38af74ea6ee568b42ec74bcb3c
Signed-off-by: Rizwan Qureshi <rizwan.qureshi@intel.com>
Signed-off-by: Sridhar Siricilla <sridhar.siricilla@intel.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/35226
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Aamir Bohra <aamir.bohra@intel.com>
This commit is contained in:
Sridhar Siricilla
2019-08-31 11:38:33 +05:30
committed by Patrick Georgi
parent bc553e6a5b
commit b9d075b0fc
5 changed files with 103 additions and 84 deletions

View File

@ -32,30 +32,6 @@ enum {
ME_WSTATE_NORMAL = 0x05, ME_WSTATE_NORMAL = 0x05,
}; };
/* Host Firmware Status Register 1 */
union hfsts1 {
uint32_t raw;
struct {
uint32_t working_state : 4;
uint32_t mfg_mode : 1;
uint32_t fpt_bad : 1;
uint32_t operation_state : 3;
uint32_t fw_init_complete : 1;
uint32_t ft_bup_ld_flr : 1;
uint32_t fw_upd_in_progress : 1;
uint32_t error_code : 4;
uint32_t operation_mode : 4;
uint32_t reset_count : 4;
uint32_t boot_options : 1;
uint32_t rsvd0 : 1;
uint32_t bist_state : 1;
uint32_t bist_reset_req : 1;
uint32_t power_source : 2;
uint32_t reserved1 : 1;
uint32_t d0i3_support_valid : 1;
} __packed fields;
};
/* Host Firmware Status Register 2 */ /* Host Firmware Status Register 2 */
union hfsts2 { union hfsts2 {
uint32_t raw; uint32_t raw;
@ -174,7 +150,7 @@ static void print_me_version(void *unused)
struct version fitc; struct version fitc;
} __packed; } __packed;
union hfsts1 hfsts1; union me_hfsts1 hfsts1;
const struct mkhi_hdr fw_ver_msg = { const struct mkhi_hdr fw_ver_msg = {
.group_id = MKHI_GEN_GROUP_ID, .group_id = MKHI_GEN_GROUP_ID,
.command = MKHI_GET_FW_VERSION, .command = MKHI_GET_FW_VERSION,
@ -189,7 +165,7 @@ static void print_me_version(void *unused)
if (!is_cse_enabled()) if (!is_cse_enabled())
return; return;
hfsts1.raw = me_read_config32(PCI_ME_HFSTS1); hfsts1.data = me_read_config32(PCI_ME_HFSTS1);
/* /*
* Prerequisites: * Prerequisites:
@ -225,7 +201,7 @@ BOOT_STATE_INIT_ENTRY(BS_DEV_ENABLE, BS_ON_EXIT, print_me_version, NULL);
void dump_me_status(void *unused) void dump_me_status(void *unused)
{ {
union hfsts1 hfsts1; union me_hfsts1 hfsts1;
union hfsts2 hfsts2; union hfsts2 hfsts2;
union hfsts3 hfsts3; union hfsts3 hfsts3;
union hfsts4 hfsts4; union hfsts4 hfsts4;
@ -235,7 +211,7 @@ void dump_me_status(void *unused)
if (!is_cse_enabled()) if (!is_cse_enabled())
return; return;
hfsts1.raw = me_read_config32(PCI_ME_HFSTS1); hfsts1.data = me_read_config32(PCI_ME_HFSTS1);
hfsts2.raw = me_read_config32(PCI_ME_HFSTS2); hfsts2.raw = me_read_config32(PCI_ME_HFSTS2);
hfsts3.raw = me_read_config32(PCI_ME_HFSTS3); hfsts3.raw = me_read_config32(PCI_ME_HFSTS3);
hfsts4.raw = me_read_config32(PCI_ME_HFSTS4); hfsts4.raw = me_read_config32(PCI_ME_HFSTS4);
@ -243,7 +219,7 @@ void dump_me_status(void *unused)
hfsts6.raw = me_read_config32(PCI_ME_HFSTS6); hfsts6.raw = me_read_config32(PCI_ME_HFSTS6);
printk(BIOS_DEBUG, "ME: HFSTS1 : 0x%08X\n", printk(BIOS_DEBUG, "ME: HFSTS1 : 0x%08X\n",
hfsts1.raw); hfsts1.data);
printk(BIOS_DEBUG, "ME: HFSTS2 : 0x%08X\n", printk(BIOS_DEBUG, "ME: HFSTS2 : 0x%08X\n",
hfsts2.raw); hfsts2.raw);
printk(BIOS_DEBUG, "ME: HFSTS3 : 0x%08X\n", printk(BIOS_DEBUG, "ME: HFSTS3 : 0x%08X\n",
@ -264,9 +240,9 @@ void dump_me_status(void *unused)
printk(BIOS_DEBUG, "ME: Firmware Init Complete : %s\n", printk(BIOS_DEBUG, "ME: Firmware Init Complete : %s\n",
hfsts1.fields.fw_init_complete ? "YES" : "NO"); hfsts1.fields.fw_init_complete ? "YES" : "NO");
printk(BIOS_DEBUG, "ME: Boot Options Present : %s\n", printk(BIOS_DEBUG, "ME: Boot Options Present : %s\n",
hfsts1.fields.boot_options ? "YES" : "NO"); hfsts1.fields.boot_options_present ? "YES" : "NO");
printk(BIOS_DEBUG, "ME: Update In Progress : %s\n", printk(BIOS_DEBUG, "ME: Update In Progress : %s\n",
hfsts1.fields.fw_upd_in_progress ? "YES" : "NO"); hfsts1.fields.update_in_progress ? "YES" : "NO");
printk(BIOS_DEBUG, "ME: D0i3 Support : %s\n", printk(BIOS_DEBUG, "ME: D0i3 Support : %s\n",
hfsts1.fields.d0i3_support_valid ? "YES" : "NO"); hfsts1.fields.d0i3_support_valid ? "YES" : "NO");
printk(BIOS_DEBUG, "ME: Low Power State Enabled : %s\n", printk(BIOS_DEBUG, "ME: Low Power State Enabled : %s\n",

View File

@ -67,6 +67,7 @@
#define MEI_HDR_CSE_ADDR_START 0 #define MEI_HDR_CSE_ADDR_START 0
#define MEI_HDR_CSE_ADDR (((1 << 8) - 1) << MEI_HDR_CSE_ADDR_START) #define MEI_HDR_CSE_ADDR (((1 << 8) - 1) << MEI_HDR_CSE_ADDR_START)
#define HECI_OP_MODE_SEC_OVERRIDE 5
static struct cse_device { static struct cse_device {
uintptr_t sec_bar; uintptr_t sec_bar;
@ -239,6 +240,43 @@ static int cse_ready(void)
return csr & CSR_READY; return csr & CSR_READY;
} }
/*
* Checks if CSE is in SEC_OVERRIDE operation mode. This is the mode where
* CSE will allow reflashing of CSE region.
*/
static uint8_t check_cse_sec_override_mode(void)
{
union me_hfsts1 hfs1;
hfs1.data = me_read_config32(PCI_ME_HFSTS1);
if (hfs1.fields.operation_mode == HECI_OP_MODE_SEC_OVERRIDE)
return 1;
return 0;
}
/* Makes the host ready to communicate with CSE */
void set_host_ready(void)
{
uint32_t csr;
csr = read_host_csr();
csr &= ~CSR_RESET;
csr |= (CSR_IG | CSR_READY);
write_host_csr(csr);
}
/* Polls for ME state 'HECI_OP_MODE_SEC_OVERRIDE' for 15 seconds */
uint8_t wait_cse_sec_override_mode(void)
{
struct stopwatch sw;
stopwatch_init_msecs_expire(&sw, HECI_DELAY_READY);
while (!check_cse_sec_override_mode()) {
udelay(HECI_DELAY);
if (stopwatch_expired(&sw))
return 0;
}
return 1;
}
static int wait_heci_ready(void) static int wait_heci_ready(void)
{ {
struct stopwatch sw; struct stopwatch sw;
@ -484,17 +522,12 @@ int heci_reset(void)
/* Send reset request */ /* Send reset request */
csr = read_host_csr(); csr = read_host_csr();
csr |= CSR_RESET; csr |= (CSR_RESET | CSR_IG);
csr |= CSR_IG;
write_host_csr(csr); write_host_csr(csr);
if (wait_heci_ready()) { if (wait_heci_ready()) {
/* Device is back on its imaginary feet, clear reset */ /* Device is back on its imaginary feet, clear reset */
csr = read_host_csr(); set_host_ready();
csr &= ~CSR_RESET;
csr |= CSR_IG;
csr |= CSR_READY;
write_host_csr(csr);
return 1; return 1;
} }

View File

@ -29,6 +29,30 @@ enum {
PCI_ME_HFSTS6 = 0x6C, PCI_ME_HFSTS6 = 0x6C,
}; };
/* ME Host Firmware Status register 1 */
union me_hfsts1 {
u32 data;
struct {
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 reset_count: 4;
u32 boot_options_present: 1;
u32 reserved1: 1;
u32 bist_test_state: 1;
u32 bist_reset_request: 1;
u32 current_power_source: 2;
u32 d3_support_valid: 1;
u32 d0i3_support_valid: 1;
} __packed fields;
};
/* set up device for use in early boot enviroument with temp bar */ /* set up device for use in early boot enviroument with temp bar */
void heci_init(uintptr_t bar); void heci_init(uintptr_t bar);
/* /*
@ -72,6 +96,16 @@ uint32_t me_read_config32(int offset);
*/ */
bool is_cse_enabled(void); bool is_cse_enabled(void);
/* Makes the host ready to communicate with CSE*/
void set_host_ready(void);
/*
* Polls for ME state 'HECI_OP_MODE_SEC_OVERRIDE' for 15 seconds.
* Returns 0 on failure a 1 on success.
*/
uint8_t wait_cse_sec_override_mode(void);
#define BIOS_HOST_ADDR 0x00 #define BIOS_HOST_ADDR 0x00
#define HECI_MKHI_ADDR 0x07 #define HECI_MKHI_ADDR 0x07

View File

@ -47,30 +47,6 @@
#define ME_HFS_POWER_SOURCE_AC 1 #define ME_HFS_POWER_SOURCE_AC 1
#define ME_HFS_POWER_SOURCE_DC 2 #define ME_HFS_POWER_SOURCE_DC 2
union me_hfs {
u32 data;
struct {
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 reset_count: 4;
u32 boot_options_present: 1;
u32 reserved1: 1;
u32 bist_test_state: 1;
u32 bist_reset_request: 1;
u32 current_power_source: 2;
u32 d3_support_valid: 1;
u32 d0i3_support_valid: 1;
} __packed fields;
};
#define PCI_ME_HFSTS2 0x48
/* Infrastructure Progress Values */ /* Infrastructure Progress Values */
#define ME_HFS2_PHASE_ROM 0 #define ME_HFS2_PHASE_ROM 0
#define ME_HFS2_PHASE_UKERNEL 2 #define ME_HFS2_PHASE_UKERNEL 2

View File

@ -229,7 +229,7 @@ static void print_me_version(void *unused)
struct fw_ver_resp resp; struct fw_ver_resp resp;
size_t resp_size = sizeof(resp); size_t resp_size = sizeof(resp);
union me_hfs hfs; union me_hfsts1 hfs1;
/* /*
* Print ME version only if UART debugging is enabled. Else, it takes ~1 * Print ME version only if UART debugging is enabled. Else, it takes ~1
@ -241,14 +241,14 @@ static void print_me_version(void *unused)
if (!is_cse_enabled()) if (!is_cse_enabled())
return; return;
hfs.data = me_read_config32(PCI_ME_HFSTS1); hfs1.data = me_read_config32(PCI_ME_HFSTS1);
/* /*
* This command can be run only if: * This command can be run only if:
* - Working state is normal and * - Working state is normal and
* - Operation mode is normal. * - Operation mode is normal.
*/ */
if ((hfs.fields.working_state != ME_HFS_CWS_NORMAL) || if ((hfs1.fields.working_state != ME_HFS_CWS_NORMAL) ||
(hfs.fields.operation_mode != ME_HFS_MODE_NORMAL)) (hfs1.fields.operation_mode != ME_HFS_MODE_NORMAL))
goto failed; goto failed;
/* /*
@ -282,7 +282,7 @@ BOOT_STATE_INIT_ENTRY(BS_DEV_ENABLE, BS_ON_EXIT, print_me_version, NULL);
void intel_me_status(void) void intel_me_status(void)
{ {
union me_hfs hfs; union me_hfsts1 hfs1;
union me_hfs2 hfs2; union me_hfs2 hfs2;
union me_hfs3 hfs3; union me_hfs3 hfs3;
union me_hfs6 hfs6; union me_hfs6 hfs6;
@ -290,13 +290,13 @@ void intel_me_status(void)
if (!is_cse_enabled()) if (!is_cse_enabled())
return; return;
hfs.data = me_read_config32(PCI_ME_HFSTS1); hfs1.data = me_read_config32(PCI_ME_HFSTS1);
hfs2.data = me_read_config32(PCI_ME_HFSTS2); hfs2.data = me_read_config32(PCI_ME_HFSTS2);
hfs3.data = me_read_config32(PCI_ME_HFSTS3); hfs3.data = me_read_config32(PCI_ME_HFSTS3);
hfs6.data = me_read_config32(PCI_ME_HFSTS6); hfs6.data = me_read_config32(PCI_ME_HFSTS6);
printk(BIOS_DEBUG, "ME: Host Firmware Status Register 1 : 0x%08X\n", printk(BIOS_DEBUG, "ME: Host Firmware Status Register 1 : 0x%08X\n",
hfs.data); hfs1.data);
printk(BIOS_DEBUG, "ME: Host Firmware Status Register 2 : 0x%08X\n", printk(BIOS_DEBUG, "ME: Host Firmware Status Register 2 : 0x%08X\n",
hfs2.data); hfs2.data);
printk(BIOS_DEBUG, "ME: Host Firmware Status Register 3 : 0x%08X\n", printk(BIOS_DEBUG, "ME: Host Firmware Status Register 3 : 0x%08X\n",
@ -309,21 +309,21 @@ void intel_me_status(void)
hfs6.data); hfs6.data);
/* Check Current States */ /* Check Current States */
printk(BIOS_DEBUG, "ME: FW Partition Table : %s\n", printk(BIOS_DEBUG, "ME: FW Partition Table : %s\n",
hfs.fields.fpt_bad ? "BAD" : "OK"); hfs1.fields.fpt_bad ? "BAD" : "OK");
printk(BIOS_DEBUG, "ME: Bringup Loader Failure : %s\n", printk(BIOS_DEBUG, "ME: Bringup Loader Failure : %s\n",
hfs.fields.ft_bup_ld_flr ? "YES" : "NO"); hfs1.fields.ft_bup_ld_flr ? "YES" : "NO");
printk(BIOS_DEBUG, "ME: Firmware Init Complete : %s\n", printk(BIOS_DEBUG, "ME: Firmware Init Complete : %s\n",
hfs.fields.fw_init_complete ? "YES" : "NO"); hfs1.fields.fw_init_complete ? "YES" : "NO");
printk(BIOS_DEBUG, "ME: Manufacturing Mode : %s\n", printk(BIOS_DEBUG, "ME: Manufacturing Mode : %s\n",
hfs.fields.mfg_mode ? "YES" : "NO"); hfs1.fields.mfg_mode ? "YES" : "NO");
printk(BIOS_DEBUG, "ME: Boot Options Present : %s\n", printk(BIOS_DEBUG, "ME: Boot Options Present : %s\n",
hfs.fields.boot_options_present ? "YES" : "NO"); hfs1.fields.boot_options_present ? "YES" : "NO");
printk(BIOS_DEBUG, "ME: Update In Progress : %s\n", printk(BIOS_DEBUG, "ME: Update In Progress : %s\n",
hfs.fields.update_in_progress ? "YES" : "NO"); hfs1.fields.update_in_progress ? "YES" : "NO");
printk(BIOS_DEBUG, "ME: D3 Support : %s\n", printk(BIOS_DEBUG, "ME: D3 Support : %s\n",
hfs.fields.d3_support_valid ? "YES" : "NO"); hfs1.fields.d3_support_valid ? "YES" : "NO");
printk(BIOS_DEBUG, "ME: D0i3 Support : %s\n", printk(BIOS_DEBUG, "ME: D0i3 Support : %s\n",
hfs.fields.d0i3_support_valid ? "YES" : "NO"); hfs1.fields.d0i3_support_valid ? "YES" : "NO");
printk(BIOS_DEBUG, "ME: Low Power State Enabled : %s\n", printk(BIOS_DEBUG, "ME: Low Power State Enabled : %s\n",
hfs2.fields.low_power_state ? "YES" : "NO"); hfs2.fields.low_power_state ? "YES" : "NO");
printk(BIOS_DEBUG, "ME: CPU Replaced : %s\n", printk(BIOS_DEBUG, "ME: CPU Replaced : %s\n",
@ -331,13 +331,13 @@ void intel_me_status(void)
printk(BIOS_DEBUG, "ME: CPU Replacement Valid : %s\n", printk(BIOS_DEBUG, "ME: CPU Replacement Valid : %s\n",
hfs2.fields.cpu_replaced_valid ? "YES" : "NO"); hfs2.fields.cpu_replaced_valid ? "YES" : "NO");
printk(BIOS_DEBUG, "ME: Current Working State : %s\n", printk(BIOS_DEBUG, "ME: Current Working State : %s\n",
me_cws_values[hfs.fields.working_state]); me_cws_values[hfs1.fields.working_state]);
printk(BIOS_DEBUG, "ME: Current Operation State : %s\n", printk(BIOS_DEBUG, "ME: Current Operation State : %s\n",
me_opstate_values[hfs.fields.operation_state]); me_opstate_values[hfs1.fields.operation_state]);
printk(BIOS_DEBUG, "ME: Current Operation Mode : %s\n", printk(BIOS_DEBUG, "ME: Current Operation Mode : %s\n",
me_opmode_values[hfs.fields.operation_mode]); me_opmode_values[hfs1.fields.operation_mode]);
printk(BIOS_DEBUG, "ME: Error Code : %s\n", printk(BIOS_DEBUG, "ME: Error Code : %s\n",
me_error_values[hfs.fields.error_code]); me_error_values[hfs1.fields.error_code]);
printk(BIOS_DEBUG, "ME: Progress Phase : %s\n", printk(BIOS_DEBUG, "ME: Progress Phase : %s\n",
me_progress_values[hfs2.fields.progress_code]); me_progress_values[hfs2.fields.progress_code]);
printk(BIOS_DEBUG, "ME: Power Management Event : %s\n", printk(BIOS_DEBUG, "ME: Power Management Event : %s\n",
@ -484,14 +484,14 @@ static int send_heci_reset_message(void)
int send_global_reset(void) int send_global_reset(void)
{ {
int status = -1; int status = -1;
union me_hfs hfs; union me_hfsts1 hfs1;
if (!is_cse_enabled()) if (!is_cse_enabled())
goto ret; goto ret;
/* Check ME operating mode */ /* Check ME operating mode */
hfs.data = me_read_config32(PCI_ME_HFSTS1); hfs1.data = me_read_config32(PCI_ME_HFSTS1);
if (hfs.fields.operation_mode) if (hfs1.fields.operation_mode)
goto ret; goto ret;
/* ME should be in Normal Mode for this command */ /* ME should be in Normal Mode for this command */