platform/x86/intel/ifs: ARRAY BIST for Sierra Forest
authorJithu Joseph <jithu.joseph@intel.com>
Thu, 5 Oct 2023 19:51:37 +0000 (12:51 -0700)
committerIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Fri, 6 Oct 2023 10:09:42 +0000 (13:09 +0300)
Array BIST MSR addresses, bit definition and semantics are different for
Sierra Forest. Branch into a separate Array BIST flow on Sierra Forest
when user invokes Array Test.

Signed-off-by: Jithu Joseph <jithu.joseph@intel.com>
Reviewed-by: Tony Luck <tony.luck@intel.com>
Tested-by: Pengfei Xu <pengfei.xu@intel.com>
Link: https://lore.kernel.org/r/20231005195137.3117166-10-jithu.joseph@intel.com
[ij: ARRAY_GEN_* -> ARRAY_GEN* for consistency]
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
drivers/platform/x86/intel/ifs/core.c
drivers/platform/x86/intel/ifs/ifs.h
drivers/platform/x86/intel/ifs/runtest.c

index 0c8927916373608ed8de6bed72070a94bf7e5cb5..7b11198d85a19a98864cca0bc0e434072351b497 100644 (file)
 
 #include "ifs.h"
 
-#define X86_MATCH(model)                               \
+#define X86_MATCH(model, array_gen)                            \
        X86_MATCH_VENDOR_FAM_MODEL_FEATURE(INTEL, 6,    \
-               INTEL_FAM6_##model, X86_FEATURE_CORE_CAPABILITIES, NULL)
+               INTEL_FAM6_##model, X86_FEATURE_CORE_CAPABILITIES, array_gen)
 
 static const struct x86_cpu_id ifs_cpu_ids[] __initconst = {
-       X86_MATCH(SAPPHIRERAPIDS_X),
-       X86_MATCH(EMERALDRAPIDS_X),
-       X86_MATCH(GRANITERAPIDS_X),
-       X86_MATCH(GRANITERAPIDS_D),
-       X86_MATCH(ATOM_CRESTMONT_X),
+       X86_MATCH(SAPPHIRERAPIDS_X, ARRAY_GEN0),
+       X86_MATCH(EMERALDRAPIDS_X, ARRAY_GEN0),
+       X86_MATCH(GRANITERAPIDS_X, ARRAY_GEN0),
+       X86_MATCH(GRANITERAPIDS_D, ARRAY_GEN0),
+       X86_MATCH(ATOM_CRESTMONT_X, ARRAY_GEN1),
        {}
 };
 MODULE_DEVICE_TABLE(x86cpu, ifs_cpu_ids);
@@ -100,6 +100,7 @@ static int __init ifs_init(void)
                        continue;
                ifs_devices[i].rw_data.generation = FIELD_GET(MSR_INTEGRITY_CAPS_SAF_GEN_MASK,
                                                              msrval);
+               ifs_devices[i].rw_data.array_gen = (u32)m->driver_data;
                ret = misc_register(&ifs_devices[i].misc);
                if (ret)
                        goto err_exit;
index f0dd849b3400606fe353bae189f33fa7468eed5b..56b9f3e3cf76a02fa28a1035d9833235449fe9d3 100644 (file)
 #define MSR_CHUNKS_AUTHENTICATION_STATUS       0x000002c5
 #define MSR_ACTIVATE_SCAN                      0x000002c6
 #define MSR_SCAN_STATUS                                0x000002c7
+#define MSR_ARRAY_TRIGGER                      0x000002d6
+#define MSR_ARRAY_STATUS                       0x000002d7
 #define MSR_SAF_CTRL                           0x000004f0
 
 #define SCAN_NOT_TESTED                                0
 #define IFS_TYPE_SAF                   0
 #define IFS_TYPE_ARRAY_BIST            1
 
+#define ARRAY_GEN0                     0
+#define ARRAY_GEN1                     1
+
 /* MSR_SCAN_HASHES_STATUS bit fields */
 union ifs_scan_hashes_status {
        u64     data;
@@ -272,6 +277,7 @@ struct ifs_test_caps {
  * @cur_batch: number indicating the currently loaded test file
  * @generation: IFS test generation enumerated by hardware
  * @chunk_size: size of a test chunk
+ * @array_gen: test generation of array test
  */
 struct ifs_data {
        int     loaded_version;
@@ -283,6 +289,7 @@ struct ifs_data {
        u32     cur_batch;
        u32     generation;
        u32     chunk_size;
+       u32     array_gen;
 };
 
 struct ifs_work {
index 4fe544d79946c0c02b5a7478ab29e07375dcf557..9c1a027bc5919445708a8c06e4e0b1c2070fad99 100644 (file)
@@ -329,6 +329,38 @@ static void ifs_array_test_core(int cpu, struct device *dev)
                ifsd->status = SCAN_TEST_PASS;
 }
 
+#define ARRAY_GEN1_TEST_ALL_ARRAYS     0x0ULL
+#define ARRAY_GEN1_STATUS_FAIL         0x1ULL
+
+static int do_array_test_gen1(void *status)
+{
+       int cpu = smp_processor_id();
+       int first;
+
+       first = cpumask_first(cpu_smt_mask(cpu));
+
+       if (cpu == first) {
+               wrmsrl(MSR_ARRAY_TRIGGER, ARRAY_GEN1_TEST_ALL_ARRAYS);
+               rdmsrl(MSR_ARRAY_STATUS, *((u64 *)status));
+       }
+
+       return 0;
+}
+
+static void ifs_array_test_gen1(int cpu, struct device *dev)
+{
+       struct ifs_data *ifsd = ifs_get_data(dev);
+       u64 status = 0;
+
+       stop_core_cpuslocked(cpu, do_array_test_gen1, &status);
+       ifsd->scan_details = status;
+
+       if (status & ARRAY_GEN1_STATUS_FAIL)
+               ifsd->status = SCAN_TEST_FAIL;
+       else
+               ifsd->status = SCAN_TEST_PASS;
+}
+
 /*
  * Initiate per core test. It wakes up work queue threads on the target cpu and
  * its sibling cpu. Once all sibling threads wake up, the scan test gets executed and
@@ -356,7 +388,10 @@ int do_core_test(int cpu, struct device *dev)
                ifs_test_core(cpu, dev);
                break;
        case IFS_TYPE_ARRAY_BIST:
-               ifs_array_test_core(cpu, dev);
+               if (ifsd->array_gen == ARRAY_GEN0)
+                       ifs_array_test_core(cpu, dev);
+               else
+                       ifs_array_test_gen1(cpu, dev);
                break;
        default:
                return -EINVAL;