vmem: no more 4GB vmem mode. only map elan RAM in naomi2 mode
Do not attempt to reserve 4GM of virtual space on 64-bit hosts. Use 512MB everywhere. Don't map elan RAM if not needed and dont protect/unprotect it in memwatch.
This commit is contained in:
parent
9069a49145
commit
32e3e7d9c5
|
@ -373,6 +373,7 @@ static void setPlatform(int platform)
|
|||
{
|
||||
if (VRAM_SIZE != 0)
|
||||
_vmem_unprotect_vram(0, VRAM_SIZE);
|
||||
elan::ERAM_SIZE = 0;
|
||||
switch (platform)
|
||||
{
|
||||
case DC_PLATFORM_DREAMCAST:
|
||||
|
@ -395,6 +396,7 @@ static void setPlatform(int platform)
|
|||
settings.platform.aram_size = 8 * 1024 * 1024;
|
||||
settings.platform.bios_size = 2 * 1024 * 1024;
|
||||
settings.platform.flash_size = 32 * 1024; // battery-backed ram
|
||||
elan::ERAM_SIZE = 32 * 1024 * 1024;
|
||||
break;
|
||||
case DC_PLATFORM_ATOMISWAVE:
|
||||
settings.platform.ram_size = 16 * 1024 * 1024;
|
||||
|
|
|
@ -361,8 +361,7 @@ void _vmem_term()
|
|||
}
|
||||
|
||||
u8* virt_ram_base;
|
||||
bool vmem_4gb_space;
|
||||
static VMemType vmemstatus = MemTypeError;
|
||||
static bool vmemAvailable = false;
|
||||
|
||||
static void *malloc_pages(size_t size)
|
||||
{
|
||||
|
@ -410,45 +409,24 @@ bool BM_LockedWrite(u8* address) {
|
|||
}
|
||||
#endif
|
||||
|
||||
static void _vmem_set_p0_mappings()
|
||||
{
|
||||
const vmem_mapping mem_mappings[] = {
|
||||
// P0/U0
|
||||
{0x00000000, 0x00800000, 0, 0, false}, // Area 0 -> unused
|
||||
{0x00800000, 0x01000000, MAP_ARAM_START_OFFSET, ARAM_SIZE, true}, // Aica
|
||||
{0x01000000, 0x02800000, 0, 0, false}, // unused
|
||||
{0x02800000, 0x03000000, MAP_ARAM_START_OFFSET, ARAM_SIZE, true}, // Aica mirror
|
||||
{0x03000000, 0x04000000, 0, 0, false}, // unused
|
||||
{0x04000000, 0x05000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // Area 1 (vram, 16MB, wrapped on DC as 2x8MB)
|
||||
{0x05000000, 0x06000000, 0, 0, false}, // 32 bit path (unused)
|
||||
{0x06000000, 0x07000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // VRAM mirror
|
||||
{0x07000000, 0x08000000, 0, 0, false}, // 32 bit path (unused) mirror
|
||||
{0x08000000, 0x0A000000, 0, 0, false}, // Area 2
|
||||
{0x0A000000, 0x0C000000, MAP_ERAM_START_OFFSET, elan::ELAN_RAM_SIZE, true}, // Area 2 (Elan RAM)
|
||||
{0x0C000000, 0x10000000, MAP_RAM_START_OFFSET, RAM_SIZE, true}, // Area 3 (main RAM + 3 mirrors)
|
||||
{0x10000000, 0x80000000, 0, 0, false}, // Area 4-7 (unused)
|
||||
};
|
||||
vmem_platform_create_mappings(&mem_mappings[0], ARRAY_SIZE(mem_mappings));
|
||||
}
|
||||
|
||||
bool _vmem_reserve()
|
||||
{
|
||||
static_assert((sizeof(Sh4RCB) % PAGE_SIZE) == 0, "sizeof(Sh4RCB) not multiple of PAGE_SIZE");
|
||||
|
||||
if (vmemstatus != MemTypeError)
|
||||
if (vmemAvailable)
|
||||
return true;
|
||||
|
||||
// Use vmem only if settings mandate so, and if we have proper exception handlers.
|
||||
#if !defined(TARGET_NO_EXCEPTIONS)
|
||||
if (!settings.dynarec.disable_nvmem)
|
||||
vmemstatus = vmem_platform_init((void**)&virt_ram_base, (void**)&p_sh4rcb, RAM_SIZE_MAX + VRAM_SIZE_MAX + ARAM_SIZE_MAX + elan::ELAN_RAM_SIZE);
|
||||
vmemAvailable = vmem_platform_init((void**)&virt_ram_base, (void**)&p_sh4rcb, RAM_SIZE_MAX + VRAM_SIZE_MAX + ARAM_SIZE_MAX + elan::ERAM_SIZE_MAX);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
static void _vmem_term_mappings()
|
||||
{
|
||||
if (vmemstatus == MemTypeError)
|
||||
if (!vmemAvailable)
|
||||
{
|
||||
free_pages(p_sh4rcb);
|
||||
p_sh4rcb = nullptr;
|
||||
|
@ -467,7 +445,7 @@ void _vmem_init_mappings()
|
|||
{
|
||||
_vmem_term_mappings();
|
||||
// Fallback to statically allocated buffers, this results in slow-ops being generated.
|
||||
if (vmemstatus == MemTypeError)
|
||||
if (!vmemAvailable)
|
||||
{
|
||||
WARN_LOG(VMEM, "Warning! nvmem is DISABLED (due to failure or not being built-in");
|
||||
virt_ram_base = nullptr;
|
||||
|
@ -488,94 +466,34 @@ void _vmem_init_mappings()
|
|||
aica_ram.size = ARAM_SIZE;
|
||||
aica_ram.data = (u8*)malloc_pages(ARAM_SIZE);
|
||||
|
||||
elan::RAM = (u8*)malloc_pages(elan::ELAN_RAM_SIZE);
|
||||
elan::RAM = (u8*)malloc_pages(elan::ERAM_SIZE);
|
||||
}
|
||||
else {
|
||||
NOTICE_LOG(VMEM, "Info: nvmem is enabled, with addr space of size %s", vmemstatus == MemType4GB ? "4GB" : "512MB");
|
||||
NOTICE_LOG(VMEM, "Info: nvmem is enabled");
|
||||
INFO_LOG(VMEM, "Info: p_sh4rcb: %p virt_ram_base: %p", p_sh4rcb, virt_ram_base);
|
||||
// Map the different parts of the memory file into the new memory range we got.
|
||||
if (vmemstatus == MemType512MB)
|
||||
{
|
||||
const vmem_mapping mem_mappings[] = {
|
||||
{0x00000000, 0x00800000, 0, 0, false}, // Area 0 -> unused
|
||||
{0x00800000, 0x01000000, MAP_ARAM_START_OFFSET, ARAM_SIZE, false}, // Aica
|
||||
{0x01000000, 0x04000000, 0, 0, false}, // More unused
|
||||
{0x04000000, 0x05000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // Area 1 (vram, 16MB, wrapped on DC as 2x8MB)
|
||||
{0x05000000, 0x06000000, 0, 0, false}, // 32 bit path (unused)
|
||||
{0x06000000, 0x07000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // VRAM mirror
|
||||
{0x07000000, 0x08000000, 0, 0, false}, // 32 bit path (unused) mirror
|
||||
{0x08000000, 0x0A000000, 0, 0, false}, // Area 2
|
||||
{0x0A000000, 0x0C000000, MAP_ERAM_START_OFFSET, elan::ELAN_RAM_SIZE, true}, // Area 2 (Elan RAM)
|
||||
{0x0C000000, 0x10000000, MAP_RAM_START_OFFSET, RAM_SIZE, true}, // Area 3 (main RAM + 3 mirrors)
|
||||
{0x10000000, 0x20000000, 0, 0, false}, // Area 4-7 (unused)
|
||||
// This is outside of the 512MB addr space. We map 8MB in all cases to help some games read past the end of aica ram
|
||||
{0x20000000, 0x20800000, MAP_ARAM_START_OFFSET, ARAM_SIZE, true}, // writable aica ram
|
||||
};
|
||||
vmem_platform_create_mappings(&mem_mappings[0], ARRAY_SIZE(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
|
||||
{0x01000000, 0x04000000, 0, 0, false}, // More unused
|
||||
{0x04000000, 0x05000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // Area 1 (vram, 16MB, wrapped on DC as 2x8MB)
|
||||
{0x05000000, 0x06000000, 0, 0, false}, // 32 bit path (unused)
|
||||
{0x06000000, 0x07000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // VRAM mirror
|
||||
{0x07000000, 0x08000000, 0, 0, false}, // 32 bit path (unused) mirror
|
||||
{0x08000000, 0x0A000000, 0, 0, false}, // Area 2
|
||||
{0x0A000000, 0x0C000000, MAP_ERAM_START_OFFSET, elan::ERAM_SIZE, true}, // Area 2 (Elan RAM)
|
||||
{0x0C000000, 0x10000000, MAP_RAM_START_OFFSET, RAM_SIZE, true}, // Area 3 (main RAM + 3 mirrors)
|
||||
{0x10000000, 0x20000000, 0, 0, false}, // Area 4-7 (unused)
|
||||
// This is outside of the 512MB addr space. We map 8MB in all cases to help some games read past the end of aica ram
|
||||
{0x20000000, 0x20800000, MAP_ARAM_START_OFFSET, ARAM_SIZE, true}, // writable aica ram
|
||||
};
|
||||
vmem_platform_create_mappings(&mem_mappings[0], ARRAY_SIZE(mem_mappings));
|
||||
|
||||
// Point buffers to actual data pointers
|
||||
aica_ram.data = &virt_ram_base[0x20000000]; // Points to the writable AICA addrspace
|
||||
vram.data = &virt_ram_base[0x04000000]; // Points to first vram mirror (writable and lockable)
|
||||
mem_b.data = &virt_ram_base[0x0C000000]; // Main memory, first mirror
|
||||
elan::RAM = &virt_ram_base[0x0A000000];
|
||||
}
|
||||
else
|
||||
{
|
||||
_vmem_set_p0_mappings();
|
||||
const vmem_mapping mem_mappings[] = {
|
||||
// P1
|
||||
{0x80000000, 0x80800000, 0, 0, false}, // Area 0 -> unused
|
||||
{0x80800000, 0x81000000, MAP_ARAM_START_OFFSET, ARAM_SIZE, true}, // Aica
|
||||
{0x81000000, 0x82800000, 0, 0, false}, // unused
|
||||
{0x82800000, 0x83000000, MAP_ARAM_START_OFFSET, ARAM_SIZE, true}, // Aica mirror
|
||||
{0x83000000, 0x84000000, 0, 0, false}, // unused
|
||||
{0x84000000, 0x85000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // Area 1 (vram, 16MB, wrapped on DC as 2x8MB)
|
||||
{0x85000000, 0x86000000, 0, 0, false}, // 32 bit path (unused)
|
||||
{0x86000000, 0x87000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // VRAM mirror
|
||||
{0x87000000, 0x88000000, 0, 0, false}, // 32 bit path (unused) mirror
|
||||
{0x88000000, 0x8A000000, 0, 0, false}, // Area 2
|
||||
{0x8A000000, 0x8C000000, MAP_ERAM_START_OFFSET, elan::ELAN_RAM_SIZE, true}, // Area 2 (Elan RAM)
|
||||
{0x8C000000, 0x90000000, MAP_RAM_START_OFFSET, RAM_SIZE, true}, // Area 3 (main RAM + 3 mirrors)
|
||||
{0x90000000, 0xA0000000, 0, 0, false}, // Area 4-7 (unused)
|
||||
// P2
|
||||
{0xA0000000, 0xA0800000, 0, 0, false}, // Area 0 -> unused
|
||||
{0xA0800000, 0xA1000000, MAP_ARAM_START_OFFSET, ARAM_SIZE, true}, // Aica
|
||||
{0xA1000000, 0xA2800000, 0, 0, false}, // unused
|
||||
{0xA2800000, 0xA3000000, MAP_ARAM_START_OFFSET, ARAM_SIZE, true}, // Aica mirror
|
||||
{0xA3000000, 0xA4000000, 0, 0, false}, // unused
|
||||
{0xA4000000, 0xA5000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // Area 1 (vram, 16MB, wrapped on DC as 2x8MB)
|
||||
{0xA5000000, 0xA6000000, 0, 0, false}, // 32 bit path (unused)
|
||||
{0xA6000000, 0xA7000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // VRAM mirror
|
||||
{0xA7000000, 0xA8000000, 0, 0, false}, // 32 bit path (unused) mirror
|
||||
{0xA8000000, 0xAA000000, 0, 0, false}, // Area 2
|
||||
{0xAA000000, 0xAC000000, MAP_ERAM_START_OFFSET, elan::ELAN_RAM_SIZE, true}, // Area 2 (Elan RAM)
|
||||
{0xAC000000, 0xB0000000, MAP_RAM_START_OFFSET, RAM_SIZE, true}, // Area 3 (main RAM + 3 mirrors)
|
||||
{0xB0000000, 0xC0000000, 0, 0, false}, // Area 4-7 (unused)
|
||||
// P3
|
||||
{0xC0000000, 0xC0800000, 0, 0, false}, // Area 0 -> unused
|
||||
{0xC0800000, 0xC1000000, MAP_ARAM_START_OFFSET, ARAM_SIZE, true}, // Aica
|
||||
{0xC1000000, 0xC2800000, 0, 0, false}, // unused
|
||||
{0xC2800000, 0xC3000000, MAP_ARAM_START_OFFSET, ARAM_SIZE, true}, // Aica mirror
|
||||
{0xC3000000, 0xC4000000, 0, 0, false}, // unused
|
||||
{0xC4000000, 0xC5000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // Area 1 (vram, 16MB, wrapped on DC as 2x8MB)
|
||||
{0xC5000000, 0xC6000000, 0, 0, false}, // 32 bit path (unused)
|
||||
{0xC6000000, 0xC7000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // VRAM mirror
|
||||
{0xC7000000, 0xC8000000, 0, 0, false}, // 32 bit path (unused) mirror
|
||||
{0xC8000000, 0xCA000000, 0, 0, false}, // Area 2
|
||||
{0xCA000000, 0xCC000000, MAP_ERAM_START_OFFSET, elan::ELAN_RAM_SIZE, true}, // Area 2 (Elan RAM)
|
||||
{0xCC000000, 0xD0000000, MAP_RAM_START_OFFSET, RAM_SIZE, true}, // Area 3 (main RAM + 3 mirrors)
|
||||
{0xD0000000, 0x100000000L, 0, 0, false}, // Area 4-7 (unused)
|
||||
};
|
||||
vmem_platform_create_mappings(&mem_mappings[0], ARRAY_SIZE(mem_mappings));
|
||||
|
||||
// Point buffers to actual data pointers
|
||||
aica_ram.data = &virt_ram_base[0x80800000]; // Points to the first AICA addrspace in P1
|
||||
vram.data = &virt_ram_base[0x84000000]; // Points to first vram mirror (writable and lockable) in P1
|
||||
mem_b.data = &virt_ram_base[0x8C000000]; // Main memory, first mirror in P1
|
||||
elan::RAM = &virt_ram_base[0x8A000000];
|
||||
|
||||
vmem_4gb_space = true;
|
||||
}
|
||||
// Point buffers to actual data pointers
|
||||
aica_ram.data = &virt_ram_base[0x20000000]; // Points to the writable AICA addrspace
|
||||
vram.data = &virt_ram_base[0x04000000]; // Points to first vram mirror (writable and lockable)
|
||||
mem_b.data = &virt_ram_base[0x0C000000]; // Main memory, first mirror
|
||||
elan::RAM = &virt_ram_base[0x0A000000];
|
||||
|
||||
aica_ram.size = ARAM_SIZE;
|
||||
vram.size = VRAM_SIZE;
|
||||
|
@ -605,7 +523,7 @@ void _vmem_release()
|
|||
_vmem_unprotect_vram(0, VRAM_SIZE);
|
||||
_vmem_term_mappings();
|
||||
}
|
||||
vmemstatus = MemTypeError;
|
||||
vmemAvailable = false;
|
||||
}
|
||||
|
||||
void _vmem_protect_vram(u32 addr, u32 size)
|
||||
|
@ -621,25 +539,6 @@ void _vmem_protect_vram(u32 addr, u32 size)
|
|||
mem_region_lock(virt_ram_base + 0x04000000 + addr + VRAM_SIZE, size); // P0 wrap
|
||||
//mem_region_lock(virt_ram_base + 0x06000000 + addr + VRAM_SIZE, size); // P0 mirror wrap
|
||||
}
|
||||
if (_nvmem_4gb_space())
|
||||
{
|
||||
mem_region_lock(virt_ram_base + 0x84000000 + addr, size); // P1
|
||||
//mem_region_lock(virt_ram_base + 0x86000000 + addr, size); // P1 - mirror
|
||||
mem_region_lock(virt_ram_base + 0xA4000000 + addr, size); // P2
|
||||
//mem_region_lock(virt_ram_base + 0xA6000000 + addr, size); // P2 - mirror
|
||||
// We should also lock P3 and its mirrors, but it doesn't seem to be used...
|
||||
//mem_region_lock(virt_ram_base + 0xC4000000 + addr, size); // P3
|
||||
//mem_region_lock(virt_ram_base + 0xC6000000 + addr, size); // P3 - mirror
|
||||
if (VRAM_SIZE == 0x800000)
|
||||
{
|
||||
mem_region_lock(virt_ram_base + 0x84000000 + addr + VRAM_SIZE, size); // P1 wrap
|
||||
//mem_region_lock(virt_ram_base + 0x86000000 + addr + VRAM_SIZE, size); // P1 - mirror wrap
|
||||
mem_region_lock(virt_ram_base + 0xA4000000 + addr + VRAM_SIZE, size); // P2 wrap
|
||||
//mem_region_lock(virt_ram_base + 0xA6000000 + addr + VRAM_SIZE, size); // P2 - mirror wrap
|
||||
//mem_region_lock(virt_ram_base + 0xC4000000 + addr + VRAM_SIZE, size); // P3 wrap
|
||||
//mem_region_lock(virt_ram_base + 0xC6000000 + addr + VRAM_SIZE, size); // P3 - mirror wrap
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -660,25 +559,6 @@ void _vmem_unprotect_vram(u32 addr, u32 size)
|
|||
mem_region_unlock(virt_ram_base + 0x04000000 + addr + VRAM_SIZE, size); // P0 wrap
|
||||
//mem_region_unlock(virt_ram_base + 0x06000000 + addr + VRAM_SIZE, size); // P0 mirror wrap
|
||||
}
|
||||
if (_nvmem_4gb_space())
|
||||
{
|
||||
mem_region_unlock(virt_ram_base + 0x84000000 + addr, size); // P1
|
||||
//mem_region_unlock(virt_ram_base + 0x86000000 + addr, size); // P1 - mirror
|
||||
mem_region_unlock(virt_ram_base + 0xA4000000 + addr, size); // P2
|
||||
//mem_region_unlock(virt_ram_base + 0xA6000000 + addr, size); // P2 - mirror
|
||||
// We should also lock P3 and its mirrors, but it doesn't seem to be used...
|
||||
//mem_region_unlock(virt_ram_base + 0xC4000000 + addr, size); // P3
|
||||
//mem_region_unlock(virt_ram_base + 0xC6000000 + addr, size); // P3 - mirror
|
||||
if (VRAM_SIZE == 0x800000)
|
||||
{
|
||||
mem_region_unlock(virt_ram_base + 0x84000000 + addr + VRAM_SIZE, size); // P1 wrap
|
||||
//mem_region_unlock(virt_ram_base + 0x86000000 + addr + VRAM_SIZE, size); // P1 - mirror wrap
|
||||
mem_region_unlock(virt_ram_base + 0xA4000000 + addr + VRAM_SIZE, size); // P2 wrap
|
||||
//mem_region_unlock(virt_ram_base + 0xA6000000 + addr + VRAM_SIZE, size); // P2 - mirror wrap
|
||||
//mem_region_unlock(virt_ram_base + 0xC4000000 + addr + VRAM_SIZE, size); // P3 wrap
|
||||
//mem_region_unlock(virt_ram_base + 0xC6000000 + addr + VRAM_SIZE, size); // P3 - mirror wrap
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -691,21 +571,9 @@ u32 _vmem_get_vram_offset(void *addr)
|
|||
if (_nvmem_enabled())
|
||||
{
|
||||
ptrdiff_t offset = (u8*)addr - virt_ram_base;
|
||||
if (_nvmem_4gb_space())
|
||||
{
|
||||
if (offset < 0 || offset >= 0xE0000000)
|
||||
return -1;
|
||||
offset &= 0x1FFFFFFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (offset < 0 || offset >= 0x20000000)
|
||||
return -1;
|
||||
}
|
||||
if ((offset >> 24) != 4)
|
||||
if (offset < 0 || offset >= 0x20000000)
|
||||
return -1;
|
||||
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
|
||||
if ((offset >> 24) != 4)
|
||||
return -1;
|
||||
|
||||
return offset & VRAM_MASK;
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
#pragma once
|
||||
#include "types.h"
|
||||
|
||||
enum VMemType {
|
||||
MemType4GB,
|
||||
MemType512MB,
|
||||
MemTypeError
|
||||
};
|
||||
|
||||
struct vmem_mapping {
|
||||
u64 start_address, end_address;
|
||||
u64 memoffset, memsize;
|
||||
|
@ -15,7 +9,7 @@ struct vmem_mapping {
|
|||
|
||||
// Platform specific vmemory API
|
||||
// To initialize (maybe) the vmem subsystem
|
||||
VMemType vmem_platform_init(void **vmem_base_addr, void **sh4rcb_addr, size_t ramSize);
|
||||
bool vmem_platform_init(void **vmem_base_addr, void **sh4rcb_addr, size_t ramSize);
|
||||
// To reset the on-demand allocated pages.
|
||||
void vmem_platform_reset_mem(void *ptr, unsigned size_bytes);
|
||||
// To handle a fault&allocate an ondemand page.
|
||||
|
@ -36,7 +30,7 @@ void vmem_platform_flush_cache(void *icache_start, void *icache_end, void *dcach
|
|||
void vmem_platform_jit_set_exec(void* code, size_t size, bool enable);
|
||||
|
||||
// Note: if you want to disable vmem magic in any given platform, implement the
|
||||
// above functions as empty functions and make vmem_platform_init return MemTypeError.
|
||||
// above functions as empty functions and make vmem_platform_init return false.
|
||||
|
||||
//Typedef's
|
||||
//ReadMem
|
||||
|
@ -99,14 +93,10 @@ void* _vmem_read_const(u32 addr,bool& ismem,u32 sz);
|
|||
void* _vmem_write_const(u32 addr,bool& ismem,u32 sz);
|
||||
|
||||
extern u8* virt_ram_base;
|
||||
extern bool vmem_4gb_space;
|
||||
|
||||
static inline bool _nvmem_enabled() {
|
||||
return virt_ram_base != 0;
|
||||
}
|
||||
static inline bool _nvmem_4gb_space() {
|
||||
return vmem_4gb_space;
|
||||
}
|
||||
void _vmem_bm_reset();
|
||||
|
||||
void _vmem_protect_vram(u32 addr, u32 size);
|
||||
|
|
|
@ -29,98 +29,30 @@ ElanRamWatcher elanWatcher;
|
|||
void AicaRamWatcher::protectMem(u32 addr, u32 size)
|
||||
{
|
||||
size = std::min(ARAM_SIZE - addr, size) & ~PAGE_MASK;
|
||||
if (_nvmem_enabled() && _nvmem_4gb_space()) {
|
||||
mem_region_lock(virt_ram_base + 0x00800000 + addr, size); // P0
|
||||
mem_region_lock(virt_ram_base + 0x02800000 + addr, size);// P0 - mirror
|
||||
mem_region_lock(virt_ram_base + 0x80800000 + addr, size); // P1
|
||||
//mem_region_lock(virt_ram_base + 0x82800000 + addr, size); // P1 - mirror
|
||||
mem_region_lock(virt_ram_base + 0xA0800000 + addr, size); // P2
|
||||
//mem_region_lock(virt_ram_base + 0xA2800000 + addr, size); // P2 - mirror
|
||||
if (ARAM_SIZE == 2 * 1024 * 1024) {
|
||||
mem_region_lock(virt_ram_base + 0x00A00000 + addr, size); // P0
|
||||
mem_region_lock(virt_ram_base + 0x00C00000 + addr, size); // P0
|
||||
mem_region_lock(virt_ram_base + 0x00E00000 + addr, size); // P0
|
||||
mem_region_lock(virt_ram_base + 0x02A00000 + addr, size);// P0 - mirror
|
||||
mem_region_lock(virt_ram_base + 0x02C00000 + addr, size);// P0 - mirror
|
||||
mem_region_lock(virt_ram_base + 0x02E00000 + addr, size);// P0 - mirror
|
||||
mem_region_lock(virt_ram_base + 0x80A00000 + addr, size); // P1
|
||||
mem_region_lock(virt_ram_base + 0x80C00000 + addr, size); // P1
|
||||
mem_region_lock(virt_ram_base + 0x80E00000 + addr, size); // P1
|
||||
mem_region_lock(virt_ram_base + 0xA0A00000 + addr, size); // P2
|
||||
mem_region_lock(virt_ram_base + 0xA0C00000 + addr, size); // P2
|
||||
mem_region_lock(virt_ram_base + 0xA0E00000 + addr, size); // P2
|
||||
}
|
||||
} else {
|
||||
mem_region_lock(aica_ram.data + addr,
|
||||
std::min(aica_ram.size - addr, size));
|
||||
}
|
||||
mem_region_lock(aica_ram.data + addr,
|
||||
std::min(aica_ram.size - addr, size));
|
||||
}
|
||||
|
||||
void AicaRamWatcher::unprotectMem(u32 addr, u32 size)
|
||||
{
|
||||
size = std::min(ARAM_SIZE - addr, size) & ~PAGE_MASK;
|
||||
if (_nvmem_enabled() && _nvmem_4gb_space()) {
|
||||
mem_region_unlock(virt_ram_base + 0x00800000 + addr, size); // P0
|
||||
mem_region_unlock(virt_ram_base + 0x02800000 + addr, size); // P0 - mirror
|
||||
mem_region_unlock(virt_ram_base + 0x80800000 + addr, size); // P1
|
||||
//mem_region_unlock(virt_ram_base + 0x82800000 + addr, size); // P1 - mirror
|
||||
mem_region_unlock(virt_ram_base + 0xA0800000 + addr, size); // P2
|
||||
//mem_region_unlock(virt_ram_base + 0xA2800000 + addr, size); // P2 - mirror
|
||||
if (ARAM_SIZE == 2 * 1024 * 1024) {
|
||||
mem_region_unlock(virt_ram_base + 0x00A00000 + addr, size); // P0
|
||||
mem_region_unlock(virt_ram_base + 0x00C00000 + addr, size); // P0
|
||||
mem_region_unlock(virt_ram_base + 0x00E00000 + addr, size); // P0
|
||||
mem_region_unlock(virt_ram_base + 0x02A00000 + addr, size); // P0 - mirror
|
||||
mem_region_unlock(virt_ram_base + 0x02C00000 + addr, size); // P0 - mirror
|
||||
mem_region_unlock(virt_ram_base + 0x02E00000 + addr, size); // P0 - mirror
|
||||
mem_region_unlock(virt_ram_base + 0x80A00000 + addr, size); // P1
|
||||
mem_region_unlock(virt_ram_base + 0x80C00000 + addr, size); // P1
|
||||
mem_region_unlock(virt_ram_base + 0x80E00000 + addr, size); // P1
|
||||
mem_region_unlock(virt_ram_base + 0xA0A00000 + addr, size); // P2
|
||||
mem_region_unlock(virt_ram_base + 0xA0C00000 + addr, size); // P2
|
||||
mem_region_unlock(virt_ram_base + 0xA0E00000 + addr, size); // P2
|
||||
}
|
||||
} else {
|
||||
mem_region_unlock(aica_ram.data + addr,
|
||||
std::min(aica_ram.size - addr, size));
|
||||
}
|
||||
mem_region_unlock(aica_ram.data + addr,
|
||||
std::min(aica_ram.size - addr, size));
|
||||
}
|
||||
|
||||
u32 AicaRamWatcher::getMemOffset(void *p)
|
||||
{
|
||||
u32 addr;
|
||||
if (_nvmem_enabled() && _nvmem_4gb_space()) {
|
||||
if ((u8*) p < virt_ram_base || (u8*) p >= virt_ram_base + 0x100000000L)
|
||||
return -1;
|
||||
addr = (u32) ((u8*) p - virt_ram_base);
|
||||
u32 area = (addr >> 29) & 7;
|
||||
if (area != 0 && area != 4 && area != 5)
|
||||
return -1;
|
||||
addr &= 0x1fffffff & ~0x02000000;
|
||||
if (addr < 0x00800000 || addr >= 0x01000000)
|
||||
return -1;
|
||||
addr &= ARAM_MASK;
|
||||
} else {
|
||||
if ((u8*) p < &aica_ram[0] || (u8*) p >= &aica_ram[ARAM_SIZE])
|
||||
return -1;
|
||||
addr = (u32) ((u8*) p - &aica_ram[0]);
|
||||
}
|
||||
return addr;
|
||||
if ((u8 *)p < &aica_ram[0] || (u8 *)p >= &aica_ram[ARAM_SIZE])
|
||||
return -1;
|
||||
return (u32)((u8 *)p - &aica_ram[0]);
|
||||
}
|
||||
|
||||
void ElanRamWatcher::protectMem(u32 addr, u32 size)
|
||||
{
|
||||
using namespace elan;
|
||||
size = std::min(ELAN_RAM_SIZE - addr, size) & ~PAGE_MASK;
|
||||
if (_nvmem_enabled())
|
||||
if (ERAM_SIZE != 0)
|
||||
{
|
||||
mem_region_lock(virt_ram_base + 0x0a000000 + addr, size); // P0
|
||||
if (_nvmem_4gb_space())
|
||||
{
|
||||
mem_region_lock(virt_ram_base + 0x8a000000 + addr, size); // P1
|
||||
mem_region_lock(virt_ram_base + 0xaa000000 + addr, size); // P2
|
||||
}
|
||||
} else {
|
||||
size = std::min(ERAM_SIZE - addr, size) & ~PAGE_MASK;
|
||||
mem_region_lock(RAM + addr, size);
|
||||
}
|
||||
}
|
||||
|
@ -128,16 +60,9 @@ void ElanRamWatcher::protectMem(u32 addr, u32 size)
|
|||
void ElanRamWatcher::unprotectMem(u32 addr, u32 size)
|
||||
{
|
||||
using namespace elan;
|
||||
size = std::min(ELAN_RAM_SIZE - addr, size) & ~PAGE_MASK;
|
||||
if (_nvmem_enabled())
|
||||
if (ERAM_SIZE != 0)
|
||||
{
|
||||
mem_region_unlock(virt_ram_base + 0x0a000000 + addr, size); // P0
|
||||
if (_nvmem_4gb_space())
|
||||
{
|
||||
mem_region_unlock(virt_ram_base + 0x8a000000 + addr, size); // P1
|
||||
mem_region_unlock(virt_ram_base + 0xaa000000 + addr, size); // P2
|
||||
}
|
||||
} else {
|
||||
size = std::min(ERAM_SIZE - addr, size) & ~PAGE_MASK;
|
||||
mem_region_unlock(RAM + addr, size);
|
||||
}
|
||||
}
|
||||
|
@ -145,25 +70,9 @@ void ElanRamWatcher::unprotectMem(u32 addr, u32 size)
|
|||
u32 ElanRamWatcher::getMemOffset(void *p)
|
||||
{
|
||||
using namespace elan;
|
||||
u32 addr;
|
||||
if (_nvmem_enabled())
|
||||
{
|
||||
if ((u8 *)p < virt_ram_base || (u8 *)p >= virt_ram_base + 0x100000000L)
|
||||
return -1;
|
||||
addr = (u32)((u8 *)p - virt_ram_base);
|
||||
u32 area = (addr >> 29) & 7;
|
||||
if (area != 0 && area != 4 && area != 5) // P0, P1 or P2 only
|
||||
return -1;
|
||||
addr &= 0x1fffffff;
|
||||
if (addr < 0x0a000000 || addr >= 0x0a000000 + ELAN_RAM_SIZE)
|
||||
return -1;
|
||||
addr &= ELAN_RAM_MASK;
|
||||
} else {
|
||||
if ((u8 *)p < RAM || (u8 *)p >= &RAM[ELAN_RAM_SIZE])
|
||||
return -1;
|
||||
addr = (u32)((u8 *)p - RAM);
|
||||
}
|
||||
return addr;
|
||||
if ((u8 *)p < RAM || (u8 *)p >= &RAM[ERAM_SIZE])
|
||||
return -1;
|
||||
return (u32)((u8 *)p - RAM);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -69,11 +69,14 @@
|
|||
|
||||
namespace elan {
|
||||
|
||||
constexpr u32 ELAN_RAM_MASK = ERAM_SIZE_MAX - 1;
|
||||
|
||||
static _vmem_handler elanRegHandler;
|
||||
static _vmem_handler elanCmdHandler;
|
||||
static _vmem_handler elanRamHandler;
|
||||
|
||||
u8 *RAM;
|
||||
u32 ERAM_SIZE;
|
||||
|
||||
static u32 reg10;
|
||||
static u32 reg74;
|
||||
|
@ -478,7 +481,7 @@ struct State
|
|||
|
||||
static u32 elanRamAddress(void *p)
|
||||
{
|
||||
if ((u8 *)p < RAM || (u8 *)p >= RAM + ELAN_RAM_SIZE)
|
||||
if ((u8 *)p < RAM || (u8 *)p >= RAM + ERAM_SIZE)
|
||||
return Null;
|
||||
else
|
||||
return (u32)((u8 *)p - RAM);
|
||||
|
@ -1441,7 +1444,7 @@ template<bool Active = true>
|
|||
static void executeCommand(u8 *data, int size)
|
||||
{
|
||||
// verify(size >= 0);
|
||||
// verify(size < (int)ELAN_RAM_SIZE);
|
||||
// verify(size < (int)ERAM_SIZE);
|
||||
// if (0x2b00 == (u32)(data - RAM))
|
||||
// for (int i = 0; i < size; i += 4)
|
||||
// DEBUG_LOG(PVR, "Elan Parse %08x: %08x", (u32)(&data[i] - RAM), *(u32 *)&data[i]);
|
||||
|
@ -1748,7 +1751,7 @@ void reset(bool hard)
|
|||
{
|
||||
if (hard)
|
||||
{
|
||||
memset(RAM, 0, ELAN_RAM_SIZE);
|
||||
memset(RAM, 0, ERAM_SIZE);
|
||||
state.reset();
|
||||
}
|
||||
}
|
||||
|
@ -1780,7 +1783,7 @@ void serialize(Serializer& ser)
|
|||
ser << reg74;
|
||||
ser << elanCmd;
|
||||
if (!ser.rollback())
|
||||
ser.serialize(RAM, ELAN_RAM_SIZE);
|
||||
ser.serialize(RAM, ERAM_SIZE);
|
||||
state.serialize(ser);
|
||||
}
|
||||
|
||||
|
@ -1792,7 +1795,7 @@ void deserialize(Deserializer& deser)
|
|||
deser >> reg74;
|
||||
deser >> elanCmd;
|
||||
if (!deser.rollback())
|
||||
deser.deserialize(RAM, ELAN_RAM_SIZE);
|
||||
deser.deserialize(RAM, ERAM_SIZE);
|
||||
state.deserialize(deser);
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,6 @@ void serialize(Serializer& ser);
|
|||
void deserialize(Deserializer& deser);
|
||||
|
||||
extern u8 *RAM;
|
||||
constexpr u32 ELAN_RAM_SIZE = 32 * 1024 * 1024;
|
||||
constexpr u32 ELAN_RAM_MASK = ELAN_RAM_SIZE - 1;
|
||||
extern u32 ERAM_SIZE;
|
||||
constexpr u32 ERAM_SIZE_MAX = 32 * 1024 * 1024;
|
||||
}
|
||||
|
|
|
@ -235,7 +235,6 @@ void bm_Reset()
|
|||
{
|
||||
// Windows cannot lock/unlock a region spanning more than one VirtualAlloc or MapViewOfFile
|
||||
// so we have to unlock each region individually
|
||||
// No need for this mess in 4GB mode since windows doesn't use it
|
||||
if (settings.platform.ram_size == 16 * 1024 * 1024)
|
||||
{
|
||||
mem_region_unlock(virt_ram_base + 0x0C000000, RAM_SIZE);
|
||||
|
@ -248,11 +247,6 @@ void bm_Reset()
|
|||
mem_region_unlock(virt_ram_base + 0x0C000000, RAM_SIZE);
|
||||
mem_region_unlock(virt_ram_base + 0x0E000000, RAM_SIZE);
|
||||
}
|
||||
if (_nvmem_4gb_space())
|
||||
{
|
||||
mem_region_unlock(virt_ram_base + 0x8C000000u, 0x90000000u - 0x8C000000u);
|
||||
mem_region_unlock(virt_ram_base + 0xAC000000u, 0xB0000000u - 0xAC000000u);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -264,38 +258,18 @@ void bm_LockPage(u32 addr, u32 size)
|
|||
{
|
||||
addr = addr & (RAM_MASK - PAGE_MASK);
|
||||
if (_nvmem_enabled())
|
||||
{
|
||||
mem_region_lock(virt_ram_base + 0x0C000000 + addr, size);
|
||||
if (_nvmem_4gb_space())
|
||||
{
|
||||
mem_region_lock(virt_ram_base + 0x8C000000 + addr, size);
|
||||
mem_region_lock(virt_ram_base + 0xAC000000 + addr, size);
|
||||
// TODO wraps
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mem_region_lock(&mem_b[addr], size);
|
||||
}
|
||||
}
|
||||
|
||||
void bm_UnlockPage(u32 addr, u32 size)
|
||||
{
|
||||
addr = addr & (RAM_MASK - PAGE_MASK);
|
||||
if (_nvmem_enabled())
|
||||
{
|
||||
mem_region_unlock(virt_ram_base + 0x0C000000 + addr, size);
|
||||
if (_nvmem_4gb_space())
|
||||
{
|
||||
mem_region_unlock(virt_ram_base + 0x8C000000 + addr, size);
|
||||
mem_region_unlock(virt_ram_base + 0xAC000000 + addr, size);
|
||||
// TODO wraps
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mem_region_unlock(&mem_b[addr], size);
|
||||
}
|
||||
}
|
||||
|
||||
void bm_ResetCache()
|
||||
|
@ -618,18 +592,10 @@ u32 bm_getRamOffset(void *p)
|
|||
{
|
||||
if (_nvmem_enabled())
|
||||
{
|
||||
if (_nvmem_4gb_space())
|
||||
{
|
||||
if ((u8 *)p < virt_ram_base || (u8 *)p >= virt_ram_base + 0x100000000L)
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((u8 *)p < virt_ram_base || (u8 *)p >= virt_ram_base + 0x20000000)
|
||||
return -1;
|
||||
}
|
||||
if ((u8 *)p < virt_ram_base || (u8 *)p >= virt_ram_base + 0x20000000)
|
||||
return -1;
|
||||
u32 addr = (u8*)p - virt_ram_base;
|
||||
if (!IsOnRam(addr) || ((addr >> 29) > 0 && (addr >> 29) < 4)) // system RAM is not mapped to 20, 40 and 60 because of laziness
|
||||
if (!IsOnRam(addr))
|
||||
return -1;
|
||||
return addr & RAM_MASK;
|
||||
}
|
||||
|
|
|
@ -385,16 +385,7 @@ static void recSh4_Init()
|
|||
|
||||
|
||||
if (_nvmem_enabled())
|
||||
{
|
||||
if (!_nvmem_4gb_space())
|
||||
{
|
||||
verify(mem_b.data==((u8*)p_sh4rcb->sq_buffer+512+0x0C000000));
|
||||
}
|
||||
else
|
||||
{
|
||||
verify(mem_b.data==((u8*)p_sh4rcb->sq_buffer+512+0x8C000000));
|
||||
}
|
||||
}
|
||||
verify(mem_b.data == ((u8*)p_sh4rcb->sq_buffer + 512 + 0x0C000000));
|
||||
|
||||
// Prepare some pointer to the pre-allocated code cache:
|
||||
void *candidate_ptr = (void*)(((unat)SH4_TCB + 4095) & ~4095);
|
||||
|
|
|
@ -118,19 +118,19 @@ static mem_handle_t allocate_shared_filemem(unsigned size)
|
|||
*/
|
||||
|
||||
// Implement vmem initialization for RAM, ARAM, VRAM and SH4 context, fpcb etc.
|
||||
// The function supports allocating 512MB or 4GB addr spaces.
|
||||
// vmem_base_addr points to an address space of 512MB (or 4GB) that can be used for fast memory ops.
|
||||
|
||||
// vmem_base_addr points to an address space of 512MB that can be used for fast memory ops.
|
||||
// In negative offsets of the pointer (up to FPCB size, usually 65/129MB) the context and jump table
|
||||
// can be found. If the platform init returns error, the user is responsible for initializing the
|
||||
// memory using a fallback (that is, regular mallocs and falling back to slow memory JIT).
|
||||
VMemType vmem_platform_init(void **vmem_base_addr, void **sh4rcb_addr, size_t ramSize)
|
||||
bool vmem_platform_init(void **vmem_base_addr, void **sh4rcb_addr, size_t ramSize)
|
||||
{
|
||||
return MemTypeError;
|
||||
return false;
|
||||
#if 0
|
||||
const unsigned size_aligned = ((RAM_SIZE_MAX + VRAM_SIZE_MAX + ARAM_SIZE_MAX + PAGE_SIZE) & (~(PAGE_SIZE-1)));
|
||||
vmem_fd_page = allocate_shared_filemem(size_aligned);
|
||||
if (vmem_fd_page < 0)
|
||||
return MemTypeError;
|
||||
return false;
|
||||
|
||||
vmem_fd_codememory = (uintptr_t)virtmemReserve(size_aligned);
|
||||
|
||||
|
@ -141,15 +141,12 @@ VMemType vmem_platform_init(void **vmem_base_addr, void **sh4rcb_addr, size_t ra
|
|||
WARN_LOG(VMEM, "Failed to set perms (platform_int)...");
|
||||
|
||||
// Now try to allocate a contiguous piece of memory.
|
||||
VMemType rv;
|
||||
if (reserved_base == NULL)
|
||||
{
|
||||
reserved_size = 512*1024*1024 + sizeof(Sh4RCB) + ARAM_SIZE_MAX + 0x10000;
|
||||
reserved_base = mem_region_reserve(NULL, reserved_size);
|
||||
if (!reserved_base)
|
||||
return MemTypeError;
|
||||
|
||||
rv = MemType512MB;
|
||||
return false;
|
||||
}
|
||||
|
||||
*sh4rcb_addr = reserved_base;
|
||||
|
@ -160,7 +157,7 @@ VMemType vmem_platform_init(void **vmem_base_addr, void **sh4rcb_addr, size_t ra
|
|||
// Now map the memory for the SH4 context, do not include FPCB on purpose (paged on demand).
|
||||
mem_region_unlock(sh4rcb_base_ptr, sizeof(Sh4RCB) - fpcb_size);
|
||||
|
||||
return rv;
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -148,39 +148,28 @@ static int allocate_shared_filemem(unsigned size) {
|
|||
}
|
||||
|
||||
// Implement vmem initialization for RAM, ARAM, VRAM and SH4 context, fpcb etc.
|
||||
// The function supports allocating 512MB or 4GB addr spaces.
|
||||
|
||||
int vmem_fd = -1;
|
||||
static int shmem_fd2 = -1;
|
||||
static void *reserved_base;
|
||||
static size_t reserved_size;
|
||||
|
||||
// vmem_base_addr points to an address space of 512MB (or 4GB) that can be used for fast memory ops.
|
||||
// vmem_base_addr points to an address space of 512MB that can be used for fast memory ops.
|
||||
// In negative offsets of the pointer (up to FPCB size, usually 65/129MB) the context and jump table
|
||||
// can be found. If the platform init returns error, the user is responsible for initializing the
|
||||
// memory using a fallback (that is, regular mallocs and falling back to slow memory JIT).
|
||||
VMemType vmem_platform_init(void **vmem_base_addr, void **sh4rcb_addr, size_t ramSize) {
|
||||
bool vmem_platform_init(void **vmem_base_addr, void **sh4rcb_addr, size_t ramSize) {
|
||||
// Firt let's try to allocate the shm-backed memory
|
||||
vmem_fd = allocate_shared_filemem(ramSize);
|
||||
if (vmem_fd < 0)
|
||||
return MemTypeError;
|
||||
return false;
|
||||
|
||||
// Now try to allocate a contiguous piece of memory.
|
||||
VMemType rv;
|
||||
#if HOST_CPU == CPU_X64 || HOST_CPU == CPU_ARM64
|
||||
reserved_size = 0x100000000L + sizeof(Sh4RCB) + 0x10000; // 4GB + context size + 64K padding
|
||||
reserved_size = 512*1024*1024 + sizeof(Sh4RCB) + ARAM_SIZE_MAX + 0x10000;
|
||||
reserved_base = mem_region_reserve(NULL, reserved_size);
|
||||
rv = MemType4GB;
|
||||
#endif
|
||||
if (reserved_base == NULL)
|
||||
{
|
||||
reserved_size = 512*1024*1024 + sizeof(Sh4RCB) + ARAM_SIZE_MAX + 0x10000;
|
||||
reserved_base = mem_region_reserve(NULL, reserved_size);
|
||||
if (!reserved_base) {
|
||||
close(vmem_fd);
|
||||
return MemTypeError;
|
||||
}
|
||||
rv = MemType512MB;
|
||||
if (!reserved_base) {
|
||||
close(vmem_fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Align pointer to 64KB too, some Linaro bug (no idea but let's just be safe I guess).
|
||||
|
@ -194,7 +183,7 @@ VMemType vmem_platform_init(void **vmem_base_addr, void **sh4rcb_addr, size_t ra
|
|||
// Now map the memory for the SH4 context, do not include FPCB on purpose (paged on demand).
|
||||
mem_region_unlock(sh4rcb_base_ptr, sizeof(Sh4RCB) - fpcb_size);
|
||||
|
||||
return rv;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Just tries to wipe as much as possible in the relevant area.
|
||||
|
|
|
@ -1825,17 +1825,10 @@ private:
|
|||
|
||||
Instruction *start_instruction = GetCursorAddress<Instruction *>();
|
||||
|
||||
// WARNING: the rewrite code relies on having 1 or 2 ops before the memory access
|
||||
// WARNING: the rewrite code relies on having 2 ops before the memory access
|
||||
// Update ngen_Rewrite (and perhaps read_memory_rewrite_size) if adding or removing code
|
||||
if (!_nvmem_4gb_space())
|
||||
{
|
||||
Ubfx(x1, x0, 0, 29);
|
||||
Add(x1, x1, sizeof(Sh4Context), LeaveFlags);
|
||||
}
|
||||
else
|
||||
{
|
||||
Add(x1, x0, sizeof(Sh4Context), LeaveFlags);
|
||||
}
|
||||
Ubfx(x1, x0, 0, 29);
|
||||
Add(x1, x1, sizeof(Sh4Context), LeaveFlags);
|
||||
|
||||
u32 size = op.flags & 0x7f;
|
||||
switch(size)
|
||||
|
@ -1998,17 +1991,10 @@ private:
|
|||
|
||||
Instruction *start_instruction = GetCursorAddress<Instruction *>();
|
||||
|
||||
// WARNING: the rewrite code relies on having 1 or 2 ops before the memory access
|
||||
// WARNING: the rewrite code relies on having 2 ops before the memory access
|
||||
// Update ngen_Rewrite (and perhaps write_memory_rewrite_size) if adding or removing code
|
||||
if (!_nvmem_4gb_space())
|
||||
{
|
||||
Ubfx(x7, x0, 0, 29);
|
||||
Add(x7, x7, sizeof(Sh4Context), LeaveFlags);
|
||||
}
|
||||
else
|
||||
{
|
||||
Add(x7, x0, sizeof(Sh4Context), LeaveFlags);
|
||||
}
|
||||
Ubfx(x7, x0, 0, 29);
|
||||
Add(x7, x7, sizeof(Sh4Context), LeaveFlags);
|
||||
|
||||
u32 size = op.flags & 0x7f;
|
||||
switch(size)
|
||||
|
@ -2279,7 +2265,7 @@ bool ngen_Rewrite(host_context_t &context, void *faultAddress)
|
|||
verify(found);
|
||||
|
||||
// Skip the preceding ops (add, ubfx)
|
||||
u32 *code_rewrite = code_ptr - 1 - (!_nvmem_4gb_space() ? 1 : 0);
|
||||
u32 *code_rewrite = code_ptr - 2;
|
||||
Arm64Assembler *assembler = new Arm64Assembler(code_rewrite);
|
||||
if (is_read)
|
||||
assembler->GenReadMemorySlow(size);
|
||||
|
|
|
@ -741,13 +741,7 @@ public:
|
|||
|
||||
//found !
|
||||
const u8 *start = getCurr();
|
||||
u32 memAddress = _nvmem_4gb_space() ?
|
||||
#ifdef _WIN32
|
||||
context.rcx
|
||||
#else
|
||||
context.rdi
|
||||
#endif
|
||||
: context.r9;
|
||||
u32 memAddress = context.r9;
|
||||
if (op == MemOp::W && size >= MemSize::S32 && (memAddress >> 26) == 0x38)
|
||||
call(MemHandlers[MemType::StoreQueue][size][MemOp::W]);
|
||||
else
|
||||
|
@ -759,12 +753,11 @@ public:
|
|||
context.pc = (uintptr_t)(retAddr - 5);
|
||||
// remove the call from the stack
|
||||
context.rsp += 8;
|
||||
if (!_nvmem_4gb_space())
|
||||
//restore the addr from r9 to arg0 (rcx or rdi) so it's valid again
|
||||
//restore the addr from r9 to arg0 (rcx or rdi) so it's valid again
|
||||
#ifdef _WIN32
|
||||
context.rcx = memAddress;
|
||||
context.rcx = memAddress;
|
||||
#else
|
||||
context.rdi = memAddress;
|
||||
context.rdi = memAddress;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
|
@ -781,6 +774,7 @@ private:
|
|||
{
|
||||
if (mmu_enabled())
|
||||
{
|
||||
#ifdef FAST_MMU
|
||||
Xbyak::Label inCache;
|
||||
Xbyak::Label done;
|
||||
|
||||
|
@ -797,15 +791,18 @@ private:
|
|||
}
|
||||
test(eax, eax);
|
||||
jne(inCache);
|
||||
#endif
|
||||
mov(call_regs[1], write);
|
||||
mov(call_regs[2], block->vaddr + op.guest_offs - (op.delay_slot ? 2 : 0)); // pc
|
||||
GenCall(mmuDynarecLookup);
|
||||
mov(call_regs[0], eax);
|
||||
#ifdef FAST_MMU
|
||||
jmp(done);
|
||||
L(inCache);
|
||||
and_(call_regs[0], 0xFFF);
|
||||
or_(call_regs[0], eax);
|
||||
L(done);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
bool GenReadMemImmediate(const shil_opcode& op, RuntimeBlockInfo* block)
|
||||
|
@ -1125,11 +1122,9 @@ private:
|
|||
if (type == MemType::Fast && _nvmem_enabled())
|
||||
{
|
||||
mov(rax, (uintptr_t)virt_ram_base);
|
||||
if (!_nvmem_4gb_space())
|
||||
{
|
||||
mov(r9, call_regs64[0]);
|
||||
and_(call_regs[0], 0x1FFFFFFF);
|
||||
}
|
||||
mov(r9, call_regs64[0]);
|
||||
and_(call_regs[0], 0x1FFFFFFF);
|
||||
|
||||
switch (size)
|
||||
{
|
||||
case MemSize::S8:
|
||||
|
|
|
@ -45,14 +45,13 @@ static std::vector<void *> unmapped_regions;
|
|||
static std::vector<void *> mapped_regions;
|
||||
|
||||
// Implement vmem initialization for RAM, ARAM, VRAM and SH4 context, fpcb etc.
|
||||
// The function supports allocating 512MB or 4GB addr spaces.
|
||||
|
||||
// Please read the POSIX implementation for more information. On Windows this is
|
||||
// rather straightforward.
|
||||
VMemType vmem_platform_init(void **vmem_base_addr, void **sh4rcb_addr, size_t ramSize)
|
||||
bool vmem_platform_init(void **vmem_base_addr, void **sh4rcb_addr, size_t ramSize)
|
||||
{
|
||||
#ifdef TARGET_UWP
|
||||
return MemTypeError;
|
||||
return false;
|
||||
#endif
|
||||
unmapped_regions.reserve(32);
|
||||
mapped_regions.reserve(32);
|
||||
|
@ -81,7 +80,7 @@ VMemType vmem_platform_init(void **vmem_base_addr, void **sh4rcb_addr, size_t ra
|
|||
verify(ptr == *vmem_base_addr);
|
||||
unmapped_regions.push_back(ptr);
|
||||
|
||||
return MemType512MB;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Just tries to wipe as much as possible in the relevant area.
|
||||
|
|
Loading…
Reference in New Issue