Nico Huber has uploaded this change for review. ( https://review.coreboot.org/25513
Change subject: WIP: sb/intel/bd82x6x/me: Try implementing HMRFPO message ......................................................................
WIP: sb/intel/bd82x6x/me: Try implementing HMRFPO message
Change-Id: I2664fc66a55b3b5cb8997114a8622a47181dd911 --- M src/mainboard/lenovo/t420/cmos.layout M src/mainboard/lenovo/t420/devicetree.cb M src/southbridge/intel/bd82x6x/me.c M src/southbridge/intel/bd82x6x/me.h M src/southbridge/intel/bd82x6x/me_8.x.c 5 files changed, 170 insertions(+), 48 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/13/25513/1
diff --git a/src/mainboard/lenovo/t420/cmos.layout b/src/mainboard/lenovo/t420/cmos.layout index 5a9e570..da1afb4 100644 --- a/src/mainboard/lenovo/t420/cmos.layout +++ b/src/mainboard/lenovo/t420/cmos.layout @@ -74,6 +74,8 @@ # coreboot config options: cpu #424 8 r 0 unused
+424 1 e 1 request_hmrfpo + # coreboot config options: northbridge 432 3 e 11 gfx_uma_size 435 2 e 12 hybrid_graphics_mode diff --git a/src/mainboard/lenovo/t420/devicetree.cb b/src/mainboard/lenovo/t420/devicetree.cb index bed406a..fe05a50 100644 --- a/src/mainboard/lenovo/t420/devicetree.cb +++ b/src/mainboard/lenovo/t420/devicetree.cb @@ -76,7 +76,7 @@ register "spi_uvscc" = "0x2005" register "spi_lvscc" = "0x2005"
- device pci 16.0 off end # Management Engine Interface 1 + device pci 16.0 on end # Management Engine Interface 1 device pci 16.1 off end # Management Engine Interface 2 device pci 16.2 off end # Management Engine IDE-R device pci 16.3 off end # Management Engine KT diff --git a/src/southbridge/intel/bd82x6x/me.c b/src/southbridge/intel/bd82x6x/me.c index a5c5e52..1b88a3d 100644 --- a/src/southbridge/intel/bd82x6x/me.c +++ b/src/southbridge/intel/bd82x6x/me.c @@ -27,6 +27,7 @@ #include <console/console.h> #include <device/pci_ids.h> #include <device/pci_def.h> +#include <pc80/mc146818rtc.h> #include <string.h> #include <delay.h> #include <elog.h> @@ -458,39 +459,6 @@ } #endif
-#if IS_ENABLED(CONFIG_CHROMEOS) && 0 /* DISABLED */ -/* Tell ME to issue a global reset */ -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, - }; - struct mei_header mei = { - .is_complete = 1, - .length = sizeof(mkhi) + sizeof(reset), - .host_address = MEI_HOST_ADDRESS, - .client_address = MEI_ADDRESS_MKHI, - }; - - printk(BIOS_NOTICE, "ME: Requesting global reset\n"); - - /* Send request and wait for response */ - if (mei_sendrecv(&mei, &mkhi, &reset, NULL, 0) < 0) { - /* No response means reset will happen shortly... */ - halt(); - } - - /* If the ME responded it rejected the reset request */ - printk(BIOS_ERR, "ME: Global Reset failed\n"); - return -1; -} -#endif - #ifdef __SMM__ static void intel_me7_finalize_smm(void) { @@ -543,6 +511,75 @@ } #else /* !__SMM__ */
+static int mkhi_hmrfpo_enable(void) +{ + u64 send = 0; + struct { + u64 unknown; + u32 status; + } receive; + struct mkhi_header mkhi = { + .group_id = MKHI_GROUP_ID_HMRFPO, + .command = MKHI_HMRFPO_ENABLE, + }; + struct mei_header mei = { + .is_complete = 1, + .length = sizeof(mkhi) + sizeof(send), + .host_address = MEI_HOST_ADDRESS, + .client_address = MEI_ADDRESS_MKHI, + }; + + /* Send request and wait for response */ + printk(BIOS_NOTICE, "ME: %s\n", __FUNCTION__); + if (mei_sendrecv(&mei, &mkhi, &send, &receive, sizeof(receive)) < 0) { + printk(BIOS_ERR, "ME: HMRFPO ENABLE message failed\n"); + return -1; + } + + if (receive.status != 0) { + printk(BIOS_ERR, "ME: HMRFPO ENABLE returned with error\n"); + return -1; + } + + return 0; +} + +static int mkhi_hmrfpo_disable(void) +{ + return -1; +} + +/* 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, + }; + struct mei_header mei = { + .is_complete = 1, + .length = sizeof(mkhi) + sizeof(reset), + .host_address = MEI_HOST_ADDRESS, + .client_address = MEI_ADDRESS_MKHI, + }; + + printk(BIOS_NOTICE, "ME: Requesting global reset\n"); + + /* Send request and wait for response */ + if (mei_sendrecv(&mei, &mkhi, &reset, NULL, 0) < 0) { + /* No response means reset will happen shortly... */ + halt(); + } + + /* If the ME responded it rejected the reset request */ + printk(BIOS_ERR, "ME: Global Reset failed\n"); + return -1; +} + /* Determine the path that we should take based on ME status */ static me_bios_path intel_me_path(device_t dev) { @@ -697,6 +734,9 @@ /* Check whether ME is present and do basic init */ static void intel_me_init(device_t dev) { + u8 request_hmrfpo = 0; + struct me_hfs hfs; + me_bios_path path = intel_me_path(dev);
/* Do initial setup and determine the BIOS path */ @@ -716,6 +756,17 @@ if (intel_mei_setup(dev) < 0) break;
+ /* Unlock ME if requested. */ + get_option(&request_hmrfpo, "request_hmrfpo"); + if (request_hmrfpo) { + /* Unlock ME flash region */ + if (mkhi_hmrfpo_enable() == 0) { + /* Issue global reset */ + mkhi_global_reset(); + return; + } + } + #if (CONFIG_DEFAULT_CONSOLE_LOGLEVEL >= BIOS_DEBUG) /* Print ME firmware version */ mkhi_get_fw_version(); @@ -729,9 +780,22 @@ */ break;
+ case ME_DISABLE_BIOS_PATH: + pci_read_dword_ptr(dev, &hfs, PCI_ME_HFS); + if (hfs.operation_mode == ME_HFS_MODE_OVER_MEI) { + mkhi_hmrfpo_disable(); + get_option(&request_hmrfpo, "request_hmrfpo"); + if (request_hmrfpo) { + request_hmrfpo = 0; + set_option("request_hmrfpo", &request_hmrfpo); + } else { + mkhi_global_reset(); + } + } + break; + case ME_ERROR_BIOS_PATH: case ME_RECOVERY_BIOS_PATH: - case ME_DISABLE_BIOS_PATH: case ME_FIRMWARE_UPDATE_BIOS_PATH: break; } diff --git a/src/southbridge/intel/bd82x6x/me.h b/src/southbridge/intel/bd82x6x/me.h index f95a0b4..0f68d6a 100644 --- a/src/southbridge/intel/bd82x6x/me.h +++ b/src/southbridge/intel/bd82x6x/me.h @@ -181,6 +181,7 @@
#define MKHI_GROUP_ID_CBM 0x00 #define MKHI_GROUP_ID_FWCAPS 0x03 +#define MKHI_GROUP_ID_HMRFPO 0x05 #define MKHI_GROUP_ID_MDES 0x08 #define MKHI_GROUP_ID_GEN 0xff
@@ -188,6 +189,10 @@
#define MKHI_FWCAPS_GET_RULE 0x02
+#define MKHI_HMRFPO_ENABLE 0x01 +#define MKHI_HMRFPO_LOCK 0x02 +#define MKHI_HMRFPO_DISABLE 0x04 + #define MKHI_MDES_ENABLE 0x09
#define MKHI_GET_FW_VERSION 0x02 diff --git a/src/southbridge/intel/bd82x6x/me_8.x.c b/src/southbridge/intel/bd82x6x/me_8.x.c index 6463f96..1e040d2 100644 --- a/src/southbridge/intel/bd82x6x/me_8.x.c +++ b/src/southbridge/intel/bd82x6x/me_8.x.c @@ -27,6 +27,7 @@ #include <console/console.h> #include <device/pci_ids.h> #include <device/pci_def.h> +#include <pc80/mc146818rtc.h> #include <string.h> #include <delay.h> #include <elog.h> @@ -425,7 +426,45 @@ } #endif
-#if IS_ENABLED(CONFIG_CHROMEOS) && 0 /* DISABLED */ +#ifndef __SMM__ +static int mkhi_hmrfpo_enable(void) +{ + u64 send = 0; + struct { + u64 unknown; + u32 status; + } receive; + struct mkhi_header mkhi = { + .group_id = MKHI_GROUP_ID_HMRFPO, + .command = MKHI_HMRFPO_ENABLE, + }; + struct mei_header mei = { + .is_complete = 1, + .length = sizeof(mkhi) + sizeof(send), + .host_address = MEI_HOST_ADDRESS, + .client_address = MEI_ADDRESS_MKHI, + }; + + /* Send request and wait for response */ + printk(BIOS_NOTICE, "ME: %s\n", __FUNCTION__); + if (mei_sendrecv(&mei, &mkhi, &send, &receive, sizeof(receive)) < 0) { + printk(BIOS_ERR, "ME: HMRFPO ENABLE message failed\n"); + return -1; + } + + if (receive.status != 0) { + printk(BIOS_ERR, "ME: HMRFPO ENABLE returned with error\n"); + return -1; + } + + return 0; +} + +static int mkhi_hmrfpo_disable(void) +{ + return -1; +} + /* Tell ME to issue a global reset */ static int mkhi_global_reset(void) { @@ -686,6 +725,8 @@ { me_bios_path path = intel_me_path(dev); me_bios_payload mbp_data; + u8 request_hmrfpo = 0; + struct me_hfs hfs;
/* Do initial setup and determine the BIOS path */ printk(BIOS_NOTICE, "ME: BIOS path: %s\n", me_bios_path_values[path]); @@ -707,19 +748,16 @@ if (intel_me_read_mbp(&mbp_data)) break;
-#if IS_ENABLED(CONFIG_CHROMEOS) && 0 /* DISABLED */ - /* - * Unlock ME in recovery mode. - */ - if (vboot_recovery_mode_enabled()) { + /* Unlock ME if requested. */ + get_option(&request_hmrfpo, "request_hmrfpo"); + if (request_hmrfpo) { /* Unlock ME flash region */ - mkhi_hmrfpo_enable(); - - /* Issue global reset */ - mkhi_global_reset(); - return; + if (mkhi_hmrfpo_enable() == 0) { + /* Issue global reset */ + mkhi_global_reset(); + return; + } } -#endif
#if (CONFIG_DEFAULT_CONSOLE_LOGLEVEL >= BIOS_DEBUG) me_print_fw_version(&mbp_data.fw_version_name); @@ -732,9 +770,22 @@ */ break;
+ case ME_DISABLE_BIOS_PATH: + pci_read_dword_ptr(dev, &hfs, PCI_ME_HFS); + if (hfs.operation_mode == ME_HFS_MODE_OVER_MEI) { + mkhi_hmrfpo_disable(); + get_option(&request_hmrfpo, "request_hmrfpo"); + if (request_hmrfpo) { + request_hmrfpo = 0; + set_option("request_hmrfpo", &request_hmrfpo); + } else { + mkhi_global_reset(); + } + } + break; + case ME_ERROR_BIOS_PATH: case ME_RECOVERY_BIOS_PATH: - case ME_DISABLE_BIOS_PATH: case ME_FIRMWARE_UPDATE_BIOS_PATH: break; }