mirror of
https://github.com/google/cpu_features.git
synced 2025-07-01 13:21:13 +02:00
Support risc-v (#287)
Co-authored-by: DaniAffCH <danieleaffinita2000@gmail.com> Co-authored-by: Corentin Le Molgat <corentinl@google.com>
This commit is contained in:

committed by
GitHub

parent
a7ea4a7783
commit
c919e9aa77
110
src/impl_riscv_linux.c
Normal file
110
src/impl_riscv_linux.c
Normal file
@ -0,0 +1,110 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "cpu_features_macros.h"
|
||||
|
||||
#ifdef CPU_FEATURES_ARCH_RISCV
|
||||
#if defined(CPU_FEATURES_OS_LINUX)
|
||||
|
||||
#include "cpuinfo_riscv.h"
|
||||
|
||||
// According to
|
||||
// https://elixir.bootlin.com/linux/latest/source/Documentation/devicetree/bindings/riscv/cpus.yaml
|
||||
// isa string should match the following regex
|
||||
// ^rv(?:64|32)imaf?d?q?c?b?v?k?h?(?:_[hsxz](?:[a-z])+)*$
|
||||
//
|
||||
// This means we can test for features in this exact order except for Z
|
||||
// extensions.
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Definitions for introspection.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#define INTROSPECTION_TABLE \
|
||||
LINE(RISCV_RV32I, RV32I, "rv32i", RISCV_HWCAP_32, 0) \
|
||||
LINE(RISCV_RV64I, RV64I, "rv64i", RISCV_HWCAP_64, 0) \
|
||||
LINE(RISCV_M, M, "m", RISCV_HWCAP_M, 0) \
|
||||
LINE(RISCV_A, A, "a", RISCV_HWCAP_A, 0) \
|
||||
LINE(RISCV_F, F, "f", RISCV_HWCAP_F, 0) \
|
||||
LINE(RISCV_D, D, "d", RISCV_HWCAP_D, 0) \
|
||||
LINE(RISCV_Q, Q, "q", RISCV_HWCAP_Q, 0) \
|
||||
LINE(RISCV_C, C, "c", RISCV_HWCAP_C, 0) \
|
||||
LINE(RISCV_Zicsr, Zicsr, "_zicsr", 0, 0) \
|
||||
LINE(RISCV_Zifencei, Zifencei, "_zifencei", 0, 0)
|
||||
#define INTROSPECTION_PREFIX Riscv
|
||||
#define INTROSPECTION_ENUM_PREFIX RISCV
|
||||
#include "define_introspection_and_hwcaps.inl"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Implementation.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "internal/filesystem.h"
|
||||
#include "internal/stack_line_reader.h"
|
||||
|
||||
static const RiscvInfo kEmptyRiscvInfo;
|
||||
|
||||
static void HandleRiscVIsaLine(StringView line, RiscvFeatures* const features) {
|
||||
for (size_t i = 0; i < RISCV_LAST_; ++i) {
|
||||
StringView flag = str(kCpuInfoFlags[i]);
|
||||
int index_of_flag = CpuFeatures_StringView_IndexOf(line, flag);
|
||||
bool is_set = index_of_flag != -1;
|
||||
kSetters[i](features, is_set);
|
||||
if (is_set)
|
||||
line = CpuFeatures_StringView_PopFront(line, index_of_flag + flag.size);
|
||||
}
|
||||
}
|
||||
|
||||
static bool HandleRiscVLine(const LineResult result, RiscvInfo* const info) {
|
||||
StringView line = result.line;
|
||||
StringView key, value;
|
||||
if (CpuFeatures_StringView_GetAttributeKeyValue(line, &key, &value)) {
|
||||
if (CpuFeatures_StringView_IsEquals(key, str("isa"))) {
|
||||
HandleRiscVIsaLine(value, &info->features);
|
||||
} else if (CpuFeatures_StringView_IsEquals(key, str("uarch"))) {
|
||||
int index = CpuFeatures_StringView_IndexOfChar(value, ',');
|
||||
if (index == -1) return true;
|
||||
StringView vendor = CpuFeatures_StringView_KeepFront(value, index);
|
||||
StringView uarch = CpuFeatures_StringView_PopFront(value, index + 1);
|
||||
CpuFeatures_StringView_CopyString(vendor, info->vendor,
|
||||
sizeof(info->vendor));
|
||||
CpuFeatures_StringView_CopyString(uarch, info->uarch,
|
||||
sizeof(info->uarch));
|
||||
}
|
||||
}
|
||||
return !result.eof;
|
||||
}
|
||||
|
||||
static void FillProcCpuInfoData(RiscvInfo* const info) {
|
||||
const int fd = CpuFeatures_OpenFile("/proc/cpuinfo");
|
||||
if (fd >= 0) {
|
||||
StackLineReader reader;
|
||||
StackLineReader_Initialize(&reader, fd);
|
||||
for (;;) {
|
||||
if (!HandleRiscVLine(StackLineReader_NextLine(&reader), info)) break;
|
||||
}
|
||||
CpuFeatures_CloseFile(fd);
|
||||
}
|
||||
}
|
||||
|
||||
RiscvInfo GetRiscvInfo(void) {
|
||||
RiscvInfo info = kEmptyRiscvInfo;
|
||||
FillProcCpuInfoData(&info);
|
||||
return info;
|
||||
}
|
||||
|
||||
#endif // defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID)
|
||||
#endif // CPU_FEATURES_ARCH_RISCV
|
@ -37,6 +37,8 @@
|
||||
#include "cpuinfo_ppc.h"
|
||||
#elif defined(CPU_FEATURES_ARCH_S390X)
|
||||
#include "cpuinfo_s390x.h"
|
||||
#elif defined(CPU_FEATURES_ARCH_RISCV)
|
||||
#include "cpuinfo_riscv.h"
|
||||
#endif
|
||||
|
||||
// Design principles
|
||||
@ -210,6 +212,9 @@ DEFINE_ADD_FLAGS(GetPPCFeaturesEnumValue, GetPPCFeaturesEnumName, PPCFeatures,
|
||||
#elif defined(CPU_FEATURES_ARCH_S390X)
|
||||
DEFINE_ADD_FLAGS(GetS390XFeaturesEnumValue, GetS390XFeaturesEnumName, S390XFeatures,
|
||||
S390X_LAST_)
|
||||
#elif defined(CPU_FEATURES_ARCH_RISCV)
|
||||
DEFINE_ADD_FLAGS(GetRiscvFeaturesEnumValue, GetRiscvFeaturesEnumName, RiscvFeatures,
|
||||
RISCV_LAST_)
|
||||
#endif
|
||||
|
||||
// Prints a json string with characters escaping.
|
||||
@ -421,6 +426,12 @@ static Node* CreateTree(void) {
|
||||
AddMapEntry(root, "model", CreateString(strings.type.platform));
|
||||
AddMapEntry(root, "# processors", CreateInt(strings.num_processors));
|
||||
AddFlags(root, &info.features);
|
||||
#elif defined(CPU_FEATURES_ARCH_RISCV)
|
||||
const RiscvInfo info = GetRiscvInfo();
|
||||
AddMapEntry(root, "arch", CreateString("risc-v"));
|
||||
AddMapEntry(root, "vendor", CreateString(info.vendor));
|
||||
AddMapEntry(root, "microarchitecture", CreateString(info.uarch));
|
||||
AddFlags(root, &info.features);
|
||||
#endif
|
||||
return root;
|
||||
}
|
||||
|
Reference in New Issue
Block a user