Francois Toguo Fotso has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/33067
Change subject: soc/intel/common: Add SMBIOS type 131 fields ......................................................................
soc/intel/common: Add SMBIOS type 131 fields
Fill SMBIOS type 131 for intel SOCs.
BUG=none TEST=Boot to OS and check with dmidecode that entry is added.
Change-Id: Ida4e1a95e20289fbab01e773c18e00ce74aa8223 Signed-off-by: Francois Toguo francois.toguo.fotso@intel.com --- M src/soc/intel/common/block/cse/cse.c M src/soc/intel/common/block/include/intelblocks/cse.h 2 files changed, 692 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/67/33067/1
diff --git a/src/soc/intel/common/block/cse/cse.c b/src/soc/intel/common/block/cse/cse.c index 302e6de..3aaf817 100644 --- a/src/soc/intel/common/block/cse/cse.c +++ b/src/soc/intel/common/block/cse/cse.c @@ -17,6 +17,7 @@ #include <assert.h> #include <commonlib/helpers.h> #include <console/console.h> +#include <cpu/x86/msr.h> #include <device/mmio.h> #include <delay.h> #include <device/pci.h> @@ -25,6 +26,7 @@ #include <intelblocks/cse.h> #include <soc/iomap.h> #include <soc/pci_devs.h> +#include <smbios.h> #include <string.h> #include <timer.h>
@@ -68,6 +70,37 @@ #define MEI_HDR_CSE_ADDR_START 0 #define MEI_HDR_CSE_ADDR (((1 << 8) - 1) << MEI_HDR_CSE_ADDR_START)
+#define MKHI_GROUP_ID_GEN 0xff +#define MKHI_GROUP_ID_FWCAPS 0x03 +#define MKHI_FWCAPS_GET_RULE 0x02 +#define MKHI_GROUP_ID_PTFTYPE 0x03 +#define MKHI_PTFTYPE_GET_RULE 0x02 +#define MKHI_GROUP_ID_FW_STATE 0x03 +#define MKHI_FW_STATE_GET_RULE 0x02 +#define MKHI_GET_FW_VERSION 0x02 +#define MKHI_GET_FW_VERSION 0x02 +#define MKHI_GET_PLATFORM_TYPE 0x02 +#define MEI_HOST_ADDRESS 0 +#define MEI_ADDRESS_MKHI 0x07 +#define TXT_IN_VMX_AND_SMX_MSR 0xFF03 +#define DEFAULT_PCI_BUS_NUMBER_PCH 0x0 +#define PCI_FN_PCH_LAN 6 +#define SMBIOS_INTEL_TYPE131 0x83 +#define BITS_0_THROUGH_2_MASK 0x7 +#define BITS_3_THROUGH_7_MASK 0x38 +#define WORD_0_MASK 0x0000ffff +#define WORD_1_MASK 0xffff0000 + +union mkhi_header { + uint32_t data; + struct { + uint32_t group_id: 8; + uint32_t command: 7; + uint32_t is_response: 1; + uint32_t reserved: 8; + uint32_t result: 8; + } __packed fields; +};
struct cse_device { uintptr_t sec_bar; @@ -491,8 +524,489 @@ return 0; }
+/* Get ME firmware version */ +int mkhi_get_fw_version(me_fw_version *version) +{ + int res; + size_t reply_size; + + struct fw_version_cmd { + union mkhi_header mkhi_hdr; + } __packed msg; + + struct fw_version_response { + union mkhi_header mkhi_hdr; + me_fw_version version_info; + } __packed rsp; + + msg.mkhi_hdr.fields.group_id = MKHI_GROUP_ID_GEN; + msg.mkhi_hdr.fields.command = MKHI_GET_FW_VERSION; + msg.mkhi_hdr.fields.is_response = 0; + + res = heci_send(&msg, sizeof(msg), BIOS_HOST_ADDR, HECI_MKHI_ADDR); + + if (!res) { + printk(BIOS_ERR, "Failed to send HECI message.\n"); + return 0; + } + + reply_size = sizeof(rsp); + res = heci_receive(&rsp, &reply_size); + + if (!res) { + printk(BIOS_ERR, "Failed to receive HECI reply.\n"); + return 0; + } + + if (rsp.mkhi_hdr.fields.result != 0) { + printk(BIOS_ERR, "Failed to get ME version.\n"); + return 0; + } + + memcpy(version, &rsp.version_info, sizeof(rsp.version_info)); + + return 1; +} + + +/* Get ME Firmware Capabilities */ +int mkhi_get_fwcaps(me_fwcaps *f_cap) +{ + int res; + size_t reply_size; + + struct fw_version_cmd { + union mkhi_header mkhi_hdr; + u32 rule_id; + } __packed msg; + + msg.mkhi_hdr.fields.group_id = MKHI_GROUP_ID_FWCAPS; + msg.mkhi_hdr.fields.command = MKHI_FWCAPS_GET_RULE; + msg.mkhi_hdr.fields.is_response = 0; + msg.rule_id = 0; + + struct fw_version_response { + union mkhi_header mkhi_hdr; + me_fwcaps fwcaps; + } __packed rsp; + rsp.fwcaps.id = 0; + rsp.fwcaps.length = 0x4; + + res = heci_send(&msg, sizeof(msg), BIOS_HOST_ADDR, HECI_MKHI_ADDR); + + if (!res) { + printk(BIOS_ERR, "Failed to send HECI message.\n"); + return 0; + } + + reply_size = sizeof(rsp); + res = heci_receive(&rsp, &reply_size); + + if (!res) { + printk(BIOS_ERR, "Failed to receive HECI reply.\n"); + return 0; + } + + if (rsp.mkhi_hdr.fields.result != 0) { + printk(BIOS_ERR, "Failed to get ME FW CAPS.\n"); + return 0; + } + + memcpy(f_cap, &rsp.fwcaps, sizeof(rsp.fwcaps)); + + return 1; +} + +/* Get ME Firmware configuration state */ +int mkhi_get_fw_fea_state(mefwcaps_sku *f_cap) +{ + int res; + size_t reply_size; + + struct fw_version_cmd { + union mkhi_header mkhi_hdr; + u32 rule_id; + } __packed msg; + + msg.mkhi_hdr.fields.group_id = MKHI_GROUP_ID_FW_STATE; + msg.mkhi_hdr.fields.command = MKHI_FW_STATE_GET_RULE; + msg.mkhi_hdr.fields.is_response = 0; + msg.rule_id = 0x20; + + struct fw_version_response { + union mkhi_header mkhi_hdr; + me_fwcaps fwcaps; + } __packed rsp; + rsp.fwcaps.id = 0; + rsp.fwcaps.length = 0x4; + + res = heci_send(&msg, sizeof(msg), BIOS_HOST_ADDR, HECI_MKHI_ADDR); + + if (!res) { + printk(BIOS_ERR, "Failed to send HECI message.\n"); + return 0; + } + + reply_size = sizeof(rsp); + res = heci_receive(&rsp, &reply_size); + + if (!res) { + printk(BIOS_ERR, "Failed to receive HECI reply.\n"); + return 0; + } + + if (rsp.mkhi_hdr.fields.result != 0) { + printk(BIOS_ERR, "Failed to get ME FW CAPS CONFIG.\n"); + return 0; + } + + memcpy(f_cap, &rsp.fwcaps.caps_sku, sizeof(rsp.fwcaps.caps_sku)); + + return 1; +} + +int mkhi_get_platform_type(me_platform_type *platf_type) +{ + int res; + size_t reply_size; + + struct fw_version_cmd { + union mkhi_header mkhi_hdr; + u32 rule_id; + } __packed msg; + + msg.mkhi_hdr.fields.group_id = MKHI_GROUP_ID_PTFTYPE; + msg.mkhi_hdr.fields.command = MKHI_PTFTYPE_GET_RULE; + msg.mkhi_hdr.fields.is_response = 0; + msg.rule_id = 0x1d; + + struct fw_version_response { + union mkhi_header mkhi_hdr; + uint32_t id; + uint8_t length; + me_platform_type platf_type; + } __packed rsp; + rsp.id = 0; + rsp.length = sizeof(union mkhi_header) + sizeof(me_platform_type); + + res = heci_send(&msg, sizeof(msg), BIOS_HOST_ADDR, HECI_MKHI_ADDR); + + if (!res) { + printk(BIOS_ERR, "Failed to send HECI message.\n"); + return 0; + } + + reply_size = sizeof(rsp); + res = heci_receive(&rsp, &reply_size); + + if (!res) { + printk(BIOS_ERR, "Failed to receive HECI reply.\n"); + return 0; + } + + if (rsp.mkhi_hdr.fields.result != 0) { + printk(BIOS_ERR, "Failed to get PLATFORM TTYPE .\n"); + return 0; + } + + memcpy(platf_type, &rsp.platf_type, sizeof(rsp.platf_type)); + + return 1; +} + +void get_me_cpu_capab(cpu_cap *cpu_capabilities) +{ + msr_t msr; + u32 feature_flag = cpuid(1).ecx; + msr = rdmsr(IA32_FEATURE_CONTROL); + + if (feature_flag & CPUID_SMX) + cpu_capabilities->lt_txt_cap = 1; + else + cpu_capabilities->lt_txt_cap = 0; + + if ((msr.lo & TXT_IN_VMX_AND_SMX_MSR) == TXT_IN_VMX_AND_SMX_MSR) + cpu_capabilities->lt_txt_enabled = 1; + else + cpu_capabilities->lt_txt_enabled = 0; + + if (feature_flag & CPUID_VMX) + cpu_capabilities->vtx_cap = 1; + else + cpu_capabilities->vtx_cap = 0; + + if (msr.lo & (1 << 2)) + cpu_capabilities->vtx_enabled = 1; + else + cpu_capabilities->vtx_enabled = 0; + + return; +} + +/* + * MEBX is a UEFI Option ROM for the ME. + * Missing without the UEFI payload. All 0s for coreboot + */ +void get_mebx_version(mebx_ver *mebx_version ) +{ + mebx_version->major = 0; + mebx_version->minor = 0; + mebx_version->hotfix = 0; + mebx_version->build = 0; + + return; +} + +void get_pch_capab(pch_cap *pch_capabilities) +{ + pch_capabilities->function_number = PCI_FUNC(PCH_DEVFN_LPC); + pch_capabilities->device_number = PCH_DEV_SLOT_LPC; + pch_capabilities->bus_number = DEFAULT_PCI_BUS_NUMBER_PCH; + pch_capabilities->device_id = pci_read_config16(PCH_DEV_LPC, PCI_DEVICE_ID); + return; +} + + +void get_me_platf_capab(me_cap *platf_cap) +{ + + me_fw_version version; + if (mkhi_get_fw_version(&version)) + { + platf_cap->me_major_ver = version.code_major; + platf_cap->me_minor_ver = version.code_minor; + platf_cap->me_build_ver = version.code_build_number; + platf_cap->me_hotfix_ver = version.code_hot_fix; + } else { + platf_cap->me_major_ver = 0; + platf_cap->me_minor_ver = 0; + platf_cap->me_build_ver = 0; + platf_cap->me_hotfix_ver = 0; + } + + platf_cap->me_enabled = 1; + + me_fwcaps fw_caps; + if (mkhi_get_fwcaps(&fw_caps)) + { + if (fw_caps.caps_sku.kvm) + platf_cap->intel_kvm = 1; + } else { + platf_cap->intel_kvm = 0; + } + + me_platform_type platf_type; + if (mkhi_get_platform_type(&platf_type)) + { + switch (platf_type.brand) + { + case IntelAmtBrand: + platf_cap->intel_amt_fw = 1; + platf_cap->local_wakeup_timer = 1; + break; + + case IntelStandardManageabilityBrand: + platf_cap->intel_amt_fw_std = 1; + break; + } + } else { + platf_cap->intel_amt_fw = 0; + platf_cap->local_wakeup_timer = 0; + platf_cap->intel_amt_fw_std = 0; + } + + return; +} + + +void get_me_platf_config_state(u32 *config_state) +{ + u32 state = 0; + mefwcaps_sku fwcaps; + if (mkhi_get_fw_fea_state(&fwcaps)) + { + state |= fwcaps.full_net ? (1 << 8) : 0; + state |= fwcaps.std_net ? (1 << 9) : 0; + state |= fwcaps.manageability ? (1 << 10) : 0; + state |= fwcaps.integrated_touch ? (1 << 11) : 0; + state |= fwcaps.intel_cls ? (1 << 12) : 0; + state |= fwcaps.ish ? (1 << 13) : 0; + state |= fwcaps.pavp ? (1 << 14) : 0; + state |= fwcaps.ipv6 ? (1 << 15) : 0; + state |= fwcaps.kvm ? (1 << 16) : 0; + state |= fwcaps.dal ? (1 << 17) : 0; + state |= fwcaps.tls ? (1 << 18) : 0; + state |= fwcaps.wlan ? (1 << 19) : 0; + state |= fwcaps.ptt ? (1 << 20) : 0; + } + *config_state = state; + + return; +} + + +void get_network_device_lan(network_dev *nwk_dev) +{ + nwk_dev->function_number = PCI_FN_PCH_LAN; + nwk_dev->device_number = PCH_DEV_SLOT_LPC; + nwk_dev->bus_number = DEFAULT_PCI_BUS_NUMBER_PCH; + nwk_dev->device_id = pci_read_config16(PCH_DEV_LPC, PCI_DEVICE_ID); + + return; +} + +void get_bios_sec_capab(bios_cap *bios_sec_cap) +{ + u32 cpu_feature_flag = cpuid(1).ecx; + if (cpu_feature_flag & CPUID_VMX) + { + bios_sec_cap->vtx_support = 1; + bios_sec_cap->vtd_support = 1; + } else { + bios_sec_cap->vtx_support = 0; + bios_sec_cap->vtd_support = 0; + } + + if (cpu_feature_flag & CPUID_SMX) + bios_sec_cap->txt_support = 1; + else + bios_sec_cap->txt_support = 0; + + return; +} + +void generate_type131_data(me_smbios_info *me_info, struct smbios_type131 *type131) +{ + + u32 cpu_capb = 0, bios_sec_cap = 0; + u64 pch_capb = 0, mebx_version = 0; + u32 platf_cap[3] = {0,0,0}, nwk_dev_lan[3] = {0,0,0}; + int i,j; + + /* CPU capabilities bits setting*/ + cpu_cap c_cap_data = me_info->cpu_capabilities; + cpu_capb |= (c_cap_data.vtx_enabled) ? (1 << 0) : 0; + cpu_capb |= (c_cap_data.lt_txt_cap) ? (1 << 1) : 0; + cpu_capb |= (c_cap_data.lt_txt_cap) ? (1 << 2) : 0; + cpu_capb |= (c_cap_data.lt_txt_enabled) ? (1 << 3) : 0; + cpu_capb |= (c_cap_data.vtx_cap) ? (1 << 4) : 0; + cpu_capb |= (c_cap_data.vtx_enabled) ? (1 << 5) : 0; + cpu_capb &= 0x3f; + type131->cpu_capability = cpu_capb; + + /* MEBx: ME BIOS Extensions bits setting*/ + u64 mask_0 = 0; + mebx_version |= me_info->mebx_version.major; + mebx_version |= (mask_0 | (me_info->mebx_version.minor)) << 16; + mebx_version |= (mask_0 | (me_info->mebx_version.hotfix)) << 32; + mebx_version |= (mask_0 | (me_info->mebx_version.build)) << 48; + type131->intel_mebx_version = mebx_version; + + /* PCH capabilities bits setting*/ + pch_cap ph_cap = me_info->pch_capabilities; + pch_capb |= ph_cap.function_number & BITS_0_THROUGH_2_MASK; + pch_capb |= (ph_cap.device_number << 3) & BITS_3_THROUGH_7_MASK; + pch_capb |= (ph_cap.bus_number << 8) & 0xff00; + pch_capb |= (ph_cap.device_id << 16) & WORD_1_MASK; + type131->pch_capability = pch_capb; + + /* ME platform capabilities bits setting */ + me_cap pf_cap = me_info->me_capabilities; + platf_cap[0] |= (pf_cap.me_enabled) ? 1: 0; + platf_cap[0] |= (pf_cap.intel_amt_fw) ? (1 << 3) : 0; + platf_cap[0] |= (pf_cap.intel_amt_fw_std) ? (1 << 4) : 0; + platf_cap[0] |= (pf_cap.intel_kvm) ? (1 << 14) : 0; + platf_cap[0] |= (pf_cap.local_wakeup_timer) ? (1 << 15) : 0; + platf_cap[1] |= pf_cap.me_minor_ver & WORD_0_MASK; + platf_cap[1] |= pf_cap.me_major_ver << 16; + platf_cap[2] |= pf_cap.me_build_ver & WORD_0_MASK; + platf_cap[2] |= pf_cap.me_hotfix_ver << 16; + + for (i=0; i < 3; i++) + memcpy(&type131->me_platf_capabilities[i], &platf_cap[i], 4); + + /* ME platform configuration state bits setting*/ + u32 config_state = 0; + get_me_platf_config_state(&config_state); + type131->me_feature_state = config_state; + + /* Network device LAN */ + network_dev net_dev = me_info->network_device; + nwk_dev_lan[0] |= net_dev.function_number & BITS_0_THROUGH_2_MASK; + nwk_dev_lan[0] |= (net_dev.device_number << 3) & BITS_3_THROUGH_7_MASK; + nwk_dev_lan[0] |= (net_dev.bus_number << 8) & 0xff00; + nwk_dev_lan[0] |= (net_dev.device_id << 16) & WORD_1_MASK; + nwk_dev_lan[1] = 0; + nwk_dev_lan[2] = 0; + for (j=0; j < 3; j++) + memcpy(&type131->network_device_lan[j],&nwk_dev_lan[j],4); + + /* BIOS securities capabilities bits setting */ + bios_cap b_cap = me_info->bios_sec_capab; + bios_sec_cap |= (b_cap.vtd_support) ? (1 << 1) : 0; + bios_sec_cap |= (b_cap.txt_support) ? (1 << 2) : 0; + bios_sec_cap |= (b_cap.vtx_support) ? (1 << 5) : 0; + type131->bios_sec_capabilities = bios_sec_cap; + + /* unique id for Intel vPro: vPro or 0x76 0x50 0x72 0x6F*/ + memcpy(&type131->structure_id, "vPro",4); + type131->reserved = 0; + + return; +} + +void save_me_smbios_info(me_smbios_info *me_info) +{ + /* CPU capabilities */ + get_me_cpu_capab(&me_info->cpu_capabilities); + + /* MEBx: ME BIOS Extensions */ + get_mebx_version(&me_info->mebx_version); + + /* PCH capabilities */ + get_pch_capab(&me_info->pch_capabilities); + + /* ME platform capabilities */ + get_me_platf_capab(&me_info->me_capabilities); + + /* ME platform configuration state */ + get_me_platf_config_state(&me_info->me_fw_config); + + /* Network device LAN */ + get_network_device_lan(&me_info->network_device); + + /* BIOS securities capabilities */ + get_bios_sec_capab(&me_info->bios_sec_capab); + + me_info->reserved = 0; + + return; +} + #if ENV_RAMSTAGE
+#if IS_ENABLED(CONFIG_GENERATE_SMBIOS_TABLES) +static int smbios_write_type131_info(struct device *dev, int *handle, unsigned long *current) +{ + me_smbios_info me_info; + save_me_smbios_info(&me_info); + + struct smbios_type131 *t = (struct smbios_type131 *)*current; + int len = sizeof(struct smbios_type131); + + memset(t, 0, sizeof(struct smbios_type131)); + t->type = SMBIOS_INTEL_TYPE131; + t->length = len - 2; + t->handle = *handle; + + generate_type131_data(&me_info, t); + + len = t->length + smbios_string_table_len(t->eos); + *current += len; + return len; +} +#endif + static void update_sec_bar(struct device *dev) { g_cse.sec_bar = find_resource(dev, PCI_BASE_ADDRESS_0)->base; @@ -511,6 +1025,9 @@ .read_resources = pci_dev_read_resources, .enable_resources = pci_dev_enable_resources, .init = pci_dev_init, +#if IS_ENABLED(CONFIG_GENERATE_SMBIOS_TABLES) + .get_smbios_data = smbios_write_type131_info, +#endif .ops_pci = &pci_dev_ops_pci, };
diff --git a/src/soc/intel/common/block/include/intelblocks/cse.h b/src/soc/intel/common/block/include/intelblocks/cse.h index d7c4d9f..24b5927 100644 --- a/src/soc/intel/common/block/include/intelblocks/cse.h +++ b/src/soc/intel/common/block/include/intelblocks/cse.h @@ -47,4 +47,179 @@ #define BIOS_HOST_ADDR 0x00 #define HECI_MKHI_ADDR 0x07
+typedef struct { + u32 vmx_state : 1; /* VMX state (On/Off) */ + u32 smx_state : 1; /* SMX state (On/Off) */ + u32 lt_txt_cap : 1; /* LT/TXT capability */ + u32 lt_txt_enabled : 1; /* LT/TXT Enabled state */ + u32 vtx_cap : 1; /* VT-x capability */ + u32 vtx_enabled : 1; /* VT-x Enabled state */ + u32 reserved : 26; +}__packed cpu_cap; + +typedef struct { + u32 function_number : 3; /* PCI Device Function Number */ + u32 device_number : 5; /* PCI Device Device Number */ + u32 bus_number : 8; /* PCI Device Bus Number */ + u32 device_id : 16; + u32 reserved : 32; +}__packed pch_cap; + +typedef struct { + u32 me_enabled : 1; /* ME enabled/Disabled */ + u32 reserved : 2; + u32 intel_amt_fw : 1; /* Intel AMT FW support */ + u32 intel_amt_fw_std : 1; /* Intel AMT Standard FW support */ + u32 reserved_1 : 9; + u32 intel_kvm : 1; /* Intel KVM supported */ + u32 local_wakeup_timer : 1; /* Local Wakeup Timer support */ + u32 reserved_2 : 16; + u32 me_minor_ver : 16; + u32 me_major_ver : 16; + u32 me_build_ver : 16; + u32 me_hotfix_ver : 16; +}__packed me_cap; + +typedef struct { + uint16_t code_minor; + uint16_t code_major; + uint16_t code_build_number; + uint16_t code_hot_fix; + uint16_t recovery_minor; + uint16_t recovery_major; + uint16_t recovery_build_number; + uint16_t recovery_hot_fix; + uint16_t fitcminor; + uint16_t fitcmajor; + uint16_t fitcbuildno; + uint16_t fitchotfix; +} __packed me_fw_version; + +typedef struct { + uint32_t full_net : 1; /* Full Network manageability */ + uint32_t std_net : 1; /* Regular Network manageability */ + uint32_t manageability : 1; /* Manageability */ + uint32_t reserved_1 : 1; + u32 integrated_touch : 1; /* Intel Integrated Touch */ + uint32_t reserved_2 : 1; + uint32_t intel_cls : 1; /* IntelR Capab Licensing Service */ + uint32_t reserved_3 : 3; + u32 ish : 1; /* IntelR Sensor Hub */ + uint32_t reserve_4 : 1; + uint32_t pavp : 1; /* Protected Audio Video Path (PAVP) */ + uint32_t reserved_5 : 4; + uint32_t ipv6 : 1; + uint32_t kvm : 1; + uint32_t reserve_6 : 1; + u32 dal : 1; /* Dynamic Application Loader (DAL) */ + u32 tls : 1; /* [21] Cipher Transport Layer (TLS) */ + uint32_t reserve_7 : 1; + uint32_t wlan : 1; /* Wireless LAN (WLAN) */ + uint32_t reserve_8 : 1; + uint32_t ptt : 1; /* Platform Trust Technology */ + uint32_t reserved_9 : 2; +}__packed mefwcaps_sku; + +typedef struct { + uint32_t id; + uint8_t length; + mefwcaps_sku caps_sku; + uint32_t reserved :3; +} __packed me_fwcaps; + + +/* Platform Type */ +typedef enum { + NoBrand, + IntelAmtBrand, + IntelStandardManageabilityBrand, + IntelReservedBrand1, + IntelReservedBrand2, + IntelReservedBrand3 +} platform_brand; + +typedef struct { + u32 function_number : 3; + u32 device_number : 5; + u32 bus_number : 8; + u32 device_id : 16; + u32 reserved1 : 16; + u32 reserved2 : 16; + u32 reserved3 : 32; +}__packed network_dev; + +typedef struct { + u32 reserved1 : 1; + u32 vtd_support : 1; ///< [1] BIOS supports VT-d + u32 txt_support : 1; ///< [2] BIOS supports TXT + u32 reserved2 : 1; + u32 reserved3 : 1; + u32 vtx_support : 1; ///< [5] BIOS supports VT-x + u32 reserved4 : 26; +}__packed bios_cap; + +typedef struct { + u16 major; + u16 minor; + u16 hotfix; + u16 build; +}__packed mebx_ver; + +typedef struct { + u32 mobile: 1; + u32 desktop: 1; + u32 server: 1; + u32 workstation: 1; + u32 corporate: 1; + u32 consumer: 1; + u32 regular_super_sku: 1; + u32 rsvd: 1; + u32 image_type: 4; + u32 brand: 4; + u32 rsvd1: 16; +} __packed me_platform_type; + +/* This is definition for SMBIOS Oem data type 131 */ +typedef struct { + cpu_cap cpu_capabilities; + mebx_ver mebx_version; + pch_cap pch_capabilities; + me_cap me_capabilities; + u32 me_fw_config; + network_dev network_device; + bios_cap bios_sec_capab; + u8 structure_identifier[4]; + u32 reserved; +}__packed me_smbios_info; + +struct smbios_type131 { + u8 type; + u8 length; + u16 handle; + u32 cpu_capability; + u64 intel_mebx_version; + u64 pch_capability; + u32 me_platf_capabilities[3]; + u32 me_feature_state; + u32 network_device_lan[3]; + u32 bios_sec_capabilities; + u32 structure_id; + u32 reserved; + u8 eos[2]; +}__packed ; + +int mkhi_get_fw_version(me_fw_version *version); +int mkhi_get_platform_type(me_platform_type *platf_type); +int mkhi_get_fw_fea_state(mefwcaps_sku *f_cap); +int mkhi_get_fwcaps(me_fwcaps *f_cap); +void get_me_cpu_capab(cpu_cap *cpu_capabilities); +void get_mebx_version(mebx_ver *mebx_verion); +void get_pch_capab(pch_cap *pch_capabilities); +void get_me_platf_capab(me_cap *platf_cap); +void get_me_platf_config_state(u32 *config_state); +void get_network_device_lan(network_dev *nwk_dev); +void get_bios_sec_capab(bios_cap *bios_sec_cap); +void save_me_smbios_info(me_smbios_info *me_info); +void generate_type131_data(me_smbios_info *me_info, struct smbios_type131 *type131); + #endif // SOC_INTEL_COMMON_MSR_H