summaryrefslogtreecommitdiffstats
path: root/src/hardware/LMI_AssociatedProcessorCacheMemoryProvider.c
diff options
context:
space:
mode:
authorPeter Schiffer <pschiffe@redhat.com>2013-04-04 19:02:29 +0200
committerPeter Schiffer <pschiffe@redhat.com>2013-04-04 19:02:29 +0200
commit381f0c0a5cd98a48dc6d5a5e0b98443707d8ea81 (patch)
treebdad2e739aac00eb02e71dfe7d4074268c6f69a4 /src/hardware/LMI_AssociatedProcessorCacheMemoryProvider.c
parentc47c5c19c5857439db30e40d4a691f5b700adf5f (diff)
downloadopenlmi-providers-381f0c0a5cd98a48dc6d5a5e0b98443707d8ea81.tar.gz
openlmi-providers-381f0c0a5cd98a48dc6d5a5e0b98443707d8ea81.tar.xz
openlmi-providers-381f0c0a5cd98a48dc6d5a5e0b98443707d8ea81.zip
Hardware: Added Processor Cache Memory Provider
New Providers: * LMI_ProcessorCacheMemoryProvider * LMI_AssociatedProcessorCacheMemoryProvider Other Changes: * Optimized usage of string constats * Fixed wrong usage of pointers in dmidecode.c * Filled unknown mandatory fields in providers with "Unknown" value * Replaced hard coded numbers with LMI constants * Minor optimization - don't gather data which won't be used
Diffstat (limited to 'src/hardware/LMI_AssociatedProcessorCacheMemoryProvider.c')
-rw-r--r--src/hardware/LMI_AssociatedProcessorCacheMemoryProvider.c652
1 files changed, 652 insertions, 0 deletions
diff --git a/src/hardware/LMI_AssociatedProcessorCacheMemoryProvider.c b/src/hardware/LMI_AssociatedProcessorCacheMemoryProvider.c
new file mode 100644
index 0000000..b06aa22
--- /dev/null
+++ b/src/hardware/LMI_AssociatedProcessorCacheMemoryProvider.c
@@ -0,0 +1,652 @@
+/*
+ * Copyright (C) 2013 Red Hat, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors: Peter Schiffer <pschiffe@redhat.com>
+ */
+
+#include <konkret/konkret.h>
+#include "LMI_AssociatedProcessorCacheMemory.h"
+#include "LMI_Processor.h"
+#include "LMI_Hardware.h"
+#include "globals.h"
+#include "dmidecode.h"
+#include "lscpu.h"
+#include "sysfs.h"
+
+CMPIUint16 get_cache_level(const unsigned level);
+CMPIUint16 get_write_policy(const char *op_mode);
+CMPIUint16 get_cache_type(const char *type);
+CMPIUint16 get_cache_associativity_dmi(const char *assoc);
+CMPIUint16 get_cache_associativity_sysfs(const unsigned ways_of_assoc);
+
+static const CMPIBroker* _cb;
+
+static void LMI_AssociatedProcessorCacheMemoryInitialize()
+{
+}
+
+static CMPIStatus LMI_AssociatedProcessorCacheMemoryCleanup(
+ CMPIInstanceMI* mi,
+ const CMPIContext* cc,
+ CMPIBoolean term)
+{
+ CMReturn(CMPI_RC_OK);
+}
+
+static CMPIStatus LMI_AssociatedProcessorCacheMemoryEnumInstanceNames(
+ CMPIInstanceMI* mi,
+ const CMPIContext* cc,
+ const CMPIResult* cr,
+ const CMPIObjectPath* cop)
+{
+ return KDefaultEnumerateInstanceNames(
+ _cb, mi, cc, cr, cop);
+}
+
+static CMPIStatus LMI_AssociatedProcessorCacheMemoryEnumInstances(
+ CMPIInstanceMI* mi,
+ const CMPIContext* cc,
+ const CMPIResult* cr,
+ const CMPIObjectPath* cop,
+ const char** properties)
+{
+ LMI_AssociatedProcessorCacheMemory lmi_assoc_cache;
+ LMI_ProcessorCacheMemoryRef lmi_cpu_cache;
+ LMI_ProcessorRef lmi_cpu;
+ CMPIUint16 cache_level, write_policy, cache_type, associativity;
+ const char *ns = KNameSpace(cop);
+ char *error_msg = NULL;
+ unsigned i, j, cpus_nb = 0;
+ DmiProcessor *dmi_cpus = NULL;
+ unsigned dmi_cpus_nb = 0;
+ LscpuProcessor lscpu;
+ DmiCpuCache *dmi_cpu_caches = NULL;
+ unsigned dmi_cpu_caches_nb = 0;
+ SysfsCpuCache *sysfs_cpu_caches = NULL;
+ unsigned sysfs_cpu_caches_nb = 0;
+
+ /* get processors and caches */
+ if (dmi_get_processors(&dmi_cpus, &dmi_cpus_nb) != 0 || dmi_cpus_nb < 1) {
+ dmi_free_processors(&dmi_cpus, &dmi_cpus_nb);
+ }
+
+ if (dmi_get_cpu_caches(&dmi_cpu_caches, &dmi_cpu_caches_nb) != 0
+ || dmi_cpu_caches_nb < 1) {
+ dmi_free_cpu_caches(&dmi_cpu_caches, &dmi_cpu_caches_nb);
+ }
+
+ /* if we don't have dmidecode data */
+ if (dmi_cpus_nb < 1 || dmi_cpu_caches_nb < 1) {
+ dmi_free_processors(&dmi_cpus, &dmi_cpus_nb);
+ dmi_free_cpu_caches(&dmi_cpu_caches, &dmi_cpu_caches_nb);
+
+ if (lscpu_get_processor(&lscpu) != 0) {
+ error_msg = "Unable to get processor information.";
+ goto done;
+ }
+
+ if (sysfs_get_cpu_caches(&sysfs_cpu_caches, &sysfs_cpu_caches_nb) != 0
+ || sysfs_cpu_caches_nb < 1) {
+ error_msg = "Unable to get processor cache information.";
+ goto done;
+ }
+ }
+
+ if (dmi_cpus_nb > 0) {
+ cpus_nb = dmi_cpus_nb;
+ } else if (lscpu.processors > 0) {
+ cpus_nb = lscpu.processors;
+ } else {
+ error_msg = "Unable to get processor information.";
+ goto done;
+ }
+
+ /* if we have cpus and caches from dmidecode */
+ /* in this case, we can match exactly cpus and caches */
+ if (dmi_cpus_nb > 0 && dmi_cpu_caches_nb > 0) {
+ /* loop cpus */
+ for (i = 0; i < dmi_cpus_nb; i++) {
+ LMI_AssociatedProcessorCacheMemory_Init(&lmi_assoc_cache, _cb, ns);
+
+ LMI_ProcessorRef_Init(&lmi_cpu, _cb, ns);
+ LMI_ProcessorRef_Set_SystemCreationClassName(&lmi_cpu,
+ get_system_creation_class_name());
+ LMI_ProcessorRef_Set_SystemName(&lmi_cpu, get_system_name());
+ LMI_ProcessorRef_Set_CreationClassName(&lmi_cpu,
+ ORGID "_" CPU_CLASS_NAME);
+ LMI_ProcessorRef_Set_DeviceID(&lmi_cpu, dmi_cpus[i].id);
+
+ /* loop caches */
+ for (j = 0; j < dmi_cpu_caches_nb; j++) {
+ /* if this cpu contains this cache */
+ if (strcmp(dmi_cpu_caches[j].id,dmi_cpus[i].l1_cache_handle) == 0
+ || strcmp(dmi_cpu_caches[j].id, dmi_cpus[i].l2_cache_handle) == 0
+ || strcmp(dmi_cpu_caches[j].id, dmi_cpus[i].l3_cache_handle) == 0) {
+ LMI_AssociatedProcessorCacheMemory_Init(
+ &lmi_assoc_cache, _cb, ns);
+
+ LMI_ProcessorCacheMemoryRef_Init(&lmi_cpu_cache, _cb, ns);
+ LMI_ProcessorCacheMemoryRef_Set_SystemCreationClassName(
+ &lmi_cpu_cache, get_system_creation_class_name());
+ LMI_ProcessorCacheMemoryRef_Set_SystemName(&lmi_cpu_cache,
+ get_system_name());
+ LMI_ProcessorCacheMemoryRef_Set_CreationClassName(
+ &lmi_cpu_cache, ORGID "_" CPU_CACHE_CLASS_NAME);
+ LMI_ProcessorCacheMemoryRef_Set_DeviceID(
+ &lmi_cpu_cache, dmi_cpu_caches[j].id);
+
+ LMI_AssociatedProcessorCacheMemory_Set_Dependent(
+ &lmi_assoc_cache, &lmi_cpu);
+ LMI_AssociatedProcessorCacheMemory_Set_Antecedent(
+ &lmi_assoc_cache, &lmi_cpu_cache);
+
+ cache_level = get_cache_level(dmi_cpu_caches[j].level);
+ if (cache_level == 1) {
+ char *other_level;
+ if (asprintf(&other_level, "%u",
+ dmi_cpu_caches[j].level) < 0) {
+ other_level = NULL;
+ error_msg = "Not enough available memory.";
+ goto done;
+ }
+ LMI_AssociatedProcessorCacheMemory_Set_OtherLevelDescription(
+ &lmi_assoc_cache, other_level);
+ free(other_level);
+ other_level = NULL;
+ }
+ write_policy = get_write_policy(dmi_cpu_caches[j].op_mode);
+ if (write_policy == 1) {
+ LMI_AssociatedProcessorCacheMemory_Set_OtherWritePolicyDescription(
+ &lmi_assoc_cache, dmi_cpu_caches[j].op_mode);
+ }
+ cache_type = get_cache_type(dmi_cpu_caches[j].type);
+ if (cache_type == 1) {
+ LMI_AssociatedProcessorCacheMemory_Set_OtherCacheTypeDescription(
+ &lmi_assoc_cache, dmi_cpu_caches[j].type);
+ }
+ associativity = get_cache_associativity_dmi(
+ dmi_cpu_caches[j].associativity);
+ if (associativity == 1) {
+ LMI_AssociatedProcessorCacheMemory_Set_OtherAssociativityDescription(
+ &lmi_assoc_cache,
+ dmi_cpu_caches[j].associativity);
+ }
+
+ LMI_AssociatedProcessorCacheMemory_Set_Level(
+ &lmi_assoc_cache, cache_level);
+ LMI_AssociatedProcessorCacheMemory_Set_WritePolicy(
+ &lmi_assoc_cache, write_policy);
+ LMI_AssociatedProcessorCacheMemory_Set_CacheType(
+ &lmi_assoc_cache, cache_type);
+ LMI_AssociatedProcessorCacheMemory_Set_Associativity(
+ &lmi_assoc_cache, associativity);
+
+ LMI_AssociatedProcessorCacheMemory_Set_ReadPolicy(
+ &lmi_assoc_cache,
+ LMI_AssociatedProcessorCacheMemory_ReadPolicy_Unknown);
+
+ KReturnInstance(cr, lmi_assoc_cache);
+ }
+ }
+ }
+ } else {
+ /* in this case, we match every cache to every cpu, assuming all the */
+ /* cpus are the same */
+ /* loop caches */
+ for (i = 0; i < sysfs_cpu_caches_nb; i++) {
+ LMI_AssociatedProcessorCacheMemory_Init(&lmi_assoc_cache, _cb, ns);
+
+ LMI_ProcessorCacheMemoryRef_Init(&lmi_cpu_cache, _cb, ns);
+ LMI_ProcessorCacheMemoryRef_Set_SystemCreationClassName(
+ &lmi_cpu_cache, get_system_creation_class_name());
+ LMI_ProcessorCacheMemoryRef_Set_SystemName(&lmi_cpu_cache,
+ get_system_name());
+ LMI_ProcessorCacheMemoryRef_Set_CreationClassName(&lmi_cpu_cache,
+ ORGID "_" CPU_CACHE_CLASS_NAME);
+ LMI_ProcessorCacheMemoryRef_Set_DeviceID(&lmi_cpu_cache,
+ sysfs_cpu_caches[i].id);
+
+ /* loop cpus */
+ for (j = 0; j < cpus_nb; j++) {
+ LMI_ProcessorRef_Init(&lmi_cpu, _cb, ns);
+ LMI_ProcessorRef_Set_SystemCreationClassName(&lmi_cpu,
+ get_system_creation_class_name());
+ LMI_ProcessorRef_Set_SystemName(&lmi_cpu, get_system_name());
+ LMI_ProcessorRef_Set_CreationClassName(&lmi_cpu,
+ ORGID "_" CPU_CLASS_NAME);
+
+ if (dmi_cpus_nb > 0) {
+ LMI_ProcessorRef_Set_DeviceID(&lmi_cpu, dmi_cpus[j].id);
+ } else {
+ char *cpu_id;
+ if (asprintf(&cpu_id, "%u", j) < 0) {
+ cpu_id = NULL;
+ error_msg = "Not enough available memory.";
+ goto done;
+ }
+ LMI_ProcessorRef_Set_DeviceID(&lmi_cpu, cpu_id);
+ free(cpu_id);
+ cpu_id = NULL;
+ }
+
+ LMI_AssociatedProcessorCacheMemory_Set_Dependent(
+ &lmi_assoc_cache, &lmi_cpu);
+ LMI_AssociatedProcessorCacheMemory_Set_Antecedent(
+ &lmi_assoc_cache, &lmi_cpu_cache);
+
+ cache_level = get_cache_level(sysfs_cpu_caches[i].level);
+ if (cache_level == 1) {
+ char *other_level;
+ if (asprintf(&other_level, "%u",
+ sysfs_cpu_caches[i].level) < 0) {
+ other_level = NULL;
+ error_msg = "Not enough available memory.";
+ goto done;
+ }
+ LMI_AssociatedProcessorCacheMemory_Set_OtherLevelDescription(
+ &lmi_assoc_cache, other_level);
+ free(other_level);
+ other_level = NULL;
+ }
+ cache_type = get_cache_type(sysfs_cpu_caches[i].type);
+ if (cache_type == 1) {
+ LMI_AssociatedProcessorCacheMemory_Set_OtherCacheTypeDescription(
+ &lmi_assoc_cache, sysfs_cpu_caches[i].type);
+ }
+
+ LMI_AssociatedProcessorCacheMemory_Set_Level(
+ &lmi_assoc_cache, cache_level);
+ LMI_AssociatedProcessorCacheMemory_Set_CacheType(
+ &lmi_assoc_cache, cache_type);
+ LMI_AssociatedProcessorCacheMemory_Set_Associativity(
+ &lmi_assoc_cache,
+ get_cache_associativity_sysfs(
+ sysfs_cpu_caches[i].ways_of_assoc));
+
+ LMI_AssociatedProcessorCacheMemory_Set_WritePolicy(
+ &lmi_assoc_cache,
+ LMI_AssociatedProcessorCacheMemory_WritePolicy_Unknown);
+ LMI_AssociatedProcessorCacheMemory_Set_ReadPolicy(
+ &lmi_assoc_cache,
+ LMI_AssociatedProcessorCacheMemory_ReadPolicy_Unknown);
+
+ if (sysfs_cpu_caches[i].line_size) {
+ LMI_AssociatedProcessorCacheMemory_Set_LineSize(
+ &lmi_assoc_cache, sysfs_cpu_caches[i].line_size);
+ }
+
+ KReturnInstance(cr, lmi_assoc_cache);
+ }
+ }
+ }
+
+done:
+ /* free lscpu only if it was used */
+ if (dmi_cpus_nb < 1 || dmi_cpu_caches_nb < 1) {
+ lscpu_free_processor(&lscpu);
+ }
+ dmi_free_processors(&dmi_cpus, &dmi_cpus_nb);
+ dmi_free_cpu_caches(&dmi_cpu_caches, &dmi_cpu_caches_nb);
+ sysfs_free_cpu_caches(&sysfs_cpu_caches, &sysfs_cpu_caches_nb);
+
+ if (error_msg) {
+ KReturn2(_cb, ERR_FAILED, error_msg);
+ }
+
+ CMReturn(CMPI_RC_OK);
+}
+
+static CMPIStatus LMI_AssociatedProcessorCacheMemoryGetInstance(
+ CMPIInstanceMI* mi,
+ const CMPIContext* cc,
+ const CMPIResult* cr,
+ const CMPIObjectPath* cop,
+ const char** properties)
+{
+ return KDefaultGetInstance(
+ _cb, mi, cc, cr, cop, properties);
+}
+
+static CMPIStatus LMI_AssociatedProcessorCacheMemoryCreateInstance(
+ CMPIInstanceMI* mi,
+ const CMPIContext* cc,
+ const CMPIResult* cr,
+ const CMPIObjectPath* cop,
+ const CMPIInstance* ci)
+{
+ CMReturn(CMPI_RC_ERR_NOT_SUPPORTED);
+}
+
+static CMPIStatus LMI_AssociatedProcessorCacheMemoryModifyInstance(
+ CMPIInstanceMI* mi,
+ const CMPIContext* cc,
+ const CMPIResult* cr,
+ const CMPIObjectPath* cop,
+ const CMPIInstance* ci,
+ const char**properties)
+{
+ CMReturn(CMPI_RC_ERR_NOT_SUPPORTED);
+}
+
+static CMPIStatus LMI_AssociatedProcessorCacheMemoryDeleteInstance(
+ CMPIInstanceMI* mi,
+ const CMPIContext* cc,
+ const CMPIResult* cr,
+ const CMPIObjectPath* cop)
+{
+ CMReturn(CMPI_RC_ERR_NOT_SUPPORTED);
+}
+
+static CMPIStatus LMI_AssociatedProcessorCacheMemoryExecQuery(
+ CMPIInstanceMI* mi,
+ const CMPIContext* cc,
+ const CMPIResult* cr,
+ const CMPIObjectPath* cop,
+ const char* lang,
+ const char* query)
+{
+ CMReturn(CMPI_RC_ERR_NOT_SUPPORTED);
+}
+
+static CMPIStatus LMI_AssociatedProcessorCacheMemoryAssociationCleanup(
+ CMPIAssociationMI* mi,
+ const CMPIContext* cc,
+ CMPIBoolean term)
+{
+ CMReturn(CMPI_RC_OK);
+}
+
+static CMPIStatus LMI_AssociatedProcessorCacheMemoryAssociators(
+ CMPIAssociationMI* mi,
+ const CMPIContext* cc,
+ const CMPIResult* cr,
+ const CMPIObjectPath* cop,
+ const char* assocClass,
+ const char* resultClass,
+ const char* role,
+ const char* resultRole,
+ const char** properties)
+{
+ return KDefaultAssociators(
+ _cb,
+ mi,
+ cc,
+ cr,
+ cop,
+ LMI_AssociatedProcessorCacheMemory_ClassName,
+ assocClass,
+ resultClass,
+ role,
+ resultRole,
+ properties);
+}
+
+static CMPIStatus LMI_AssociatedProcessorCacheMemoryAssociatorNames(
+ CMPIAssociationMI* mi,
+ const CMPIContext* cc,
+ const CMPIResult* cr,
+ const CMPIObjectPath* cop,
+ const char* assocClass,
+ const char* resultClass,
+ const char* role,
+ const char* resultRole)
+{
+ return KDefaultAssociatorNames(
+ _cb,
+ mi,
+ cc,
+ cr,
+ cop,
+ LMI_AssociatedProcessorCacheMemory_ClassName,
+ assocClass,
+ resultClass,
+ role,
+ resultRole);
+}
+
+static CMPIStatus LMI_AssociatedProcessorCacheMemoryReferences(
+ CMPIAssociationMI* mi,
+ const CMPIContext* cc,
+ const CMPIResult* cr,
+ const CMPIObjectPath* cop,
+ const char* assocClass,
+ const char* role,
+ const char** properties)
+{
+ return KDefaultReferences(
+ _cb,
+ mi,
+ cc,
+ cr,
+ cop,
+ LMI_AssociatedProcessorCacheMemory_ClassName,
+ assocClass,
+ role,
+ properties);
+}
+
+static CMPIStatus LMI_AssociatedProcessorCacheMemoryReferenceNames(
+ CMPIAssociationMI* mi,
+ const CMPIContext* cc,
+ const CMPIResult* cr,
+ const CMPIObjectPath* cop,
+ const char* assocClass,
+ const char* role)
+{
+ return KDefaultReferenceNames(
+ _cb,
+ mi,
+ cc,
+ cr,
+ cop,
+ LMI_AssociatedProcessorCacheMemory_ClassName,
+ assocClass,
+ role);
+}
+
+/*
+ * Get CIM Cache Level.
+ * @param level
+ * @return CIM Cache Level
+ */
+CMPIUint16 get_cache_level(const unsigned level)
+{
+ static struct {
+ CMPIUint16 cim_level; /* CIM cache level */
+ unsigned level; /* cache level */
+ } levels[] = {
+ {0, 0},
+ /*
+ {1, },
+ {2, },
+ */
+ {3, 1},
+ {4, 2},
+ {5, 3},
+ };
+
+ size_t i, lvl_length = sizeof(levels) / sizeof(levels[0]);
+
+ for (i = 0; i < lvl_length; i++) {
+ if (level == levels[i].level) {
+ return levels[i].cim_level;
+ }
+ }
+
+ return 1; /* Other */
+}
+
+/*
+ * Get CIM Write Policy according to dmidecode.
+ * @param op_mode operational mode from dmidecode
+ * @return CIM Write Policy
+ */
+CMPIUint16 get_write_policy(const char *op_mode)
+{
+ static struct {
+ CMPIUint16 write_policy; /* CIM write policy */
+ char *op_mode; /* op mode from dmidecode */
+ } modes[] = {
+ {0, "Unknown"},
+ /*
+ {1, },
+ */
+ {2, "Write Back"},
+ {3, "Write Through"},
+ {4, "Varies With Memory Address"},
+ /*
+ {5, },
+ */
+ };
+
+ size_t i, mode_length = sizeof(modes) / sizeof(modes[0]);
+
+ for (i = 0; i < mode_length; i++) {
+ if (strcmp(op_mode, modes[i].op_mode) == 0) {
+ return modes[i].write_policy;
+ }
+ }
+
+ return 1; /* Other */
+}
+
+/*
+ * Get CIM Cache Type according to dmidecode and sysfs.
+ * @param type cache type from dmidecode and sysfs
+ * @return CIM Cache Type
+ */
+CMPIUint16 get_cache_type(const char *type)
+{
+ static struct {
+ CMPIUint16 cache_type; /* CIM cache type */
+ char *type; /* type from dmidecode and sysfs */
+ } types[] = {
+ {0, "Unknown"},
+ {1, "Other"},
+ {2, "Instruction"},
+ {3, "Data"},
+ {4, "Unified"},
+ };
+
+ size_t i, types_length = sizeof(types) / sizeof(types[0]);
+
+ for (i = 0; i < types_length; i++) {
+ if (strcmp(type, types[i].type) == 0) {
+ return types[i].cache_type;
+ }
+ }
+
+ return 1; /* Other */
+}
+
+/*
+ * Get CIM Cache Associativity according to dmidecode.
+ * @param assoc of cache from dmidecode
+ * @return CIM Cache Associativity
+ */
+CMPIUint16 get_cache_associativity_dmi(const char *assoc)
+{
+ static struct {
+ CMPIUint16 cache_assoc; /* CIM cache associativity */
+ char *assoc; /* associativity from dmidecode */
+ } assocs[] = {
+ {0, "Unknown"},
+ {1, "Other"},
+ {2, "Direct Mapped"},
+ {3, "2-way Set-associative"},
+ {4, "4-way Set-associative"},
+ {5, "Fully Associative"},
+ {6, "8-way Set-associative"},
+ {7, "16-way Set-associative"},
+ {8, "12-way Set-associative"},
+ {9, "24-way Set-associative"},
+ {10, "32-way Set-associative"},
+ {11, "48-way Set-associative"},
+ {12, "64-way Set-associative"},
+ {13, "20-way Set-associative"},
+ };
+
+ size_t i, assocs_length = sizeof(assocs) / sizeof(assocs[0]);
+
+ for (i = 0; i < assocs_length; i++) {
+ if (strcmp(assoc, assocs[i].assoc) == 0) {
+ return assocs[i].cache_assoc;
+ }
+ }
+
+ return 1; /* Other */
+}
+
+/*
+ * Get CIM Cache Associativity according to sysfs.
+ * @param ways_of_assoc from sysfs
+ * @return CIM Cache Associativity
+ */
+CMPIUint16 get_cache_associativity_sysfs(const unsigned ways_of_assoc)
+{
+ static struct {
+ CMPIUint16 cache_assoc; /* CIM cache associativity */
+ unsigned ways; /* ways of associativity from sysfs */
+ } assocs[] = {
+ {0, 0},
+ /*
+ {1, "Other"},
+ {2, "Direct Mapped"},
+ */
+ {3, 2},
+ {4, 4},
+ /*
+ {5, "Fully Associative"},
+ */
+ {6, 8},
+ {7, 16},
+ {8, 12},
+ {9, 24},
+ {10, 32},
+ {11, 48},
+ {12, 64},
+ {13, 20},
+ };
+
+ size_t i, assocs_length = sizeof(assocs) / sizeof(assocs[0]);
+
+ for (i = 0; i < assocs_length; i++) {
+ if (ways_of_assoc == assocs[i].ways) {
+ return assocs[i].cache_assoc;
+ }
+ }
+
+ return 1; /* Other */
+}
+
+CMInstanceMIStub(
+ LMI_AssociatedProcessorCacheMemory,
+ LMI_AssociatedProcessorCacheMemory,
+ _cb,
+ LMI_AssociatedProcessorCacheMemoryInitialize())
+
+CMAssociationMIStub(
+ LMI_AssociatedProcessorCacheMemory,
+ LMI_AssociatedProcessorCacheMemory,
+ _cb,
+ LMI_AssociatedProcessorCacheMemoryInitialize())
+
+KONKRET_REGISTRATION(
+ "root/cimv2",
+ "LMI_AssociatedProcessorCacheMemory",
+ "LMI_AssociatedProcessorCacheMemory",
+ "instance association")