mirror of
https://github.com/libretro/ppsspp.git
synced 2025-01-07 09:00:40 +00:00
Merge pull request #8769 from unknownbrackets/cpuinfo
Add ugly invalidation workaround for SGS7s
This commit is contained in:
commit
9b63a44c86
@ -16,6 +16,7 @@
|
||||
#include "Arm64Emitter.h"
|
||||
#include "MathUtil.h"
|
||||
#include "CommonTypes.h"
|
||||
#include "CPUDetect.h"
|
||||
|
||||
namespace Arm64Gen
|
||||
{
|
||||
@ -312,6 +313,13 @@ void ARM64XEmitter::FlushIcache()
|
||||
|
||||
void ARM64XEmitter::FlushIcacheSection(u8* start, u8* end)
|
||||
{
|
||||
if (cpu_info.sBugs.bExynos8890Invalidation)
|
||||
{
|
||||
// Over invalidate to force this CPU to listen.
|
||||
start = m_startcode + 4096 < start ? start - 4096 : m_startcode;
|
||||
end += 4096;
|
||||
}
|
||||
|
||||
#if defined(IOS)
|
||||
// Header file says this is equivalent to: sys_icache_invalidate(start, end - start);
|
||||
sys_cache_control(kCacheFunctionPrepareForExecution, start, end - start);
|
||||
|
@ -23,6 +23,9 @@
|
||||
#ifdef BLACKBERRY
|
||||
#include <bps/deviceinfo.h>
|
||||
#endif
|
||||
#ifdef ANDROID
|
||||
#include <sys/system_properties.h>
|
||||
#endif
|
||||
|
||||
// Only Linux platforms have /proc/cpuinfo
|
||||
#if defined(__linux__)
|
||||
@ -30,51 +33,70 @@ const char procfile[] = "/proc/cpuinfo";
|
||||
// https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-devices-system-cpu
|
||||
const char syscpupresentfile[] = "/sys/devices/system/cpu/present";
|
||||
|
||||
std::string GetCPUString()
|
||||
{
|
||||
std::string line, marker = "Hardware\t: ";
|
||||
std::string cpu_string = "Unknown";
|
||||
std::string GetCPUString() {
|
||||
std::string cpu_string;
|
||||
std::fstream file;
|
||||
if (!File::OpenCPPFile(file, procfile, std::ios::in))
|
||||
return cpu_string;
|
||||
|
||||
while (std::getline(file, line))
|
||||
{
|
||||
if (line.find(marker) != std::string::npos)
|
||||
{
|
||||
cpu_string = line.substr(marker.length());
|
||||
if (cpu_string.back() == '\n')
|
||||
cpu_string.pop_back(); // Drop the new-line character
|
||||
|
||||
if (File::OpenCPPFile(file, procfile, std::ios::in)) {
|
||||
std::string line, marker = "Hardware\t: ";
|
||||
while (std::getline(file, line)) {
|
||||
if (line.find(marker) != std::string::npos) {
|
||||
cpu_string = line.substr(marker.length());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ANDROID
|
||||
if (cpu_string.empty()) {
|
||||
char temp[PROP_VALUE_MAX];
|
||||
if (__system_property_get("ro.product.board", temp) != 0) {
|
||||
cpu_string = temp;
|
||||
} else if (__system_property_get("ro.product.name", temp) != 0) {
|
||||
cpu_string = temp;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (cpu_string.empty())
|
||||
cpu_string = "Unknown";
|
||||
else if (cpu_string.back() == '\n')
|
||||
cpu_string.pop_back(); // Drop the new-line character
|
||||
|
||||
return cpu_string;
|
||||
}
|
||||
|
||||
std::string GetCPUBrandString()
|
||||
{
|
||||
std::string line, marker = "Processor\t: ";
|
||||
std::string brand_string = "Unknown";
|
||||
std::string GetCPUBrandString() {
|
||||
std::string brand_string;
|
||||
std::fstream file;
|
||||
if (!File::OpenCPPFile(file, procfile, std::ios::in))
|
||||
return brand_string;
|
||||
|
||||
while (std::getline(file, line))
|
||||
{
|
||||
if (line.find(marker) != std::string::npos)
|
||||
{
|
||||
brand_string = line.substr(marker.length());
|
||||
if (brand_string.back() == '\n')
|
||||
brand_string.pop_back(); // Drop the new-line character
|
||||
|
||||
if (brand_string.length() == 0 || isdigit(brand_string[0])) {
|
||||
brand_string = "Unknown";
|
||||
continue;
|
||||
if (File::OpenCPPFile(file, procfile, std::ios::in)) {
|
||||
std::string line, marker = "Processor\t: ";
|
||||
while (std::getline(file, line)) {
|
||||
if (line.find(marker) != std::string::npos) {
|
||||
brand_string = line.substr(marker.length());
|
||||
if (brand_string.length() != 0 && !isdigit(brand_string[0])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ANDROID
|
||||
if (brand_string.empty()) {
|
||||
char temp[PROP_VALUE_MAX];
|
||||
if (__system_property_get("ro.product.model", temp) != 0) {
|
||||
brand_string = temp;
|
||||
} else if (__system_property_get("ro.product.name", temp) != 0) {
|
||||
brand_string = temp;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (brand_string.empty())
|
||||
brand_string = "Unknown";
|
||||
else if (brand_string.back() == '\n')
|
||||
brand_string.pop_back(); // Drop the new-line character
|
||||
|
||||
return brand_string;
|
||||
}
|
||||
|
||||
@ -274,6 +296,8 @@ void CPUInfo::Detect()
|
||||
// Whether the above detection failed or not, on ARM64 we do have ASIMD/NEON.
|
||||
bNEON = true;
|
||||
bASIMD = true;
|
||||
|
||||
sBugs.bExynos8890Invalidation = strcmp(cpu_string, "universal8890") == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -89,6 +89,15 @@ struct CPUInfo {
|
||||
bool bXBurst1;
|
||||
bool bXBurst2;
|
||||
|
||||
// Bugs
|
||||
struct {
|
||||
// Samsung Galaxy S7 devices (Exynos 8890) have a bug that causes invalidation to work incorrectly.
|
||||
// This may be caused by interaction between the separate CPU cores.
|
||||
// Padding jit blocks and over-invalidating seems to "solve" it.
|
||||
// Only affects ARM64.
|
||||
bool bExynos8890Invalidation;
|
||||
} sBugs;
|
||||
|
||||
// Call Detect()
|
||||
explicit CPUInfo();
|
||||
|
||||
|
@ -329,6 +329,14 @@ const u8 *Arm64Jit::DoJit(u32 em_address, JitBlock *b) {
|
||||
if (dontLogBlocks > 0)
|
||||
dontLogBlocks--;
|
||||
|
||||
if (cpu_info.sBugs.bExynos8890Invalidation) {
|
||||
// What a waste. If we don't do both this and over-invalidate, the device crashes.
|
||||
// This space won't ever get run, but it's wasted jit cache space.
|
||||
for (int i = 0; i < 32; ++i) {
|
||||
HINT(HINT_NOP);
|
||||
}
|
||||
}
|
||||
|
||||
// Don't forget to zap the newly written instructions in the instruction cache!
|
||||
FlushIcache();
|
||||
|
||||
|
@ -275,6 +275,14 @@ JittedVertexDecoder VertexDecoderJitCache::Compile(const VertexDecoder &dec, int
|
||||
|
||||
RET();
|
||||
|
||||
if (cpu_info.sBugs.bExynos8890Invalidation) {
|
||||
// Apparently the vertex cache hasn't been the problem, but adding this here for the same
|
||||
// reasons as the standard jit.
|
||||
for (int i = 0; i < 32; ++i) {
|
||||
HINT(HINT_NOP);
|
||||
}
|
||||
}
|
||||
|
||||
FlushIcache();
|
||||
|
||||
if (log) {
|
||||
|
Loading…
Reference in New Issue
Block a user