soc/intel/common/cse: Add option to set IME mode
Add function to have CSME firmware enter Soft Temporary Disable mode, and a corresponding function to put it back into Normal mode. A global reset is required for the CSME to change modes. Control changing modes by a new option "ime_mode". Possible values are - Enable (0): Set the current operation mode to Normal - Disable (1): Set the current operation mode to Soft Temporary Disable Reference: - Intel doc #612229 (CSME 15.0 BIOS Specification) Change-Id: I38d320fbb157a628c5decc90e6ced78efbf85e0d Signed-off-by: Tim Crawford <tcrawford@system76.com>
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
#include <device/pci_ids.h>
|
||||
#include <device/pci_ops.h>
|
||||
#include <intelblocks/cse.h>
|
||||
#include <option.h>
|
||||
#include <security/vboot/misc.h>
|
||||
#include <security/vboot/vboot_common.h>
|
||||
#include <soc/iomap.h>
|
||||
@@ -961,12 +962,135 @@ bool set_cse_device_state(unsigned int devfn, enum cse_device_state requested_st
|
||||
|
||||
#if ENV_RAMSTAGE
|
||||
|
||||
/*
|
||||
* Sets the ME firmware to "Soft Temporary Disable" mode.
|
||||
*
|
||||
* Sends FWCAPS_SET_RULE command with SET_ME_DISABLE rule to CSE.
|
||||
* Returns 0 on failure and 1 on success.
|
||||
*/
|
||||
static int cse_soft_disable(void)
|
||||
{
|
||||
struct disable_msg {
|
||||
struct mkhi_hdr hdr;
|
||||
uint32_t rule_id;
|
||||
uint8_t rule_len;
|
||||
uint32_t rule_data;
|
||||
} __packed msg = {
|
||||
.hdr = {
|
||||
.group_id = MKHI_GROUP_ID_FWCAPS,
|
||||
.command = MKHI_FWCAPS_SET_RULE,
|
||||
},
|
||||
.rule_id = MKHI_FWCAPS_RULE_SET_ME_DISABLE,
|
||||
.rule_len = 4,
|
||||
.rule_data = 0,
|
||||
};
|
||||
|
||||
struct disable_resp {
|
||||
struct mkhi_hdr hdr;
|
||||
uint32_t rule_id;
|
||||
} __packed;
|
||||
|
||||
struct disable_resp resp;
|
||||
size_t resp_size = sizeof(resp);
|
||||
|
||||
printk(BIOS_DEBUG, "HECI: Send Set ME Disable message\n");
|
||||
|
||||
/*
|
||||
* Allow sending Set ME Disable message only if:
|
||||
* - CSE's current working state is Normal and current operation mode is Normal
|
||||
* - Intel AMT is not opened in SoL, SRoU, or KVM session (TODO)
|
||||
*/
|
||||
if (!cse_is_hfs1_cws_normal() || !cse_is_hfs1_com_normal())
|
||||
return 0;
|
||||
|
||||
if (!heci_send_receive(&msg, sizeof(msg), &resp, &resp_size, HECI_MKHI_ADDR))
|
||||
return 0;
|
||||
|
||||
if (resp.hdr.result) {
|
||||
printk(BIOS_ERR, "HECI: Set ME Disable failed: %d\n", resp.hdr.result);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Global reset is required after issuing this message */
|
||||
cse_request_global_reset();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Takes the ME firmware out of "Soft Temporary Disable" mode.
|
||||
*
|
||||
* Sends SET_ME_ENABLE command to CSE.
|
||||
* Returns 0 on failure and 1 on success.
|
||||
*/
|
||||
static int cse_soft_enable(void)
|
||||
{
|
||||
struct enable_msg {
|
||||
struct mkhi_hdr hdr;
|
||||
} __packed;
|
||||
|
||||
struct enable_msg msg = {
|
||||
.hdr = {
|
||||
.group_id = MKHI_GROUP_ID_BUP_COMMON,
|
||||
.command = MKHI_BUP_COMMON_SET_ME_ENABLE,
|
||||
},
|
||||
};
|
||||
|
||||
struct enable_resp {
|
||||
struct mkhi_hdr hdr;
|
||||
} __packed;
|
||||
|
||||
struct enable_resp resp;
|
||||
size_t resp_size = sizeof(resp);
|
||||
|
||||
printk(BIOS_DEBUG, "HECI: Send Set ME Enable message\n");
|
||||
|
||||
/*
|
||||
* Allow sending Set ME Enable message only if:
|
||||
* - CSE's current operation mode is Soft Temporary Disable
|
||||
*/
|
||||
if (!cse_is_hfs1_com_soft_temp_disable())
|
||||
return 0;
|
||||
|
||||
if (!heci_send_receive(&msg, sizeof(msg), &resp, &resp_size, HECI_MKHI_ADDR))
|
||||
return 0;
|
||||
|
||||
if (resp.hdr.result == 0) {
|
||||
/* Global reset is required after issuing this message */
|
||||
cse_request_global_reset();
|
||||
} else {
|
||||
printk(BIOS_ERR, "HECI: ME not in Soft Temporary Disable mode\n");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void cse_enable(struct device *dev)
|
||||
{
|
||||
enum {
|
||||
ENABLE,
|
||||
DISABLE,
|
||||
DONT_TOUCH = 0xff,
|
||||
} mode;
|
||||
|
||||
mode = get_uint_option("ime_mode", DONT_TOUCH);
|
||||
if (mode == DONT_TOUCH)
|
||||
return;
|
||||
|
||||
if (mode == ENABLE)
|
||||
cse_soft_enable();
|
||||
else if (mode == DISABLE)
|
||||
cse_soft_disable();
|
||||
}
|
||||
|
||||
|
||||
static struct device_operations cse_ops = {
|
||||
.set_resources = pci_dev_set_resources,
|
||||
.read_resources = pci_dev_read_resources,
|
||||
.enable_resources = pci_dev_enable_resources,
|
||||
.init = pci_dev_init,
|
||||
.ops_pci = &pci_dev_ops_pci,
|
||||
.enable = cse_enable,
|
||||
};
|
||||
|
||||
static const unsigned short pci_device_ids[] = {
|
||||
|
@@ -8,6 +8,7 @@
|
||||
|
||||
/* MKHI Command groups */
|
||||
#define MKHI_GROUP_ID_CBM 0x0
|
||||
#define MKHI_GROUP_ID_FWCAPS 0x3
|
||||
#define MKHI_GROUP_ID_HMRFPO 0x5
|
||||
#define MKHI_GROUP_ID_GEN 0xff
|
||||
#define MKHI_GROUP_ID_BUP_COMMON 0xf0
|
||||
@@ -18,6 +19,13 @@
|
||||
/* Origin of Global Reset command */
|
||||
#define GR_ORIGIN_BIOS_POST 0x2
|
||||
|
||||
/* Get/Set Firmware Capabilities Command IDs */
|
||||
#define MKHI_FWCAPS_GET_RULE 0x2
|
||||
#define MKHI_FWCAPS_SET_RULE 0x3
|
||||
|
||||
/* Firmware Capabilities Rule IDs */
|
||||
#define MKHI_FWCAPS_RULE_SET_ME_DISABLE 0x6
|
||||
|
||||
/* HMRFPO Command Ids */
|
||||
#define MKHI_HMRFPO_ENABLE 0x1
|
||||
#define MKHI_HMRFPO_GET_STATUS 0x3
|
||||
@@ -31,6 +39,9 @@
|
||||
/* Set End-of-POST in CSE */
|
||||
#define MKHI_END_OF_POST 0xc
|
||||
|
||||
/* Enable IME command */
|
||||
#define MKHI_BUP_COMMON_SET_ME_ENABLE 0x03
|
||||
|
||||
/* Boot partition info and set boot partition info command ids */
|
||||
#define MKHI_BUP_COMMON_GET_BOOT_PARTITION_INFO 0x1c
|
||||
#define MKHI_BUP_COMMON_SET_BOOT_PARTITION_INFO 0x1d
|
||||
|
Reference in New Issue
Block a user