area 7 access to sh4 mm registers only through mmu translation
on-chip ram area isn't translated in both user and supervisor modes vmem: return 0 for non-mapped region reads Fixes dolphin blue crash/freeze. Issue #62 Fixes Resident Evil - Code Veronica X (Chris) floor 1F crash
This commit is contained in:
parent
4d815570d0
commit
b3de6a166d
|
@ -103,7 +103,7 @@ void* _vmem_write_const(u32 addr,bool& ismem,u32 sz)
|
|||
template<typename T,typename Trv>
|
||||
INLINE Trv DYNACALL _vmem_readt(u32 addr)
|
||||
{
|
||||
const u32 sz=sizeof(T);
|
||||
constexpr u32 sz = sizeof(T);
|
||||
|
||||
u32 page=addr>>24; //1 op, shift/extract
|
||||
unat iirf=(unat)_vmem_MemInfo_ptr[page]; //2 ops, insert + read [vmem table will be on reg ]
|
||||
|
@ -154,7 +154,7 @@ template u64 DYNACALL _vmem_readt<u64, u64>(u32 addr);
|
|||
template<typename T>
|
||||
INLINE void DYNACALL _vmem_writet(u32 addr,T data)
|
||||
{
|
||||
const u32 sz=sizeof(T);
|
||||
constexpr u32 sz = sizeof(T);
|
||||
|
||||
u32 page=addr>>24;
|
||||
unat iirf=(unat)_vmem_MemInfo_ptr[page];
|
||||
|
@ -214,8 +214,7 @@ void DYNACALL _vmem_WriteMem16(u32 Address,u16 data) { _vmem_writet<u16>(Address
|
|||
void DYNACALL _vmem_WriteMem32(u32 Address,u32 data) { _vmem_writet<u32>(Address,data); }
|
||||
void DYNACALL _vmem_WriteMem64(u32 Address,u64 data) { _vmem_writet<u64>(Address,data); }
|
||||
|
||||
//0xDEADC0D3 or 0
|
||||
#define MEM_ERROR_RETURN_VALUE 0xDEADC0D3
|
||||
#define MEM_ERROR_RETURN_VALUE 0
|
||||
|
||||
//default read handlers
|
||||
static u8 DYNACALL _vmem_ReadMem8_not_mapped(u32 addresss)
|
||||
|
@ -378,6 +377,8 @@ static void* malloc_pages(size_t size) {
|
|||
#endif
|
||||
}
|
||||
|
||||
#if FEAT_SHREC != DYNAREC_NONE
|
||||
|
||||
// Resets the FPCB table (by either clearing it to the default val
|
||||
// or by flushing it and making it fault on access again.
|
||||
void _vmem_bm_reset()
|
||||
|
@ -410,6 +411,7 @@ bool BM_LockedWrite(u8* address) {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void _vmem_set_p0_mappings()
|
||||
{
|
||||
|
@ -481,7 +483,9 @@ void _vmem_init_mappings()
|
|||
|
||||
// Allocate it all and initialize it.
|
||||
p_sh4rcb = (Sh4RCB*)malloc_pages(sizeof(Sh4RCB));
|
||||
#if FEAT_SHREC != DYNAREC_NONE
|
||||
bm_vmem_pagefill((void**)p_sh4rcb->fpcb, sizeof(p_sh4rcb->fpcb));
|
||||
#endif
|
||||
|
||||
mem_b.size = RAM_SIZE;
|
||||
mem_b.data = (u8*)malloc_pages(RAM_SIZE);
|
||||
|
@ -726,7 +730,9 @@ u32 _vmem_get_vram_offset(void *addr)
|
|||
}
|
||||
if ((offset >> 24) != 4)
|
||||
return -1;
|
||||
verify((((u8*)addr - virt_ram_base) >> 29) == 0 || (((u8*)addr - virt_ram_base) >> 29) == 4 || (((u8*)addr - virt_ram_base) >> 29) == 5); // others areas aren't mapped atm
|
||||
if ((((u8*)addr - virt_ram_base) >> 29) != 0 && (((u8*)addr - virt_ram_base) >> 29) != 4 && (((u8*)addr - virt_ram_base) >> 29) != 5)
|
||||
// other areas aren't mapped atm
|
||||
return -1;
|
||||
|
||||
return offset & VRAM_MASK;
|
||||
}
|
||||
|
|
|
@ -279,6 +279,7 @@ static u32 vmem32_map_mmu(u32 address, bool write)
|
|||
}
|
||||
else if (offset >= MAP_RAM_START_OFFSET && offset < MAP_RAM_START_OFFSET + RAM_SIZE)
|
||||
{
|
||||
#if FEAT_SHREC != DYNAREC_NONE
|
||||
// Check system RAM protected pages
|
||||
u32 start = offset - MAP_RAM_START_OFFSET;
|
||||
|
||||
|
@ -297,6 +298,7 @@ static u32 vmem32_map_mmu(u32 address, bool write)
|
|||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
verify(vmem32_map_buffer(vpn, page_size, offset, page_size, allow_write) != NULL);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -299,8 +299,9 @@ u32 mmu_data_translation(u32 va, u32& rv)
|
|||
}
|
||||
}
|
||||
|
||||
if (sr.MD == 1 && ((va & 0xFC000000) == 0x7C000000))
|
||||
if ((va & 0xFC000000) == 0x7C000000)
|
||||
{
|
||||
// On-chip RAM area isn't translated
|
||||
rv = va;
|
||||
return MMU_ERROR_NONE;
|
||||
}
|
||||
|
@ -313,7 +314,9 @@ u32 mmu_data_translation(u32 va, u32& rv)
|
|||
|
||||
const TLB_Entry *entry;
|
||||
u32 lookup = mmu_full_lookup(va, &entry, rv);
|
||||
|
||||
if (lookup == MMU_ERROR_NONE && (rv & 0x1C000000) == 0x1C000000)
|
||||
// map 1C000000-1FFFFFFF to P4 memory-mapped registers
|
||||
rv |= 0xF0000000;
|
||||
#ifdef TRACE_WINCE_SYSCALLS
|
||||
if (unresolved_unicode_string != 0 && lookup == MMU_ERROR_NONE)
|
||||
{
|
||||
|
|
|
@ -486,9 +486,9 @@ u32 mmu_data_translation(u32 va, u32& rv)
|
|||
return MMU_ERROR_BADADDR;
|
||||
}
|
||||
|
||||
if (sr.MD == 1 && ((va & 0xFC000000) == 0x7C000000))
|
||||
if ((va & 0xFC000000) == 0x7C000000)
|
||||
{
|
||||
// 7C000000 to 7FFFFFFF in P0 not translated in supervisor mode
|
||||
// 7C000000 to 7FFFFFFF in P0/U0 not translated
|
||||
rv = va;
|
||||
return MMU_ERROR_NONE;
|
||||
}
|
||||
|
@ -537,6 +537,10 @@ u32 mmu_data_translation(u32 va, u32& rv)
|
|||
else if (entry->Data.D == 0)
|
||||
return MMU_ERROR_FIRSTWRITE;
|
||||
}
|
||||
if ((rv & 0x1C000000) == 0x1C000000)
|
||||
// map 1C000000-1FFFFFFF to P4 memory-mapped registers
|
||||
rv |= 0xF0000000;
|
||||
|
||||
return MMU_ERROR_NONE;
|
||||
}
|
||||
template u32 mmu_data_translation<MMU_TT_DREAD, u8>(u32 va, u32& rv);
|
||||
|
|
|
@ -98,17 +98,9 @@ bool mmu_is_translated(u32 va, u32 size)
|
|||
//SQ writes are not translated, only write backs are.
|
||||
return false;
|
||||
}
|
||||
#ifndef sr
|
||||
// This is why the preprocessor sucks
|
||||
#define sr Sh4cntx.sr
|
||||
#define undef_sr
|
||||
#endif
|
||||
if (sr.MD == 1 && (va & 0xFC000000) == 0x7C000000)
|
||||
if ((va & 0xFC000000) == 0x7C000000)
|
||||
// On-chip RAM area isn't translated
|
||||
return false;
|
||||
#ifdef undef_sr
|
||||
#undef sr
|
||||
#undef undef_sr
|
||||
#endif
|
||||
|
||||
if (fast_reg_lut[va >> 29] != 0)
|
||||
return false;
|
||||
|
|
|
@ -198,8 +198,8 @@ private:
|
|||
cached = CCN_CCR.ICE == 1 && cachedArea(area);
|
||||
|
||||
if (CCN_MMUCR.AT == 0 || !translatedArea(area)
|
||||
// 7C000000 to 7FFFFFFF in P0 not translated in supervisor mode
|
||||
|| (!userMode && (address & 0xFC000000) == 0x7C000000))
|
||||
// 7C000000 to 7FFFFFFF in P0/U0 not translated
|
||||
|| (address & 0xFC000000) == 0x7C000000)
|
||||
{
|
||||
physAddr = address;
|
||||
}
|
||||
|
@ -531,8 +531,8 @@ private:
|
|||
copyBack = area == 4 ? CCN_CCR.CB : !CCN_CCR.WT;
|
||||
|
||||
if (CCN_MMUCR.AT == 0 || !translatedArea(area)
|
||||
// 7C000000 to 7FFFFFFF in P0 not translated in supervisor mode
|
||||
|| (!userMode && (address & 0xFC000000) == 0x7C000000))
|
||||
// 7C000000 to 7FFFFFFF in P0/U0 not translated
|
||||
|| (address & 0xFC000000) == 0x7C000000)
|
||||
{
|
||||
physAddr = address;
|
||||
}
|
||||
|
@ -563,6 +563,10 @@ private:
|
|||
copyBack = copyBack && entry->Data.WT == 0;
|
||||
}
|
||||
cached = cached && entry->Data.C == 1;
|
||||
if ((physAddr & 0x1C000000) == 0x1C000000)
|
||||
// map 1C000000-1FFFFFFF to P4 memory-mapped registers
|
||||
physAddr |= 0xF0000000;
|
||||
|
||||
}
|
||||
return MMU_ERROR_NONE;
|
||||
}
|
||||
|
|
|
@ -389,10 +389,11 @@ void DYNACALL WriteMem_P4(u32 addr,T data)
|
|||
//***********
|
||||
|
||||
#define OUT_OF_RANGE(reg) INFO_LOG(SH4, "Out of range on register %s index %x", reg, addr)
|
||||
#define A7_REG_HASH(addr) (((addr) >> 16) & 0x1FFF)
|
||||
|
||||
//Read Area7
|
||||
//Read P4 memory-mapped registers
|
||||
template <class T>
|
||||
T DYNACALL ReadMem_area7(u32 addr)
|
||||
T DYNACALL ReadMem_p4mmr(u32 addr)
|
||||
{
|
||||
constexpr size_t sz = sizeof(T);
|
||||
/*
|
||||
|
@ -415,7 +416,7 @@ T DYNACALL ReadMem_area7(u32 addr)
|
|||
|
||||
addr&=0x1FFFFFFF;
|
||||
u32 map_base=addr>>16;
|
||||
switch (map_base)
|
||||
switch (expected(map_base, A7_REG_HASH(TMU_BASE_addr)))
|
||||
{
|
||||
case A7_REG_HASH(CCN_BASE_addr):
|
||||
if (addr<=0x1F000044)
|
||||
|
@ -562,13 +563,13 @@ T DYNACALL ReadMem_area7(u32 addr)
|
|||
break;
|
||||
}
|
||||
|
||||
INFO_LOG(SH4, "Unknown Read from Area7 - addr=%x", addr);
|
||||
INFO_LOG(SH4, "Unknown Read from P4 mmr - addr=%x", addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Write Area7
|
||||
//Write P4 memory-mapped registers
|
||||
template <class T>
|
||||
void DYNACALL WriteMem_area7(u32 addr,T data)
|
||||
void DYNACALL WriteMem_p4mmr(u32 addr,T data)
|
||||
{
|
||||
constexpr size_t sz = sizeof(T);
|
||||
if (likely(addr==0xFF000038))
|
||||
|
@ -720,59 +721,30 @@ void DYNACALL WriteMem_area7(u32 addr,T data)
|
|||
break;
|
||||
}
|
||||
|
||||
INFO_LOG(SH4, "Write to Area7 not implemented, addr=%x, data=%x", addr, data);
|
||||
INFO_LOG(SH4, "Write to P4 mmr not implemented, addr=%x, data=%x", addr, data);
|
||||
}
|
||||
|
||||
|
||||
//***********
|
||||
//On Chip Ram
|
||||
//***********
|
||||
//Read OCR
|
||||
template <class T>
|
||||
T DYNACALL ReadMem_area7_OCR_T(u32 addr)
|
||||
T DYNACALL ReadMem_area7_OCR(u32 addr)
|
||||
{
|
||||
if (CCN_CCR.ORA)
|
||||
{
|
||||
if (sizeof(T) == 1)
|
||||
return (T)OnChipRAM[addr&OnChipRAM_MASK];
|
||||
else if (sizeof(T) == 2)
|
||||
return (T)*(u16*)&OnChipRAM[addr&OnChipRAM_MASK];
|
||||
else if (sizeof(T) == 4)
|
||||
return (T)*(u32*)&OnChipRAM[addr&OnChipRAM_MASK];
|
||||
else
|
||||
{
|
||||
ERROR_LOG(SH4, "ReadMem_area7_OCR_T: template SZ is wrong = %zd", sizeof(T));
|
||||
return 0xDE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
INFO_LOG(SH4, "On Chip Ram Read, but OCR is disabled. addr %x", addr);
|
||||
return 0xDE;
|
||||
}
|
||||
if (CCN_CCR.ORA == 1)
|
||||
return *(T *)&OnChipRAM[addr & OnChipRAM_MASK];
|
||||
|
||||
INFO_LOG(SH4, "On Chip Ram Read, but OCR is disabled. addr %x", addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Write OCR
|
||||
template <class T>
|
||||
void DYNACALL WriteMem_area7_OCR_T(u32 addr,T data)
|
||||
void DYNACALL WriteMem_area7_OCR(u32 addr, T data)
|
||||
{
|
||||
if (CCN_CCR.ORA)
|
||||
{
|
||||
if (sizeof(T) == 1)
|
||||
OnChipRAM[addr&OnChipRAM_MASK]=(u8)data;
|
||||
else if (sizeof(T) == 2)
|
||||
*(u16*)&OnChipRAM[addr&OnChipRAM_MASK]=(u16)data;
|
||||
else if (sizeof(T) == 4)
|
||||
*(u32*)&OnChipRAM[addr&OnChipRAM_MASK]=data;
|
||||
else
|
||||
{
|
||||
ERROR_LOG(SH4, "WriteMem_area7_OCR_T: template SZ is wrong = %zd", sizeof(T));
|
||||
}
|
||||
}
|
||||
if (CCN_CCR.ORA == 1)
|
||||
*(T *)&OnChipRAM[addr & OnChipRAM_MASK] = data;
|
||||
else
|
||||
{
|
||||
INFO_LOG(SH4, "On Chip Ram Write, but OCR is disabled. addr %x", addr);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
|
@ -863,42 +835,31 @@ void sh4_mmr_term()
|
|||
ccn_term();
|
||||
bsc_term();
|
||||
}
|
||||
//Mem map :)
|
||||
|
||||
//AREA 7--Sh4 Regs
|
||||
_vmem_handler area7_handler;
|
||||
|
||||
_vmem_handler area7_orc_handler;
|
||||
// AREA 7--Sh4 Regs
|
||||
static _vmem_handler p4mmr_handler;
|
||||
static _vmem_handler area7_ocr_handler;
|
||||
|
||||
void map_area7_init()
|
||||
{
|
||||
//=_vmem_register_handler(ReadMem8_area7,ReadMem16_area7,ReadMem32_area7,
|
||||
// WriteMem8_area7,WriteMem16_area7,WriteMem32_area7);
|
||||
|
||||
//default area7 handler
|
||||
area7_handler= _vmem_register_handler_Template(ReadMem_area7,WriteMem_area7);
|
||||
|
||||
area7_orc_handler= _vmem_register_handler_Template(ReadMem_area7_OCR_T,WriteMem_area7_OCR_T);
|
||||
p4mmr_handler = _vmem_register_handler_Template(ReadMem_p4mmr, WriteMem_p4mmr);
|
||||
area7_ocr_handler = _vmem_register_handler_Template(ReadMem_area7_OCR, WriteMem_area7_OCR);
|
||||
}
|
||||
|
||||
void map_area7(u32 base)
|
||||
{
|
||||
//OCR @
|
||||
//((addr>=0x7C000000) && (addr<=0x7FFFFFFF))
|
||||
if (base==0x60)
|
||||
_vmem_map_handler(area7_orc_handler,0x1C | base , 0x1F| base);
|
||||
else
|
||||
{
|
||||
_vmem_map_handler(area7_handler,0x1C | base , 0x1F| base);
|
||||
}
|
||||
// on-chip RAM: 7C000000-7FFFFFFF
|
||||
if (base == 0x60)
|
||||
_vmem_map_handler(area7_ocr_handler, 0x7C, 0x7F);
|
||||
}
|
||||
|
||||
//P4
|
||||
void map_p4()
|
||||
{
|
||||
//P4 Region :
|
||||
_vmem_handler p4_handler = _vmem_register_handler_Template(ReadMem_P4,WriteMem_P4);
|
||||
_vmem_handler p4_handler = _vmem_register_handler_Template(ReadMem_P4, WriteMem_P4);
|
||||
|
||||
//register this before area7 and SQ , so they overwrite it and handle em :)
|
||||
//register this before mmr and SQ so they overwrite it and handle em
|
||||
//default P4 handler
|
||||
//0xE0000000-0xFFFFFFFF
|
||||
_vmem_map_handler(p4_handler,0xE0,0xFF);
|
||||
|
@ -909,5 +870,5 @@ void map_p4()
|
|||
_vmem_map_block(sq_both,0xE2,0xE2,63);
|
||||
_vmem_map_block(sq_both,0xE3,0xE3,63);
|
||||
|
||||
map_area7(0xE0);
|
||||
_vmem_map_handler(p4mmr_handler, 0xFF, 0xFF);
|
||||
}
|
||||
|
|
|
@ -31,8 +31,6 @@ void sh4_mmr_term();
|
|||
template<typename T>
|
||||
void sh4_rio_reg(T& arr, u32 addr, RegIO flags, u32 sz, RegReadAddrFP* rf=0, RegWriteAddrFP* wf=0);
|
||||
|
||||
#define A7_REG_HASH(addr) (((addr) >> 16) & 0x1FFF)
|
||||
|
||||
#define SH4IO_REGN(mod, addr, size) ((mod)[((addr) & 255) / 4].data##size)
|
||||
#define SH4IO_REG(mod, name, size) SH4IO_REGN(mod, mod##_##name##_addr, size)
|
||||
#define SH4IO_REG_T(mod, name, size) ((mod##_##name##_type&)SH4IO_REG(mod, name, size))
|
||||
|
|
Loading…
Reference in New Issue