summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authordegasus <wickmarkus@web.de>2016-09-03 14:53:22 +0200
committerdegasus <wickmarkus@web.de>2016-09-06 08:43:31 +0200
commita4d72ac6e367a930eb31c3a73a63f9b3a092ac59 (patch)
tree6b8bb9370720037f2bcf909fbec94ec55386b39c /Source/Core
parentce5dac11a25bd4f7c02cbd3f43fa3ec39b53ab67 (diff)
MMU: Add small BAT comment.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/PowerPC/MMU.cpp36
-rw-r--r--Source/Core/Core/PowerPC/PowerPC.h8
2 files changed, 29 insertions, 15 deletions
diff --git a/Source/Core/Core/PowerPC/MMU.cpp b/Source/Core/Core/PowerPC/MMU.cpp
index 04224a77cc..2853c94280 100644
--- a/Source/Core/Core/PowerPC/MMU.cpp
+++ b/Source/Core/Core/PowerPC/MMU.cpp
@@ -753,35 +753,36 @@ u32 IsOptimizableMMIOAccess(u32 address, u32 accessSize)
return 0;
// Translate address
- u32 bat_result = dbat_table[address >> BAT_INDEX_SHIFT];
- if ((bat_result & 1) == 0)
- return false;
- u32 translated = (bat_result & ~3) | (address & 0x0001FFFF);
+ // If we also optimize for TLB mappings, we'd have to clear the
+ // JitCache on each TLB invalidation.
+ if (!TranslateBatAddess(dbat_table, &address))
+ return 0;
// Check whether the address is an aligned address of an MMIO register.
- bool aligned = (translated & ((accessSize >> 3) - 1)) == 0;
- if (!aligned || !MMIO::IsMMIOAddress(translated))
+ bool aligned = (address & ((accessSize >> 3) - 1)) == 0;
+ if (!aligned || !MMIO::IsMMIOAddress(address))
return 0;
- return translated;
+
+ return address;
}
bool IsOptimizableGatherPipeWrite(u32 address)
{
#ifdef ENABLE_MEM_CHECK
- return false;
+ return 0;
#endif
if (!UReg_MSR(MSR).DR)
- return false;
+ return 0;
- // Translate address
- u32 bat_result = dbat_table[address >> BAT_INDEX_SHIFT];
- if ((bat_result & 1) == 0)
- return false;
- u32 translated = (bat_result & ~3) | (address & 0x0001FFFF);
+ // Translate address, only check BAT mapping.
+ // If we also optimize for TLB mappings, we'd have to clear the
+ // JitCache on each TLB invalidation.
+ if (!TranslateBatAddess(dbat_table, &address))
+ return 0;
// Check whether the translated address equals the address in WPAR.
- return translated == 0x0C008000;
+ return address == 0x0C008000;
}
TranslateResult JitCache_TranslateAddress(u32 address)
@@ -1207,6 +1208,8 @@ void DBATUpdated()
UpdateFakeMMUBat(dbat_table, 0x70000000);
}
Memory::UpdateLogicalMemory(dbat_table);
+
+ // IsOptimizable*Address and dcbz depends on the BAT mapping, so we need a flush here.
JitInterface::ClearSafe();
}
@@ -1227,6 +1230,9 @@ void IBATUpdated()
}
// Translate effective address using BAT or PAT. Returns 0 if the address cannot be translated.
+// Through the hardware looks up BAT and TLB in parallel, BAT is used first if available.
+// So we first check if there is a matching BAT entry, else we look for the TLB in
+// TranslatePageAddress().
template <const XCheckTLBFlag flag>
TranslateAddressResult TranslateAddress(const u32 address)
{
diff --git a/Source/Core/Core/PowerPC/PowerPC.h b/Source/Core/Core/PowerPC/PowerPC.h
index 8ecc2c327d..51dc8eb658 100644
--- a/Source/Core/Core/PowerPC/PowerPC.h
+++ b/Source/Core/Core/PowerPC/PowerPC.h
@@ -288,6 +288,14 @@ static const int BAT_INDEX_SHIFT = 17;
using BatTable = std::array<u32, 1 << (32 - BAT_INDEX_SHIFT)>; // 128 KB
extern BatTable ibat_table;
extern BatTable dbat_table;
+inline bool TranslateBatAddess(const BatTable& bat_table, u32* address)
+{
+ u32 bat_result = bat_table[*address >> BAT_INDEX_SHIFT];
+ if ((bat_result & 1) == 0)
+ return false;
+ *address = (bat_result & ~3) | (*address & 0x0001FFFF);
+ return true;
+}
} // namespace
enum CRBits