1*b9707d46SDavid E. Box // SPDX-License-Identifier: GPL-2.0 2*b9707d46SDavid E. Box /* 3*b9707d46SDavid E. Box * Intel Platform Monitory Technology Discovery KUNIT tests 4*b9707d46SDavid E. Box * 5*b9707d46SDavid E. Box * Copyright (c) 2025, Intel Corporation. 6*b9707d46SDavid E. Box * All Rights Reserved. 7*b9707d46SDavid E. Box */ 8*b9707d46SDavid E. Box 9*b9707d46SDavid E. Box #include <kunit/test.h> 10*b9707d46SDavid E. Box #include <linux/err.h> 11*b9707d46SDavid E. Box #include <linux/intel_pmt_features.h> 12*b9707d46SDavid E. Box #include <linux/intel_vsec.h> 13*b9707d46SDavid E. Box #include <linux/module.h> 14*b9707d46SDavid E. Box #include <linux/slab.h> 15*b9707d46SDavid E. Box 16*b9707d46SDavid E. Box #define PMT_FEATURE_COUNT (FEATURE_MAX + 1) 17*b9707d46SDavid E. Box 18*b9707d46SDavid E. Box static void 19*b9707d46SDavid E. Box validate_pmt_regions(struct kunit *test, struct pmt_feature_group *feature_group, int feature_id) 20*b9707d46SDavid E. Box { 21*b9707d46SDavid E. Box int i; 22*b9707d46SDavid E. Box 23*b9707d46SDavid E. Box kunit_info(test, "Feature ID %d [%s] has %d regions.\n", feature_id, 24*b9707d46SDavid E. Box pmt_feature_names[feature_id], feature_group->count); 25*b9707d46SDavid E. Box 26*b9707d46SDavid E. Box for (i = 0; i < feature_group->count; i++) { 27*b9707d46SDavid E. Box struct telemetry_region *region = &feature_group->regions[i]; 28*b9707d46SDavid E. Box 29*b9707d46SDavid E. Box kunit_info(test, " - Region %d: cdie_mask=%u, package_id=%u, partition=%u, segment=%u,", 30*b9707d46SDavid E. Box i, region->plat_info.cdie_mask, region->plat_info.package_id, 31*b9707d46SDavid E. Box region->plat_info.partition, region->plat_info.segment); 32*b9707d46SDavid E. Box kunit_info(test, "\t\tbus=%u, device=%u, function=%u, guid=0x%x,", 33*b9707d46SDavid E. Box region->plat_info.bus_number, region->plat_info.device_number, 34*b9707d46SDavid E. Box region->plat_info.function_number, region->guid); 35*b9707d46SDavid E. Box kunit_info(test, "\t\taddr=%p, size=%lu, num_rmids=%u", region->addr, region->size, 36*b9707d46SDavid E. Box region->num_rmids); 37*b9707d46SDavid E. Box 38*b9707d46SDavid E. Box 39*b9707d46SDavid E. Box KUNIT_ASSERT_GE(test, region->plat_info.cdie_mask, 0); 40*b9707d46SDavid E. Box KUNIT_ASSERT_GE(test, region->plat_info.package_id, 0); 41*b9707d46SDavid E. Box KUNIT_ASSERT_GE(test, region->plat_info.partition, 0); 42*b9707d46SDavid E. Box KUNIT_ASSERT_GE(test, region->plat_info.segment, 0); 43*b9707d46SDavid E. Box KUNIT_ASSERT_GE(test, region->plat_info.bus_number, 0); 44*b9707d46SDavid E. Box KUNIT_ASSERT_GE(test, region->plat_info.device_number, 0); 45*b9707d46SDavid E. Box KUNIT_ASSERT_GE(test, region->plat_info.function_number, 0); 46*b9707d46SDavid E. Box 47*b9707d46SDavid E. Box KUNIT_ASSERT_NE(test, region->guid, 0); 48*b9707d46SDavid E. Box 49*b9707d46SDavid E. Box KUNIT_ASSERT_NOT_ERR_OR_NULL(test, (__force const void *)region->addr); 50*b9707d46SDavid E. Box } 51*b9707d46SDavid E. Box } 52*b9707d46SDavid E. Box 53*b9707d46SDavid E. Box static void linebreak(struct kunit *test) 54*b9707d46SDavid E. Box { 55*b9707d46SDavid E. Box kunit_info(test, "*****************************************************************************\n"); 56*b9707d46SDavid E. Box } 57*b9707d46SDavid E. Box 58*b9707d46SDavid E. Box static void test_intel_pmt_get_regions_by_feature(struct kunit *test) 59*b9707d46SDavid E. Box { 60*b9707d46SDavid E. Box struct pmt_feature_group *feature_group; 61*b9707d46SDavid E. Box int num_available = 0; 62*b9707d46SDavid E. Box int feature_id; 63*b9707d46SDavid E. Box 64*b9707d46SDavid E. Box /* Iterate through all possible feature IDs */ 65*b9707d46SDavid E. Box for (feature_id = 1; feature_id < PMT_FEATURE_COUNT; feature_id++, linebreak(test)) { 66*b9707d46SDavid E. Box const char *name; 67*b9707d46SDavid E. Box 68*b9707d46SDavid E. Box if (!pmt_feature_id_is_valid(feature_id)) 69*b9707d46SDavid E. Box continue; 70*b9707d46SDavid E. Box 71*b9707d46SDavid E. Box name = pmt_feature_names[feature_id]; 72*b9707d46SDavid E. Box 73*b9707d46SDavid E. Box feature_group = intel_pmt_get_regions_by_feature(feature_id); 74*b9707d46SDavid E. Box if (IS_ERR(feature_group)) { 75*b9707d46SDavid E. Box if (PTR_ERR(feature_group) == -ENOENT) 76*b9707d46SDavid E. Box kunit_warn(test, "intel_pmt_get_regions_by_feature() reporting feature %d [%s] is not present.\n", 77*b9707d46SDavid E. Box feature_id, name); 78*b9707d46SDavid E. Box else 79*b9707d46SDavid E. Box kunit_warn(test, "intel_pmt_get_regions_by_feature() returned error %ld while attempt to lookup %d [%s].\n", 80*b9707d46SDavid E. Box PTR_ERR(feature_group), feature_id, name); 81*b9707d46SDavid E. Box 82*b9707d46SDavid E. Box continue; 83*b9707d46SDavid E. Box } 84*b9707d46SDavid E. Box 85*b9707d46SDavid E. Box if (!feature_group) { 86*b9707d46SDavid E. Box kunit_warn(test, "Feature ID %d: %s is not available.\n", feature_id, name); 87*b9707d46SDavid E. Box continue; 88*b9707d46SDavid E. Box } 89*b9707d46SDavid E. Box 90*b9707d46SDavid E. Box num_available++; 91*b9707d46SDavid E. Box 92*b9707d46SDavid E. Box validate_pmt_regions(test, feature_group, feature_id); 93*b9707d46SDavid E. Box 94*b9707d46SDavid E. Box intel_pmt_put_feature_group(feature_group); 95*b9707d46SDavid E. Box } 96*b9707d46SDavid E. Box 97*b9707d46SDavid E. Box if (num_available == 0) 98*b9707d46SDavid E. Box kunit_warn(test, "No PMT region groups were available for any feature ID (0-10).\n"); 99*b9707d46SDavid E. Box } 100*b9707d46SDavid E. Box 101*b9707d46SDavid E. Box static struct kunit_case intel_pmt_discovery_test_cases[] = { 102*b9707d46SDavid E. Box KUNIT_CASE(test_intel_pmt_get_regions_by_feature), 103*b9707d46SDavid E. Box {} 104*b9707d46SDavid E. Box }; 105*b9707d46SDavid E. Box 106*b9707d46SDavid E. Box static struct kunit_suite intel_pmt_discovery_test_suite = { 107*b9707d46SDavid E. Box .name = "pmt_discovery_test", 108*b9707d46SDavid E. Box .test_cases = intel_pmt_discovery_test_cases, 109*b9707d46SDavid E. Box }; 110*b9707d46SDavid E. Box 111*b9707d46SDavid E. Box kunit_test_suite(intel_pmt_discovery_test_suite); 112*b9707d46SDavid E. Box 113*b9707d46SDavid E. Box MODULE_IMPORT_NS("INTEL_PMT_DISCOVERY"); 114*b9707d46SDavid E. Box MODULE_AUTHOR("David E. Box <david.e.box@linux.intel.com>"); 115*b9707d46SDavid E. Box MODULE_DESCRIPTION("Intel PMT Discovery KUNIT test driver"); 116*b9707d46SDavid E. Box MODULE_LICENSE("GPL"); 117