diff --git a/common/load_unload_module.sh b/common/load_unload_module.sh new file mode 100755 index 00000000..e8f5bc42 --- /dev/null +++ b/common/load_unload_module.sh @@ -0,0 +1,116 @@ +#!/usr/bin/env bash +############################################################################### +# SPDX-License-Identifier: GPL-2.0-only # +# Copyright (c) 2024 Intel Corporation. # +# # +# Common driver module load and unload check # +############################################################################### + +cd "$(dirname "$0")" 2>/dev/null || exit 1 +source ../.env + +usage() { + cat <<_EOF + Usage:./${0##*/} [-l] [-u] [-c] [-p PARAMS] [-d DRIVER] [-h] + Option: + -l Load module + -u Unload module + -c Check module + -d Driver to be loaded/unloded/checked + -p Module Parameter + -h Look for usage +_EOF +} + +# LOAD DRIVER MODULE +load_module() { + local mod=$1 + local param=$2 + + if [ -z "$mod" ]; then + test_print_err "Please input module to be loaded" + return 1 + fi + + do_cmd modprobe "$mod" "$param" + + test_print_trc "$mod : Loaded" + mod_loaded=$(echo "$mod" | tr '-' '_') + check_lsmod "$mod_loaded" +} + +# UNLOAD DRIVER MODULE +unload_module() { + local mod=$1 + + if [ $# -ne 1 ]; then + test_print_err "Please input module to be unloaded" + return 1 + fi + + mod_loaded=$(echo "$mod" | tr '-' '_') + do_cmd modprobe -r "$mod_loaded" + + test_print_trc "$mod : Unloaded" + check_lsmod "$mod_loaded" +} + +# CHECK DRIVER MODULE LOADED WITH 'lsmod' COMMAND +check_lsmod() { + local mod=$1 + + if [ $# -ne 1 ]; then + test_print_err "Please input module to be check" + return 1 + fi + + LSMOD=$(lsmod | grep -w -e "^$mod") + if [ -z "$LSMOD" ]; then + test_print_trc "Module $mod is not loaded" + return 1 + fi + + test_print_trc "lsmod:$LSMOD" +} + +################################ DO THE WORK ################################## + +while getopts :lucd:p:h arg; do + case $arg in + l) LOAD=1 ;; + u) UNLOAD=1 ;; + c) CHECK=1 ;; + d) DRIVER="$OPTARG" ;; + p) PARAMS="$OPTARG" ;; + h) usage ;; + :) + test_print_err "Must supply an argument to -$OPTARG." >&2 + exit 1 + ;; + \?) + test_print_err "Invalid Option -$OPTARG ignored." >&2 + usage + exit 1 + ;; + esac +done + +# DEFAULT VALUES IF NOT SET IN 'getopts' +: "${LOAD:='0'}" +: "${UNLOAD:='0'}" +: "${CHECK:='0'}" +: "${PARAMS:=''}" + +# LOAD MODULE DRIVER +if [ "$LOAD" -eq 1 ]; then + load_module "$DRIVER" "$PARAMS" +fi + +# UNLOAD MODULE DRIVER +if [ "$UNLOAD" -eq 1 ]; then + unload_module "$DRIVER" +fi + +if [ "$CHECK" -eq 1 ]; then + check_lsmod "$DRIVER" +fi diff --git a/tpmi/README.md b/tpmi/README.md new file mode 100644 index 00000000..d039b0e9 --- /dev/null +++ b/tpmi/README.md @@ -0,0 +1,23 @@ +# Release Notes for Topology Aware Register and PM Capsule Interface test cases + +The tpmi cases are designed to test the basic functionality of the intel_vsec +and intel_tpmi driver modules on Intel® Architecture-based server platforms. +These cases are supported on the GRANITERAPIDS and will be compatibale with +subsequent platforms as well. + + +You can run the cases one by one, e.g. command + +``` +./intel_tpmi.sh -t pm_feature_list +``` +You also can run the cases together with runtests command, e.g. + +``` +cd .. +./runtests -f tpmi/tests -o logfile +``` + +These are the basic cases for intel_vsec and intel_tpmi driver module, +If you have good idea to improve cstate cases, you are welcomed to +send us the patches, thanks! diff --git a/tpmi/intel_tpmi.sh b/tpmi/intel_tpmi.sh new file mode 100755 index 00000000..01307ca0 --- /dev/null +++ b/tpmi/intel_tpmi.sh @@ -0,0 +1,416 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-only +# Copyright (c) 2024 Intel Corporation +# Description: Test script for Intel_TPMI(Topology Aware Register and PM Capsule Interface) +# driver which is supported on both Intel® server platforms: GRANITERAPIDS and is +# compatible with subsequent server platforms +# @Author wendy.wang@intel.com +# @History Created May 06 2024 - Created + +cd "$(dirname "$0")" 2>/dev/null || exit 1 +source ../.env + +TPMI_DRIVER_PATH="/sys/module/intel_vsec_tpmi/drivers/auxiliary" +TPMI_DEBUGFS_PATH="/sys/kernel/debug" + +: "${CASE_NAME:=""}" + +usage() { + cat <<__EOF + usage: ./${0##*/} [-t TESTCASE_ID] [-H] + -t TEST CASE ID + -H show this +__EOF +} + +get_vsec_oobmsm_device() { + dev_lines=$(lspci -d 8086:09a7 | wc -l 2>&1) + if [[ $dev_lines == 0 ]]; then + dev_lines=$(lspci -d 8086:09a1 | wc -l 2>&1) + fi + [[ "$dev_lines" -ne 0 ]] || block_test "Did not detect tpmi pci device." +} + +unload_module() { + # $1 is the driver module name + local module_name=$1 + is_kmodule_builtin "$module_name" && skip_test + load_unload_module.sh -c -d "$module_name" && + do_cmd "load_unload_module.sh -u -d $module_name" +} + +load_module() { + # $1 is the driver module name + local module_name=$1 + is_kmodule_builtin "$module_name" && skip_test + do_cmd "load_unload_module.sh -l -d $module_name" && + load_unload_module.sh -c -d "$module_name" +} + +tpmi_driver_interface() { + test_print_trc "Check intel_vsec_tpmi driver interface:" + + [[ -d "$TPMI_DRIVER_PATH":intel_vsec_tpmi ]] || + die "intel_vsec_tpmi driver SYSFS does not exist!" + + lines=$(ls "$TPMI_DRIVER_PATH":intel_vsec_tpmi 2>&1) + for line in $lines; do + test_print_trc "$line" + done +} + +tpmi_debugfs_interface() { + local socket_num + local tpmi_debugfs_instance + local tpmi_debugfs_instance_num + local tpmi_pci_device + + socket_num=$(lscpu | grep "Socket(s)" | awk -F " " '{print $2}' 2>&1) + test_print_trc "Check how many socket the system supports: $socket_num" + + tpmi_debugfs_instance=$(ls "$TPMI_DEBUGFS_PATH" | grep "tpmi-*" 2>&1) + tpmi_debugfs_instance_num=$(ls "$TPMI_DEBUGFS_PATH" | grep -c "tpmi-*" 2>&1) + test_print_trc "Check how many intel_vesc_tpmi debugfs instance:" + test_print_trc "$tpmi_debugfs_instance" + + get_vsec_oobmsm_device + + test_print_trc "Check tpmi pci device:" + tpmi_pci_device=$(lspci -d 8086:09a7 2>&1) + test_print_trc "$tpmi_pci_device" + + if [[ -n "$tpmi_debugfs_instance" ]] && [[ -n "$tpmi_pci_device" ]] && + [[ "$socket_num" -eq "$tpmi_debugfs_instance_num" ]] && + [[ "$socket_num" -eq "$dev_lines" ]]; then + test_print_trc "intel_vsec_tpmi 09a7 debugfs file exist and instance number is correct" + elif [[ -z "$tpmi_pci_device" ]]; then + tpmi_pci_device=$(lspci -d 8086:09a1 2>&1) + socket_num=$((socket_num * 2)) + if [[ -n "$tpmi_debugfs_instance" ]] && [[ -n "$tpmi_pci_device" ]] && + [[ "$socket_num" -eq "$tpmi_debugfs_instance_num" ]] && + [[ "$socket_num" -eq "$dev_lines" ]]; then + test_print_trc "intel_vsec_tpmi debugfs file exist and instance number is correct" + else + die "intel_vsec_tpmi 09a1 debugfs file and instance number is not correct!" + fi + else + die "intel_vsec_tpmi debugfs is not correct!" + fi + + lines=$(ls -A "$TPMI_DEBUGFS_PATH"/tpmi-* 2>&1) + for line in $lines; do + test_print_trc "$line" + done +} + +# PFS: PM Feature Structure +dump_pfs_pm_feature_list() { + local expected_tpmi_id="0x80 0x00 0x01 0x02 0x03 0x04 0x05 0x0a 0x06 0x0c 0x0d 0x81 0xfd 0xfe 0xff" + local test_tpmi_id="" + local line_num="" + local dev_name="" + local pfs_item="" + + get_vsec_oobmsm_device + + test_print_trc "Dump PM Feature Structure:" + for ((i = 1; i <= dev_lines; i++)); do + dev_name=$(lspci -d 8086:09a7 | awk -F " " '{print $1}' | sed -n "$i, 1p") + [[ -e "$TPMI_DEBUGFS_PATH"/tpmi-0000:"$dev_name"/pfs_dump ]] || + block_test "tpmi debugfs pfs_dump does not exist." + test_print_trc "The $TPMI_DEBUGFS_PATH/tpmi-0000:$dev_name/pfs_dump is:" + cat "$TPMI_DEBUGFS_PATH"/tpmi-0000:"$dev_name"/pfs_dump 2>&1 + done + + test_print_trc "Check if all the PFS TPMI_ID are expected:" + # Calculate the tpmi debugfs device lines num + for ((i = 1; i <= dev_lines; i++)); do + dev_name=$(lspci -d 8086:09a7 | awk -F " " '{print $1}' | sed -n "$i, 1p") + + # Calculate the TPMI_ID lines num + line_num=$(awk 'END { print NR}' "$TPMI_DEBUGFS_PATH"/tpmi-0000:"$dev_name"/pfs_dump 2>&1) + # Calculate if the pfs_dump shows the duplicated features + pfs_item=$(uniq -c "$TPMI_DEBUGFS_PATH"/tpmi-0000:"$dev_name"/pfs_dump | wc -l 2>&1) + [[ $pfs_item -eq 17 ]] || die "$TPMI_DEBUGFS_PATH/tpmi-0000:$dev_name/pfs_dump \ +shows feature list is not align with spec." + + # Check each TPMI_ID in PFS dump + for ((j = 3; j <= line_num; j++)); do + test_tpmi_id=$(awk '{print $1}' "$TPMI_DEBUGFS_PATH"/tpmi-0000:"$dev_name"/pfs_dump 2>&1 | + sed -n "$j, 1p") + if [[ $expected_tpmi_id =~ $test_tpmi_id ]]; then + test_print_trc "PFS TPMI_ID $test_tpmi_id in tpmi-0000:$dev_name is detected." + else + die "PFS TPMI_ID $test_tpmi_id in tpmi-0000:$dev_name is not detected." + fi + done + done +} + +dump_pfs_lock_disable_status() { + local line_num="" + local dev_name="" + local disabled_status="" + + get_vsec_oobmsm_device + + test_print_trc "Check intel_vsec_tpmi dump_pfs lock and disable status:" + for ((i = 1; i <= dev_lines; i++)); do + dev_name=$(lspci -d 8086:09a7 | awk -F " " '{print $1}' | sed -n "$i, 1p") + if [[ -n "$dev_name" ]]; then + [[ -e "$TPMI_DEBUGFS_PATH"/tpmi-0000:"$dev_name"/pfs_dump ]] || + block_test "tpmi debugfs pfs_dump does not exist." + test_print_trc "The $TPMI_DEBUGFS_PATH/tpmi-0000:$dev_name/pfs_dump is:" + cat "$TPMI_DEBUGFS_PATH"/tpmi-0000:"$dev_name"/pfs_dump 2>&1 + + disabled_status=$(awk '{for(k=0;++k<=NF;)a[k]=a[k]?a[k] FS $k:$k} END{for(k=0;k++&1 + + disabled_status=$(awk '{for(k=0;++k<=NF;)a[k]=a[k]?a[k] FS $k:$k} END{for(k=0;k++&1) + if [[ -n "$dev_name" ]]; then + test_print_trc "$TPMI_DEBUGFS_PATH/tpmi-0000:$dev_name/tpmi-id-$id/mem_dump is:" + if [[ -e "$TPMI_DEBUGFS_PATH/tpmi-0000:$dev_name/tpmi-id-$id/mem_dump" ]]; then + cat "$TPMI_DEBUGFS_PATH"/tpmi-0000:"$dev_name"/tpmi-id-"$id"/mem_dump + else + die "$TPMI_DEBUGFS_PATH/tpmi-0000:$dev_name/tpmi-id-$id/mem_dump does not exist." + fi + mem_value=$(cut -d ] -f 2 "$TPMI_DEBUGFS_PATH"/tpmi-0000:"$dev_name"/tpmi-id-"$id"/mem_dump 2>&1 | + sed -n '/[1-9a-fA-F]/p') + if [[ -z "$mem_value" ]]; then + die "The tpmi-0000:$dev_name tpmi-id-$id pm feature mem_value is not expected" + else + test_print_trc "The tpmi-0000:$dev_name tpmi-id-$id pm feature mem_value is non-zero." + fi + + else + dev_name=$(lspci -d 8086:09a1 | awk -F " " '{print $1}' | sed -n "$i, 1p") + test_print_trc "$TPMI_DEBUGFS_PATH/tpmi-$dev_name/tpmi-id-$id/mem_dump is:" + if [[ -e "$TPMI_DEBUGFS_PATH/tpmi-$dev_name/tpmi-id-$id/mem_dump" ]]; then + cat "$TPMI_DEBUGFS_PATH"/tpmi-"$dev_name"/tpmi-id-"$id"/mem_dump + else + die "$TPMI_DEBUGFS_PATH/tpmi-$dev_name/tpmi-id-$id/mem_dump does not exist." + fi + mem_value=$(cut -d ] -f 2 "$TPMI_DEBUGFS_PATH"/tpmi-"$dev_name"/tpmi-id-"$id"/mem_dump 2>&1 | + sed -n '/[1-9a-fA-F]/p') + if [[ -z "$mem_value" ]]; then + die "The tpmi-$dev_name tpmi-id-$id pm feature mem_value is not expected" + else + test_print_trc "The tpmi-$dev_name tpmi-id-$id pm feature mem_value is non-zero." + fi + fi + done +} + +mem_write_read() { + local dev_name="" + local mem_ori="" + local mem_aft="" + + get_vsec_oobmsm_device + + test_print_trc "Check mem_write and mem_dump:" + for ((i = 1; i <= dev_lines; i++)); do + dev_name=$(lspci -d 8086:09a7 | awk -F " " '{print $1}' | sed -n "$i, 1p") + if [[ -n "$dev_name" ]]; then + test_print_trc "Choose tpmi-id-02 UFS feature to check mem_write and mem_dump for device $dev_name:" + mem_ori=$(cat $TPMI_DEBUGFS_PATH/tpmi-0000:"$dev_name"/tpmi-id-02/mem_dump | grep "00000020" | head -1 | awk '{print $2}') + test_print_trc "The tpmi-id-02 feature instance 0 mem original value at 0x0020 is: $mem_ori" + test_print_trc "Will write 0x1234 to tpmi-id-02 UFS feature instance 0 with mem address 0x0020" + do_cmd "echo 0,0x20,0x1234 > $TPMI_DEBUGFS_PATH/tpmi-0000:$dev_name/tpmi-id-02/mem_write" + + test_print_trc "Confirm if mem_write successful:" + mem_aft=$(cat $TPMI_DEBUGFS_PATH/tpmi-0000:"$dev_name"/tpmi-id-02/mem_dump | grep "00000020" | head -1 | awk '{print $2}') + test_print_trc "The tpmi-id-02 UFS feature mem value after writing 0x1234 at 0x0020 is: $mem_aft" + if [[ "$mem_aft" == 00001234 ]]; then + test_print_trc "mem_write is successful." + else + die "mem_dump is not expected after mem_write: $mem_aft" + fi + + test_print_trc "Recover mem_dump to the original value:" + do_cmd "echo 0,0x20,0x$mem_ori > $TPMI_DEBUGFS_PATH/tpmi-0000:$dev_name/tpmi-id-02/mem_write" + + else + dev_name=$(lspci -d 8086:09a1 | awk -F " " '{print $1}' | sed -n "$i, 1p") + + test_print_trc "Choose tpmi-id-02 UFS feature to check mem_write and mem_dump for device $dev_name:" + mem_ori=$(cat $TPMI_DEBUGFS_PATH/tpmi-"$dev_name"/tpmi-id-02/mem_dump | grep "00000020" | head -1 | awk '{print $2}') + test_print_trc "The tpmi-id-02 feature instance 0 mem original value at 0x0020 is: $mem_ori" + test_print_trc "Will write 0x1234 to tpmi-id-02 UFS feature instance 0 with mem address 0x0020" + do_cmd "echo 0,0x20,0x1234 > $TPMI_DEBUGFS_PATH/tpmi-$dev_name/tpmi-id-02/mem_write" + + test_print_trc "Confirm if mem_write successful:" + mem_aft=$(cat $TPMI_DEBUGFS_PATH/tpmi-"$dev_name"/tpmi-id-02/mem_dump | grep "00000020" | head -1 | awk '{print $2}') + test_print_trc "The tpmi-id-02 UFS feature mem value after writing 0x1234 at 0x0020 is: $mem_aft" + if [[ "$mem_aft" == 00001234 ]]; then + test_print_trc "mem_write is successful." + else + die "mem_dump is not expected after mem_write: $mem_aft" + fi + + test_print_trc "Recover mem_dump to the original value:" + do_cmd "echo 0,0x20,0x$mem_ori > $TPMI_DEBUGFS_PATH/tpmi-$dev_name/tpmi-id-02/mem_write" + + fi + done +} + +dmesg_check() { + local dmesg_log + + dmesg_log=$(extract_case_dmesg) + + if echo "$dmesg_log" | grep -iE "fail|Call Trace|error"; then + die "Kernel dmesg shows failure: $dmesg_log" + else + test_print_trc "Kernel dmesg shows Okay." + fi + should_fail "extract_case_dmesg | grep Unsupported" +} + +intel_tpmi_test() { + case $TEST_SCENARIO in + tpmi_remove_all_drivers) + unload_module intel_rapl_tpmi + unload_module isst_tpmi + unload_module isst_tpmi_core + unload_module isst_if_mmio + unload_module intel_uncore_frequency_tpmi + unload_module intel_vsec_tpmi + unload_module intel_vsec + load_module intel_vsec + load_module intel_vsec_tpmi + load_module intel_rapl_tpmi + load_module isst_if_mmio + load_module isst_tpmi_core + load_module isst_tpmi + load_module intel_uncore_frequency_tpmi + ;; + tpmi_sysfs) + tpmi_driver_interface + ;; + tpmi_debugfs) + tpmi_debugfs_interface + ;; + pm_feature_list) + dump_pfs_pm_feature_list + ;; + dump_pfs_locked_disabled_status) + dump_pfs_lock_disable_status + ;; + mem_value_00) + tpmi_id_mem_value_read 00 + ;; + mem_value_01) + tpmi_id_mem_value_read 01 + ;; + mem_value_02) + tpmi_id_mem_value_read 02 + ;; + mem_value_03) + tpmi_id_mem_value_read 03 + ;; + mem_value_04) + tpmi_id_mem_value_read 04 + ;; + mem_value_05) + tpmi_id_mem_value_read 05 + ;; + mem_value_0a) + tpmi_id_mem_value_read 0a + ;; + mem_value_06) + tpmi_id_mem_value_read 06 + ;; + mem_value_0c) + tpmi_id_mem_value_read 0c + ;; + mem_value_0d) + tpmi_id_mem_value_read 0d + ;; + mem_value_80) + tpmi_id_mem_value_read 80 + ;; + mem_value_81) + tpmi_id_mem_value_read 81 + ;; + mem_value_fd) + tpmi_id_mem_value_read fd + ;; + mem_value_fe) + tpmi_id_mem_value_read fe + ;; + mem_value_ff) + tpmi_id_mem_value_read ff + ;; + mem_write_read) + mem_write_read + ;; + esac + dmesg_check + return 0 +} + +while getopts :t:H arg; do + case $arg in + t) + TEST_SCENARIO=$OPTARG + ;; + H) + usage && exit 0 + ;; + \?) + usage + die "Invalid Option -$OPTARG" + ;; + :) + usage + die "Option -$OPTARG requires an argument." + ;; + esac +done + +intel_tpmi_test diff --git a/tpmi/tests b/tpmi/tests new file mode 100755 index 00000000..164785e0 --- /dev/null +++ b/tpmi/tests @@ -0,0 +1,40 @@ +# This file collects the test cases which can run against intel_tpmi driver +# on Intel® Architecture-based server platforms. +# Encoding of TPMI_ID(hex): +# 0x0: RAPL - Socket RAPL, DRAM RAPL, Platform RAPL, etc. +# 0x1: PEM - Power and Performance Excursion Monitors +# 0x2: UFS - Uncore Frequency Scaling +# 0x3: PMAX, +# 0x4: DRC +# 0x5: SST - Intel Speed Select Technology +# 0x6: MISC_CTRL - Misc control and status registers - package root instance +# 0xA: FHM - FIVR Health Monitor +# 0xC: PLR - Perf Limit Reason +# 0xD: BMC_CTL - BMC to Primecode mailbox interface +# 0x80: TPMI Control Interface +# 0x81: TPMI Info Registers +# 0xFD: CSR on all punits +# 0xFE: CSR on compute punit(s) +# 0xFF: CSR on package root punit + +intel_tpmi.sh -t tpmi_remove_all_drivers +intel_tpmi.sh -t tpmi_sysfs +intel_tpmi.sh -t tpmi_debugfs +intel_tpmi.sh -t pm_feature_list +intel_tpmi.sh -t dump_pfs_locked_disabled_status +intel_tpmi.sh -t mem_value_00 +intel_tpmi.sh -t mem_value_01 +intel_tpmi.sh -t mem_value_02 +intel_tpmi.sh -t mem_value_03 +intel_tpmi.sh -t mem_value_04 +intel_tpmi.sh -t mem_value_05 +intel_tpmi.sh -t mem_value_06 +intel_tpmi.sh -t mem_value_0a +intel_tpmi.sh -t mem_value_0c +intel_tpmi.sh -t mem_value_0d +intel_tpmi.sh -t mem_value_80 +intel_tpmi.sh -t mem_value_81 +intel_tpmi.sh -t mem_value_fd +intel_tpmi.sh -t mem_value_fe +intel_tpmi.sh -t mem_value_ff +intel_tpmi.sh -t mem_write_read