1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Implementation of get_cpuid(). 4 * 5 * Author: Nikita Shubin <n.shubin@yadro.com> 6 * Bibo Mao <maobibo@loongson.cn> 7 * Huacai Chen <chenhuacai@loongson.cn> 8 */ 9 10 #include <stdio.h> 11 #include <stdlib.h> 12 #include <api/fs/fs.h> 13 #include <errno.h> 14 #include "util/debug.h" 15 #include "util/header.h" 16 17 /* 18 * Output example from /proc/cpuinfo 19 * CPU Family : Loongson-64bit 20 * Model Name : Loongson-3C5000 21 * CPU Revision : 0x10 22 * FPU Revision : 0x01 23 */ 24 #define CPUINFO_MODEL "Model Name" 25 #define CPUINFO "/proc/cpuinfo" 26 27 static char *_get_field(const char *line) 28 { 29 char *line2, *nl; 30 31 line2 = strrchr(line, ' '); 32 if (!line2) 33 return NULL; 34 35 line2++; 36 nl = strrchr(line, '\n'); 37 if (!nl) 38 return NULL; 39 40 return strndup(line2, nl - line2); 41 } 42 43 static char *_get_cpuid(void) 44 { 45 unsigned long line_sz; 46 char *line, *model, *cpuid; 47 FILE *file; 48 49 file = fopen(CPUINFO, "r"); 50 if (file == NULL) 51 return NULL; 52 53 line = model = cpuid = NULL; 54 while (getline(&line, &line_sz, file) != -1) { 55 if (strncmp(line, CPUINFO_MODEL, strlen(CPUINFO_MODEL))) 56 continue; 57 58 model = _get_field(line); 59 if (!model) 60 goto out_free; 61 break; 62 } 63 64 if (model && (asprintf(&cpuid, "%s", model) < 0)) 65 cpuid = NULL; 66 67 out_free: 68 fclose(file); 69 free(model); 70 return cpuid; 71 } 72 73 int get_cpuid(char *buffer, size_t sz) 74 { 75 int ret = 0; 76 char *cpuid = _get_cpuid(); 77 78 if (!cpuid) 79 return EINVAL; 80 81 if (sz < strlen(cpuid)) { 82 ret = ENOBUFS; 83 goto out_free; 84 } 85 86 scnprintf(buffer, sz, "%s", cpuid); 87 88 out_free: 89 free(cpuid); 90 return ret; 91 } 92 93 char *get_cpuid_str(struct perf_pmu *pmu __maybe_unused) 94 { 95 return _get_cpuid(); 96 } 97