From b9d075b0fc12c26316eaaca2de6bfa659f0cb6c1 Mon Sep 17 00:00:00 2001 From: Sridhar Siricilla Date: Sat, 31 Aug 2019 11:38:33 +0530 Subject: 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 Signed-off-by: Sridhar Siricilla Reviewed-on: https://review.coreboot.org/c/coreboot/+/35226 Tested-by: build bot (Jenkins) Reviewed-by: Aamir Bohra --- src/soc/intel/cannonlake/me.c | 38 ++++------------- src/soc/intel/common/block/cse/cse.c | 47 ++++++++++++++++++---- .../intel/common/block/include/intelblocks/cse.h | 34 ++++++++++++++++ src/soc/intel/skylake/include/soc/me.h | 24 ----------- src/soc/intel/skylake/me.c | 44 ++++++++++---------- 5 files changed, 103 insertions(+), 84 deletions(-) (limited to 'src') diff --git a/src/soc/intel/cannonlake/me.c b/src/soc/intel/cannonlake/me.c index cd94be5c24..d6dfec9dca 100644 --- a/src/soc/intel/cannonlake/me.c +++ b/src/soc/intel/cannonlake/me.c @@ -32,30 +32,6 @@ enum { 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 */ union hfsts2 { uint32_t raw; @@ -174,7 +150,7 @@ static void print_me_version(void *unused) struct version fitc; } __packed; - union hfsts1 hfsts1; + union me_hfsts1 hfsts1; const struct mkhi_hdr fw_ver_msg = { .group_id = MKHI_GEN_GROUP_ID, .command = MKHI_GET_FW_VERSION, @@ -189,7 +165,7 @@ static void print_me_version(void *unused) if (!is_cse_enabled()) return; - hfsts1.raw = me_read_config32(PCI_ME_HFSTS1); + hfsts1.data = me_read_config32(PCI_ME_HFSTS1); /* * 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) { - union hfsts1 hfsts1; + union me_hfsts1 hfsts1; union hfsts2 hfsts2; union hfsts3 hfsts3; union hfsts4 hfsts4; @@ -235,7 +211,7 @@ void dump_me_status(void *unused) if (!is_cse_enabled()) 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); hfsts3.raw = me_read_config32(PCI_ME_HFSTS3); 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); printk(BIOS_DEBUG, "ME: HFSTS1 : 0x%08X\n", - hfsts1.raw); + hfsts1.data); printk(BIOS_DEBUG, "ME: HFSTS2 : 0x%08X\n", hfsts2.raw); 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", hfsts1.fields.fw_init_complete ? "YES" : "NO"); 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", - hfsts1.fields.fw_upd_in_progress ? "YES" : "NO"); + hfsts1.fields.update_in_progress ? "YES" : "NO"); printk(BIOS_DEBUG, "ME: D0i3 Support : %s\n", hfsts1.fields.d0i3_support_valid ? "YES" : "NO"); printk(BIOS_DEBUG, "ME: Low Power State Enabled : %s\n", diff --git a/src/soc/intel/common/block/cse/cse.c b/src/soc/intel/common/block/cse/cse.c index 1671970a19..223eab5fb2 100644 --- a/src/soc/intel/common/block/cse/cse.c +++ b/src/soc/intel/common/block/cse/cse.c @@ -67,6 +67,7 @@ #define MEI_HDR_CSE_ADDR_START 0 #define MEI_HDR_CSE_ADDR (((1 << 8) - 1) << MEI_HDR_CSE_ADDR_START) +#define HECI_OP_MODE_SEC_OVERRIDE 5 static struct cse_device { uintptr_t sec_bar; @@ -239,6 +240,43 @@ static int cse_ready(void) 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) { struct stopwatch sw; @@ -484,17 +522,12 @@ int heci_reset(void) /* Send reset request */ csr = read_host_csr(); - csr |= CSR_RESET; - csr |= CSR_IG; + csr |= (CSR_RESET | CSR_IG); write_host_csr(csr); if (wait_heci_ready()) { /* Device is back on its imaginary feet, clear reset */ - csr = read_host_csr(); - csr &= ~CSR_RESET; - csr |= CSR_IG; - csr |= CSR_READY; - write_host_csr(csr); + set_host_ready(); return 1; } diff --git a/src/soc/intel/common/block/include/intelblocks/cse.h b/src/soc/intel/common/block/include/intelblocks/cse.h index bce615c172..30d17c865a 100644 --- a/src/soc/intel/common/block/include/intelblocks/cse.h +++ b/src/soc/intel/common/block/include/intelblocks/cse.h @@ -29,6 +29,30 @@ enum { 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 */ void heci_init(uintptr_t bar); /* @@ -72,6 +96,16 @@ uint32_t me_read_config32(int offset); */ 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 HECI_MKHI_ADDR 0x07 diff --git a/src/soc/intel/skylake/include/soc/me.h b/src/soc/intel/skylake/include/soc/me.h index fbe5033d7c..ef84f59686 100644 --- a/src/soc/intel/skylake/include/soc/me.h +++ b/src/soc/intel/skylake/include/soc/me.h @@ -47,30 +47,6 @@ #define ME_HFS_POWER_SOURCE_AC 1 #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 */ #define ME_HFS2_PHASE_ROM 0 #define ME_HFS2_PHASE_UKERNEL 2 diff --git a/src/soc/intel/skylake/me.c b/src/soc/intel/skylake/me.c index 9e17ef1e3d..5fc817fd50 100644 --- a/src/soc/intel/skylake/me.c +++ b/src/soc/intel/skylake/me.c @@ -229,7 +229,7 @@ static void print_me_version(void *unused) struct fw_ver_resp 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 @@ -241,14 +241,14 @@ static void print_me_version(void *unused) if (!is_cse_enabled()) return; - hfs.data = me_read_config32(PCI_ME_HFSTS1); + hfs1.data = me_read_config32(PCI_ME_HFSTS1); /* * This command can be run only if: * - Working state is normal and * - Operation mode is normal. */ - if ((hfs.fields.working_state != ME_HFS_CWS_NORMAL) || - (hfs.fields.operation_mode != ME_HFS_MODE_NORMAL)) + if ((hfs1.fields.working_state != ME_HFS_CWS_NORMAL) || + (hfs1.fields.operation_mode != ME_HFS_MODE_NORMAL)) 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) { - union me_hfs hfs; + union me_hfsts1 hfs1; union me_hfs2 hfs2; union me_hfs3 hfs3; union me_hfs6 hfs6; @@ -290,13 +290,13 @@ void intel_me_status(void) if (!is_cse_enabled()) 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); hfs3.data = me_read_config32(PCI_ME_HFSTS3); hfs6.data = me_read_config32(PCI_ME_HFSTS6); 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", hfs2.data); printk(BIOS_DEBUG, "ME: Host Firmware Status Register 3 : 0x%08X\n", @@ -309,21 +309,21 @@ void intel_me_status(void) hfs6.data); /* Check Current States */ 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", - 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", - hfs.fields.fw_init_complete ? "YES" : "NO"); + hfs1.fields.fw_init_complete ? "YES" : "NO"); 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", - hfs.fields.boot_options_present ? "YES" : "NO"); + hfs1.fields.boot_options_present ? "YES" : "NO"); 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", - hfs.fields.d3_support_valid ? "YES" : "NO"); + hfs1.fields.d3_support_valid ? "YES" : "NO"); 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", hfs2.fields.low_power_state ? "YES" : "NO"); 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", hfs2.fields.cpu_replaced_valid ? "YES" : "NO"); 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", - me_opstate_values[hfs.fields.operation_state]); + me_opstate_values[hfs1.fields.operation_state]); 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", - me_error_values[hfs.fields.error_code]); + me_error_values[hfs1.fields.error_code]); printk(BIOS_DEBUG, "ME: Progress Phase : %s\n", me_progress_values[hfs2.fields.progress_code]); 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 status = -1; - union me_hfs hfs; + union me_hfsts1 hfs1; if (!is_cse_enabled()) goto ret; /* Check ME operating mode */ - hfs.data = me_read_config32(PCI_ME_HFSTS1); - if (hfs.fields.operation_mode) + hfs1.data = me_read_config32(PCI_ME_HFSTS1); + if (hfs1.fields.operation_mode) goto ret; /* ME should be in Normal Mode for this command */ -- cgit v1.2.3