Add ugly invalidation workaround for SGS7s.

Otherwise they just crash, and crash often.  Special thanks to Jaaan for
numerous trials to try to find the best way to solve the crashes.
This commit is contained in:
Unknown W. Brackets 2016-05-23 21:35:28 -07:00
parent 70c78effb0
commit 4113fd940c
5 changed files with 35 additions and 0 deletions

View File

@ -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);

View File

@ -296,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
}

View File

@ -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();

View File

@ -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();

View File

@ -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) {