162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Implementation of get_cpuid(). 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Author: Nikita Shubin <n.shubin@yadro.com> 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <stdio.h> 962306a36Sopenharmony_ci#include <stdlib.h> 1062306a36Sopenharmony_ci#include <api/fs/fs.h> 1162306a36Sopenharmony_ci#include <errno.h> 1262306a36Sopenharmony_ci#include "../../util/debug.h" 1362306a36Sopenharmony_ci#include "../../util/header.h" 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#define CPUINFO_MVEN "mvendorid" 1662306a36Sopenharmony_ci#define CPUINFO_MARCH "marchid" 1762306a36Sopenharmony_ci#define CPUINFO_MIMP "mimpid" 1862306a36Sopenharmony_ci#define CPUINFO "/proc/cpuinfo" 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_cistatic char *_get_field(const char *line) 2162306a36Sopenharmony_ci{ 2262306a36Sopenharmony_ci char *line2, *nl; 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci line2 = strrchr(line, ' '); 2562306a36Sopenharmony_ci if (!line2) 2662306a36Sopenharmony_ci return NULL; 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci line2++; 2962306a36Sopenharmony_ci nl = strrchr(line, '\n'); 3062306a36Sopenharmony_ci if (!nl) 3162306a36Sopenharmony_ci return NULL; 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci return strndup(line2, nl - line2); 3462306a36Sopenharmony_ci} 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_cistatic char *_get_cpuid(void) 3762306a36Sopenharmony_ci{ 3862306a36Sopenharmony_ci char *line = NULL; 3962306a36Sopenharmony_ci char *mvendorid = NULL; 4062306a36Sopenharmony_ci char *marchid = NULL; 4162306a36Sopenharmony_ci char *mimpid = NULL; 4262306a36Sopenharmony_ci char *cpuid = NULL; 4362306a36Sopenharmony_ci int read; 4462306a36Sopenharmony_ci unsigned long line_sz; 4562306a36Sopenharmony_ci FILE *cpuinfo; 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci cpuinfo = fopen(CPUINFO, "r"); 4862306a36Sopenharmony_ci if (cpuinfo == NULL) 4962306a36Sopenharmony_ci return cpuid; 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci while ((read = getline(&line, &line_sz, cpuinfo)) != -1) { 5262306a36Sopenharmony_ci if (!strncmp(line, CPUINFO_MVEN, strlen(CPUINFO_MVEN))) { 5362306a36Sopenharmony_ci mvendorid = _get_field(line); 5462306a36Sopenharmony_ci if (!mvendorid) 5562306a36Sopenharmony_ci goto free; 5662306a36Sopenharmony_ci } else if (!strncmp(line, CPUINFO_MARCH, strlen(CPUINFO_MARCH))) { 5762306a36Sopenharmony_ci marchid = _get_field(line); 5862306a36Sopenharmony_ci if (!marchid) 5962306a36Sopenharmony_ci goto free; 6062306a36Sopenharmony_ci } else if (!strncmp(line, CPUINFO_MIMP, strlen(CPUINFO_MIMP))) { 6162306a36Sopenharmony_ci mimpid = _get_field(line); 6262306a36Sopenharmony_ci if (!mimpid) 6362306a36Sopenharmony_ci goto free; 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci break; 6662306a36Sopenharmony_ci } 6762306a36Sopenharmony_ci } 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci if (!mvendorid || !marchid || !mimpid) 7062306a36Sopenharmony_ci goto free; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci if (asprintf(&cpuid, "%s-%s-%s", mvendorid, marchid, mimpid) < 0) 7362306a36Sopenharmony_ci cpuid = NULL; 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_cifree: 7662306a36Sopenharmony_ci fclose(cpuinfo); 7762306a36Sopenharmony_ci free(mvendorid); 7862306a36Sopenharmony_ci free(marchid); 7962306a36Sopenharmony_ci free(mimpid); 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci return cpuid; 8262306a36Sopenharmony_ci} 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ciint get_cpuid(char *buffer, size_t sz) 8562306a36Sopenharmony_ci{ 8662306a36Sopenharmony_ci char *cpuid = _get_cpuid(); 8762306a36Sopenharmony_ci int ret = 0; 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci if (sz < strlen(cpuid)) { 9062306a36Sopenharmony_ci ret = -EINVAL; 9162306a36Sopenharmony_ci goto free; 9262306a36Sopenharmony_ci } 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci scnprintf(buffer, sz, "%s", cpuid); 9562306a36Sopenharmony_cifree: 9662306a36Sopenharmony_ci free(cpuid); 9762306a36Sopenharmony_ci return ret; 9862306a36Sopenharmony_ci} 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_cichar * 10162306a36Sopenharmony_ciget_cpuid_str(struct perf_pmu *pmu __maybe_unused) 10262306a36Sopenharmony_ci{ 10362306a36Sopenharmony_ci return _get_cpuid(); 10462306a36Sopenharmony_ci} 105