diff --git a/core/emulator.cpp b/core/emulator.cpp index e46ec6b1b..3f0aa823d 100644 --- a/core/emulator.cpp +++ b/core/emulator.cpp @@ -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; diff --git a/core/hw/mem/_vmem.cpp b/core/hw/mem/_vmem.cpp index c5da88c0c..c8153f5ff 100644 --- a/core/hw/mem/_vmem.cpp +++ b/core/hw/mem/_vmem.cpp @@ -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; diff --git a/core/hw/mem/_vmem.h b/core/hw/mem/_vmem.h index bccb03f9f..996710cdc 100644 --- a/core/hw/mem/_vmem.h +++ b/core/hw/mem/_vmem.h @@ -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); diff --git a/core/hw/mem/mem_watch.cpp b/core/hw/mem/mem_watch.cpp index d76396a78..06c732740 100644 --- a/core/hw/mem/mem_watch.cpp +++ b/core/hw/mem/mem_watch.cpp @@ -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); } } diff --git a/core/hw/pvr/elan.cpp b/core/hw/pvr/elan.cpp index 83596c4f9..038896dc2 100644 --- a/core/hw/pvr/elan.cpp +++ b/core/hw/pvr/elan.cpp @@ -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 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); } diff --git a/core/hw/pvr/elan.h b/core/hw/pvr/elan.h index 3c28b3287..b1dea22f6 100644 --- a/core/hw/pvr/elan.h +++ b/core/hw/pvr/elan.h @@ -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; } diff --git a/core/hw/sh4/dyna/blockmanager.cpp b/core/hw/sh4/dyna/blockmanager.cpp index e88fbaa05..d9f9779c1 100644 --- a/core/hw/sh4/dyna/blockmanager.cpp +++ b/core/hw/sh4/dyna/blockmanager.cpp @@ -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; } diff --git a/core/hw/sh4/dyna/driver.cpp b/core/hw/sh4/dyna/driver.cpp index 0d67bf1e3..b78c9dda3 100644 --- a/core/hw/sh4/dyna/driver.cpp +++ b/core/hw/sh4/dyna/driver.cpp @@ -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); diff --git a/core/linux/libnx_vmem.cpp b/core/linux/libnx_vmem.cpp index 1545f2265..45af8458e 100644 --- a/core/linux/libnx_vmem.cpp +++ b/core/linux/libnx_vmem.cpp @@ -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 } diff --git a/core/linux/posix_vmem.cpp b/core/linux/posix_vmem.cpp index a2ab3c718..3f95379f7 100644 --- a/core/linux/posix_vmem.cpp +++ b/core/linux/posix_vmem.cpp @@ -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. diff --git a/core/rec-ARM64/rec_arm64.cpp b/core/rec-ARM64/rec_arm64.cpp index f96a506ed..acd75f74e 100644 --- a/core/rec-ARM64/rec_arm64.cpp +++ b/core/rec-ARM64/rec_arm64.cpp @@ -1825,17 +1825,10 @@ private: Instruction *start_instruction = GetCursorAddress(); - // 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(); - // 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); diff --git a/core/rec-x64/rec_x64.cpp b/core/rec-x64/rec_x64.cpp index 00c3dc789..7ba4dfce8 100644 --- a/core/rec-x64/rec_x64.cpp +++ b/core/rec-x64/rec_x64.cpp @@ -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: diff --git a/core/windows/win_vmem.cpp b/core/windows/win_vmem.cpp index 5fe995a25..dfc953842 100644 --- a/core/windows/win_vmem.cpp +++ b/core/windows/win_vmem.cpp @@ -45,14 +45,13 @@ static std::vector unmapped_regions; static std::vector 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.