Commit 9ae97bdc authored by Flyinghead's avatar Flyinghead
Browse files

wince: unify _vmem and vmem32. Use 4GB virtual space on 64-bit arch

On 64-bit architectures, _vmem first tries to allocate 4GB then falls
back to 512 MB.
The same virtual space is now used by _vmem and vmem32 (mmu)

Enable/disable vmem32 based on mmu state
parent d1090a6d
......@@ -243,6 +243,10 @@
#endif
#endif
#if HOST_CPU == CPU_X64 || HOST_CPU == CPU_ARM64
#define HOST_64BIT_CPU
#endif
//Depricated build configs
#ifdef HOST_NO_REC
#error Dont use HOST_NO_REC
......
......@@ -522,7 +522,7 @@ bool _vmem_reserve(void)
// Map the different parts of the memory file into the new memory range we got.
if (vmemstatus == MemType512MB)
{
vmem_mapping mem_mappings[] = {
const vmem_mapping mem_mappings[] = {
{0x00000000, 0x00800000, 0, 0, false}, // Area 0 -> unused
{0x00800000, 0x01000000, MAP_ARAM_START_OFFSET, ARAM_SIZE, false}, // Aica
{0x20000000, 0x20000000+ARAM_SIZE, MAP_ARAM_START_OFFSET, ARAM_SIZE, true},
......
......@@ -305,7 +305,6 @@ extern "C" void DYNACALL TAWriteSQ(u32 address,u8* sqb)
if (SB_LMMODE0 == 0)
{
// 64b path
u8* vram=sqb+512+0x04000000;
MemWrite32(&vram[address_w&(VRAM_MASK-0x1F)],sq);
}
else
......
......@@ -11,6 +11,12 @@
#define CODE_SIZE (16*1024*1024)
typedef void (*DynarecCodeEntryPtr)();
#ifdef NO_MMU
#define TEMP_CODE_SIZE (0)
#else
#define TEMP_CODE_SIZE (1024*1024)
#endif
extern u8* CodeCache;
struct RuntimeBlockInfo_Core
......@@ -94,7 +100,7 @@ struct BlockMapCMP
{
static bool is_code(RuntimeBlockInfo* blk)
{
if ((unat)((u8*)blk-CodeCache)<CODE_SIZE)
if ((unat)((u8*)blk - CodeCache) < CODE_SIZE + TEMP_CODE_SIZE)
return true;
else
return false;
......
......@@ -45,12 +45,6 @@
#include "decoder.h"
#include "blockmanager.h"
#ifdef NO_MMU
#define TEMP_CODE_SIZE (0)
#else
#define TEMP_CODE_SIZE (1024*1024)
#endif
// When NO_RWX is enabled there's two address-spaces, one executable and
// one writtable. The emitter and most of the code in rec-* will work with
// the RW pointer. However the fpcb table and other pointers during execution
......@@ -85,8 +79,6 @@ DynarecCodeEntryPtr DYNACALL rdv_FailedToFindBlock_pc();
DynarecCodeEntryPtr DYNACALL rdv_BlockCheckFail(u32 pc);
//Called to compile code @pc
DynarecCodeEntryPtr rdv_CompilePC(u32 blockcheck_failures);
//Returns 0 if there is no code @pc, code ptr otherwise
//DynarecCodeEntryPtr rdv_FindCode();
//Finds or compiles code @pc
DynarecCodeEntryPtr rdv_FindOrCompile();
......
......@@ -52,8 +52,10 @@ int UpdateSystem(void)
int UpdateSystem_INTC(void)
{
UpdateSystem();
return UpdateINTC();
if (UpdateSystem())
return UpdateINTC();
else
return 0;
}
void Sh4_int_Stop(void)
......@@ -145,8 +147,6 @@ void Sh4_int_Reset(bool Manual)
old_fpscr=fpscr;
UpdateFPSCR();
p_sh4rcb->cntx.vmem32_base = virt_ram_base;
//Any more registers have default value ?
printf("Sh4 Reset\n");
}
......
......@@ -142,7 +142,6 @@ bool UTLB_Sync(u32 entry)
// Used when FullMMU is off
u32 vpn_sq = ((UTLB[entry].Address.VPN & 0x7FFFF) >> 10) & 0x3F;//upper bits are always known [0xE0/E1/E2/E3]
sq_remap[vpn_sq] = UTLB[entry].Data.PPN << 10;
printf_mmu("SQ remap %d : 0x%X to 0x%X\n", entry, UTLB[entry].Address.VPN << 10, UTLB[entry].Data.PPN << 10);
return true;
}
......@@ -255,7 +254,7 @@ void mmu_raise_exception(u32 mmu_error, u32 address, u32 am)
void DoMMUException(u32 address, u32 mmu_error, u32 access_type)
{
printf_mmu("DoMMUException -> pc = 0x%X : ", next_pc);
printf_mmu("DoMMUException -> pc = 0x%X : %d ", next_pc, access_type);
CCN_TEA = address;
CCN_PTEH.VPN = address >> 10;
......@@ -268,7 +267,7 @@ void DoMMUException(u32 address, u32 mmu_error, u32 access_type)
//TLB miss
case MMU_ERROR_TLB_MISS:
printf_mmu("MMU_ERROR_UTLB_MISS 0x%X, handled access_type %d\n", address, access_type);
printf_mmu("MMU_ERROR_UTLB_MISS 0x%X, handled\n", address);
if (access_type == MMU_TT_DWRITE) //WTLBMISS - Write Data TLB Miss Exception
Do_Exception(next_pc, 0x60, 0x400);
else if (access_type == MMU_TT_DREAD) //RTLBMISS - Read Data TLB Miss Exception
......@@ -323,7 +322,7 @@ void DoMMUException(u32 address, u32 mmu_error, u32 access_type)
Do_Exception(next_pc, 0xE0, 0x100);
return;
}
printf("MMU_ERROR_BADADDR(d) 0x%X, handled\n", address);
printf_mmu("MMU_ERROR_BADADDR(d) 0x%X, handled\n", address);
return;
break;
......@@ -376,7 +375,6 @@ u32 mmu_full_lookup(u32 va, const TLB_Entry** tlb_entry_ret, u32& rv)
u32 entry = -1;
u32 nom = 0;
for (u32 i = 0; i<64; i++)
{
//verify(sz!=0);
......@@ -484,6 +482,7 @@ u32 mmu_data_translation(u32 va, u32& rv)
u32 lookup = mmu_full_SQ<translation_type>(va, rv);
if (lookup != MMU_ERROR_NONE)
return lookup;
rv = va; //SQ writes are not translated, only write backs are.
return MMU_ERROR_NONE;
}
......@@ -596,6 +595,7 @@ retry_ITLB_Match:
if (lookup != MMU_ERROR_NONE)
return lookup;
u32 replace_index = ITLB_LRU_USE[CCN_MMUCR.LRUI];
verify(replace_index != 0xFFFFFFFF);
ITLB[replace_index] = *tlb_entry;
......@@ -627,7 +627,6 @@ retry_ITLB_Match:
{
return MMU_ERROR_PROTECTED;
}
return MMU_ERROR_NONE;
}
#endif
......@@ -647,6 +646,7 @@ void mmu_set_state()
WriteMem16 = &mmu_WriteMem<u16>;
WriteMem32 = &mmu_WriteMem<u32>;
WriteMem64 = &mmu_WriteMem<u64>;
_vmem_enable_mmu(true);
mmu_flush_table();
}
else
......@@ -661,6 +661,7 @@ void mmu_set_state()
WriteMem16 = &_vmem_WriteMem16;
WriteMem32 = &_vmem_WriteMem32;
WriteMem64 = &_vmem_WriteMem64;
_vmem_enable_mmu(false);
}
}
......@@ -727,7 +728,7 @@ u16 DYNACALL mmu_IReadMem16(u32 vaddr)
u32 rv = mmu_instruction_translation(vaddr, addr, shared);
if (rv != MMU_ERROR_NONE)
mmu_raise_exception(rv, vaddr, MMU_TT_IREAD);
return _vmem_ReadMem16(addr);
return _vmem_ReadMem16(addr);
}
template<typename T>
......@@ -742,17 +743,17 @@ void DYNACALL mmu_WriteMem(u32 adr, T data)
template<typename T>
T DYNACALL mmu_ReadMemNoEx(u32 adr, u32 *exception_occurred)
{
{
u32 addr;
u32 rv = mmu_data_translation<MMU_TT_DREAD, T>(adr, addr);
if (rv != MMU_ERROR_NONE)
{
{
DoMMUException(adr, rv, MMU_TT_DREAD);
*exception_occurred = 1;
return 0;
}
else
{
{
*exception_occurred = 0;
return _vmem_readt<T, T>(addr);
}
......@@ -763,7 +764,7 @@ template u32 mmu_ReadMemNoEx<u32>(u32 adr, u32 *exception_occurred);
template u64 mmu_ReadMemNoEx<u64>(u32 adr, u32 *exception_occurred);
u16 DYNACALL mmu_IReadMem16NoEx(u32 vaddr, u32 *exception_occurred)
{
{
u32 addr;
bool shared;
u32 rv = mmu_instruction_translation(vaddr, addr, shared);
......@@ -774,11 +775,11 @@ u16 DYNACALL mmu_IReadMem16NoEx(u32 vaddr, u32 *exception_occurred)
return 0;
}
else
{
{
*exception_occurred = 0;
return _vmem_ReadMem16(addr);
}
}
}
template<typename T>
u32 DYNACALL mmu_WriteMemNoEx(u32 adr, T data)
......@@ -804,6 +805,7 @@ bool mmu_TranslateSQW(u32 adr, u32* out)
{
//This will only work for 1 mb pages .. hopefully nothing else is used
//*FIXME* to work for all page sizes ?
*out = sq_remap[(adr >> 20) & 0x3F] | (adr & 0xFFFE0);
}
else
......
......@@ -350,7 +350,6 @@ struct Sh4Context
u32 interrupt_pend;
u32 exception_pc;
u8 *vmem32_base;
};
u64 raw[64-8];
};
......@@ -368,16 +367,14 @@ void DYNACALL do_sqw_nommu_full(u32 dst, u8* sqb);
typedef void DYNACALL sqw_fp(u32 dst,u8* sqb);
typedef void DYNACALL TaListVoidFP(void* data);
// Naomi edit: was RAM_SIZE/2
#define FPCB_SIZE (32*1024*1024/2)
#define FPCB_SIZE (RAM_SIZE_MAX/2)
#define FPCB_MASK (FPCB_SIZE -1)
//#defeine FPCB_PAD 0x40000
#define FPCB_PAD 0x100000
#define FPCB_OFFSET (-(FPCB_SIZE*sizeof(void*) + FPCB_PAD))
struct Sh4RCB
{
/* Naomi edit - allow for max possible RAM_SIZE here */
void* fpcb[((32*1024*1024)/*RAM_SIZE*//2)];
void* fpcb[FPCB_SIZE];
u64 _pad[(FPCB_PAD-sizeof(Sh4Context)-64-sizeof(void*)*2)/8];
TaListVoidFP* tacmd_voud; //*TODO* remove (not used)
sqw_fp* do_sqw_nommu;
......
......@@ -478,7 +478,7 @@ T DYNACALL ReadMem_area7(u32 addr)
switch (map_base & 0x1FFF)
{
case A7_REG_HASH(CCN_BASE_addr):
if (addr<=0x1F00003C)
if (addr<=0x1F000044)
{
return (T)sh4_rio_read<sz>(CCN,addr & 0xFF);
}
......@@ -560,7 +560,7 @@ T DYNACALL ReadMem_area7(u32 addr)
break;
case A7_REG_HASH(INTC_BASE_addr):
if (addr<=0x1FD0000C)
if (addr<=0x1FD00010)
{
return (T)sh4_rio_read<sz>(INTC,addr & 0xFF);
}
......@@ -891,7 +891,7 @@ void sh4_mmr_init(void)
void sh4_mmr_reset(void)
{
memset(OnChipRAM.data, 0, sizeof(u8) * OnChipRAM.Size);
OnChipRAM.Zero();
//Reset register values
bsc_reset();
ccn_reset();
......
......@@ -2038,7 +2038,6 @@ bool retro_unserialize(const void * data, size_t size)
}
#endif
sh4_cpu.ResetCache();
#if FEAT_AREC == DYNAREC_JIT
FlushCache();
#endif
......@@ -2046,6 +2045,7 @@ bool retro_unserialize(const void * data, size_t size)
result = dc_unserialize(&data_ptr, &total_size, size) ;
mmu_set_state();
sh4_cpu.ResetCache();
dsp.dyndirty = true;
sh4_sched_ffts();
CalculateSync();
......
......@@ -217,8 +217,7 @@ void vmem_platform_create_mappings(const vmem_mapping *vmem_maps, unsigned numma
// Ignore unmapped stuff, it is already reserved as PROT_NONE
if (!vmem_maps[i].memsize)
continue;
printf("vmem_platform_create_mappings: start %lx end %lx size %lx\n",
vmem_maps[i].start_address, vmem_maps[i].end_address, vmem_maps[i].memsize);
// Calculate the number of mirrors
u64 address_range_size = vmem_maps[i].end_address - vmem_maps[i].start_address;
unsigned num_mirrors = (address_range_size) / vmem_maps[i].memsize;
......
......@@ -540,8 +540,7 @@ public:
cmp(regalloc.MapRegister(op.rs3), 1); // C = ~rs3
cmc(); // C = rs3
adc(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs2)); // (C,rd)=rs1+rs2+rs3(C)
setc(al);
movzx(regalloc.MapRegister(op.rd2), al); // rd2 = C
setc(regalloc.MapRegister(op.rd2).cvt8()); // rd2 = C
break;
/* FIXME buggy
case shop_sbc:
......@@ -1133,9 +1132,6 @@ public:
void InitializeRewrite(RuntimeBlockInfo *block, size_t opid)
{
// shouldn't be necessary since all regs are flushed before mem access when mmu is enabled
//regalloc.DoAlloc(block);
regalloc.current_opid = opid;
}
void FinalizeRewrite()
......@@ -1346,7 +1342,7 @@ private:
mov(rax, (uintptr_t)&p_sh4rcb->cntx.exception_pc);
mov(dword[rax], block->vaddr + op.guest_offs - (op.delay_slot ? 2 : 0));
mov(rax, (uintptr_t)p_sh4rcb->cntx.vmem32_base);
mov(rax, (uintptr_t)virt_ram_base);
u32 size = op.flags & 0x7f;
//verify(getCurr() - start_addr == 26);
......@@ -1394,7 +1390,7 @@ private:
mov(rax, (uintptr_t)&p_sh4rcb->cntx.exception_pc);
mov(dword[rax], block->vaddr + op.guest_offs - (op.delay_slot ? 2 : 0));
mov(rax, (uintptr_t)p_sh4rcb->cntx.vmem32_base);
mov(rax, (uintptr_t)virt_ram_base);
u32 size = op.flags & 0x7f;
//verify(getCurr() - start_addr == 26);
......
......@@ -215,8 +215,28 @@ vram_block* libCore_vramlock_Lock(u32 start_offset64,
if (_nvmem_enabled() && VRAM_SIZE == 0x800000) {
vram.LockRegion(block->start + VRAM_SIZE, block->len);
}
if (mmu_enabled())
if (!mmu_enabled())
{
if (_nvmem_4gb_space())
{
// In 4GB mode, vram.LockRegion() locks in the P1 area only so we also need to lock P0
// We should also lock P2 and P3 but they don't seem to be used...
mem_region_lock(virt_ram_base + 0x04000000 + block->start, block->len);
//mem_region_lock(virt_ram_base + 0xA4000000 + block->start, block->len);
//mem_region_lock(virt_ram_base + 0xC4000000 + block->start, block->len);
if (VRAM_SIZE == 0x800000)
{
mem_region_lock(virt_ram_base + 0x04000000 + block->start + VRAM_SIZE, block->len);
//mem_region_lock(virt_ram_base + 0xA4000000 + block->start + VRAM_SIZE, block->len);
//mem_region_lock(virt_ram_base + 0xC4000000 + block->start + VRAM_SIZE, block->len);
}
}
}
else
{
vmem32_protect_vram(block);
}
vramlock_list_add(block);
......@@ -253,12 +273,19 @@ bool VramLockedWriteOffset(size_t offset)
}
list->clear();
vram.UnLockRegion((u32)offset&(~(PAGE_SIZE-1)),PAGE_SIZE);
u32 aligned_offset = (u32)offset & ~(PAGE_SIZE - 1);
vram.UnLockRegion(aligned_offset, PAGE_SIZE);
//TODO: Fix this for 32M wrap as well
if (_nvmem_enabled() && VRAM_SIZE == 0x800000) {
vram.UnLockRegion((u32)offset&(~(PAGE_SIZE-1)) + VRAM_SIZE,PAGE_SIZE);
}
vram.UnLockRegion(aligned_offset + VRAM_SIZE, PAGE_SIZE);
}
if (_nvmem_4gb_space() && !mmu_enabled())
{
mem_region_unlock(virt_ram_base + 0x04000000 + aligned_offset, PAGE_SIZE);
if (VRAM_SIZE == 0x800000)
mem_region_unlock(virt_ram_base + 0x04000000 + aligned_offset + VRAM_SIZE, PAGE_SIZE);
}
vramlist_lock.Unlock();
}
......@@ -275,8 +302,16 @@ bool VramLockedWrite(u8* address)
if (offset < 0x01000000)
return VramLockedWriteOffset(offset & (VRAM_SIZE - 1));
else
return false;
if (_nvmem_4gb_space() && !mmu_enabled())
{
offset = address - virt_ram_base;
if (offset >= 0x04000000 && offset < 0x05000000)
return VramLockedWriteOffset((offset - 0x04000000) & (VRAM_SIZE - 1));
// 32MB wrap not set yet
//if (offset >= 0x06000000 && offset < 0x07000000)
// return VramLockedWriteOffset((offset - 0x06000000) & (VRAM_SIZE - 1));
}
return false;
}
//unlocks mem
......@@ -405,7 +440,6 @@ void UpscalexBRZ(int factor, u32* source, u32* dest, int width, int height, bool
parallelize(
std::bind(&xbrz::scale, factor, source, dest, width, height, has_alpha ? xbrz::ColorFormat::ARGB : xbrz::ColorFormat::RGB, xbrz_cfg,
std::placeholders::_1, std::placeholders::_2), 0, height, width);
// xbrz::scale(factor, source, dest, width, height, has_alpha ? xbrz::ColorFormat::ARGB : xbrz::ColorFormat::RGB, xbrz_cfg);
#else
xbrz::scale(factor, source, dest, width, height, has_alpha ? xbrz::ColorFormat::ARGB : xbrz::ColorFormat::RGB, xbrz_cfg);
#endif
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment