From bff61814c9fb581c7452a8d17addd7cde6db5381 Mon Sep 17 00:00:00 2001 From: Danil Klimuk Date: Wed, 25 Mar 2026 15:59:19 +0100 Subject: [PATCH 1/3] include: dts-functions: extend ME operation mode detection Add parsing HFSTS1 bits 19:16 via coreboot logs. Add checking coreboot logs for CSE operating mode. Signed-off-by: Danil Klimuk --- include/dts-functions.sh | 132 ++++++++++++++++++++------------ include/hal/common-mock-func.sh | 13 +++- include/hal/dts-hal.sh | 14 +++- 3 files changed, 108 insertions(+), 51 deletions(-) diff --git a/include/dts-functions.sh b/include/dts-functions.sh index ec702d81..b799c24d 100644 --- a/include/dts-functions.sh +++ b/include/dts-functions.sh @@ -596,61 +596,97 @@ check_blobs_in_binary() { fi } +check_me_op_mode_hfsts1() { + # This function checks the HFSTS1, then reports to logs the ME state and + # informs DTS the ME state via return value basing on the HFSTS1 value. + # Mappings between the HFSTS1 values and the prints are done according to: + # + # * coreboot source code: https://github.com/coreboot/coreboot/blob/1879b6a34a6e93a93d691a0d9f2457d6251a17c1/src/soc/intel/skylake/me.c#L44 + # The 6 and 7 values were reported by a firmware developer but not confirmed + # by any public documentation/code: + local hfsts1="$1" + if [ "$hfsts1" == "0" ]; then + echo "ME is not disabled" >>$ERR_LOG_FILE + return 0 + elif [ "$hfsts1" == "2" ]; then + echo "ME is disabled (HAP/Debug Mode)" >>$ERR_LOG_FILE + return 2 + elif [ "$hfsts1" == "3" ]; then + echo "ME is soft disabled (HECI)" >>$ERR_LOG_FILE + return 1 + elif [ "$hfsts1" == "4" ]; then + echo "ME disabled by Security Override Jumper/FDOPS" >>$ERR_LOG_FILE + return 1 + elif [ "$hfsts1" == "5" ]; then + echo "ME disabled by Security Override MEI Message/HMRFPO" >>$ERR_LOG_FILE + return 1 + elif [ "$hfsts1" == "6" ]; then + echo "ME disabled by Security Override MEI Message/HMRFPO" >>$ERR_LOG_FILE + return 1 + elif [ "$hfsts1" == "7" ]; then + echo "ME disabled (Enhanced Debug Mode) or runs Ignition FW" >>$ERR_LOG_FILE + return 1 + else + echo "Cannot determine ME operation mode from HFSTS1 register" >>$ERR_LOG_FILE + return 0 + fi +} + check_if_me_disabled() { - ME_DISABLED=0 + # This function checks the ME operation mode. Depending on the result of the + # check it reports the ME mode to ERR_LOG_FILE/DTS UI and informs DTS via + # ME_DISABLED global variable. + # + # Possible ME_DISABLED values: + # 0: ME is enabled. This mode means the ME cannot be flashed or the flashing + # might cause issues. + # 1: ME is in any state other than enabled or HAP disabled. It is assumed to + # be a safe state to flash ME. + # 2: ME is HAP disabled. It is a safe state to flash ME. + # + # Currently, there are 3 possible methods implemented. This function uses + # every method in the following order, and exits immediately after any of the + # methods detects that the ME is not in the enabled mode: + # 1. Check the HFSTS1 bits 19:16 via PCI + # 2. Check the coreboot logs for ME/CSE mode reports + # 3. Check the HFSTS1 bits 19:16 via coreboot logs + local hfsts1 + ME_DISABLED="0" if [ $BOARD_HAS_ME_REGION -eq 0 ]; then - # No ME region - ME_DISABLED=2 + # No ME region declared in the board's DTS metadata, assume HAP disabled: + ME_DISABLED="2" return fi + # Check for the ME state using HFSTS1 via PCI: if check_if_heci_present; then - ME_OPMODE="$(check_me_op_mode)" - if [ $ME_OPMODE == "0" ]; then - echo "ME is not disabled" >>$ERR_LOG_FILE - return - elif [ $ME_OPMODE == "2" ]; then - echo "ME is disabled (HAP/Debug Mode)" >>$ERR_LOG_FILE - ME_DISABLED=2 - return - elif [ $ME_OPMODE == "3" ]; then - echo "ME is soft disabled (HECI)" >>$ERR_LOG_FILE - ME_DISABLED=1 - return - elif [ $ME_OPMODE == "4" ]; then - echo "ME disabled by Security Override Jumper/FDOPS" >>$ERR_LOG_FILE - ME_DISABLED=1 - return - elif [ $ME_OPMODE == "5" ]; then - echo "ME disabled by Security Override MEI Message/HMRFPO" >>$ERR_LOG_FILE - ME_DISABLED=1 - return - elif [ $ME_OPMODE == "6" ]; then - echo "ME disabled by Security Override MEI Message/HMRFPO" >>$ERR_LOG_FILE - ME_DISABLED=1 - return - elif [ $ME_OPMODE == "7" ]; then - echo "ME disabled (Enhanced Debug Mode) or runs Ignition FW" >>$ERR_LOG_FILE - ME_DISABLED=1 - return - else - print_warning "Unknown ME operation mode, assuming enabled." - echo "Unknown ME operation mode, assuming enabled." >>$ERR_LOG_FILE - return - fi - else - # If we are running coreboot, check for status in logs - $CBMEM check_if_me_disabled_mock -1 | - grep "ME is disabled" &>/dev/null && ME_DISABLED=1 && return # HECI (soft) disabled - $CBMEM check_if_me_disabled_mock -1 | - grep "ME is HAP disabled" &>/dev/null && ME_DISABLED=2 && return # HAP disabled - # TODO: If proprietary BIOS, then also try to check SMBIOS for ME FWSTS - # BTW we could do the same in coreboot, expose FWSTS in SMBIOS before it - # gets disabled - print_warning "Can not determine if ME is disabled, assuming enabled." - echo "Can not determine if ME is disabled, assuming enabled." >>$ERR_LOG_FILE - fi + hfsts1="$(check_hfsts1_heci)" + check_me_op_mode_hfsts1 "$hfsts1" + ME_DISABLED="$?" + [ "$ME_DISABLED" -ne "0" ] && return + fi + + # If we are running coreboot, check for status in logs. The CSE, CSME, and ME + # are interchangeable names for the same Intel technology: ME + # (https://www.intel.com/content/www/us/en/support/articles/000100063/processors.html). + # So it is ok to conclude on the ME state using the "CSE is disabled". + $CBMEM check_if_me_disabled_mock -1 | + grep "ME is HAP disabled" &>/dev/null && ME_DISABLED=2 && return # HAP disabled + $CBMEM check_if_me_disabled_mock -1 | + grep "\(CSE\|ME\) is disabled" &>/dev/null && ME_DISABLED=1 && return # HECI (soft) disabled + + # Check for the ME state using HFSTS1 via coreboot logs: + hfsts1="$(check_hfsts1_cbmem)" + check_me_op_mode_hfsts1 "$hfsts1" + ME_DISABLED="$?" + [ "$ME_DISABLED" -ne "0" ] && return + + # TODO: If proprietary BIOS, then also try to check SMBIOS for ME FWSTS + # BTW we could do the same in coreboot, expose FWSTS in SMBIOS before it + # gets disabled + print_warning "Can not determine if ME is disabled, assuming enabled." + echo "Can not determine if ME is disabled, assuming enabled." >>$ERR_LOG_FILE } force_me_update() { diff --git a/include/hal/common-mock-func.sh b/include/hal/common-mock-func.sh index 50f90c62..6c73e9ec 100644 --- a/include/hal/common-mock-func.sh +++ b/include/hal/common-mock-func.sh @@ -367,6 +367,7 @@ ifdtool_check_blobs_in_binary_mock() { ################################################################################ TEST_ME_DISABLED="${TEST_ME_DISABLED:-true}" TEST_ME_HAP_DISABLED="${TEST_ME_HAP_DISABLED:-}" +TEST_CSE_DISABLED="${TEST_CSE_DISABLED:-false}" cbmem_common_mock() { # should fail if fw is not coreboot @@ -386,11 +387,21 @@ cbmem_check_if_me_disabled_mock() { echo "ME is HAP disabled" elif [ "$TEST_ME_DISABLED" = "true" ]; then echo "ME is disabled" + elif [ "$TEST_CSE_DISABLED" = "true" ]; then + echo "CSE is disabled" fi return 0 } +cbmem_check_hfsts1_mock() { + # Emulating current ME operation mode, check functions check_if_me_disabled and + # check_me_op_mode: + echo "HFSTS1 : 0x000${TEST_ME_OP_MODE}0000" + + return 0 +} + ################################################################################ # cbfstool ################################################################################ @@ -725,7 +736,7 @@ fsread_tool_cat_mock() { ################################################################################ TEST_ME_OP_MODE="${TEST_ME_OP_MODE:-0}" -setpci_check_me_op_mode_mock() { +setpci_check_hfsts1_mock() { # Emulating current ME operation mode, check functions check_if_me_disabled and # check_me_op_mode: echo "0$TEST_ME_OP_MODE" diff --git a/include/hal/dts-hal.sh b/include/hal/dts-hal.sh index 7ab91345..721e1013 100644 --- a/include/hal/dts-hal.sh +++ b/include/hal/dts-hal.sh @@ -196,17 +196,27 @@ check_if_heci_present() { return $? } -check_me_op_mode() { +check_hfsts1_heci() { # Checks ME Current Operation Mode at offset 0x40 bits 19:16: local _mode - _mode="$($SETPCI check_me_op_mode_mock -s 00:16.0 42.B 2>>"$ERR_LOG_FILE" | cut -c2-)" + _mode="$($SETPCI check_hfsts1_mock -s 00:16.0 42.B 2>>"$ERR_LOG_FILE" | cut -c2-)" echo "$_mode" return 0 } +check_hfsts1_cbmem() { + local _mode + + _mode=$($CBMEM check_hfsts1_mock -1 | grep HFSTS1) + + echo "${_mode: -5:-4}" + + return 0 +} + check_if_uefi() { # Check if current firmware has UEFI payload. Returns 0 on success, otherwise # returns 1. From 47bb77e6aeaad97fa4b7dab0ca2d405ac9f1aa90 Mon Sep 17 00:00:00 2001 From: Danil Klimuk Date: Thu, 26 Mar 2026 12:40:27 +0100 Subject: [PATCH 2/3] include: dts-functions: add print for when ME is enabled Signed-off-by: Danil Klimuk --- include/dts-functions.sh | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/include/dts-functions.sh b/include/dts-functions.sh index b799c24d..41108fd3 100644 --- a/include/dts-functions.sh +++ b/include/dts-functions.sh @@ -628,7 +628,7 @@ check_me_op_mode_hfsts1() { return 1 else echo "Cannot determine ME operation mode from HFSTS1 register" >>$ERR_LOG_FILE - return 0 + return 3 fi } @@ -643,6 +643,8 @@ check_if_me_disabled() { # 1: ME is in any state other than enabled or HAP disabled. It is assumed to # be a safe state to flash ME. # 2: ME is HAP disabled. It is a safe state to flash ME. + # 3: ME is in unknown state. The variable ME_DISABLED should not have this + # value assigned after this function returns. # # Currently, there are 3 possible methods implemented. This function uses # every method in the following order, and exits immediately after any of the @@ -664,7 +666,7 @@ check_if_me_disabled() { hfsts1="$(check_hfsts1_heci)" check_me_op_mode_hfsts1 "$hfsts1" ME_DISABLED="$?" - [ "$ME_DISABLED" -ne "0" ] && return + [ "$ME_DISABLED" != "3" ] && return fi # If we are running coreboot, check for status in logs. The CSE, CSME, and ME @@ -680,13 +682,16 @@ check_if_me_disabled() { hfsts1="$(check_hfsts1_cbmem)" check_me_op_mode_hfsts1 "$hfsts1" ME_DISABLED="$?" - [ "$ME_DISABLED" -ne "0" ] && return + [ "$ME_DISABLED" != "3" ] && return # TODO: If proprietary BIOS, then also try to check SMBIOS for ME FWSTS # BTW we could do the same in coreboot, expose FWSTS in SMBIOS before it # gets disabled + print_warning "Can not determine if ME is disabled, assuming enabled." echo "Can not determine if ME is disabled, assuming enabled." >>$ERR_LOG_FILE + ME_DISABLED="0" + return } force_me_update() { From 6dd5a1c94cd898e144bfff7946dabac39a3b9c9a Mon Sep 17 00:00:00 2001 From: Danil Klimuk Date: Fri, 27 Mar 2026 13:38:05 +0100 Subject: [PATCH 3/3] include: hal: common-mock-func: cbmem_check_hfsts1_mock must return 1 if the platform do not have coreboot Signed-off-by: Danil Klimuk --- include/hal/common-mock-func.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/hal/common-mock-func.sh b/include/hal/common-mock-func.sh index 6c73e9ec..beec3533 100644 --- a/include/hal/common-mock-func.sh +++ b/include/hal/common-mock-func.sh @@ -395,6 +395,8 @@ cbmem_check_if_me_disabled_mock() { } cbmem_check_hfsts1_mock() { + [ "$TEST_IS_COREBOOT" != "true" ] && return 1 + # Emulating current ME operation mode, check functions check_if_me_disabled and # check_me_op_mode: echo "HFSTS1 : 0x000${TEST_ME_OP_MODE}0000"