diff --git a/src/config.c b/src/config.c index 8bd8d2a..c6ff242 100644 --- a/src/config.c +++ b/src/config.c @@ -20,6 +20,7 @@ #include "platform.h" #include "config.h" #include "util.h" +#include "cpu.h" #include "input/evdev.h" #include "audio/audio.h" @@ -353,23 +354,15 @@ void config_parse(int argc, char* argv[], PCONFIGURATION config) { if (has_fast_aes()) { config->stream.encryptionFlags = ENCFLG_ALL; } + else if (has_slow_aes()) { + // For extremely slow CPUs, opt out of audio encryption + config->stream.encryptionFlags = ENCFLG_NONE; + printf("Disabling encryption on low performance CPU\n"); + } else { config->stream.encryptionFlags = ENCFLG_AUDIO; } -#ifdef __arm__ - char cpuinfo[4096] = {}; - if (read_file("/proc/cpuinfo", cpuinfo, sizeof(cpuinfo) - 1) > 0) { - // If this is a ARMv6 CPU (like the Pi 1), we'll assume it's not - // powerful enough to handle audio encryption. The Pi 1 could - // barely handle Opus decoding alone. - if (strstr(cpuinfo, "ARMv6")) { - config->stream.encryptionFlags = ENCFLG_NONE; - printf("Disabling encryption on low performance CPU\n"); - } - } -#endif - config->debug_level = 0; config->platform = "auto"; config->app = "Steam"; diff --git a/src/cpu.c b/src/cpu.c new file mode 100644 index 0000000..914ceaf --- /dev/null +++ b/src/cpu.c @@ -0,0 +1,120 @@ +/* + * This file is part of Moonlight Embedded. + * + * Moonlight is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Moonlight is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Moonlight; if not, see . + */ + +#include "cpu.h" +#include "util.h" + +#include +#include +#include + +#ifdef HAVE_GETAUXVAL +#include + +#ifndef HWCAP2_AES +#define HWCAP2_AES (1 << 0) +#endif +#endif + +#if defined(__linux__) && defined(__riscv) +#if __has_include() +#include +#else +#include + +#if __has_include() +#include +#include +#else +#define __NR_riscv_hwprobe 258 +struct riscv_hwprobe { + int64_t key; + uint64_t value; +}; +#define RISCV_HWPROBE_KEY_IMA_EXT_0 4 +#endif + +// RISC-V Scalar AES [E]ncryption and [D]ecryption +#ifndef RISCV_HWPROBE_EXT_ZKND +#define RISCV_HWPROBE_EXT_ZKND (1 << 11) +#define RISCV_HWPROBE_EXT_ZKNE (1 << 12) +#endif + +// RISC-V Vector AES +#ifndef RISCV_HWPROBE_EXT_ZVKNED +#define RISCV_HWPROBE_EXT_ZVKNED (1 << 21) +#endif + +static int __riscv_hwprobe(struct riscv_hwprobe *pairs, size_t pair_count, + size_t cpu_count, unsigned long *cpus, + unsigned int flags) +{ + return syscall(__NR_riscv_hwprobe, pairs, pair_count, cpu_count, cpus, flags); +} + +#endif +#endif + +bool has_fast_aes() { +#if defined(HAVE_GETAUXVAL) && (defined(__arm__) || defined(__aarch64__)) + #if defined(__arm__) && defined(HWCAP2_AES) + return !!(getauxval(AT_HWCAP2) & HWCAP2_AES); + #elif defined(__aarch64__) + return !!(getauxval(AT_HWCAP) & HWCAP_AES); + #else + return false; + #endif +#elif defined(HAVE_BICS_AES) + return __builtin_cpu_supports("aes"); +#elif defined(__BUILTIN_CPU_SUPPORTS__) && defined(__powerpc__) + return __builtin_cpu_supports("vcrypto"); +#elif defined(__linux__) && defined(__riscv) + struct riscv_hwprobe pairs[1] = { + { RISCV_HWPROBE_KEY_IMA_EXT_0, 0 }, + }; + + // If this syscall is not implemented, we'll get -ENOSYS + // and the value field will remain zero. + __riscv_hwprobe(pairs, sizeof(pairs) / sizeof(struct riscv_hwprobe), 0, NULL, 0); + + return (pairs[0].value & (RISCV_HWPROBE_EXT_ZKNE | RISCV_HWPROBE_EXT_ZKND)) == + (RISCV_HWPROBE_EXT_ZKNE | RISCV_HWPROBE_EXT_ZKND) || + (pairs[0].value & RISCV_HWPROBE_EXT_ZVKNED); +#elif __SIZEOF_SIZE_T__ == 4 + #warning Unknown 32-bit platform. Assuming AES is slow on this CPU. + return false; +#else + #warning Unknown 64-bit platform. Assuming AES is fast on this CPU. + return true; +#endif +} + +bool has_slow_aes() { +#ifdef __arm__ + char cpuinfo[4096] = {}; + if (read_file("/proc/cpuinfo", cpuinfo, sizeof(cpuinfo) - 1) > 0) { + // If this is a ARMv6 CPU (like the Pi 1), we'll assume it's not + // powerful enough to handle audio encryption. The Pi 1 could + // barely handle Opus decoding alone. + if (strstr(cpuinfo, "ARMv6")) { + return true; + } + } +#endif + + return false; +} \ No newline at end of file diff --git a/src/cpu.h b/src/cpu.h new file mode 100644 index 0000000..8e00ba6 --- /dev/null +++ b/src/cpu.h @@ -0,0 +1,21 @@ +/* + * This file is part of Moonlight Embedded. + * + * Moonlight is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Moonlight is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Moonlight; if not, see . + */ + +#include + +bool has_fast_aes(void); +bool has_slow_aes(void); diff --git a/src/util.c b/src/util.c index f9dd8e3..04c4b96 100644 --- a/src/util.c +++ b/src/util.c @@ -26,53 +26,6 @@ #include #include -#ifdef HAVE_GETAUXVAL -#include - -#ifndef HWCAP2_AES -#define HWCAP2_AES (1 << 0) -#endif -#endif - -#if defined(__linux__) && defined(__riscv) -#if __has_include() -#include -#else -#include - -#if __has_include() -#include -#include -#else -#define __NR_riscv_hwprobe 258 -struct riscv_hwprobe { - int64_t key; - uint64_t value; -}; -#define RISCV_HWPROBE_KEY_IMA_EXT_0 4 -#endif - -// RISC-V Scalar AES [E]ncryption and [D]ecryption -#ifndef RISCV_HWPROBE_EXT_ZKND -#define RISCV_HWPROBE_EXT_ZKND (1 << 11) -#define RISCV_HWPROBE_EXT_ZKNE (1 << 12) -#endif - -// RISC-V Vector AES -#ifndef RISCV_HWPROBE_EXT_ZVKNED -#define RISCV_HWPROBE_EXT_ZVKNED (1 << 21) -#endif - -static int __riscv_hwprobe(struct riscv_hwprobe *pairs, size_t pair_count, - size_t cpu_count, unsigned long *cpus, - unsigned int flags) -{ - return syscall(__NR_riscv_hwprobe, pairs, pair_count, cpu_count, cpus, flags); -} - -#endif -#endif - int write_bool(char *path, bool val) { int fd = open(path, O_RDWR); @@ -111,37 +64,3 @@ bool ensure_buf_size(void **buf, size_t *buf_size, size_t required_size) { return true; } - -bool has_fast_aes() { -#if defined(HAVE_GETAUXVAL) && (defined(__arm__) || defined(__aarch64__)) - #if defined(__arm__) && defined(HWCAP2_AES) - return !!(getauxval(AT_HWCAP2) & HWCAP2_AES); - #elif defined(__aarch64__) - return !!(getauxval(AT_HWCAP) & HWCAP_AES); - #else - return false; - #endif -#elif defined(HAVE_BICS_AES) - return __builtin_cpu_supports("aes"); -#elif defined(__BUILTIN_CPU_SUPPORTS__) && defined(__powerpc__) - return __builtin_cpu_supports("vcrypto"); -#elif defined(__linux__) && defined(__riscv) - struct riscv_hwprobe pairs[1] = { - { RISCV_HWPROBE_KEY_IMA_EXT_0, 0 }, - }; - - // If this syscall is not implemented, we'll get -ENOSYS - // and the value field will remain zero. - __riscv_hwprobe(pairs, sizeof(pairs) / sizeof(struct riscv_hwprobe), 0, NULL, 0); - - return (pairs[0].value & (RISCV_HWPROBE_EXT_ZKNE | RISCV_HWPROBE_EXT_ZKND)) == - (RISCV_HWPROBE_EXT_ZKNE | RISCV_HWPROBE_EXT_ZKND) || - (pairs[0].value & RISCV_HWPROBE_EXT_ZVKNED); -#elif __SIZEOF_SIZE_T__ == 4 - #warning Unknown 32-bit platform. Assuming AES is slow on this CPU. - return false; -#else - #warning Unknown 64-bit platform. Assuming AES is fast on this CPU. - return true; -#endif -} \ No newline at end of file