Further clean up, removal of magic numbers from CP15.cpp

Split the cp15 constants into CP15_Constants.h instead from MemConstants.
This commit is contained in:
DesperateProgrammer 2024-02-01 08:36:52 +01:00
parent 06ea3f68ec
commit c8204a8c63
5 changed files with 311 additions and 286 deletions

View File

@ -1152,69 +1152,57 @@ u32 ARMv5::ReadMem(u32 addr, int size)
}
#endif
void ARMv4::DataRead8(u32 addr, u32* val)
void ARMv4::DataRead8(const u32 addr, u32* val)
{
*val = BusRead8(addr);
DataRegion = addr;
DataCycles = NDS.ARM7MemTimings[addr >> 15][0];
}
void ARMv4::DataRead16(u32 addr, u32* val)
void ARMv4::DataRead16(const u32 addr, u32* val)
{
addr &= ~1;
*val = BusRead16(addr);
*val = BusRead16(addr & ~1);
DataRegion = addr;
DataCycles = NDS.ARM7MemTimings[addr >> 15][0];
}
void ARMv4::DataRead32(u32 addr, u32* val)
void ARMv4::DataRead32(const u32 addr, u32* val)
{
addr &= ~3;
*val = BusRead32(addr);
*val = BusRead32(addr & ~3);
DataRegion = addr;
DataCycles = NDS.ARM7MemTimings[addr >> 15][2];
}
void ARMv4::DataRead32S(u32 addr, u32* val)
void ARMv4::DataRead32S(const u32 addr, u32* val)
{
addr &= ~3;
*val = BusRead32(addr);
*val = BusRead32(addr & ~3);
DataCycles += NDS.ARM7MemTimings[addr >> 15][3];
}
void ARMv4::DataWrite8(u32 addr, u8 val)
void ARMv4::DataWrite8(const u32 addr, const u8 val)
{
BusWrite8(addr, val);
DataRegion = addr;
DataCycles = NDS.ARM7MemTimings[addr >> 15][0];
}
void ARMv4::DataWrite16(u32 addr, u16 val)
void ARMv4::DataWrite16(const u32 addr, const u16 val)
{
addr &= ~1;
BusWrite16(addr, val);
BusWrite16(addr & ~1, val);
DataRegion = addr;
DataCycles = NDS.ARM7MemTimings[addr >> 15][0];
}
void ARMv4::DataWrite32(u32 addr, u32 val)
void ARMv4::DataWrite32(const u32 addr, const u32 val)
{
addr &= ~3;
BusWrite32(addr, val);
BusWrite32(addr & ~3, val);
DataRegion = addr;
DataCycles = NDS.ARM7MemTimings[addr >> 15][2];
}
void ARMv4::DataWrite32S(u32 addr, u32 val)
void ARMv4::DataWrite32S(const u32 addr, const u32 val)
{
addr &= ~3;
BusWrite32(addr, val);
BusWrite32(addr & ~3, val);
DataCycles += NDS.ARM7MemTimings[addr >> 15][3];
}

View File

@ -25,6 +25,7 @@
#include "types.h"
#include "MemRegion.h"
#include "MemConstants.h"
#include "CP15_Constants.h"
#ifdef GDBSTUB_ENABLED
#include "debug/GdbStub.h"
@ -128,14 +129,14 @@ public:
void SetupCodeMem(u32 addr);
virtual void DataRead8(u32 addr, u32* val) = 0;
virtual void DataRead16(u32 addr, u32* val) = 0;
virtual void DataRead32(u32 addr, u32* val) = 0;
virtual void DataRead32S(u32 addr, u32* val) = 0;
virtual void DataWrite8(u32 addr, u8 val) = 0;
virtual void DataWrite16(u32 addr, u16 val) = 0;
virtual void DataWrite32(u32 addr, u32 val) = 0;
virtual void DataWrite32S(u32 addr, u32 val) = 0;
virtual void DataRead8(const u32 addr, u32* val) = 0;
virtual void DataRead16(const u32 addr, u32* val) = 0;
virtual void DataRead32(const u32 addr, u32* val) = 0;
virtual void DataRead32S(const u32 addr, u32* val) = 0;
virtual void DataWrite8(const u32 addr, const u8 val) = 0;
virtual void DataWrite16(const u32 addr, const u16 val) = 0;
virtual void DataWrite32(const u32 addr, const u32 val) = 0;
virtual void DataWrite32S(const u32 addr, const u32 val) = 0;
virtual void AddCycles_C() = 0;
virtual void AddCycles_CI(s32 numI) = 0;
@ -247,16 +248,16 @@ public:
#endif
// all code accesses are forced nonseq 32bit
u32 CodeRead32(u32 addr, bool branch);
u32 CodeRead32(const u32 addr, const bool branch);
void DataRead8(u32 addr, u32* val) override;
void DataRead16(u32 addr, u32* val) override;
void DataRead32(u32 addr, u32* val) override;
void DataRead32S(u32 addr, u32* val) override;
void DataWrite8(u32 addr, u8 val) override;
void DataWrite16(u32 addr, u16 val) override;
void DataWrite32(u32 addr, u32 val) override;
void DataWrite32S(u32 addr, u32 val) override;
void DataRead8(const u32 addr, u32* val) override;
void DataRead16(const u32 addr, u32* val) override;
void DataRead32(const u32 addr, u32* val) override;
void DataRead32S(const u32 addr, u32* val) override;
void DataWrite8(const u32 addr, const u8 val) override;
void DataWrite16(const u32 addr, const u16 val) override;
void DataWrite32(const u32 addr, const u32 val) override;
void DataWrite32S(const u32 addr, const u32 val) override;
void AddCycles_C() override
{
@ -317,7 +318,6 @@ public:
void ICacheInvalidateByAddr(const u32 addr);
void ICacheInvalidateBySetAndWay(const u8 cacheSet, const u8 cacheLine);
u32 DCacheLookup(const u32 addr);
void DCacheWrite32(const u32 addr, const u32 val);
void DCacheWrite16(const u32 addr, const u16 val);
@ -361,7 +361,6 @@ public:
u8 DCache[DCACHE_SIZE];
u32 DCacheTags[DCACHE_LINESPERSET*DCACHE_SETS];
u8 DCacheCount;
u32 DCacheLFSRStates;
u32 PU_CodeCacheable;
u32 PU_DataCacheable;
@ -383,9 +382,6 @@ public:
// code/16N/32N/32S
u8 MemTimings[0x100000][4];
u8* CurICacheLine;
u8* CurDCacheLine;
bool (*GetMemRegion)(u32 addr, bool write, MemRegion* region);
#ifdef GDBSTUB_ENABLED
@ -416,24 +412,24 @@ public:
void ExecuteJIT() override;
#endif
u16 CodeRead16(u32 addr)
u16 CodeRead16(const u32 addr)
{
return BusRead16(addr);
}
u32 CodeRead32(u32 addr)
u32 CodeRead32(const u32 addr)
{
return BusRead32(addr);
}
void DataRead8(u32 addr, u32* val) override;
void DataRead16(u32 addr, u32* val) override;
void DataRead32(u32 addr, u32* val) override;
void DataRead32S(u32 addr, u32* val) override;
void DataWrite8(u32 addr, u8 val) override;
void DataWrite16(u32 addr, u16 val) override;
void DataWrite32(u32 addr, u32 val) override;
void DataWrite32S(u32 addr, u32 val) override;
void DataRead8(const u32 addr, u32* val) override;
void DataRead16(const u32 addr, u32* val) override;
void DataRead32(const u32 addr, u32* val) override;
void DataRead32S(const u32 addr, u32* val) override;
void DataWrite8(const u32 addr, const u8 val) override;
void DataWrite16(const u32 addr, const u16 val) override;
void DataWrite32(const u32 addr, const u32 val) override;
void DataWrite32S(const u32 addr, const u32 val) override;
void AddCycles_C() override;
void AddCycles_CI(s32 num) override;
void AddCycles_CDI() override;

View File

@ -24,6 +24,7 @@
#include "Platform.h"
#include "ARMJIT_Memory.h"
#include "ARMJIT.h"
#include "CP15_Constants.h"
namespace melonDS
{
@ -67,10 +68,6 @@ void ARMv5::CP15Reset()
DCacheInvalidateAll();
DCacheCount = 0;
// make sure that both half words are not the same otherwise the random of the DCache set selection only produces
// '00' and '11'
DCacheLFSRStates = 0xDEADBEEF;
PU_CodeCacheable = 0;
PU_DataCacheable = 0;
PU_DataCacheWrite = 0;
@ -78,10 +75,9 @@ void ARMv5::CP15Reset()
PU_CodeRW = 0;
PU_DataRW = 0;
memset(PU_Region, 0, 8*sizeof(u32));
memset(PU_Region, 0, CP15_REGION_COUNT*sizeof(u32));
UpdatePURegions(true);
CurICacheLine = NULL;
}
void ARMv5::CP15DoSavestate(Savestate* file)
@ -103,7 +99,6 @@ void ARMv5::CP15DoSavestate(Savestate* file)
file->VarArray(DCache, sizeof(DCache));
file->VarArray(DCacheTags, sizeof(DCacheTags));
file->Var8(&DCacheCount);
file->Var32(&DCacheLFSRStates);
file->Var32(&DCacheLockDown);
file->Var32(&ICacheLockDown);
@ -116,7 +111,7 @@ void ARMv5::CP15DoSavestate(Savestate* file)
file->Var32(&PU_CodeRW);
file->Var32(&PU_DataRW);
file->VarArray(PU_Region, 8*sizeof(u32));
file->VarArray(PU_Region, CP15_REGION_COUNT*sizeof(u32));
if (!file->Saving)
{
@ -178,8 +173,11 @@ void ARMv5::UpdatePURegion(u32 n)
if (!(CP15Control & CP15_CR_MPUENABLE))
return;
u32 coderw = (PU_CodeRW >> (4*n)) & 0xF;
u32 datarw = (PU_DataRW >> (4*n)) & 0xF;
if (n >= CP15_REGION_COUNT)
return;
u32 coderw = (PU_CodeRW >> (CP15_REGIONACCESS_BITS_PER_REGION * n)) & CP15_REGIONACCESS_REGIONMASK;
u32 datarw = (PU_DataRW >> (CP15_REGIONACCESS_BITS_PER_REGION * n)) & CP15_REGIONACCESS_REGIONMASK;
u32 codecache, datacache, datawrite;
@ -211,60 +209,60 @@ void ARMv5::UpdatePURegion(u32 n)
return;
}
u32 start = rgn >> 12;
u32 sz = 2 << ((rgn >> 1) & 0x1F);
u32 end = start + (sz >> 12);
u32 start = (rgn & CP15_REGION_BASE_MASK) >> CP15_MAP_ENTRYSIZE_LOG2;
u32 sz = 2 << ((rgn & CP15_REGION_SIZE_MASK) >> 1);
u32 end = start + (sz >> CP15_MAP_ENTRYSIZE_LOG2);
// TODO: check alignment of start
u8 usermask = 0;
u8 privmask = 0;
u8 usermask = CP15_MAP_NOACCESS;
u8 privmask = CP15_MAP_NOACCESS;
switch (datarw)
{
case 0: break;
case 1: privmask |= 0x03; break;
case 2: privmask |= 0x03; usermask |= 0x01; break;
case 3: privmask |= 0x03; usermask |= 0x03; break;
case 5: privmask |= 0x01; break;
case 6: privmask |= 0x01; usermask |= 0x01; break;
case 1: privmask |= CP15_MAP_READABLE | CP15_MAP_WRITEABLE; break;
case 2: privmask |= CP15_MAP_READABLE | CP15_MAP_WRITEABLE; usermask |= CP15_MAP_READABLE; break;
case 3: privmask |= CP15_MAP_READABLE | CP15_MAP_WRITEABLE; usermask |= CP15_MAP_READABLE | CP15_MAP_WRITEABLE; break;
case 5: privmask |= CP15_MAP_READABLE; break;
case 6: privmask |= CP15_MAP_READABLE; usermask |= CP15_MAP_READABLE; break;
default: Log(LogLevel::Warn, "!! BAD DATARW VALUE %d\n", datarw&0xF);
}
switch (coderw)
{
case 0: break;
case 1: privmask |= 0x04; break;
case 2: privmask |= 0x04; usermask |= 0x04; break;
case 3: privmask |= 0x04; usermask |= 0x04; break;
case 5: privmask |= 0x04; break;
case 6: privmask |= 0x04; usermask |= 0x04; break;
case 1: privmask |= CP15_MAP_EXECUTABLE; break;
case 2: privmask |= CP15_MAP_EXECUTABLE; usermask |= CP15_MAP_EXECUTABLE; break;
case 3: privmask |= CP15_MAP_EXECUTABLE; usermask |= CP15_MAP_EXECUTABLE; break;
case 5: privmask |= CP15_MAP_EXECUTABLE; break;
case 6: privmask |= CP15_MAP_EXECUTABLE; usermask |= CP15_MAP_EXECUTABLE; break;
default: Log(LogLevel::Warn, "!! BAD CODERW VALUE %d\n", datarw&0xF);
}
if (datacache & 0x1)
{
privmask |= 0x10;
usermask |= 0x10;
privmask |= CP15_MAP_DCACHEABLE;
usermask |= CP15_MAP_DCACHEABLE;
if (datawrite & 0x1)
{
privmask |= 0x20;
usermask |= 0x20;
privmask |= CP15_MAP_DCACHEWRITEBACK;
usermask |= CP15_MAP_DCACHEWRITEBACK;
}
}
if (codecache & 0x1)
{
privmask |= 0x40;
usermask |= 0x40;
privmask |= CP15_MAP_ICACHEABLE;
usermask |= CP15_MAP_ICACHEABLE;
}
Log(
LogLevel::Debug,
"PU region %d: %08X-%08X, user=%02X priv=%02X, %08X/%08X\n",
n,
start << 12,
end << 12,
start << CP15_MAP_ENTRYSIZE_LOG2,
end << CP15_MAP_ENTRYSIZE_LOG2,
usermask,
privmask,
PU_DataRW,
@ -286,9 +284,9 @@ void ARMv5::UpdatePURegions(bool update_all)
{
// PU disabled
u8 mask = 0x07;
if (CP15Control & CP15_CACHE_CR_DCACHEENABLE) mask |= 0x30;
if (CP15Control & CP15_CACHE_CR_ICACHEENABLE) mask |= 0x40;
u8 mask = CP15_MAP_READABLE | CP15_MAP_WRITEABLE | CP15_MAP_EXECUTABLE;
if (CP15Control & CP15_CACHE_CR_DCACHEENABLE) mask |= CP15_MAP_DCACHEABLE | CP15_MAP_DCACHEWRITEBACK ;
if (CP15Control & CP15_CACHE_CR_ICACHEENABLE) mask |= CP15_MAP_ICACHEABLE;
memset(PU_UserMap, mask, 0x100000);
memset(PU_PrivMap, mask, 0x100000);
@ -299,11 +297,11 @@ void ARMv5::UpdatePURegions(bool update_all)
if (update_all)
{
memset(PU_UserMap, 0, 0x100000);
memset(PU_PrivMap, 0, 0x100000);
memset(PU_UserMap, CP15_MAP_NOACCESS, 0x100000);
memset(PU_PrivMap, CP15_MAP_NOACCESS, 0x100000);
}
for (int n = 0; n < 8; n++)
for (int n = 0; n < CP15_REGION_COUNT; n++)
{
UpdatePURegion(n);
}
@ -322,7 +320,7 @@ void ARMv5::UpdateRegionTimings(u32 addrstart, u32 addrend)
u8 pu = PU_Map[i];
u8* bustimings = NDS.ARM9MemTimings[i >> 2];
if (pu & 0x40)
if (pu & CP15_MAP_ICACHEABLE)
{
MemTimings[i][0] = 0xFF;//kCodeCacheTiming;
}
@ -331,7 +329,7 @@ void ARMv5::UpdateRegionTimings(u32 addrstart, u32 addrend)
MemTimings[i][0] = bustimings[2] << NDS.ARM9ClockShift;
}
if (pu & 0x10)
if (pu & CP15_MAP_DCACHEABLE)
{
MemTimings[i][1] = kDataCacheTiming;
MemTimings[i][2] = kDataCacheTiming;
@ -364,7 +362,7 @@ u32 ARMv5::ICacheLookup(const u32 addr)
for (int set=0;set<ICACHE_SETS;set++)
{
if ((ICacheTags[id+set] & ~0x0F) == (tag | CACHE_FLAG_VALID))
if ((ICacheTags[id+set] & ~(CACHE_FLAG_DIRTY_MASK | CACHE_FLAG_SET_MASK)) == (tag | CACHE_FLAG_VALID))
{
CodeCycles = 1;
u32 *cacheLine = (u32 *)&ICache[(id+set) << ICACHE_LINELENGTH_LOG2];
@ -448,7 +446,7 @@ void ARMv5::ICacheInvalidateByAddr(const u32 addr)
for (int set=0;set<ICACHE_SETS;set++)
{
if ((ICacheTags[id+set] & ~0x0F) == tag)
if ((ICacheTags[id+set] & ~(CACHE_FLAG_DIRTY_MASK | CACHE_FLAG_SET_MASK)) == tag)
{
ICacheTags[id+set] &= ~CACHE_FLAG_VALID; ;
return;
@ -476,7 +474,7 @@ void ARMv5::ICacheInvalidateAll()
bool ARMv5::IsAddressICachable(const u32 addr) const
{
return PU_Map[addr >> 12] & 0x40 ;
return PU_Map[addr >> CP15_MAP_ENTRYSIZE_LOG2] & CP15_MAP_ICACHEABLE ;
}
u32 ARMv5::DCacheLookup(const u32 addr)
@ -487,7 +485,7 @@ u32 ARMv5::DCacheLookup(const u32 addr)
for (int set=0;set<DCACHE_SETS;set++)
{
if ((DCacheTags[id+set] & ~0x0F) == (tag | CACHE_FLAG_VALID))
if ((DCacheTags[id+set] & ~(CACHE_FLAG_DIRTY_MASK | CACHE_FLAG_SET_MASK)) == (tag | CACHE_FLAG_VALID))
{
DataCycles = 1;
u32 *cacheLine = (u32 *)&DCache[(id+set) << DCACHE_LINELENGTH_LOG2];
@ -578,13 +576,11 @@ void ARMv5::DCacheWrite32(const u32 addr, const u32 val)
for (int set=0;set<DCACHE_SETS;set++)
{
if ((DCacheTags[id+set] & ~0x0F) == tag)
if ((DCacheTags[id+set] & ~(CACHE_FLAG_DIRTY_MASK | CACHE_FLAG_SET_MASK)) == tag)
{
u32 *cacheLine = (u32 *)&DCache[(id+set) << DCACHE_LINELENGTH_LOG2];
cacheLine[(addr & (ICACHE_LINELENGTH-1)) >> 2] = val;
DataCycles = 1;
//Log(LogLevel::Debug,"DCache write32 hit @ %08x -> %08lx\n", addr, ((u32 *)CurDCacheLine)[(addr & (DCACHE_LINELENGTH-1)) >> 2]);
return;
}
}
@ -597,13 +593,11 @@ void ARMv5::DCacheWrite16(const u32 addr, const u16 val)
for (int set=0;set<DCACHE_SETS;set++)
{
if ((DCacheTags[id+set] & ~0x0F) == tag)
if ((DCacheTags[id+set] & ~(CACHE_FLAG_DIRTY_MASK | CACHE_FLAG_SET_MASK)) == tag)
{
u16 *cacheLine = (u16 *)&DCache[(id+set) << DCACHE_LINELENGTH_LOG2];
cacheLine[(addr & (ICACHE_LINELENGTH-1)) >> 1] = val;
DataCycles = 1;
//Log(LogLevel::Debug,"DCache write16 hit @ %08x -> %04x\n", addr, ((u16 *)CurDCacheLine)[(addr & (DCACHE_LINELENGTH-1)) >> 2]);
return;
}
}
@ -616,13 +610,11 @@ void ARMv5::DCacheWrite8(const u32 addr, const u8 val)
for (int set=0;set<DCACHE_SETS;set++)
{
if ((DCacheTags[id+set] & ~0x0F) == tag)
if ((DCacheTags[id+set] & ~(CACHE_FLAG_DIRTY_MASK | CACHE_FLAG_SET_MASK)) == tag)
{
u8 *cacheLine = &DCache[(id+set) << DCACHE_LINELENGTH_LOG2];
cacheLine[addr & (ICACHE_LINELENGTH-1)] = val;
DataCycles = 1;
//Log(LogLevel::Debug,"DCache write hit8 @ %08x -> %02x\n", addr, ((u8 *)CurDCacheLine)[(addr & (DCACHE_LINELENGTH-1)) >> 2]);
return;
}
}
@ -635,7 +627,7 @@ void ARMv5::DCacheInvalidateByAddr(const u32 addr)
for (int set=0;set<DCACHE_SETS;set++)
{
if ((DCacheTags[id+set] & ~0x0Ful) == tag)
if ((DCacheTags[id+set] & ~(CACHE_FLAG_DIRTY_MASK | CACHE_FLAG_SET_MASK)) == tag)
{
//Log(LogLevel::Debug,"DCache invalidated %08lx\n", addr & ~(ICACHE_LINELENGTH-1));
DCacheTags[id+set] &= ~CACHE_FLAG_VALID; ;
@ -682,7 +674,7 @@ void ARMv5::DCacheClearByASetAndWay(const u8 cacheSet, const u8 cacheLine)
bool ARMv5::IsAddressDCachable(const u32 addr) const
{
return PU_Map[addr >> 12] & 0x10 ;
return PU_Map[addr >> CP15_MAP_ENTRYSIZE_LOG2] & CP15_MAP_DCACHEABLE ;
}
void ARMv5::CP15Write(u32 id, u32 val)
@ -700,13 +692,14 @@ void ARMv5::CP15Write(u32 id, u32 val)
//Log(LogLevel::Debug, "CP15Control = %08X (%08X->%08X)\n", CP15Control, old, val);
UpdateDTCMSetting();
UpdateITCMSetting();
if ((old & 0x1005) != (val & 0x1005))
u32 changedBits = old^val;
if (changedBits & (CP15_CR_MPUENABLE | CP15_CACHE_CR_ICACHEENABLE| CP15_CACHE_CR_DCACHEENABLE))
{
UpdatePURegions((old & 0x1) != (val & 0x1));
UpdatePURegions(changedBits & CP15_CR_MPUENABLE);
}
if (val & CP15_CR_BIGENDIAN) Log(LogLevel::Warn, "!!!! ARM9 BIG ENDIAN MODE. VERY BAD. SHIT GONNA ASPLODE NOW\n");
if (val & CP15_CR_HIGHEXCEPTIONBASE) ExceptionBase = 0xFFFF0000;
else ExceptionBase = 0x00000000;
if (val & CP15_CR_HIGHEXCEPTIONBASE) ExceptionBase = CP15_EXCEPTIONBASE_HIGH;
else ExceptionBase = CP15_EXCEPTIONBASE_LOW;
}
return;
@ -715,7 +708,7 @@ void ARMv5::CP15Write(u32 id, u32 val)
{
u32 diff = PU_DataCacheable ^ val;
PU_DataCacheable = val;
for (u32 i = 0; i < 8; i++)
for (u32 i = 0; i < CP15_REGION_COUNT; i++)
{
if (diff & (1<<i)) UpdatePURegion(i);
}
@ -726,7 +719,7 @@ void ARMv5::CP15Write(u32 id, u32 val)
{
u32 diff = PU_CodeCacheable ^ val;
PU_CodeCacheable = val;
for (u32 i = 0; i < 8; i++)
for (u32 i = 0; i < CP15_REGION_COUNT; i++)
{
if (diff & (1<<i)) UpdatePURegion(i);
}
@ -738,7 +731,7 @@ void ARMv5::CP15Write(u32 id, u32 val)
{
u32 diff = PU_DataCacheWrite ^ val;
PU_DataCacheWrite = val;
for (u32 i = 0; i < 8; i++)
for (u32 i = 0; i < CP15_REGION_COUNT; i++)
{
if (diff & (1<<i)) UpdatePURegion(i);
}
@ -759,9 +752,9 @@ void ARMv5::CP15Write(u32 id, u32 val)
PU_DataRW |= ((val & 0x3000) << 12);
PU_DataRW |= ((val & 0xC000) << 14);
u32 diff = old ^ PU_DataRW;
for (u32 i = 0; i < 8; i++)
for (u32 i = 0; i < CP15_REGION_COUNT; i++)
{
if (diff & (0xF<<(i*4))) UpdatePURegion(i);
if (diff & (CP15_REGIONACCESS_REGIONMASK<<(i*CP15_REGIONACCESS_BITS_PER_REGION))) UpdatePURegion(i);
}
}
return;
@ -779,9 +772,9 @@ void ARMv5::CP15Write(u32 id, u32 val)
PU_CodeRW |= ((val & 0x3000) << 12);
PU_CodeRW |= ((val & 0xC000) << 14);
u32 diff = old ^ PU_CodeRW;
for (u32 i = 0; i < 8; i++)
for (u32 i = 0; i < CP15_REGION_COUNT; i++)
{
if (diff & (0xF<<(i*4))) UpdatePURegion(i);
if (diff & (CP15_REGIONACCESS_REGIONMASK<<(i*CP15_REGIONACCESS_BITS_PER_REGION))) UpdatePURegion(i);
}
}
return;
@ -790,9 +783,9 @@ void ARMv5::CP15Write(u32 id, u32 val)
{
u32 diff = PU_DataRW ^ val;
PU_DataRW = val;
for (u32 i = 0; i < 8; i++)
for (u32 i = 0; i < CP15_REGION_COUNT; i++)
{
if (diff & (0xF<<(i*4))) UpdatePURegion(i);
if (diff & (CP15_REGIONACCESS_REGIONMASK<<(i*CP15_REGIONACCESS_BITS_PER_REGION))) UpdatePURegion(i);
}
}
return;
@ -801,9 +794,9 @@ void ARMv5::CP15Write(u32 id, u32 val)
{
u32 diff = PU_CodeRW ^ val;
PU_CodeRW = val;
for (u32 i = 0; i < 8; i++)
for (u32 i = 0; i < CP15_REGION_COUNT; i++)
{
if (diff & (0xF<<(i*4))) UpdatePURegion(i);
if (diff & (CP15_REGIONACCESS_REGIONMASK<<(i*CP15_REGIONACCESS_BITS_PER_REGION))) UpdatePURegion(i);
}
}
return;
@ -825,21 +818,16 @@ void ARMv5::CP15Write(u32 id, u32 val)
case 0x661:
case 0x670:
case 0x671:
char log_output[1024];
PU_Region[(id >> 4) & 0xF] = val;
PU_Region[(id >> CP15_REGIONACCESS_BITS_PER_REGION) & CP15_REGIONACCESS_REGIONMASK] = val;
std::snprintf(log_output,
sizeof(log_output),
Log(LogLevel::Debug,
"PU: region %d = %08X : %s, %08X-%08X\n",
(id >> 4) & 0xF,
(id >> CP15_REGIONACCESS_BITS_PER_REGION) & CP15_REGIONACCESS_REGIONMASK,
val,
val & 1 ? "enabled" : "disabled",
val & 0xFFFFF000,
(val & 0xFFFFF000) + (2 << ((val & 0x3E) >> 1))
val & CP15_REGION_BASE_MASK,
(val & CP15_REGION_BASE_MASK) + (2 << ((val & CP15_REGION_SIZE_MASK) >> 1))
);
Log(LogLevel::Debug, "%s", log_output);
// Some implementations of Log imply a newline, so we build up the line before printing it
// TODO: smarter region update for this?
UpdatePURegions(true);
return;
@ -854,7 +842,6 @@ void ARMv5::CP15Write(u32 id, u32 val)
case 0x750:
// Can be executed in user and priv mode
ICacheInvalidateAll();
//Halt(255);
return;
case 0x751:
// requires priv mode or causes UNKNOWN INSTRUCTION exception
@ -1179,10 +1166,6 @@ void ARMv5::CP15Write(u32 id, u32 val)
}
if ((id & 0xF00) == 0xF00) // test/debug shit?
return;
if ((id & 0xF00) != 0x700)
Log(LogLevel::Debug, "unknown CP15 write op %03X %08X\n", id, val);
}
@ -1198,7 +1181,7 @@ u32 ARMv5::CP15Read(u32 id) const
case 0x005:
case 0x006:
case 0x007:
return 0x41059461;
return CP15_MAINID_IMPLEMENTOR_ARM | CP15_MAINID_VARIANT_0 | CP15_MAINID_ARCH_v5TE | CP15_MAINID_IMPLEMENTATION_946 | CP15_MAINID_REVISION_1;
case 0x001: // cache type
return CACHE_TR_LOCKDOWN_TYPE_B | CACHE_TR_NONUNIFIED
@ -1269,7 +1252,7 @@ u32 ARMv5::CP15Read(u32 id) const
case 0x661:
case 0x670:
case 0x671:
return PU_Region[(id >> 4) & 0xF];
return PU_Region[(id >> CP15_REGIONACCESS_BITS_PER_REGION) & 0xF];
case 0x7A6:
// read Cache Dirty Bit (optional)
@ -1346,9 +1329,6 @@ u32 ARMv5::CP15Read(u32 id) const
}
}
if ((id & 0xF00) == 0xF00) // test/debug shit?
return 0;
Log(LogLevel::Debug, "unknown CP15 read op %03X\n", id);
return 0;
}
@ -1357,24 +1337,9 @@ u32 ARMv5::CP15Read(u32 id) const
// TCM are handled here.
// TODO: later on, handle PU
u32 ARMv5::CodeRead32(u32 addr, bool branch)
u32 ARMv5::CodeRead32(const u32 addr, bool const branch)
{
/*if (branch || (!(addr & 0xFFF)))
{
if (!(PU_Map[addr>>12] & 0x04))
{
PrefetchAbort();
return 0;
}
}*/
if (addr < ITCMSize)
{
CodeCycles = 1;
return *(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)];
}
CodeCycles = RegionCodeCycles;
#ifdef JIT_ENABLED
if (!NDS.IsJITEnabled())
#endif
@ -1386,27 +1351,33 @@ u32 ARMv5::CodeRead32(u32 addr, bool branch)
return ICacheLookup(addr);
}
}
} else
}
if (addr < ITCMSize)
{
CodeCycles = 1;
return *(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)];
}
CodeCycles = RegionCodeCycles;
if (CodeCycles == 0xFF) // cached memory. hax
{
if (branch || !(addr & 0x1F))
if (branch || !(addr & (ICACHE_LINELENGTH-1)))
CodeCycles = kCodeCacheTiming;//ICacheLookup(addr);
else
CodeCycles = 1;
}
//return *(u32*)&CurICacheLine[addr & 0x1C];
}
}
if (CodeMem.Mem) return *(u32*)&CodeMem.Mem[addr & CodeMem.Mask];
return BusRead32(addr);
}
void ARMv5::DataRead8(u32 addr, u32* val)
void ARMv5::DataRead8(const u32 addr, u32* val)
{
if (!(PU_Map[addr>>12] & 0x01))
if (!(PU_Map[addr>>CP15_MAP_ENTRYSIZE_LOG2] & CP15_MAP_READABLE))
{
Log(LogLevel::Debug, "data8 abort @ %08lx\n", addr);
DataAbort();
@ -1421,7 +1392,7 @@ void ARMv5::DataRead8(u32 addr, u32* val)
{
if (CP15Control & CP15_CACHE_CR_DCACHEENABLE)
{
if (PU_Map[addr >> 12] & 0x10)
if (IsAddressDCachable(addr))
{
*val = (DCacheLookup(addr) >> (8 * (addr & 3))) & 0xff;
return;
@ -1443,12 +1414,12 @@ void ARMv5::DataRead8(u32 addr, u32* val)
}
*val = BusRead8(addr);
DataCycles = MemTimings[addr >> 12][1];
DataCycles = MemTimings[addr >> BUSCYCLES_MAP_GRANULARITY_LOG2][BUSCYCLES_S16];
}
void ARMv5::DataRead16(u32 addr, u32* val)
void ARMv5::DataRead16(const u32 addr, u32* val)
{
if (!(PU_Map[addr>>12] & 0x01))
if (!(PU_Map[addr>>CP15_MAP_ENTRYSIZE_LOG2] & CP15_MAP_READABLE))
{
Log(LogLevel::Debug, "data16 abort @ %08lx\n", addr);
DataAbort();
@ -1463,7 +1434,7 @@ void ARMv5::DataRead16(u32 addr, u32* val)
{
if (CP15Control & CP15_CACHE_CR_DCACHEENABLE)
{
if (PU_Map[addr >> 12] & 0x10)
if (IsAddressDCachable(addr))
{
*val = (DCacheLookup(addr) >> (8* (addr & 2))) & 0xffff;
return;
@ -1471,28 +1442,26 @@ void ARMv5::DataRead16(u32 addr, u32* val)
}
}
addr &= ~1;
if (addr < ITCMSize)
{
DataCycles = 1;
*val = *(u16*)&ITCM[addr & (ITCMPhysicalSize - 1)];
*val = *(u16*)&ITCM[addr & (ITCMPhysicalSize - 2)];
return;
}
if ((addr & DTCMMask) == DTCMBase)
{
DataCycles = 1;
*val = *(u16*)&DTCM[addr & (DTCMPhysicalSize - 1)];
*val = *(u16*)&DTCM[addr & (DTCMPhysicalSize - 2)];
return;
}
*val = BusRead16(addr);
DataCycles = MemTimings[addr >> 12][1];
*val = BusRead16(addr & ~1);
DataCycles = MemTimings[addr >> BUSCYCLES_MAP_GRANULARITY_LOG2][BUSCYCLES_S16];
}
void ARMv5::DataRead32(u32 addr, u32* val)
void ARMv5::DataRead32(const u32 addr, u32* val)
{
if (!(PU_Map[addr>>12] & 0x01))
if (!(PU_Map[addr>>CP15_MAP_ENTRYSIZE_LOG2] & CP15_MAP_READABLE))
{
Log(LogLevel::Debug, "data32 abort @ %08lx\n", addr);
DataAbort();
@ -1507,7 +1476,7 @@ void ARMv5::DataRead32(u32 addr, u32* val)
{
if (CP15Control & CP15_CACHE_CR_DCACHEENABLE)
{
if (PU_Map[addr >> 12] & 0x10)
if (IsAddressDCachable(addr))
{
*val = DCacheLookup(addr);
return;
@ -1515,36 +1484,32 @@ void ARMv5::DataRead32(u32 addr, u32* val)
}
}
addr &= ~3;
if (addr < ITCMSize)
{
DataCycles = 1;
*val = *(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)];
*val = *(u32*)&ITCM[addr & (ITCMPhysicalSize - 3)];
return;
}
if ((addr & DTCMMask) == DTCMBase)
{
DataCycles = 1;
*val = *(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)];
*val = *(u32*)&DTCM[addr & (DTCMPhysicalSize - 3)];
return;
}
*val = BusRead32(addr);
DataCycles = MemTimings[addr >> 12][2];
*val = BusRead32(addr & ~0x03);
DataCycles = MemTimings[addr >> BUSCYCLES_MAP_GRANULARITY_LOG2][BUSCYCLES_N32];
}
void ARMv5::DataRead32S(u32 addr, u32* val)
void ARMv5::DataRead32S(const u32 addr, u32* val)
{
addr &= ~3;
#ifdef JIT_ENABLED
if (!NDS.IsJITEnabled())
#endif
{
if (CP15Control & CP15_CACHE_CR_DCACHEENABLE)
{
if (PU_Map[addr >> 12] & 0x10)
if (IsAddressDCachable(addr))
{
*val = DCacheLookup(addr);
return;
@ -1555,23 +1520,23 @@ void ARMv5::DataRead32S(u32 addr, u32* val)
if (addr < ITCMSize)
{
DataCycles += 1;
*val = *(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)];
*val = *(u32*)&ITCM[addr & (ITCMPhysicalSize - 3)];
return;
}
if ((addr & DTCMMask) == DTCMBase)
{
DataCycles += 1;
*val = *(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)];
*val = *(u32*)&DTCM[addr & (DTCMPhysicalSize - 3)];
return;
}
*val = BusRead32(addr);
DataCycles += MemTimings[addr >> 12][3];
*val = BusRead32(addr & ~0x03);
DataCycles += MemTimings[addr >> BUSCYCLES_MAP_GRANULARITY_LOG2][BUSCYCLES_S32];
}
void ARMv5::DataWrite8(u32 addr, u8 val)
void ARMv5::DataWrite8(const u32 addr, const u8 val)
{
if (!(PU_Map[addr>>12] & 0x02))
if (!(PU_Map[addr>>CP15_MAP_ENTRYSIZE_LOG2] & CP15_MAP_WRITEABLE))
{
DataAbort();
return;
@ -1583,10 +1548,9 @@ void ARMv5::DataWrite8(u32 addr, u8 val)
{
if (CP15Control & CP15_CACHE_CR_DCACHEENABLE)
{
if (PU_Map[addr >> 12] & 0x10)
if (IsAddressDCachable(addr))
{
DCacheWrite8(addr, val);
//DCacheInvalidateByAddr(addr);
}
}
}
@ -1608,12 +1572,12 @@ void ARMv5::DataWrite8(u32 addr, u8 val)
}
BusWrite8(addr, val);
DataCycles = MemTimings[addr >> 12][1];
DataCycles = MemTimings[addr >> BUSCYCLES_MAP_GRANULARITY_LOG2][BUSCYCLES_S16];
}
void ARMv5::DataWrite16(u32 addr, u16 val)
void ARMv5::DataWrite16(const u32 addr, const u16 val)
{
if (!(PU_Map[addr>>12] & 0x02))
if (!(PU_Map[addr>>CP15_MAP_ENTRYSIZE_LOG2] & CP15_MAP_WRITEABLE))
{
DataAbort();
return;
@ -1625,39 +1589,36 @@ void ARMv5::DataWrite16(u32 addr, u16 val)
{
if (CP15Control & CP15_CACHE_CR_DCACHEENABLE)
{
if (PU_Map[addr >> 12] & 0x10)
if (IsAddressDCachable(addr))
{
DCacheWrite16(addr, val);
// DCacheInvalidateByAddr(addr);
}
}
}
DataRegion = addr;
addr &= ~1;
if (addr < ITCMSize)
{
DataCycles = 1;
*(u16*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val;
*(u16*)&ITCM[addr & (ITCMPhysicalSize - 2)] = val;
NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr);
return;
}
if ((addr & DTCMMask) == DTCMBase)
{
DataCycles = 1;
*(u16*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val;
*(u16*)&DTCM[addr & (DTCMPhysicalSize - 2)] = val;
return;
}
BusWrite16(addr, val);
DataCycles = MemTimings[addr >> 12][1];
BusWrite16(addr & ~1, val);
DataCycles = MemTimings[addr >> BUSCYCLES_MAP_GRANULARITY_LOG2][BUSCYCLES_S16];
}
void ARMv5::DataWrite32(u32 addr, u32 val)
void ARMv5::DataWrite32(const u32 addr, const u32 val)
{
if (!(PU_Map[addr>>12] & 0x02))
if (!(PU_Map[addr>>CP15_MAP_ENTRYSIZE_LOG2] & CP15_MAP_WRITEABLE))
{
DataAbort();
return;
@ -1669,50 +1630,44 @@ void ARMv5::DataWrite32(u32 addr, u32 val)
{
if (CP15Control & CP15_CACHE_CR_DCACHEENABLE)
{
if (PU_Map[addr >> 12] & 0x10)
if (IsAddressDCachable(addr))
{
DCacheWrite32(addr, val);
// DCacheInvalidateByAddr(addr);
}
}
}
DataRegion = addr;
addr &= ~3;
if (addr < ITCMSize)
{
DataCycles = 1;
*(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val;
*(u32*)&ITCM[addr & (ITCMPhysicalSize - 3)] = val;
NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr);
return;
}
if ((addr & DTCMMask) == DTCMBase)
{
DataCycles = 1;
*(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val;
*(u32*)&DTCM[addr & (DTCMPhysicalSize - 3)] = val;
return;
}
BusWrite32(addr, val);
DataCycles = MemTimings[addr >> 12][2];
BusWrite32(addr & ~3, val);
DataCycles = MemTimings[addr >> BUSCYCLES_MAP_GRANULARITY_LOG2][BUSCYCLES_N32];
}
void ARMv5::DataWrite32S(u32 addr, u32 val)
void ARMv5::DataWrite32S(const u32 addr, const u32 val)
{
addr &= ~3;
#ifdef JIT_ENABLED
if (!NDS.IsJITEnabled())
#endif
{
if (CP15Control & CP15_CACHE_CR_DCACHEENABLE)
{
if (PU_Map[addr >> 12] & 0x10)
if (IsAddressDCachable(addr))
{
DCacheWrite32(addr, val);
// DCacheInvalidateByAddr(addr);
}
}
}
@ -1720,7 +1675,7 @@ void ARMv5::DataWrite32S(u32 addr, u32 val)
if (addr < ITCMSize)
{
DataCycles += 1;
*(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val;
*(u32*)&ITCM[addr & (ITCMPhysicalSize - 3)] = val;
#ifdef JIT_ENABLED
NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr);
#endif
@ -1729,23 +1684,16 @@ void ARMv5::DataWrite32S(u32 addr, u32 val)
if ((addr & DTCMMask) == DTCMBase)
{
DataCycles += 1;
*(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val;
*(u32*)&DTCM[addr & (DTCMPhysicalSize - 3)] = val;
return;
}
BusWrite32(addr, val);
DataCycles += MemTimings[addr >> 12][3];
BusWrite32(addr & ~3, val);
DataCycles += MemTimings[addr >> BUSCYCLES_MAP_GRANULARITY_LOG2][BUSCYCLES_S32];
}
void ARMv5::GetCodeMemRegion(u32 addr, MemRegion* region)
{
/*if (addr < ITCMSize)
{
region->Mem = ITCM;
region->Mask = 0x7FFF;
return;
}*/
NDS.ARM9GetMemRegion(addr, false, &CodeMem);
}

131
src/CP15_Constants.h Normal file
View File

@ -0,0 +1,131 @@
/*
Copyright 2016-2023 melonDS team
This file is part of melonDS.
melonDS 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.
melonDS 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 melonDS. If not, see http://www.gnu.org/licenses/.
*/
#ifndef MELONDS_CP15CONSTANTS_H
#define MELONDS_CP15CONSTANTS_H
#include "types.h"
namespace melonDS
{
/* ICACHE Layout constants */
constexpr u32 ICACHE_SIZE_LOG2 = 13;
constexpr u32 ICACHE_SIZE = 1 << ICACHE_SIZE_LOG2;
constexpr u32 ICACHE_SETS_LOG2 = 2;
constexpr u32 ICACHE_SETS = 1 << ICACHE_SETS_LOG2;
constexpr u32 ICACHE_LINELENGTH_ENCODED = 2;
constexpr u32 ICACHE_LINELENGTH_LOG2 = ICACHE_LINELENGTH_ENCODED + 3;
constexpr u32 ICACHE_LINELENGTH = 8 * (1 << ICACHE_LINELENGTH_ENCODED);
constexpr u32 ICACHE_LINESPERSET = ICACHE_SIZE / (ICACHE_SETS * ICACHE_LINELENGTH);
/* DCACHE Layout constants */
constexpr u32 DCACHE_SIZE_LOG2 = 12;
constexpr u32 DCACHE_SIZE = 1 << DCACHE_SIZE_LOG2;
constexpr u32 DCACHE_SETS_LOG2 = 2;
constexpr u32 DCACHE_SETS = 1 << DCACHE_SETS_LOG2;
constexpr u32 DCACHE_LINELENGTH_ENCODED = 2;
constexpr u32 DCACHE_LINELENGTH_LOG2 = DCACHE_LINELENGTH_ENCODED + 3;
constexpr u32 DCACHE_LINELENGTH = 8 * (1 << DCACHE_LINELENGTH_ENCODED);
constexpr u32 DCACHE_LINESPERSET = DCACHE_SIZE / (DCACHE_SETS * DCACHE_LINELENGTH);
/* CP15 Cache Data TAGs */
constexpr u32 CACHE_FLAG_VALID = (1 << 4);
constexpr u32 CACHE_FLAG_DIRTY_LOWERHALF = (1 << 2);
constexpr u32 CACHE_FLAG_DIRTY_UPPERHALF = (1 << 3);
constexpr u32 CACHE_FLAG_DIRTY_MASK = (3 << 2);
constexpr u32 CACHE_FLAG_SET_MASK = (3 << 0);
/* CP15 Cache Type Register */
constexpr u32 CACHE_TR_LOCKDOWN_TYPE_B = (7 << 25);
constexpr u32 CACHE_TR_NONUNIFIED = (1 << 24);
/* CP15 I/DCache LockDown registers */
constexpr u32 CACHE_LOCKUP_L = (1 << 31);
/* CP15 Main ID register */
constexpr u32 CP15_MAINID_IMPLEMENTOR_ARM = (0x41 << 24);
constexpr u32 CP15_MAINID_IMPLEMENTOR_DEC = (0x44 << 24);
constexpr u32 CP15_MAINID_IMPLEMENTOR_MOTOROLA = (0x4D << 24);
constexpr u32 CP15_MAINID_IMPLEMENTOR_MARVELL = (0x56 << 24);
constexpr u32 CP15_MAINID_IMPLEMENTOR_INTEL = (0x69 << 24);
constexpr u32 CP15_MAINID_VARIANT_0 = (0 << 20);
constexpr u32 CP15_MAINID_ARCH_v4 = (1 << 16);
constexpr u32 CP15_MAINID_ARCH_v4T = (2 << 16);
constexpr u32 CP15_MAINID_ARCH_v5 = (3 << 16);
constexpr u32 CP15_MAINID_ARCH_v5T = (4 << 16);
constexpr u32 CP15_MAINID_ARCH_v5TE = (5 << 16);
constexpr u32 CP15_MAINID_ARCH_v5TEJ = (6 << 16);
constexpr u32 CP15_MAINID_ARCH_v6 = (7 << 16);
constexpr u32 CP15_MAINID_IMPLEMENTATION_946 = (0x946 << 4);
constexpr u32 CP15_MAINID_REVISION_0 = (0 << 0);
constexpr u32 CP15_MAINID_REVISION_1 = (1 << 0);
/* CP15 Control Register */
constexpr u32 CP15_CR_MPUENABLE = (1 << 0);
constexpr u32 CP15_CR_BIGENDIAN = (1 << 7);
constexpr u32 CP15_CR_HIGHEXCEPTIONBASE = (1 << 13);
/* CP15 Internal Exception base value */
constexpr u32 CP15_EXCEPTIONBASE_HIGH = 0xFFFF0000;
constexpr u32 CP15_EXCEPTIONBASE_LOW = 0x00000000;
/* CP15 Cache and Write Buffer Conrol Register */
constexpr u32 CP15_CACHE_CR_ROUNDROBIN = (1 << 14);
constexpr u32 CP15_CACHE_CR_ICACHEENABLE = (1 << 12);
constexpr u32 CP15_CACHE_CR_DCACHEENABLE = (1 << 2);
constexpr u32 CP15_CACHE_CR_WRITEBUFFERENABLE = (1 << 3);
/* CP15 TCM Control Register */
constexpr u32 CP15_TCM_CR_DTCM_ENABLE = (1 << 16);
constexpr u32 CP15_TCM_CR_ITCM_ENABLE = (1 << 18);
/* CP15 Region Base and Size Register */
constexpr u32 CP15_REGION_COUNT = 8;
constexpr u32 CP15_REGION_ENABLE = (1 << 0);
constexpr u32 CP15_REGION_SIZE_MASK = (0x1F << 1);
constexpr u32 CP15_REGION_BASE_GRANULARITY_LOG2 = 12;
constexpr u32 CP15_REGION_BASE_GRANULARITY = (1 << CP15_REGION_BASE_GRANULARITY_LOG2);
constexpr u32 CP15_REGION_BASE_MASK = ~(CP15_REGION_BASE_GRANULARITY_LOG2-1);
/* CP15 Region access mask registers */
constexpr u32 CP15_REGIONACCESS_BITS_PER_REGION = 4;
constexpr u32 CP15_REGIONACCESS_REGIONMASK = (1 << CP15_REGIONACCESS_BITS_PER_REGION) - 1;
/* Flags in the melonDS internal PU_PrivMap and PU_UserMap */
constexpr u32 CP15_MAP_NOACCESS = 0x00;
constexpr u32 CP15_MAP_READABLE = 0x01;
constexpr u32 CP15_MAP_WRITEABLE = 0x02;
constexpr u32 CP15_MAP_EXECUTABLE = 0x04;
constexpr u32 CP15_MAP_DCACHEABLE = 0x10;
constexpr u32 CP15_MAP_DCACHEWRITEBACK = 0x20;
constexpr u32 CP15_MAP_ICACHEABLE = 0x40;
constexpr u32 CP15_MAP_ENTRYSIZE_LOG2 = CP15_REGION_BASE_GRANULARITY_LOG2;
constexpr u32 CP15_MAP_ENTRYSIZE = (1 << CP15_MAP_ENTRYSIZE_LOG2);
/* Internal Timing Constants */
constexpr u32 BUSCYCLES_N16 = 0;
constexpr u32 BUSCYCLES_S16 = 1;
constexpr u32 BUSCYCLES_N32 = 2;
constexpr u32 BUSCYCLES_S32 = 3;
constexpr u32 BUSCYCLES_MAP_GRANULARITY_LOG2 = CP15_REGION_BASE_GRANULARITY_LOG2;
}
#endif // MELONDS_CP15CONSTANTS_H

View File

@ -34,44 +34,6 @@ constexpr u32 ITCMPhysicalSize = 0x8000;
constexpr u32 DTCMPhysicalSize = 0x4000;
constexpr u32 ARM7BIOSCRC32 = 0x1280f0d5;
constexpr u32 ARM9BIOSCRC32 = 0x2ab23573;
constexpr u32 ICACHE_SIZE_LOG2 = 13;
constexpr u32 ICACHE_SIZE = 1 << ICACHE_SIZE_LOG2;
constexpr u32 ICACHE_SETS_LOG2 = 2;
constexpr u32 ICACHE_SETS = 1 << ICACHE_SETS_LOG2;
constexpr u32 ICACHE_LINELENGTH_ENCODED = 2;
constexpr u32 ICACHE_LINELENGTH_LOG2 = ICACHE_LINELENGTH_ENCODED + 3;
constexpr u32 ICACHE_LINELENGTH = 8 * (1 << ICACHE_LINELENGTH_ENCODED);
constexpr u32 ICACHE_LINESPERSET = ICACHE_SIZE / (ICACHE_SETS * ICACHE_LINELENGTH);
constexpr u32 DCACHE_SIZE_LOG2 = 12;
constexpr u32 DCACHE_SIZE = 1 << DCACHE_SIZE_LOG2;
constexpr u32 DCACHE_SETS_LOG2 = 2;
constexpr u32 DCACHE_SETS = 1 << DCACHE_SETS_LOG2;
constexpr u32 DCACHE_LINELENGTH_ENCODED = 2;
constexpr u32 DCACHE_LINELENGTH_LOG2 = DCACHE_LINELENGTH_ENCODED + 3;
constexpr u32 DCACHE_LINELENGTH = 8 * (1 << DCACHE_LINELENGTH_ENCODED);
constexpr u32 DCACHE_LINESPERSET = DCACHE_SIZE / (DCACHE_SETS * DCACHE_LINELENGTH);
constexpr u32 CACHE_FLAG_VALID = (1 << 4);
constexpr u32 CACHE_FLAG_DIRTY_LOWERHALF = (1 << 2);
constexpr u32 CACHE_FLAG_DIRTY_UPPERHALF = (1 << 3);
constexpr u32 CACHE_TR_LOCKDOWN_TYPE_B = (7 << 25);
constexpr u32 CACHE_TR_NONUNIFIED = (1 << 24);
constexpr u32 CACHE_LOCKUP_L = (1 << 31);
constexpr u32 CP15_CR_MPUENABLE = (1 << 0);
constexpr u32 CP15_CR_BIGENDIAN = (1 << 7);
constexpr u32 CP15_CR_HIGHEXCEPTIONBASE = (1 << 13);
constexpr u32 CP15_CACHE_CR_ROUNDROBIN = (1 << 14);
constexpr u32 CP15_CACHE_CR_ICACHEENABLE = (1 << 12);
constexpr u32 CP15_CACHE_CR_DCACHEENABLE = (1 << 2);
constexpr u32 CP15_CACHE_CR_WRITEBUFFERENABLE = (1 << 3);
constexpr u32 CP15_TCM_CR_DTCM_ENABLE = (1 << 16);
constexpr u32 CP15_TCM_CR_ITCM_ENABLE = (1 << 18);
}
#endif // MELONDS_MEMCONSTANTS_H