1// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#include "vm/globals.h"
6#if defined(DART_HOST_OS_LINUX)
7
8#include "vm/cpuid.h"
9#include "vm/cpuinfo.h"
10#include "vm/proccpuinfo.h"
11
12#include "platform/assert.h"
13
14// As with Windows, on IA32 and X64, we use the cpuid instruction.
15// The analogous instruction is privileged on ARM, so we resort to
16// reading from /proc/cpuinfo.
17
18namespace dart {
19
20CpuInfoMethod CpuInfo::method_ = kCpuInfoDefault;
21const char* CpuInfo::fields_[kCpuInfoMax] = {};
22
23void CpuInfo::Init() {
24#if defined(HOST_ARCH_IA32) || defined(HOST_ARCH_X64)
25 fields_[kCpuInfoProcessor] = "vendor_id";
26 fields_[kCpuInfoModel] = "model name";
27 fields_[kCpuInfoHardware] = "model name";
28 fields_[kCpuInfoFeatures] = "flags";
29 fields_[kCpuInfoArchitecture] = "CPU architecture";
30 method_ = kCpuInfoCpuId;
31 CpuId::Init();
32#elif defined(HOST_ARCH_ARM)
33 fields_[kCpuInfoProcessor] = "Processor";
34 fields_[kCpuInfoModel] = "model name";
35 fields_[kCpuInfoHardware] = "Hardware";
36 fields_[kCpuInfoFeatures] = "Features";
37 fields_[kCpuInfoArchitecture] = "CPU architecture";
38 method_ = kCpuInfoSystem;
39 ProcCpuInfo::Init();
40#elif defined(HOST_ARCH_ARM64)
41 fields_[kCpuInfoProcessor] = "Processor";
42 fields_[kCpuInfoModel] = "CPU implementer";
43 fields_[kCpuInfoHardware] = "CPU implementer";
44 fields_[kCpuInfoFeatures] = "Features";
45 fields_[kCpuInfoArchitecture] = "CPU architecture";
46 method_ = kCpuInfoSystem;
47 ProcCpuInfo::Init();
48#elif defined(HOST_ARCH_RISCV32) || defined(HOST_ARCH_RISCV64)
49 // We only rely on the base Linux configuration of IMAFDC, so don't need
50 // dynamic feature detection.
51 method_ = kCpuInfoNone;
52#else
53#error Unrecognized target architecture
54#endif
55}
56
57void CpuInfo::Cleanup() {
58 if (method_ == kCpuInfoCpuId) {
59 CpuId::Cleanup();
60 } else if (method_ == kCpuInfoSystem) {
61 ProcCpuInfo::Cleanup();
62 } else {
63 ASSERT(method_ == kCpuInfoNone);
64 }
65}
66
67bool CpuInfo::FieldContains(CpuInfoIndices idx, const char* search_string) {
68 if (method_ == kCpuInfoCpuId) {
69 const char* field = CpuId::field(idx);
70 if (field == nullptr) return false;
71 bool contains = (strstr(field, search_string) != nullptr);
72 free(const_cast<char*>(field));
73 return contains;
74 } else if (method_ == kCpuInfoSystem) {
75 return ProcCpuInfo::FieldContains(field: FieldName(idx), search_string);
76 } else {
77 UNREACHABLE();
78 }
79}
80
81const char* CpuInfo::ExtractField(CpuInfoIndices idx) {
82 if (method_ == kCpuInfoCpuId) {
83 return CpuId::field(idx);
84 } else if (method_ == kCpuInfoSystem) {
85 return ProcCpuInfo::ExtractField(field: FieldName(idx));
86 } else {
87 UNREACHABLE();
88 }
89}
90
91bool CpuInfo::HasField(const char* field) {
92 if (method_ == kCpuInfoCpuId) {
93 return (strcmp(field, fields_[kCpuInfoProcessor]) == 0) ||
94 (strcmp(field, fields_[kCpuInfoModel]) == 0) ||
95 (strcmp(field, fields_[kCpuInfoHardware]) == 0) ||
96 (strcmp(field, fields_[kCpuInfoFeatures]) == 0);
97 } else if (method_ == kCpuInfoSystem) {
98 return ProcCpuInfo::HasField(field);
99 } else if (method_ == kCpuInfoNone) {
100 return false;
101 } else {
102 UNREACHABLE();
103 }
104}
105
106} // namespace dart
107
108#endif // defined(DART_HOST_OS_LINUX)
109

source code of dart_sdk/runtime/vm/cpuinfo_linux.cc