diff options
Diffstat (limited to 'src/CP15.cpp')
-rw-r--r-- | src/CP15.cpp | 297 |
1 files changed, 123 insertions, 174 deletions
diff --git a/src/CP15.cpp b/src/CP15.cpp index 0665137..0d1be76 100644 --- a/src/CP15.cpp +++ b/src/CP15.cpp @@ -22,6 +22,11 @@ #include "ARM.h" +// access timing for cached regions +// this would be an average between cache hits and cache misses +const int kDataCacheTiming = 2; +const int kCodeCacheTiming = 1; + void ARMv5::CP15Reset() { @@ -211,6 +216,47 @@ void ARMv5::UpdatePURegions() codecache >>= 1; datacache >>= 1; datawrite >>= 1; + + // TODO: this will not be enough if they change their PU regions after the intial setup + //UpdateRegionTimings(start<<12, end<<12); + } + + UpdateRegionTimings(0x00000000, 0xFFFFFFFF); +} + +void ARMv5::UpdateRegionTimings(u32 addrstart, u32 addrend) +{ + addrstart >>= 12; + addrend >>= 12; + + if (addrend == 0xFFFFF) addrend++; + + for (u32 i = addrstart; i < addrend; i++) + { + u8 pu = PU_Map[i]; + u8* bustimings = NDS::ARM9MemTimings[i >> 2]; + + if (pu & 0x40) + { + MemTimings[i][0] = kCodeCacheTiming; + } + else + { + MemTimings[i][0] = bustimings[2] << ClockShift; + } + + if (pu & 0x10) + { + MemTimings[i][1] = kDataCacheTiming; + MemTimings[i][2] = kDataCacheTiming; + MemTimings[i][3] = kDataCacheTiming; + } + else + { + MemTimings[i][1] = bustimings[0] << ClockShift; + MemTimings[i][2] = bustimings[2] << ClockShift; + MemTimings[i][3] = bustimings[3] << ClockShift; + } } } @@ -460,280 +506,183 @@ u32 ARMv5::CP15Read(u32 id) u32 ARMv5::CodeRead32(u32 addr) { - u8 pu = PU_Map[addr>>12]; - if (addr < ITCMSize) { - CodeRegion = NDS::Region9_ITCM; return *(u32*)&ITCM[addr & 0x7FFF]; } - u32 ret; - CodeRegion = NDS::ARM9Read32(addr, &ret); - if (pu & 0x40) CodeRegion = NDS::Region9_ICache; - return ret; + return NDS::ARM9Read32(addr); } -bool ARMv5::DataRead8(u32 addr, u32* val, u32 flags) +void ARMv5::DataRead8(u32 addr, u32* val) { - u8 pu = PU_Map[addr>>12]; - /*if (!(pu & 0x01)) - { - DataAbort(); - return false; - }*/ - if (addr < ITCMSize) { - DataRegion = NDS::Region9_ITCM; - if (flags & RWFlags_Nonseq) DataCycles = 1; - else DataCycles += 1; + DataCycles = 1; *val = *(u8*)&ITCM[addr & 0x7FFF]; - return true; + return; } if (addr >= DTCMBase && addr < (DTCMBase + DTCMSize)) { - DataRegion = NDS::Region9_DTCM; - if (flags & RWFlags_Nonseq) DataCycles = 1; - else DataCycles += 1; + DataCycles = 1; *val = *(u8*)&DTCM[(addr - DTCMBase) & 0x3FFF]; - return true; + return; } - DataRegion = NDS::ARM9Read8(addr, val); - if (pu & 0x10) - { - DataRegion = NDS::Region9_DCache; - if (flags & RWFlags_Nonseq) DataCycles = 2; - else DataCycles += 2; - } - else - { - if (flags & RWFlags_Nonseq) DataCycles = NDS::ARM9MemTimings[DataRegion][0]; - else DataCycles += NDS::ARM9MemTimings[DataRegion][1]; - } - return true; + *val = NDS::ARM9Read8(addr); + DataCycles = MemTimings[addr >> 12][1]; } -bool ARMv5::DataRead16(u32 addr, u32* val, u32 flags) +void ARMv5::DataRead16(u32 addr, u32* val) { addr &= ~1; - u8 pu = PU_Map[addr>>12]; - /*if (!(pu & 0x01)) - { - DataAbort(); - return false; - }*/ - if (addr < ITCMSize) { - DataRegion = NDS::Region9_ITCM; - if (flags & RWFlags_Nonseq) DataCycles = 1; - else DataCycles += 1; + DataCycles = 1; *val = *(u16*)&ITCM[addr & 0x7FFF]; - return true; + return; } if (addr >= DTCMBase && addr < (DTCMBase + DTCMSize)) { - DataRegion = NDS::Region9_DTCM; - if (flags & RWFlags_Nonseq) DataCycles = 1; - else DataCycles += 1; + DataCycles = 1; *val = *(u16*)&DTCM[(addr - DTCMBase) & 0x3FFF]; - return true; + return; } - DataRegion = NDS::ARM9Read16(addr, val); - if (pu & 0x10) - { - DataRegion = NDS::Region9_DCache; - if (flags & RWFlags_Nonseq) DataCycles = 2; - else DataCycles += 2; - } - else - { - if (flags & RWFlags_Nonseq) DataCycles = NDS::ARM9MemTimings[DataRegion][0]; - else DataCycles += NDS::ARM9MemTimings[DataRegion][1]; - } - return true; + *val = NDS::ARM9Read16(addr); + DataCycles = MemTimings[addr >> 12][1]; } -bool ARMv5::DataRead32(u32 addr, u32* val, u32 flags) +void ARMv5::DataRead32(u32 addr, u32* val) { addr &= ~3; - u8 pu = PU_Map[addr>>12]; - /*if (!(pu & 0x01)) - { - DataAbort(); - return false; - }*/ - if (addr < ITCMSize) { - DataRegion = NDS::Region9_ITCM; - if (flags & RWFlags_Nonseq) DataCycles = 1; - else DataCycles += 1; + DataCycles = 1; *val = *(u32*)&ITCM[addr & 0x7FFF]; - return true; + return; } if (addr >= DTCMBase && addr < (DTCMBase + DTCMSize)) { - DataRegion = NDS::Region9_DTCM; - if (flags & RWFlags_Nonseq) DataCycles = 1; - else DataCycles += 1; + DataCycles = 1; *val = *(u32*)&DTCM[(addr - DTCMBase) & 0x3FFF]; - return true; + return; } - DataRegion = NDS::ARM9Read32(addr, val); - if (pu & 0x10) + *val = NDS::ARM9Read32(addr); + DataCycles = MemTimings[addr >> 12][2]; +} + +void ARMv5::DataRead32S(u32 addr, u32* val) +{ + addr &= ~3; + + if (addr < ITCMSize) { - DataRegion = NDS::Region9_DCache; - if (flags & RWFlags_Nonseq) DataCycles = 2; - else DataCycles += 2; + DataCycles += 1; + *val = *(u32*)&ITCM[addr & 0x7FFF]; + return; } - else + if (addr >= DTCMBase && addr < (DTCMBase + DTCMSize)) { - if (flags & RWFlags_Nonseq) DataCycles = NDS::ARM9MemTimings[DataRegion][0]; - else DataCycles += NDS::ARM9MemTimings[DataRegion][1]; + DataCycles += 1; + *val = *(u32*)&DTCM[(addr - DTCMBase) & 0x3FFF]; + return; } - return true; + + *val = NDS::ARM9Read32(addr); + DataCycles += MemTimings[addr >> 12][3]; } -bool ARMv5::DataWrite8(u32 addr, u8 val, u32 flags) +void ARMv5::DataWrite8(u32 addr, u8 val) { - u8 pu = PU_Map[addr>>12]; - /*if (!(pu & 0x02)) - { - DataAbort(); - return false; - }*/ - if (addr < ITCMSize) { - DataRegion = NDS::Region9_ITCM; - if (flags & RWFlags_Nonseq) DataCycles = 1; - else DataCycles += 1; + DataCycles = 1; *(u8*)&ITCM[addr & 0x7FFF] = val; - return true; + return; } if (addr >= DTCMBase && addr < (DTCMBase + DTCMSize)) { - DataRegion = NDS::Region9_DTCM; - if (flags & RWFlags_Nonseq) DataCycles = 1; - else DataCycles += 1; + DataCycles = 1; *(u8*)&DTCM[(addr - DTCMBase) & 0x3FFF] = val; - return true; + return; } - DataRegion = NDS::ARM9Write8(addr, val); - if (pu & 0x20) - { - DataRegion = NDS::Region9_DCache; - if (flags & RWFlags_Nonseq) DataCycles = 2; - else DataCycles += 2; - } - else - { - if (flags & RWFlags_Nonseq) DataCycles = NDS::ARM9MemTimings[DataRegion][0]; - else DataCycles += NDS::ARM9MemTimings[DataRegion][1]; - } - return true; + NDS::ARM9Write8(addr, val); + DataCycles = MemTimings[addr >> 12][1]; } -bool ARMv5::DataWrite16(u32 addr, u16 val, u32 flags) +void ARMv5::DataWrite16(u32 addr, u16 val) { addr &= ~1; - u8 pu = PU_Map[addr>>12]; - /*if (!(pu & 0x02)) - { - DataAbort(); - return false; - }*/ - if (addr < ITCMSize) { - DataRegion = NDS::Region9_ITCM; - if (flags & RWFlags_Nonseq) DataCycles = 1; - else DataCycles += 1; + DataCycles = 1; *(u16*)&ITCM[addr & 0x7FFF] = val; - return true; + return; } if (addr >= DTCMBase && addr < (DTCMBase + DTCMSize)) { - DataRegion = NDS::Region9_DTCM; - if (flags & RWFlags_Nonseq) DataCycles = 1; - else DataCycles += 1; + DataCycles = 1; *(u16*)&DTCM[(addr - DTCMBase) & 0x3FFF] = val; - return true; + return; } - DataRegion = NDS::ARM9Write16(addr, val); - if (pu & 0x20) - { - DataRegion = NDS::Region9_DCache; - if (flags & RWFlags_Nonseq) DataCycles = 2; - else DataCycles += 2; - } - else - { - if (flags & RWFlags_Nonseq) DataCycles = NDS::ARM9MemTimings[DataRegion][0]; - else DataCycles += NDS::ARM9MemTimings[DataRegion][1]; - } - return true; + NDS::ARM9Write16(addr, val); + DataCycles = MemTimings[addr >> 12][1]; } -bool ARMv5::DataWrite32(u32 addr, u32 val, u32 flags) +void ARMv5::DataWrite32(u32 addr, u32 val) { addr &= ~3; - u8 pu = PU_Map[addr>>12]; - /*if (!(pu & 0x02)) - { - DataAbort(); - return false; - }*/ - if (addr < ITCMSize) { - DataRegion = NDS::Region9_ITCM; - if (flags & RWFlags_Nonseq) DataCycles = 1; - else DataCycles += 1; + DataCycles = 1; *(u32*)&ITCM[addr & 0x7FFF] = val; - return true; + return; } if (addr >= DTCMBase && addr < (DTCMBase + DTCMSize)) { - DataRegion = NDS::Region9_DTCM; - if (flags & RWFlags_Nonseq) DataCycles = 1; - else DataCycles += 1; + DataCycles = 1; *(u32*)&DTCM[(addr - DTCMBase) & 0x3FFF] = val; - return true; + return; } - DataRegion = NDS::ARM9Write32(addr, val); - if (pu & 0x20) + NDS::ARM9Write32(addr, val); + DataCycles = MemTimings[addr >> 12][2]; +} + +void ARMv5::DataWrite32S(u32 addr, u32 val) +{ + addr &= ~3; + + if (addr < ITCMSize) { - DataRegion = NDS::Region9_DCache; - if (flags & RWFlags_Nonseq) DataCycles = 2; - else DataCycles += 2; + DataCycles += 1; + *(u32*)&ITCM[addr & 0x7FFF] = val; + return; } - else + if (addr >= DTCMBase && addr < (DTCMBase + DTCMSize)) { - if (flags & RWFlags_Nonseq) DataCycles = NDS::ARM9MemTimings[DataRegion][0]; - else DataCycles += NDS::ARM9MemTimings[DataRegion][1]; + DataCycles += 1; + *(u32*)&DTCM[(addr - DTCMBase) & 0x3FFF] = val; + return; } - return true; + + NDS::ARM9Write32(addr, val); + DataCycles += MemTimings[addr >> 12][3]; } void ARMv5::GetCodeMemRegion(u32 addr, NDS::MemRegion* region) { if (addr < ITCMSize) { - region->Region = NDS::Region9_ITCM; region->Mem = ITCM; region->Mask = 0x7FFF; return; |