mirror of
https://github.com/google/cpu_features.git
synced 2025-04-28 07:23:37 +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:
parent
a7ea4a7783
commit
c919e9aa77
28
.github/workflows/riscv_linux_cmake.yml
vendored
Normal file
28
.github/workflows/riscv_linux_cmake.yml
vendored
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
name: RISCV Linux CMake
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
pull_request:
|
||||||
|
schedule:
|
||||||
|
# min hours day(month) month day(week)
|
||||||
|
- cron: '0 0 7,22 * *'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
# Building using the github runner environement directly.
|
||||||
|
make:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
targets: [
|
||||||
|
[riscv32],
|
||||||
|
[riscv64],
|
||||||
|
]
|
||||||
|
fail-fast: false
|
||||||
|
env:
|
||||||
|
TARGET: ${{ matrix.targets[0] }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Build
|
||||||
|
run: make --directory=cmake/ci ${TARGET}_build
|
||||||
|
- name: Test
|
||||||
|
run: make --directory=cmake/ci ${TARGET}_test
|
@ -50,6 +50,7 @@ set(PROCESSOR_IS_AARCH64 FALSE)
|
|||||||
set(PROCESSOR_IS_X86 FALSE)
|
set(PROCESSOR_IS_X86 FALSE)
|
||||||
set(PROCESSOR_IS_POWER FALSE)
|
set(PROCESSOR_IS_POWER FALSE)
|
||||||
set(PROCESSOR_IS_S390X FALSE)
|
set(PROCESSOR_IS_S390X FALSE)
|
||||||
|
set(PROCESSOR_IS_RISCV FALSE)
|
||||||
|
|
||||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips")
|
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips")
|
||||||
set(PROCESSOR_IS_MIPS TRUE)
|
set(PROCESSOR_IS_MIPS TRUE)
|
||||||
@ -63,6 +64,8 @@ elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)")
|
|||||||
set(PROCESSOR_IS_POWER TRUE)
|
set(PROCESSOR_IS_POWER TRUE)
|
||||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(s390x)")
|
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(s390x)")
|
||||||
set(PROCESSOR_IS_S390X TRUE)
|
set(PROCESSOR_IS_S390X TRUE)
|
||||||
|
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^riscv")
|
||||||
|
set(PROCESSOR_IS_RISCV TRUE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
macro(add_cpu_features_headers_and_sources HDRS_LIST_NAME SRCS_LIST_NAME)
|
macro(add_cpu_features_headers_and_sources HDRS_LIST_NAME SRCS_LIST_NAME)
|
||||||
@ -84,6 +87,8 @@ macro(add_cpu_features_headers_and_sources HDRS_LIST_NAME SRCS_LIST_NAME)
|
|||||||
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_ppc.h)
|
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_ppc.h)
|
||||||
elseif(PROCESSOR_IS_S390X)
|
elseif(PROCESSOR_IS_S390X)
|
||||||
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_s390x.h)
|
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_s390x.h)
|
||||||
|
elseif(PROCESSOR_IS_RISCV)
|
||||||
|
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_riscv.h)
|
||||||
else()
|
else()
|
||||||
message(FATAL_ERROR "Unsupported architectures ${CMAKE_SYSTEM_PROCESSOR}")
|
message(FATAL_ERROR "Unsupported architectures ${CMAKE_SYSTEM_PROCESSOR}")
|
||||||
endif()
|
endif()
|
||||||
|
38
README.md
38
README.md
@ -7,12 +7,12 @@ instructions) at runtime.
|
|||||||
|
|
||||||
[comment]: <> (The following lines are generated by "scripts/generate_badges.d" that you can run online https://run.dlang.io/)
|
[comment]: <> (The following lines are generated by "scripts/generate_badges.d" that you can run online https://run.dlang.io/)
|
||||||
|
|
||||||
| Os | amd64 | AArch64 | ARM | MIPS | s390x | POWER |
|
| Os | amd64 | AArch64 | ARM | MIPS | POWER | RISCV | s390x |
|
||||||
| :-- | --: | --: | --: | --: | --: | --: |
|
| :-- | --: | --: | --: | --: | --: | --: | --: |
|
||||||
| Linux | [![][i1a0]][l1a0]<br/>[![][i1a1]][l1a1] | [![][i1b0]][l1b0]<br/>![][d1] | [![][i1c0]][l1c0]<br/>![][d1] | [![][i1d0]][l1d0]<br/>![][d1] | [![][i1e0]][l1e0]<br/>![][d1] | [![][i1f0]][l1f0]<br/>![][d1] |
|
| Linux | [![][i1a0]][l1a0]<br/>[![][i1a1]][l1a1] | [![][i1b0]][l1b0]<br/>![][d1] | [![][i1c0]][l1c0]<br/>![][d1] | [![][i1d0]][l1d0]<br/>![][d1] | [![][i1e0]][l1e0]<br/>![][d1] | [![][i1f0]][l1f0]<br/>![][d1] | [![][i1g0]][l1g0]<br/>![][d1] |
|
||||||
| FreeBSD | [![][i2a0]][l2a0]<br/>![][d1] | ![][d0]<br/>![][d1] | ![][d0]<br/>![][d1] | ![][d0]<br/>![][d1] | ![][d0]<br/>![][d1] | ![][d0]<br/>![][d1] |
|
| FreeBSD | [![][i2a0]][l2a0]<br/>![][d1] | ![][d0]<br/>![][d1] | ![][d0]<br/>![][d1] | ![][d0]<br/>![][d1] | ![][d0]<br/>![][d1] | ![][d0]<br/>![][d1] | ![][d0]<br/>![][d1] |
|
||||||
| MacOS | [![][i3a0]][l3a0]<br/>![][d1] | ![][d0]<br/>![][d1] | ![][d0]<br/>![][d1] | ![][d0]<br/>![][d1] | ![][d0]<br/>![][d1] | ![][d0]<br/>![][d1] |
|
| MacOS | [![][i3a0]][l3a0]<br/>![][d1] | ![][d0]<br/>![][d1] | ![][d0]<br/>![][d1] | ![][d0]<br/>![][d1] | ![][d0]<br/>![][d1] | ![][d0]<br/>![][d1] | ![][d0]<br/>![][d1] |
|
||||||
| Windows | [![][i4a0]][l4a0]<br/>![][d1] | ![][d0]<br/>![][d1] | ![][d0]<br/>![][d1] | ![][d0]<br/>![][d1] | ![][d0]<br/>![][d1] | ![][d0]<br/>![][d1] |
|
| Windows | [![][i4a0]][l4a0]<br/>![][d1] | ![][d0]<br/>![][d1] | ![][d0]<br/>![][d1] | ![][d0]<br/>![][d1] | ![][d0]<br/>![][d1] | ![][d0]<br/>![][d1] | ![][d0]<br/>![][d1] |
|
||||||
|
|
||||||
[d0]: https://img.shields.io/badge/CMake-N%2FA-lightgrey
|
[d0]: https://img.shields.io/badge/CMake-N%2FA-lightgrey
|
||||||
[d1]: https://img.shields.io/badge/Bazel-N%2FA-lightgrey
|
[d1]: https://img.shields.io/badge/Bazel-N%2FA-lightgrey
|
||||||
@ -21,8 +21,9 @@ instructions) at runtime.
|
|||||||
[i1b0]: https://img.shields.io/github/workflow/status/google/cpu_features/AArch64%20Linux%20CMake/main?label=CMake
|
[i1b0]: https://img.shields.io/github/workflow/status/google/cpu_features/AArch64%20Linux%20CMake/main?label=CMake
|
||||||
[i1c0]: https://img.shields.io/github/workflow/status/google/cpu_features/ARM%20Linux%20CMake/main?label=CMake
|
[i1c0]: https://img.shields.io/github/workflow/status/google/cpu_features/ARM%20Linux%20CMake/main?label=CMake
|
||||||
[i1d0]: https://img.shields.io/github/workflow/status/google/cpu_features/MIPS%20Linux%20CMake/main?label=CMake
|
[i1d0]: https://img.shields.io/github/workflow/status/google/cpu_features/MIPS%20Linux%20CMake/main?label=CMake
|
||||||
[i1e0]: https://img.shields.io/github/workflow/status/google/cpu_features/s390x%20Linux%20CMake/main?label=CMake
|
[i1e0]: https://img.shields.io/github/workflow/status/google/cpu_features/POWER%20Linux%20CMake/main?label=CMake
|
||||||
[i1f0]: https://img.shields.io/github/workflow/status/google/cpu_features/POWER%20Linux%20CMake/main?label=CMake
|
[i1f0]: https://img.shields.io/github/workflow/status/google/cpu_features/RISCV%20Linux%20CMake/main?label=CMake
|
||||||
|
[i1g0]: https://img.shields.io/github/workflow/status/google/cpu_features/s390x%20Linux%20CMake/main?label=CMake
|
||||||
[i2a0]: https://img.shields.io/github/workflow/status/google/cpu_features/amd64%20FreeBSD%20CMake/main?label=CMake
|
[i2a0]: https://img.shields.io/github/workflow/status/google/cpu_features/amd64%20FreeBSD%20CMake/main?label=CMake
|
||||||
[i3a0]: https://img.shields.io/github/workflow/status/google/cpu_features/amd64%20MacOS%20CMake/main?label=CMake
|
[i3a0]: https://img.shields.io/github/workflow/status/google/cpu_features/amd64%20MacOS%20CMake/main?label=CMake
|
||||||
[i4a0]: https://img.shields.io/github/workflow/status/google/cpu_features/amd64%20Windows%20CMake/main?label=CMake
|
[i4a0]: https://img.shields.io/github/workflow/status/google/cpu_features/amd64%20Windows%20CMake/main?label=CMake
|
||||||
@ -31,8 +32,9 @@ instructions) at runtime.
|
|||||||
[l1b0]: https://github.com/google/cpu_features/actions/workflows/aarch64_linux_cmake.yml
|
[l1b0]: https://github.com/google/cpu_features/actions/workflows/aarch64_linux_cmake.yml
|
||||||
[l1c0]: https://github.com/google/cpu_features/actions/workflows/arm_linux_cmake.yml
|
[l1c0]: https://github.com/google/cpu_features/actions/workflows/arm_linux_cmake.yml
|
||||||
[l1d0]: https://github.com/google/cpu_features/actions/workflows/mips_linux_cmake.yml
|
[l1d0]: https://github.com/google/cpu_features/actions/workflows/mips_linux_cmake.yml
|
||||||
[l1e0]: https://github.com/google/cpu_features/actions/workflows/s390x_linux_cmake.yml
|
[l1e0]: https://github.com/google/cpu_features/actions/workflows/power_linux_cmake.yml
|
||||||
[l1f0]: https://github.com/google/cpu_features/actions/workflows/power_linux_cmake.yml
|
[l1f0]: https://github.com/google/cpu_features/actions/workflows/riscv_linux_cmake.yml
|
||||||
|
[l1g0]: https://github.com/google/cpu_features/actions/workflows/s390x_linux_cmake.yml
|
||||||
[l2a0]: https://github.com/google/cpu_features/actions/workflows/amd64_freebsd_cmake.yml
|
[l2a0]: https://github.com/google/cpu_features/actions/workflows/amd64_freebsd_cmake.yml
|
||||||
[l3a0]: https://github.com/google/cpu_features/actions/workflows/amd64_macos_cmake.yml
|
[l3a0]: https://github.com/google/cpu_features/actions/workflows/amd64_macos_cmake.yml
|
||||||
[l4a0]: https://github.com/google/cpu_features/actions/workflows/amd64_windows_cmake.yml
|
[l4a0]: https://github.com/google/cpu_features/actions/workflows/amd64_windows_cmake.yml
|
||||||
@ -176,14 +178,14 @@ flags : aes,avx,cx16,smx,sse4_1,sse4_2,ssse3
|
|||||||
<a name="support"></a>
|
<a name="support"></a>
|
||||||
## What's supported
|
## What's supported
|
||||||
|
|
||||||
| | x86³ | AArch64 | ARM | MIPS⁴ | s390x | POWER |
|
| | x86³ | AArch64 | ARM | MIPS⁴ | POWER | RISCV | s390x |
|
||||||
|---------|:----:|:-------:|:-------:|:-------:|:-------:|:-------:|
|
|---------|:----:|:-------:|:-------:|:-------:|:-------:|:-------:|:-------:|
|
||||||
| Linux | yes² | yes¹ | yes¹ | yes¹ | yes¹ | yes¹ |
|
| Linux | yes² | yes¹ | yes¹ | yes¹ | yes¹ | yes¹ | yes¹ |
|
||||||
| FreeBSD | yes² | not yet | not yet | not yet | not yet | not yet |
|
| FreeBSD | yes² | not yet | not yet | not yet | not yet | N/A | not yet |
|
||||||
| MacOs | yes² | not yet | N/A | N/A | no | no |
|
| MacOs | yes² | not yet | N/A | N/A | no | N/A | no |
|
||||||
| Windows | yes² | not yet | not yet | N/A | N/A | N/A |
|
| Windows | yes² | not yet | not yet | N/A | N/A | N/A | N/A |
|
||||||
| Android | yes² | yes¹ | yes¹ | yes¹ | N/A | N/A |
|
| Android | yes² | yes¹ | yes¹ | yes¹ | N/A | N/A | N/A |
|
||||||
| iOS | N/A | not yet | not yet | N/A | N/A | N/A |
|
| iOS | N/A | not yet | not yet | N/A | N/A | N/A | N/A |
|
||||||
|
|
||||||
1. **Features revealed from Linux.** We gather data from several sources
|
1. **Features revealed from Linux.** We gather data from several sources
|
||||||
depending on availability:
|
depending on availability:
|
||||||
|
@ -55,6 +55,8 @@ help:
|
|||||||
@echo -e "\t\t${BOLD}ppc${RESET} (bootlin toolchain)"
|
@echo -e "\t\t${BOLD}ppc${RESET} (bootlin toolchain)"
|
||||||
@echo -e "\t\t${BOLD}ppc64${RESET} (bootlin toolchain)"
|
@echo -e "\t\t${BOLD}ppc64${RESET} (bootlin toolchain)"
|
||||||
@echo -e "\t\t${BOLD}ppc64le${RESET} (bootlin toolchain)"
|
@echo -e "\t\t${BOLD}ppc64le${RESET} (bootlin toolchain)"
|
||||||
|
@echo -e "\t\t${BOLD}riscv32${RESET} (bootlin toolchain)"
|
||||||
|
@echo -e "\t\t${BOLD}riscv64${RESET} (bootlin toolchain)"
|
||||||
@echo -e "\t\t${BOLD}s390x${RESET} (bootlin toolchain)"
|
@echo -e "\t\t${BOLD}s390x${RESET} (bootlin toolchain)"
|
||||||
@echo
|
@echo
|
||||||
@echo -e "\tWith ${BOLD}<toolchain_stage>${RESET}:"
|
@echo -e "\tWith ${BOLD}<toolchain_stage>${RESET}:"
|
||||||
@ -154,6 +156,7 @@ TOOLCHAIN_TARGETS = \
|
|||||||
aarch64-linux-gnu aarch64_be-linux-gnu \
|
aarch64-linux-gnu aarch64_be-linux-gnu \
|
||||||
mips32 mips32el mips64 mips64el \
|
mips32 mips32el mips64 mips64el \
|
||||||
ppc ppc64 ppc64le \
|
ppc ppc64 ppc64le \
|
||||||
|
riscv32 riscv64 \
|
||||||
s390x
|
s390x
|
||||||
TOOLCHAIN_STAGES = env devel build test
|
TOOLCHAIN_STAGES = env devel build test
|
||||||
define toolchain-stage-target =
|
define toolchain-stage-target =
|
||||||
|
70
include/cpuinfo_riscv.h
Normal file
70
include/cpuinfo_riscv.h
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
#ifndef CPU_FEATURES_INCLUDE_CPUINFO_RISCV_H_
|
||||||
|
#define CPU_FEATURES_INCLUDE_CPUINFO_RISCV_H_
|
||||||
|
|
||||||
|
#include "cpu_features_cache_info.h"
|
||||||
|
#include "cpu_features_macros.h"
|
||||||
|
|
||||||
|
#if !defined(CPU_FEATURES_ARCH_RISCV)
|
||||||
|
#error "Including cpuinfo_riscv.h from a non-riscv target."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CPU_FEATURES_START_CPP_NAMESPACE
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
// Base
|
||||||
|
int RV32I : 1; // Base Integer Instruction Set, 32-bit
|
||||||
|
int RV64I : 1; // Base Integer Instruction Set, 64-bit
|
||||||
|
|
||||||
|
// Extension
|
||||||
|
int M : 1; // Standard Extension for Integer Multiplication/Division
|
||||||
|
int A : 1; // Standard Extension for Atomic Instructions
|
||||||
|
int F : 1; // Standard Extension for Single-Precision Floating-Point
|
||||||
|
int D : 1; // Standard Extension for Double-Precision Floating-Point
|
||||||
|
int Q : 1; // Standard Extension for Quad-Precision Floating-Point
|
||||||
|
int C : 1; // Standard Extension for Compressed Instructions
|
||||||
|
int Zicsr : 1; // Control and Status Register (CSR)
|
||||||
|
int Zifencei : 1; // Instruction-Fetch Fence
|
||||||
|
} RiscvFeatures;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
RiscvFeatures features;
|
||||||
|
char uarch[64]; // 0 terminated string
|
||||||
|
char vendor[64]; // 0 terminated string
|
||||||
|
} RiscvInfo;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
RISCV_RV32I,
|
||||||
|
RISCV_RV64I,
|
||||||
|
RISCV_M,
|
||||||
|
RISCV_A,
|
||||||
|
RISCV_F,
|
||||||
|
RISCV_D,
|
||||||
|
RISCV_Q,
|
||||||
|
RISCV_C,
|
||||||
|
RISCV_Zicsr,
|
||||||
|
RISCV_Zifencei,
|
||||||
|
RISCV_LAST_,
|
||||||
|
} RiscvFeaturesEnum;
|
||||||
|
|
||||||
|
RiscvInfo GetRiscvInfo(void);
|
||||||
|
int GetRiscvFeaturesEnumValue(const RiscvFeatures* features,
|
||||||
|
RiscvFeaturesEnum value);
|
||||||
|
const char* GetRiscvFeaturesEnumName(RiscvFeaturesEnum);
|
||||||
|
|
||||||
|
CPU_FEATURES_END_CPP_NAMESPACE
|
||||||
|
|
||||||
|
#endif // CPU_FEATURES_INCLUDE_CPUINFO_RISCV_H_
|
@ -205,15 +205,15 @@ CPU_FEATURES_START_CPP_NAMESPACE
|
|||||||
#define HWCAP_S390_SIE 4194304
|
#define HWCAP_S390_SIE 4194304
|
||||||
|
|
||||||
// https://elixir.bootlin.com/linux/latest/source/arch/riscv/include/uapi/asm/hwcap.h
|
// https://elixir.bootlin.com/linux/latest/source/arch/riscv/include/uapi/asm/hwcap.h
|
||||||
#define RISCV_HWCAP_A (1UL << ('A' - 'A'))
|
#define RISCV_HWCAP_32 0x32
|
||||||
#define RISCV_HWCAP_C (1UL << ('C' - 'A'))
|
#define RISCV_HWCAP_64 0x64
|
||||||
#define RISCV_HWCAP_D (1UL << ('D' - 'A'))
|
#define RISCV_HWCAP_128 0x128
|
||||||
#define RISCV_HWCAP_E (1UL << ('E' - 'A'))
|
|
||||||
#define RISCV_HWCAP_F (1UL << ('F' - 'A'))
|
|
||||||
#define RISCV_HWCAP_I (1UL << ('I' - 'A'))
|
|
||||||
#define RISCV_HWCAP_M (1UL << ('M' - 'A'))
|
#define RISCV_HWCAP_M (1UL << ('M' - 'A'))
|
||||||
#define RISCV_HWCAP_V (1UL << ('V' - 'A'))
|
#define RISCV_HWCAP_A (1UL << ('A' - 'A'))
|
||||||
|
#define RISCV_HWCAP_F (1UL << ('F' - 'A'))
|
||||||
|
#define RISCV_HWCAP_D (1UL << ('D' - 'A'))
|
||||||
#define RISCV_HWCAP_Q (1UL << ('Q' - 'A'))
|
#define RISCV_HWCAP_Q (1UL << ('Q' - 'A'))
|
||||||
|
#define RISCV_HWCAP_C (1UL << ('C' - 'A'))
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned long hwcaps;
|
unsigned long hwcaps;
|
||||||
|
@ -18,8 +18,9 @@ enum Cpu
|
|||||||
AArch64,
|
AArch64,
|
||||||
ARM,
|
ARM,
|
||||||
MIPS,
|
MIPS,
|
||||||
s390x,
|
|
||||||
POWER,
|
POWER,
|
||||||
|
RISCV,
|
||||||
|
s390x,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Os
|
enum Os
|
||||||
|
@ -162,6 +162,14 @@ function expand_bootlin_config() {
|
|||||||
local -r TOOLCHAIN_URL="https://toolchains.bootlin.com/downloads/releases/toolchains/powerpc-440fp/tarballs/powerpc-440fp--glibc--stable-2021.11-1.tar.bz2"
|
local -r TOOLCHAIN_URL="https://toolchains.bootlin.com/downloads/releases/toolchains/powerpc-440fp/tarballs/powerpc-440fp--glibc--stable-2021.11-1.tar.bz2"
|
||||||
local -r GCC_PREFIX="powerpc"
|
local -r GCC_PREFIX="powerpc"
|
||||||
;;
|
;;
|
||||||
|
"riscv32")
|
||||||
|
local -r TOOLCHAIN_URL="https://toolchains.bootlin.com/downloads/releases/toolchains/riscv32-ilp32d/tarballs/riscv32-ilp32d--glibc--bleeding-edge-2022.08-1.tar.bz2"
|
||||||
|
local -r GCC_PREFIX="riscv32"
|
||||||
|
;;
|
||||||
|
"riscv64")
|
||||||
|
local -r TOOLCHAIN_URL="https://toolchains.bootlin.com/downloads/releases/toolchains/riscv64-lp64d/tarballs/riscv64-lp64d--glibc--stable-2022.08-1.tar.bz2"
|
||||||
|
local -r GCC_PREFIX="riscv64"
|
||||||
|
;;
|
||||||
"s390x")
|
"s390x")
|
||||||
local -r TOOLCHAIN_URL="https://toolchains.bootlin.com/downloads/releases/toolchains/s390x-z13/tarballs/s390x-z13--glibc--stable-2022.08-1.tar.bz2"
|
local -r TOOLCHAIN_URL="https://toolchains.bootlin.com/downloads/releases/toolchains/s390x-z13/tarballs/s390x-z13--glibc--stable-2022.08-1.tar.bz2"
|
||||||
local -r GCC_PREFIX="s390x"
|
local -r GCC_PREFIX="s390x"
|
||||||
@ -362,6 +370,7 @@ DESCRIPTION
|
|||||||
\t\tmips64 mips64el (codespace)
|
\t\tmips64 mips64el (codespace)
|
||||||
\t\tppc (bootlin)
|
\t\tppc (bootlin)
|
||||||
\t\tppc64 ppc64le (bootlin)
|
\t\tppc64 ppc64le (bootlin)
|
||||||
|
\t\triscv32 riscv64 (bootlin)
|
||||||
\t\ts390x (bootlin)
|
\t\ts390x (bootlin)
|
||||||
|
|
||||||
OPTIONS
|
OPTIONS
|
||||||
@ -448,6 +457,12 @@ function main() {
|
|||||||
ppc)
|
ppc)
|
||||||
expand_bootlin_config
|
expand_bootlin_config
|
||||||
declare -r QEMU_ARCH=ppc ;;
|
declare -r QEMU_ARCH=ppc ;;
|
||||||
|
riscv32)
|
||||||
|
expand_bootlin_config
|
||||||
|
declare -r QEMU_ARCH=riscv32 ;;
|
||||||
|
riscv64)
|
||||||
|
expand_bootlin_config
|
||||||
|
declare -r QEMU_ARCH=riscv64 ;;
|
||||||
s390x)
|
s390x)
|
||||||
expand_bootlin_config
|
expand_bootlin_config
|
||||||
declare -r QEMU_ARCH=s390x ;;
|
declare -r QEMU_ARCH=s390x ;;
|
||||||
|
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"
|
#include "cpuinfo_ppc.h"
|
||||||
#elif defined(CPU_FEATURES_ARCH_S390X)
|
#elif defined(CPU_FEATURES_ARCH_S390X)
|
||||||
#include "cpuinfo_s390x.h"
|
#include "cpuinfo_s390x.h"
|
||||||
|
#elif defined(CPU_FEATURES_ARCH_RISCV)
|
||||||
|
#include "cpuinfo_riscv.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Design principles
|
// Design principles
|
||||||
@ -210,6 +212,9 @@ DEFINE_ADD_FLAGS(GetPPCFeaturesEnumValue, GetPPCFeaturesEnumName, PPCFeatures,
|
|||||||
#elif defined(CPU_FEATURES_ARCH_S390X)
|
#elif defined(CPU_FEATURES_ARCH_S390X)
|
||||||
DEFINE_ADD_FLAGS(GetS390XFeaturesEnumValue, GetS390XFeaturesEnumName, S390XFeatures,
|
DEFINE_ADD_FLAGS(GetS390XFeaturesEnumValue, GetS390XFeaturesEnumName, S390XFeatures,
|
||||||
S390X_LAST_)
|
S390X_LAST_)
|
||||||
|
#elif defined(CPU_FEATURES_ARCH_RISCV)
|
||||||
|
DEFINE_ADD_FLAGS(GetRiscvFeaturesEnumValue, GetRiscvFeaturesEnumName, RiscvFeatures,
|
||||||
|
RISCV_LAST_)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Prints a json string with characters escaping.
|
// Prints a json string with characters escaping.
|
||||||
@ -421,6 +426,12 @@ static Node* CreateTree(void) {
|
|||||||
AddMapEntry(root, "model", CreateString(strings.type.platform));
|
AddMapEntry(root, "model", CreateString(strings.type.platform));
|
||||||
AddMapEntry(root, "# processors", CreateInt(strings.num_processors));
|
AddMapEntry(root, "# processors", CreateInt(strings.num_processors));
|
||||||
AddFlags(root, &info.features);
|
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
|
#endif
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
@ -96,3 +96,10 @@ if(PROCESSOR_IS_S390X)
|
|||||||
target_link_libraries(cpuinfo_s390x_test all_libraries)
|
target_link_libraries(cpuinfo_s390x_test all_libraries)
|
||||||
add_test(NAME cpuinfo_s390x_test COMMAND cpuinfo_s390x_test)
|
add_test(NAME cpuinfo_s390x_test COMMAND cpuinfo_s390x_test)
|
||||||
endif()
|
endif()
|
||||||
|
##------------------------------------------------------------------------------
|
||||||
|
## cpuinfo_riscv_test
|
||||||
|
if(PROCESSOR_IS_RISCV)
|
||||||
|
add_executable(cpuinfo_riscv_test cpuinfo_riscv_test.cc ../src/impl_riscv_linux.c)
|
||||||
|
target_link_libraries(cpuinfo_riscv_test all_libraries)
|
||||||
|
add_test(NAME cpuinfo_riscv_test COMMAND cpuinfo_riscv_test)
|
||||||
|
endif()
|
||||||
|
156
test/cpuinfo_riscv_test.cc
Normal file
156
test/cpuinfo_riscv_test.cc
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
// 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 "cpuinfo_riscv.h"
|
||||||
|
|
||||||
|
#include "filesystem_for_testing.h"
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
#include "hwcaps_for_testing.h"
|
||||||
|
|
||||||
|
namespace cpu_features {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
TEST(CpuinfoRiscvTest, Sipeed_Lichee_RV_FromCpuInfo) {
|
||||||
|
ResetHwcaps();
|
||||||
|
auto& fs = GetEmptyFilesystem();
|
||||||
|
fs.CreateFile("/proc/cpuinfo", R"(processor : 0
|
||||||
|
hart : 0
|
||||||
|
isa : rv64imafdc
|
||||||
|
mmu : sv39
|
||||||
|
uarch : thead,c906)");
|
||||||
|
const auto info = GetRiscvInfo();
|
||||||
|
EXPECT_STREQ(info.uarch, "c906");
|
||||||
|
EXPECT_STREQ(info.vendor, "thead");
|
||||||
|
|
||||||
|
EXPECT_FALSE(info.features.RV32I);
|
||||||
|
EXPECT_TRUE(info.features.RV64I);
|
||||||
|
EXPECT_TRUE(info.features.M);
|
||||||
|
EXPECT_TRUE(info.features.A);
|
||||||
|
EXPECT_TRUE(info.features.F);
|
||||||
|
EXPECT_TRUE(info.features.D);
|
||||||
|
EXPECT_FALSE(info.features.Q);
|
||||||
|
EXPECT_TRUE(info.features.C);
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://github.com/ThomasKaiser/sbc-bench/blob/284e82b016ec1beeac42a5fcbe556b670f68441a/results/Kendryte-K510-4.17.0.cpuinfo
|
||||||
|
TEST(CpuinfoRiscvTest, Kendryte_K510_FromCpuInfo) {
|
||||||
|
ResetHwcaps();
|
||||||
|
auto& fs = GetEmptyFilesystem();
|
||||||
|
fs.CreateFile("/proc/cpuinfo", R"(
|
||||||
|
hart : 0
|
||||||
|
isa : rv64i2p0m2p0a2p0f2p0d2p0c2p0xv5-0p0
|
||||||
|
mmu : sv39
|
||||||
|
|
||||||
|
hart : 1
|
||||||
|
isa : rv64i2p0m2p0a2p0f2p0d2p0c2p0xv5-0p0
|
||||||
|
mmu : sv39");
|
||||||
|
const auto info = GetRiscvInfo();
|
||||||
|
EXPECT_STREQ(info.uarch, "");
|
||||||
|
EXPECT_STREQ(info.vendor, "");
|
||||||
|
|
||||||
|
EXPECT_FALSE(info.features.RV32I);
|
||||||
|
EXPECT_TRUE(info.features.RV64I);
|
||||||
|
EXPECT_TRUE(info.features.M);
|
||||||
|
EXPECT_TRUE(info.features.A);
|
||||||
|
EXPECT_TRUE(info.features.F);
|
||||||
|
EXPECT_TRUE(info.features.D);
|
||||||
|
EXPECT_FALSE(info.features.Q);
|
||||||
|
EXPECT_TRUE(info.features.C);
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://github.com/ThomasKaiser/sbc-bench/blob/284e82b016ec1beeac42a5fcbe556b670f68441a/results/T-Head-C910-5.10.4.cpuinfo
|
||||||
|
TEST(CpuinfoRiscvTest, T_Head_C910_FromCpuInfo) {
|
||||||
|
ResetHwcaps();
|
||||||
|
auto& fs = GetEmptyFilesystem();
|
||||||
|
fs.CreateFile("/proc/cpuinfo", R"(
|
||||||
|
processor : 0
|
||||||
|
hart : 0
|
||||||
|
isa : rv64imafdcsu
|
||||||
|
mmu : sv39
|
||||||
|
cpu-freq : 1.2Ghz
|
||||||
|
cpu-icache : 64KB
|
||||||
|
cpu-dcache : 64KB
|
||||||
|
cpu-l2cache : 2MB
|
||||||
|
cpu-tlb : 1024 4-ways
|
||||||
|
cpu-cacheline : 64Bytes
|
||||||
|
cpu-vector : 0.7.1
|
||||||
|
|
||||||
|
processor : 1
|
||||||
|
hart : 1
|
||||||
|
isa : rv64imafdcsu
|
||||||
|
mmu : sv39
|
||||||
|
cpu-freq : 1.2Ghz
|
||||||
|
cpu-icache : 64KB
|
||||||
|
cpu-dcache : 64KB
|
||||||
|
cpu-l2cache : 2MB
|
||||||
|
cpu-tlb : 1024 4-ways
|
||||||
|
cpu-cacheline : 64Bytes
|
||||||
|
cpu-vector : 0.7.1");
|
||||||
|
const auto info = GetRiscvInfo();
|
||||||
|
EXPECT_STREQ(info.uarch, "");
|
||||||
|
EXPECT_STREQ(info.vendor, "");
|
||||||
|
|
||||||
|
EXPECT_FALSE(info.features.RV32I);
|
||||||
|
EXPECT_TRUE(info.features.RV64I);
|
||||||
|
EXPECT_TRUE(info.features.M);
|
||||||
|
EXPECT_TRUE(info.features.A);
|
||||||
|
EXPECT_TRUE(info.features.F);
|
||||||
|
EXPECT_TRUE(info.features.D);
|
||||||
|
EXPECT_FALSE(info.features.Q);
|
||||||
|
EXPECT_TRUE(info.features.C);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(CpuinfoRiscvTest, UnknownFromCpuInfo) {
|
||||||
|
ResetHwcaps();
|
||||||
|
auto& fs = GetEmptyFilesystem();
|
||||||
|
fs.CreateFile("/proc/cpuinfo", R"(
|
||||||
|
processor : 0
|
||||||
|
hart : 2
|
||||||
|
isa : rv64imafdc
|
||||||
|
mmu : sv39
|
||||||
|
uarch : sifive,bullet0
|
||||||
|
|
||||||
|
processor : 1
|
||||||
|
hart : 1
|
||||||
|
isa : rv64imafdc
|
||||||
|
mmu : sv39
|
||||||
|
uarch : sifive,bullet0
|
||||||
|
|
||||||
|
processor : 2
|
||||||
|
hart : 3
|
||||||
|
isa : rv64imafdc
|
||||||
|
mmu : sv39
|
||||||
|
uarch : sifive,bullet0
|
||||||
|
|
||||||
|
processor : 3
|
||||||
|
hart : 4
|
||||||
|
isa : rv64imafdc
|
||||||
|
mmu : sv39
|
||||||
|
uarch : sifive,bullet0)");
|
||||||
|
const auto info = GetRiscvInfo();
|
||||||
|
EXPECT_STREQ(info.uarch, "bullet0");
|
||||||
|
EXPECT_STREQ(info.vendor, "sifive");
|
||||||
|
|
||||||
|
EXPECT_FALSE(info.features.RV32I);
|
||||||
|
EXPECT_TRUE(info.features.RV64I);
|
||||||
|
EXPECT_TRUE(info.features.M);
|
||||||
|
EXPECT_TRUE(info.features.A);
|
||||||
|
EXPECT_TRUE(info.features.F);
|
||||||
|
EXPECT_TRUE(info.features.D);
|
||||||
|
EXPECT_FALSE(info.features.Q);
|
||||||
|
EXPECT_TRUE(info.features.C);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
} // namespace cpu_features
|
Loading…
x
Reference in New Issue
Block a user