From 74007d5e5d84f5fbc965949132c78c25807d7bde Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Sat, 4 Oct 2014 18:43:46 +0400 Subject: [PATCH] Small changes in memory and RSXIOMem Some bugs fixed, some other changes. --- rpcs3/Emu/Cell/SPUInterpreter.h | 5 +- rpcs3/Emu/Cell/SPURecompiler.h | 6 +- rpcs3/Emu/Cell/SPUThread.cpp | 6 ++ rpcs3/Emu/Cell/SPUThread.h | 3 +- rpcs3/Emu/Memory/Memory.cpp | 70 +++++++++++------------ rpcs3/Emu/Memory/MemoryBlock.h | 7 ++- rpcs3/Emu/Memory/vm.h | 12 ---- rpcs3/Emu/RSX/RSXThread.cpp | 30 ++++++---- rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp | 29 +++++----- rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp | 11 +++- rpcs3/Emu/SysCalls/lv2/sys_spu.cpp | 4 +- rpcs3/Emu/SysCalls/lv2/sys_vm.cpp | 2 +- rpcs3/Loader/ELF64.cpp | 2 +- 13 files changed, 95 insertions(+), 92 deletions(-) diff --git a/rpcs3/Emu/Cell/SPUInterpreter.h b/rpcs3/Emu/Cell/SPUInterpreter.h index eb5b90eb7b..d903353991 100644 --- a/rpcs3/Emu/Cell/SPUInterpreter.h +++ b/rpcs3/Emu/Cell/SPUInterpreter.h @@ -432,9 +432,7 @@ private: } void LQX(u32 rt, u32 ra, u32 rb) { - u32 a = CPU.GPR[ra]._u32[3], b = CPU.GPR[rb]._u32[3]; - - u32 lsa = (a + b) & 0x3fff0; + u32 lsa = (CPU.GPR[ra]._u32[3] + CPU.GPR[rb]._u32[3]) & 0x3fff0; CPU.GPR[rt] = CPU.ReadLS128(lsa); } @@ -1088,6 +1086,7 @@ private: for (int i = 0; i < 4; i++) { CPU.GPR[rt]._f[i] = (float)CPU.GPR[ra]._u32[i]; + u32 exp = ((CPU.GPR[rt]._u32[i] >> 23) & 0xff) - scale; if (exp > 255) //< 0 diff --git a/rpcs3/Emu/Cell/SPURecompiler.h b/rpcs3/Emu/Cell/SPURecompiler.h index 455e058658..dafae1842b 100644 --- a/rpcs3/Emu/Cell/SPURecompiler.h +++ b/rpcs3/Emu/Cell/SPURecompiler.h @@ -1964,12 +1964,12 @@ private: void CLZ(u32 rt, u32 ra) { XmmInvalidate(rt); + c.mov(*qw0, 32 + 31); for (u32 i = 0; i < 4; i++) { c.bsr(*addr, cpu_dword(GPR[ra]._u32[i])); - c.cmovz(*addr, dword_ptr(*g_imm_var, (s32)offsetof(g_imm_table_struct, fsmb_table[0xffff]))); // load 0xffffffff - c.neg(*addr); - c.add(*addr, 31); + c.cmovz(*addr, qw0->r32()); + c.xor_(*addr, 31); c.mov(cpu_dword(GPR[rt]._u32[i]), *addr); } LOG_OPCODE(); diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index 6d494b7ca0..04bb14b88f 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -1016,6 +1016,12 @@ void SPUThread::StopAndSignal(u32 code) break; } + case 0x003: + { + GPR[3]._u32[3] = m_code3_func(*this); + break; + } + case 0x110: { /* ===== sys_spu_thread_receive_event ===== */ diff --git a/rpcs3/Emu/Cell/SPUThread.h b/rpcs3/Emu/Cell/SPUThread.h index f97c9b2cd6..8eef83d71f 100644 --- a/rpcs3/Emu/Cell/SPUThread.h +++ b/rpcs3/Emu/Cell/SPUThread.h @@ -450,7 +450,8 @@ public: void WriteLS64 (const u32 lsa, const u64& data) const { vm::write64 (lsa + m_offset, data); } void WriteLS128(const u32 lsa, const u128& data) const { vm::write128(lsa + m_offset, data); } - std::function m_custom_task; + std::function m_custom_task; + std::function m_code3_func; public: SPUThread(CPUThreadType type = CPU_THREAD_SPU); diff --git a/rpcs3/Emu/Memory/Memory.cpp b/rpcs3/Emu/Memory/Memory.cpp index c11f8e2de0..1cc432d4cd 100644 --- a/rpcs3/Emu/Memory/Memory.cpp +++ b/rpcs3/Emu/Memory/Memory.cpp @@ -578,73 +578,71 @@ bool VirtualMemoryBlock::IsMyAddress(const u64 addr) return false; } -u64 VirtualMemoryBlock::Map(u64 realaddr, u32 size, u64 addr) +u64 VirtualMemoryBlock::Map(u64 realaddr, u32 size) { - if(addr) + for (u64 addr = GetStartAddr(); addr <= GetEndAddr() - GetReservedAmount() - size;) { - if(!IsInMyRange(addr, size) && (IsMyAddress(addr) || IsMyAddress(addr + size - 1))) - return 0; + bool is_good_addr = true; - m_mapped_memory.emplace_back(addr, realaddr, size); - return addr; - } - else - { - for(u64 addr = GetStartAddr(); addr <= GetEndAddr() - GetReservedAmount() - size;) + // check if address is already mapped + for (u32 i = 0; i= m_mapped_memory[i].addr && addr < m_mapped_memory[i].addr + m_mapped_memory[i].size) || + (m_mapped_memory[i].addr >= addr && m_mapped_memory[i].addr < addr + size)) { - if((addr >= m_mapped_memory[i].addr && addr < m_mapped_memory[i].addr + m_mapped_memory[i].size) || - (m_mapped_memory[i].addr >= addr && m_mapped_memory[i].addr < addr + size)) - { - is_good_addr = false; - addr = m_mapped_memory[i].addr + m_mapped_memory[i].size; - break; - } + is_good_addr = false; + addr = m_mapped_memory[i].addr + m_mapped_memory[i].size; + break; } - - if(!is_good_addr) continue; - - m_mapped_memory.emplace_back(addr, realaddr, size); - - return addr; } - return 0; + if (!is_good_addr) continue; + + m_mapped_memory.emplace_back(addr, realaddr, size); + + return addr; } + + return 0; } -u32 VirtualMemoryBlock::UnmapRealAddress(u64 realaddr) +bool VirtualMemoryBlock::Map(u64 realaddr, u32 size, u64 addr) +{ + if(!IsInMyRange(addr, size) && (IsMyAddress(addr) || IsMyAddress(addr + size - 1))) + return false; + + m_mapped_memory.emplace_back(addr, realaddr, size); + return true; +} + +bool VirtualMemoryBlock::UnmapRealAddress(u64 realaddr, u32& size) { for(u32 i=0; i - T* const get_ptr(u64 addr) - { - return get_ptr((u32)addr); - } template T& get_ref(u32 addr) @@ -25,12 +19,6 @@ namespace vm return *get_ptr(addr); } - template - T& get_ref(u64 addr) - { - return get_ref((u32)addr); - } - namespace ps3 { static u8 read8(u32 addr) diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 02231cf848..b1de17eb0e 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -48,7 +48,7 @@ u32 GetAddress(u32 offset, u32 location) switch(location) { case CELL_GCM_LOCATION_LOCAL: return (u32)Memory.RSXFBMem.GetStartAddr() + offset; - case CELL_GCM_LOCATION_MAIN: return (u32)Memory.RSXIOMem.RealAddr(Memory.RSXIOMem.GetStartAddr() + offset); // TODO: Error Check? + case CELL_GCM_LOCATION_MAIN: return (u32)Memory.RSXIOMem.RealAddr(offset); // TODO: Error Check? } LOG_ERROR(RSX, "GetAddress(offset=0x%x, location=0x%x)", location); @@ -296,9 +296,10 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const if(m_flip_handler) { auto cb = m_flip_handler; - Emu.GetCallbackManager().Async([cb]() + Emu.GetCallbackManager().Register([cb]() { cb(1); + return 0; }); } @@ -1947,13 +1948,17 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const u8* pixels_src = vm::get_ptr(GetAddress(offset, m_context_dma_img_src - 0xfeed0000)); u8* pixels_dst = vm::get_ptr(GetAddress(m_dst_offset, m_context_dma_img_dst - 0xfeed0000)); + LOG_WARNING(RSX, "NV3089_IMAGE_IN_SIZE: width=%d, height=%d, pitch=%d, origin=%d, inter=%d, offset=0x%x, u=%d, v=%d", width, height, pitch, origin, inter, offset, u, v); + LOG_WARNING(RSX, "*** m_dst_offset=0x%x, m_color: conv_in_h=0x%x, format_src_pitch=0x%x, conv_in_x=0x%x, conv_in_y=0x%x, conv_out_x=0x%x, conv_out_y=0x%x", + m_dst_offset, m_color_conv_in_h, m_color_format_src_pitch, m_color_conv_in_x, m_color_conv_in_y, m_color_conv_out_x, m_color_conv_out_y); + for(u16 y=0; y> 18) & 0x7ff; //if(cmd == 0) continue; + //LOG_NOTICE(Log::RSX, "put=0x%x, get=0x%x, cmd=0x%x (%s)", put, get, cmd, GetMethodName(cmd & 0xffff).c_str()); if(cmd & CELL_GCM_METHOD_FLAG_JUMP) { @@ -2212,7 +2220,7 @@ void RSXThread::Task() { m_call_stack.push(get + 4); u32 offs = cmd & ~CELL_GCM_METHOD_FLAG_CALL; - //u32 addr = Memory.RSXIOMem.GetStartAddr() + offs; + //u32 addr = offs; //LOG_WARNING(RSX, "rsx call(0x%x) #0x%x - 0x%x - 0x%x", offs, addr, cmd, get); m_ctrl->get = offs; continue; @@ -2234,14 +2242,14 @@ void RSXThread::Task() if(cmd == 0) { + LOG_ERROR(Log::RSX, "null cmd: cmd=0x%x, put=0x%x, get=0x%x (addr=0x%x)", cmd, put, get, (u32)Memory.RSXIOMem.RealAddr(get)); + Emu.Pause(); //HACK! We couldn't be here - //ConLog.Error("null cmd: addr=0x%x, put=0x%x, get=0x%x", Memory.RSXIOMem.GetStartAddr() + get, m_ctrl->put, get); - //Emu.Pause(); m_ctrl->get = get + (count + 1) * 4; continue; } - auto args = vm::ptr>::make((u32)Memory.RSXIOMem.RealAddr(Memory.RSXIOMem.GetStartAddr() + get + 4)); + auto args = vm::ptr>::make((u32)Memory.RSXIOMem.RealAddr(get + 4)); for(u32 i=0; i context, u32 cmdSize, u32 ioSiz if (system_mode == CELL_GCM_SYSTEM_MODE_IOMAP_512MB) { cellGcmSys->Warning("cellGcmInit(): 512MB io address space used"); - Memory.RSXIOMem.SetRange(0x50000000, 0x20000000 /*512MB*/); + Memory.RSXIOMem.SetRange(0, 0x20000000 /*512MB*/); } else { cellGcmSys->Warning("cellGcmInit(): 256MB io address space used"); - Memory.RSXIOMem.SetRange(0x50000000, 0x10000000 /*256MB*/); + Memory.RSXIOMem.SetRange(0, 0x10000000 /*256MB*/); } if(cellGcmMapEaIoAddress(ioAddress, 0, ioSize) != CELL_OK) @@ -833,7 +833,7 @@ u32 cellGcmGetMaxIoMapSize() { cellGcmSys->Log("cellGcmGetMaxIoMapSize()"); - return (u32)(Memory.RSXIOMem.GetEndAddr() - Memory.RSXIOMem.GetStartAddr() - Memory.RSXIOMem.GetReservedAmount()); + return (u32)(Memory.RSXIOMem.GetEndAddr() - Memory.RSXIOMem.GetReservedAmount()); } void cellGcmGetOffsetTable(vm::ptr table) @@ -850,7 +850,7 @@ s32 cellGcmIoOffsetToAddress(u32 ioOffset, u64 address) u64 realAddr; - if (!Memory.RSXIOMem.getRealAddr(Memory.RSXIOMem.GetStartAddr() + ioOffset, realAddr)) + if (!Memory.RSXIOMem.getRealAddr(ioOffset, realAddr)) return CELL_GCM_ERROR_FAILURE; vm::write64(address, realAddr); @@ -865,7 +865,7 @@ s32 cellGcmMapEaIoAddress(u32 ea, u32 io, u32 size) if ((ea & 0xFFFFF) || (io & 0xFFFFF) || (size & 0xFFFFF)) return CELL_GCM_ERROR_FAILURE; // Check if the mapping was successfull - if (Memory.RSXIOMem.Map(ea, size, Memory.RSXIOMem.GetStartAddr() + io)) + if (Memory.RSXIOMem.Map(ea, size, io)) { // Fill the offset table for (u32 i = 0; i<(size >> 20); i++) @@ -914,16 +914,13 @@ s32 cellGcmMapMainMemory(u32 ea, u32 size, vm::ptr> offset) { cellGcmSys->Warning("cellGcmMapMainMemory(ea=0x%x,size=0x%x,offset_addr=0x%x)", ea, size, offset.addr()); - u32 io; - if ((ea & 0xFFFFF) || (size & 0xFFFFF)) return CELL_GCM_ERROR_FAILURE; - //check if the mapping was successfull - if (io = (u32)Memory.RSXIOMem.Map(ea, size, 0)) - { - // convert to offset - io = io - (u32)Memory.RSXIOMem.GetStartAddr(); + u32 io = Memory.RSXIOMem.Map(ea, size); + //check if the mapping was successfull + if (Memory.RSXIOMem.Write32(io, 0)) + { //fill the offset table for (u32 i = 0; i<(size >> 20); i++) { @@ -968,8 +965,8 @@ s32 cellGcmUnmapEaIoAddress(u64 ea) { cellGcmSys->Log("cellGcmUnmapEaIoAddress(ea=0x%llx)", ea); - u32 size = Memory.RSXIOMem.UnmapRealAddress(ea); - if (size) + u32 size; + if (Memory.RSXIOMem.UnmapRealAddress(ea, size)) { u64 io; ea = ea >> 20; @@ -994,8 +991,8 @@ s32 cellGcmUnmapIoAddress(u64 io) { cellGcmSys->Log("cellGcmUnmapIoAddress(io=0x%llx)", io); - u32 size = Memory.RSXIOMem.UnmapAddress(io); - if (size) + u32 size; + if (Memory.RSXIOMem.UnmapAddress(io, size)) { u64 ea; io = io >> 20; diff --git a/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp b/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp index f47af44642..ac46056b38 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp @@ -106,11 +106,11 @@ s64 spursInit( // default or system workload: #ifdef PRX_DEBUG spurs->m.wklSysG.pm.set(be_t::make(vm::read32(libsre_rtoc - 0x7EA4))); + spurs->m.wklSysG.size = 0x2200; #else spurs->m.wklSysG.pm.set(be_t::make(0x100)); // wrong 64-bit address #endif spurs->m.wklSysG.data = 0; - spurs->m.wklSysG.size = 0x2200; spurs->m.wklSysG.copy.write_relaxed(0xff); u32 sem; for (u32 i = 0; i < 0x10; i++) @@ -170,6 +170,10 @@ s64 spursInit( SPU.GPR[4]._u64[1] = spurs.addr(); return SPU.FastCall(SPU.PC); #endif + //SPU.WriteLS32(0x808, 2); // hack for cellSpursModuleExit + //SPU.WriteLS32(0x260, 3); // hack for cellSpursModulePollStatus + //SPU.WriteLS32(0x264, 0x35000000); // bi $0 + SPU.WriteLS128(0x1c0, u128::from32r(0, spurs.addr(), num, 0x1f)); u32 wid = 0x20; @@ -189,7 +193,7 @@ s64 spursInit( // load executable code: memcpy(vm::get_ptr(SPU.ls_offset + 0xa00), wkl.pm.get_ptr(), wkl.size); SPU.WriteLS64(0x1d0, wkl.pm.addr()); - SPU.WriteLS32(0x1d8, wkl.priority.ToLE() >> 24 & 0xff); // ??? + SPU.WriteLS32(0x1d8, wkl.copy.read_relaxed()); } if (!isSecond) SPU.WriteLS16(0x1e8, 0); @@ -213,7 +217,8 @@ s64 spursInit( } // get workload id: - + //SPU.GPR[3].clear(); + //wid = SPU.m_code3_func(SPU); } })->GetId(); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp b/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp index 94326ef56e..7ca0a0ebb6 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp @@ -88,8 +88,8 @@ SPUThread* spu_thread_initialize(SpuGroupInfo* group, u32 spu_num, sys_spu_image if (group) group->list[spu_num] = id; new_thread.group = group; - sys_spu.Warning("*** New SPU Thread [%s] (ep=0x%x, opt=0x%x, a1=0x%llx, a2=0x%llx, a3=0x%llx, a4=0x%llx): id=%d", - name.c_str(), spu_ep, option, a1, a2, a3, a4, id); + sys_spu.Warning("*** New SPU Thread [%s] (ep=0x%x, opt=0x%x, a1=0x%llx, a2=0x%llx, a3=0x%llx, a4=0x%llx): id=%d, spu_offset=0x%x", + name.c_str(), spu_ep, option, a1, a2, a3, a4, id, spu_offset); return &new_thread; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_vm.cpp b/rpcs3/Emu/SysCalls/lv2/sys_vm.cpp index 8eca02c483..d2557be42d 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_vm.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_vm.cpp @@ -6,7 +6,7 @@ #include "sys_memory.h" #include "sys_vm.h" -SysCallBase sys_vm("vm"); +SysCallBase sys_vm("sys_vm"); MemoryContainerInfo* current_ct; s32 sys_vm_memory_map(u32 vsize, u32 psize, u32 cid, u64 flag, u64 policy, u32 addr) diff --git a/rpcs3/Loader/ELF64.cpp b/rpcs3/Loader/ELF64.cpp index 90fb00cd5f..2b236aace5 100644 --- a/rpcs3/Loader/ELF64.cpp +++ b/rpcs3/Loader/ELF64.cpp @@ -455,7 +455,7 @@ bool ELF64Loader::LoadPhdrData(u64 offset) const u32 nid = vm::read32(stub.s_nid + i * 4); const u32 text = vm::read32(stub.s_text + i * 4); - if (module && !module->Load(nid)) + if (!module || !module->Load(nid)) { LOG_WARNING(LOADER, "Unimplemented function '%s' in '%s' module", SysCalls::GetHLEFuncName(nid).c_str(), module_name.c_str()); }