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