CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/Common/LoongArchCPUDetect.cpp
Views: 1401
// Copyright (C) 2003 Dolphin Project.12// This program is free software: you can redistribute it and/or modify3// it under the terms of the GNU General Public License as published by4// the Free Software Foundation, version 2.0.56// This program is distributed in the hope that it will be useful,7// but WITHOUT ANY WARRANTY; without even the implied warranty of8// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the9// GNU General Public License 2.0 for more details.1011// A copy of the GPL 2.0 should have been included with the program.12// If not, see http://www.gnu.org/licenses/1314// Official SVN repository and contact information can be found at15// http://code.google.com/p/dolphin-emu/1617#include "ppsspp_config.h"18#if PPSSPP_ARCH(LOONGARCH64)1920#include "ext/cpu_features/include/cpuinfo_loongarch.h"2122#if defined(CPU_FEATURES_OS_LINUX)23#define USE_CPU_FEATURES 124#endif2526#include <cstring>27#include <set>28#include <sstream>29#include <sys/auxv.h>30#include <vector>31#include "Common/Common.h"32#include "Common/CPUDetect.h"33#include "Common/StringUtils.h"34#include "Common/File/FileUtil.h"35#include "Common/Data/Encoding/Utf8.h"3637// Only Linux platforms have /proc/cpuinfo38#if defined(__linux__)39const char procfile[] = "/proc/cpuinfo";40// https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-devices-system-cpu41const char syscpupresentfile[] = "/sys/devices/system/cpu/present";4243class LoongArchCPUInfoParser {44public:45LoongArchCPUInfoParser();4647int ProcessorCount();48int TotalLogicalCount();4950private:51std::vector<std::vector<std::string>> cores_;52};5354LoongArchCPUInfoParser::LoongArchCPUInfoParser() {55std::string procdata, line;56if (!File::ReadSysTextFileToString(Path(procfile), &procdata))57return;5859std::istringstream file(procdata);60int index = -1;61while (std::getline(file, line)) {62if (line.length() == 0) {63index = -1;64} else {65if (index == -1) {66index = (int)cores_.size();67cores_.push_back(std::vector<std::string>());68}69cores_[index].push_back(line);70}71}72}7374int LoongArchCPUInfoParser::ProcessorCount() {75static const char * const marker = "core";76std::set<std::string> coreIndex;77for (auto core : cores_) {78for (auto line : core) {79if (line.find(marker) != line.npos)80coreIndex.insert(line);81}82}8384return (int)coreIndex.size();85}8687int LoongArchCPUInfoParser::TotalLogicalCount() {88std::string presentData, line;89bool presentSuccess = File::ReadSysTextFileToString(Path(syscpupresentfile), &presentData);90if (presentSuccess) {91std::istringstream presentFile(presentData);9293int low, high, found;94std::getline(presentFile, line);95found = sscanf(line.c_str(), "%d-%d", &low, &high);96if (found == 1){97return 1;98}99if (found == 2){100return high - low + 1;101}102}else{103return 1;104}105}106107#endif108109static bool ExtensionSupported(unsigned long v, unsigned int i) {110// https://github.com/torvalds/linux/blob/master/arch/loongarch/include/uapi/asm/hwcap.h111unsigned long mask = 1 << i;112return v & mask;113}114115CPUInfo cpu_info;116117CPUInfo::CPUInfo() {118Detect();119}120121// Detects the various cpu features122void CPUInfo::Detect()123{124// Set some defaults here125HTT = false;126#if PPSSPP_ARCH(LOONGARCH64)127OS64bit = true;128CPU64bit = true;129Mode64bit = true;130#else131OS64bit = false;132CPU64bit = false;133Mode64bit = false;134#endif135vendor = VENDOR_OTHER;136truncate_cpy(brand_string, "Loongson");137truncate_cpy(cpu_string, "Loongson");138#if !defined(__linux__)139num_cores = 1;140logical_cpu_count = 1;141truncate_cpy(brand_string, "Unknown");142truncate_cpy(cpu_string, "Unknown");143#else // __linux__144LoongArchCPUInfoParser parser;145num_cores = parser.ProcessorCount();146logical_cpu_count = parser.TotalLogicalCount() / num_cores;147if (logical_cpu_count <= 0)148logical_cpu_count = 1;149#endif150151unsigned long hwcap = getauxval(AT_HWCAP);152LOONGARCH_CPUCFG = true;153LOONGARCH_LAM = ExtensionSupported(hwcap, 1);154LOONGARCH_UAL = ExtensionSupported(hwcap, 2);155LOONGARCH_FPU = ExtensionSupported(hwcap, 3);156LOONGARCH_LSX = ExtensionSupported(hwcap, 4);157LOONGARCH_LASX = ExtensionSupported(hwcap, 5);158LOONGARCH_CRC32 = ExtensionSupported(hwcap, 6);159LOONGARCH_COMPLEX = ExtensionSupported(hwcap, 7);160LOONGARCH_CRYPTO = ExtensionSupported(hwcap, 8);161LOONGARCH_LVZ = ExtensionSupported(hwcap, 9);162LOONGARCH_LBT_X86 = ExtensionSupported(hwcap, 10);163LOONGARCH_LBT_ARM = ExtensionSupported(hwcap, 11);164LOONGARCH_LBT_MIPS = ExtensionSupported(hwcap, 12);165LOONGARCH_PTW = ExtensionSupported(hwcap, 13);166167#ifdef USE_CPU_FEATURES168cpu_features::LoongArchInfo info = cpu_features::GetLoongArchInfo();169LOONGARCH_CPUCFG = true;170LOONGARCH_LAM = info.features.LAM;171LOONGARCH_UAL = info.features.UAL;172LOONGARCH_FPU = info.features.FPU;173LOONGARCH_LSX = info.features.LSX;174LOONGARCH_LASX = info.features.LASX;175LOONGARCH_CRC32 = info.features.CRC32;176LOONGARCH_COMPLEX = info.features.COMPLEX;177LOONGARCH_CRYPTO = info.features.CRYPTO;178LOONGARCH_LVZ = info.features.LVZ;179LOONGARCH_LBT_X86 = info.features.LBT_X86;180LOONGARCH_LBT_ARM = info.features.LBT_ARM;181LOONGARCH_LBT_MIPS = info.features.LBT_MIPS;182LOONGARCH_PTW = info.features.PTW;183#endif184}185186std::vector<std::string> CPUInfo::Features() {187std::vector<std::string> features;188189struct Flag {190bool &flag;191const char *str;192};193const Flag list[] = {194{ LOONGARCH_CPUCFG, "Identify CPU Features" },195{ LOONGARCH_LAM, "Atomic Memory Access Instructions" },196{ LOONGARCH_UAL, "Non-Aligned Memory Access" },197{ LOONGARCH_FPU, "Basic Floating-Point Instructions" },198{ LOONGARCH_LSX, "Loongson SIMD eXtension" },199{ LOONGARCH_LASX, "Loongson Advanced SIMD eXtension" },200{ LOONGARCH_CRC32, "Cyclic Redundancy Check Instructions" },201{ LOONGARCH_COMPLEX, "Complex Vector Operation Instructions" },202{ LOONGARCH_CRYPTO, "Encryption And Decryption Vector Instructions" },203{ LOONGARCH_LVZ, "Virtualization" },204{ LOONGARCH_LBT_X86, "X86 Binary Translation Extension" },205{ LOONGARCH_LBT_ARM, "ARM Binary Translation Extension" },206{ LOONGARCH_LBT_MIPS, "MIPS Binary Translation Extension" },207{ LOONGARCH_PTW, "Page Table Walker" },208};209210for (auto &item : list) {211if (item.flag) {212features.push_back(item.str);213}214}215216return features;217}218219// Turn the cpu info into a string we can show220std::string CPUInfo::Summarize() {221std::string sum;222if (num_cores == 1)223sum = StringFromFormat("%s, %i core", cpu_string, num_cores);224else225sum = StringFromFormat("%s, %i cores", cpu_string, num_cores);226227auto features = Features();228for (std::string &feature : features) {229sum += ", " + feature;230}231return sum;232}233234#endif // PPSSPP_ARCH(LOONGARCH64)235236237