Added check of op1 in MCR/MRC
Fixed Cache Debug registers were accessible, when op1 != 3 in MCR/MRC instructions Added BIST Test Status register and its cache linefill disable bits
This commit is contained in:
parent
81c9434116
commit
9fa814b68e
|
@ -343,6 +343,7 @@ public:
|
|||
u32 DCacheLockDown, ICacheLockDown;
|
||||
u32 CacheDebugRegisterIndex;
|
||||
u32 CP15TraceProcessId;
|
||||
u32 CP15BISTTestStateRegister;
|
||||
|
||||
// for aarch64 JIT they need to go up here
|
||||
// to be addressable by a 12-bit immediate
|
||||
|
|
|
@ -212,14 +212,14 @@ void A_MCR(ARM* cpu)
|
|||
return A_UNK(cpu);
|
||||
|
||||
u32 cp = (cpu->CurInstr >> 8) & 0xF;
|
||||
//u32 op = (cpu->CurInstr >> 21) & 0x7;
|
||||
u32 op = (cpu->CurInstr >> 21) & 0x7;
|
||||
u32 cn = (cpu->CurInstr >> 16) & 0xF;
|
||||
u32 cm = cpu->CurInstr & 0xF;
|
||||
u32 cpinfo = (cpu->CurInstr >> 5) & 0x7;
|
||||
|
||||
if (cpu->Num==0 && cp==15)
|
||||
{
|
||||
((ARMv5*)cpu)->CP15Write((cn<<8)|(cm<<4)|cpinfo, cpu->R[(cpu->CurInstr>>12)&0xF]);
|
||||
((ARMv5*)cpu)->CP15Write((cn<<8)|(cm<<4)|cpinfo|(op<<12), cpu->R[(cpu->CurInstr>>12)&0xF]);
|
||||
}
|
||||
else if (cpu->Num==1 && cp==14)
|
||||
{
|
||||
|
@ -227,7 +227,7 @@ void A_MCR(ARM* cpu)
|
|||
}
|
||||
else
|
||||
{
|
||||
Log(LogLevel::Warn, "bad MCR opcode p%d,%d,%d,%d on ARM%d\n", cp, cn, cm, cpinfo, cpu->Num?7:9);
|
||||
Log(LogLevel::Warn, "bad MCR opcode p%d, %d, reg, c%d, c%d, %d on ARM%d\n", cp, op, cn, cm, cpinfo, cpu->Num?7:9);
|
||||
return A_UNK(cpu); // TODO: check what kind of exception it really is
|
||||
}
|
||||
|
||||
|
@ -240,14 +240,14 @@ void A_MRC(ARM* cpu)
|
|||
return A_UNK(cpu);
|
||||
|
||||
u32 cp = (cpu->CurInstr >> 8) & 0xF;
|
||||
//u32 op = (cpu->CurInstr >> 21) & 0x7;
|
||||
u32 op = (cpu->CurInstr >> 21) & 0x7;
|
||||
u32 cn = (cpu->CurInstr >> 16) & 0xF;
|
||||
u32 cm = cpu->CurInstr & 0xF;
|
||||
u32 cpinfo = (cpu->CurInstr >> 5) & 0x7;
|
||||
|
||||
if (cpu->Num==0 && cp==15)
|
||||
{
|
||||
cpu->R[(cpu->CurInstr>>12)&0xF] = ((ARMv5*)cpu)->CP15Read((cn<<8)|(cm<<4)|cpinfo);
|
||||
cpu->R[(cpu->CurInstr>>12)&0xF] = ((ARMv5*)cpu)->CP15Read((cn<<8)|(cm<<4)|cpinfo|(op<<12));
|
||||
}
|
||||
else if (cpu->Num==1 && cp==14)
|
||||
{
|
||||
|
@ -255,7 +255,7 @@ void A_MRC(ARM* cpu)
|
|||
}
|
||||
else
|
||||
{
|
||||
Log(LogLevel::Warn, "bad MRC opcode p%d,%d,%d,%d on ARM%d\n", cp, cn, cm, cpinfo, cpu->Num?7:9);
|
||||
Log(LogLevel::Warn, "bad MRC opcode p%d, %d, reg, c%d, c%d, %d on ARM%d\n", cp, op, cn, cm, cpinfo, cpu->Num?7:9);
|
||||
return A_UNK(cpu); // TODO: check what kind of exception it really is
|
||||
}
|
||||
|
||||
|
|
66
src/CP15.cpp
66
src/CP15.cpp
|
@ -69,6 +69,7 @@ void ARMv5::CP15Reset()
|
|||
ICacheLockDown = 0;
|
||||
DCacheLockDown = 0;
|
||||
CacheDebugRegisterIndex = 0;
|
||||
CP15BISTTestStateRegister = 0;
|
||||
|
||||
memset(ICache, 0, ICACHE_SIZE);
|
||||
ICacheInvalidateAll();
|
||||
|
@ -116,6 +117,7 @@ void ARMv5::CP15DoSavestate(Savestate* file)
|
|||
file->Var32(&ICacheLockDown);
|
||||
file->Var32(&CacheDebugRegisterIndex);
|
||||
file->Var32(&CP15TraceProcessId);
|
||||
file->Var32(&CP15BISTTestStateRegister);
|
||||
|
||||
file->Var32(&PU_CodeCacheable);
|
||||
file->Var32(&PU_DataCacheable);
|
||||
|
@ -384,6 +386,21 @@ u32 ARMv5::ICacheLookup(const u32 addr)
|
|||
}
|
||||
|
||||
// cache miss
|
||||
|
||||
// We do not fill the cacheline if it is disabled in the
|
||||
// BIST test State register (See arm946e-s Rev 1 technical manual, 2.3.15 "Register 15, test State Register")
|
||||
if (CP15BISTTestStateRegister & CP15_BIST_TR_DISABLE_ICACHE_LINEFILL)
|
||||
{
|
||||
CodeCycles = NDS.ARM9MemTimings[tag >> 14][2];
|
||||
if (CodeMem.Mem)
|
||||
{
|
||||
return *(u32*)&CodeMem.Mem[(addr & CodeMem.Mask) & ~3];
|
||||
} else
|
||||
{
|
||||
return NDS.ARM9Read32(addr & ~3);
|
||||
}
|
||||
}
|
||||
|
||||
u32 line;
|
||||
#if 0
|
||||
// caclulate in which cacheline the data is to be filled
|
||||
|
@ -507,6 +524,25 @@ u32 ARMv5::DCacheLookup(const u32 addr)
|
|||
}
|
||||
|
||||
// cache miss
|
||||
|
||||
// We do not fill the cacheline if it is disabled in the
|
||||
// BIST test State register (See arm946e-s Rev 1 technical manual, 2.3.15 "Register 15, test State Register")
|
||||
if (CP15BISTTestStateRegister & CP15_BIST_TR_DISABLE_DCACHE_LINEFILL)
|
||||
{
|
||||
DataCycles = NDS.ARM9MemTimings[tag >> 14][2];
|
||||
if (addr < ITCMSize)
|
||||
{
|
||||
return *(u32*)&ITCM[addr & (ITCMPhysicalSize - 3)];
|
||||
} else
|
||||
if ((addr & DTCMMask) == DTCMBase)
|
||||
{
|
||||
return *(u32*)&DTCM[addr & (DTCMPhysicalSize - 3)];
|
||||
} else
|
||||
{
|
||||
return BusRead32(addr & ~3);
|
||||
}
|
||||
}
|
||||
|
||||
u32 line;
|
||||
#if 0
|
||||
// caclulate in which cacheline the data is to be filled
|
||||
|
@ -694,7 +730,7 @@ void ARMv5::CP15Write(u32 id, u32 val)
|
|||
{
|
||||
//if(id!=0x704)printf("CP15 write op %03X %08X %08X\n", id, val, R[15]);
|
||||
|
||||
switch (id)
|
||||
switch (id & 0xFFF)
|
||||
{
|
||||
case 0x100:
|
||||
{
|
||||
|
@ -1112,7 +1148,20 @@ void ARMv5::CP15Write(u32 id, u32 val)
|
|||
else
|
||||
return ARMInterpreter::A_UNK(this);
|
||||
} else
|
||||
CacheDebugRegisterIndex = val;
|
||||
{
|
||||
if (((id >> 12) & 0x0f) == 0x03)
|
||||
CacheDebugRegisterIndex = val;
|
||||
else if (((id >> 12) & 0x0f) == 0x00)
|
||||
CP15BISTTestStateRegister = val;
|
||||
else
|
||||
{
|
||||
if (CPSR & 0x20) // THUMB
|
||||
return ARMInterpreter::T_UNK(this);
|
||||
else
|
||||
return ARMInterpreter::A_UNK(this);
|
||||
}
|
||||
|
||||
}
|
||||
return;
|
||||
|
||||
case 0xF10:
|
||||
|
@ -1184,14 +1233,14 @@ void ARMv5::CP15Write(u32 id, u32 val)
|
|||
|
||||
}
|
||||
|
||||
Log(LogLevel::Debug, "unknown CP15 write op %03X %08X\n", id, val);
|
||||
Log(LogLevel::Debug, "unknown CP15 write op %04X %08X\n", id, val);
|
||||
}
|
||||
|
||||
u32 ARMv5::CP15Read(u32 id) const
|
||||
{
|
||||
//printf("CP15 read op %03X %08X\n", id, NDS::ARM9->R[15]);
|
||||
|
||||
switch (id)
|
||||
switch (id & 0xFFF)
|
||||
{
|
||||
case 0x000: // CPU ID
|
||||
case 0x003:
|
||||
|
@ -1304,7 +1353,12 @@ u32 ARMv5::CP15Read(u32 id) const
|
|||
{
|
||||
return 0;
|
||||
} else
|
||||
return CacheDebugRegisterIndex;
|
||||
{
|
||||
if (((id >> 12) & 0x0f) == 0x03)
|
||||
return CacheDebugRegisterIndex;
|
||||
if (((id >> 12) & 0x0f) == 0x00)
|
||||
return CP15BISTTestStateRegister;
|
||||
}
|
||||
case 0xF10:
|
||||
// instruction cache Tag register
|
||||
if (PU_Map != PU_PrivMap)
|
||||
|
@ -1351,7 +1405,7 @@ u32 ARMv5::CP15Read(u32 id) const
|
|||
}
|
||||
}
|
||||
|
||||
Log(LogLevel::Debug, "unknown CP15 read op %03X\n", id);
|
||||
Log(LogLevel::Debug, "unknown CP15 read op %04X\n", id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -91,6 +91,10 @@ 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 BIST Test State register */
|
||||
constexpr u32 CP15_BIST_TR_DISABLE_ICACHE_LINEFILL = (1 << 9);
|
||||
constexpr u32 CP15_BIST_TR_DISABLE_DCACHE_LINEFILL = (1 << 10);
|
||||
|
||||
/* CP15 TCM Control Register */
|
||||
constexpr u32 CP15_TCM_CR_DTCM_ENABLE = (1 << 16);
|
||||
constexpr u32 CP15_TCM_CR_ITCM_ENABLE = (1 << 18);
|
||||
|
|
Loading…
Reference in New Issue