diff --git a/rpcs3/Emu/ARMv7/ARMv7Context.h b/rpcs3/Emu/ARMv7/ARMv7Context.h index 1316a26786..692592e5ec 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Context.h +++ b/rpcs3/Emu/ARMv7/ARMv7Context.h @@ -37,6 +37,25 @@ struct ARMv7Context }; u32 LR; + + union + { + struct + { + u32 reserved0 : 16; + u32 GE : 4; + u32 reserved1 : 4; + u32 dummy : 3; + u32 Q : 1; // Set to 1 if an SSAT or USAT instruction changes (saturates) the input value for the signed or unsigned range of the result + u32 V : 1; // Overflow condition code flag + u32 C : 1; // Carry condition code flag + u32 Z : 1; // Zero condition code flag + u32 N : 1; // Negative condition code flag + }; + + u32 APSR; + + } APSR; }; struct @@ -45,22 +64,6 @@ struct ARMv7Context }; }; - union - { - struct - { - u32 N : 1; //Negative condition code flag - u32 Z : 1; //Zero condition code flag - u32 C : 1; //Carry condition code flag - u32 V : 1; //Overflow condition code flag - u32 Q : 1; //Set to 1 if an SSAT or USAT instruction changes (saturates) the input value for the signed or unsigned range of the result - u32 dummy : 27; - }; - - u32 APSR; - - } APSR; - union { struct diff --git a/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp b/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp index 78c17f4fda..6ea768832b 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp +++ b/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp @@ -316,10 +316,10 @@ void ARMv7_instrs::MRC_(ARMv7Context& context, const ARMv7Code code, const ARMv7 switch (type) { - case T1: - case A1: + case T1: case A1: + case T2: case A2: { - cond = context.ITSTATE.advance(); + cond = type == A1 ? code.data >> 28 : context.ITSTATE.advance(); t = (code.data & 0xf000) >> 12; cp = (code.data & 0xf00) >> 8; opc1 = (code.data & 0xe00000) >> 21; @@ -327,8 +327,8 @@ void ARMv7_instrs::MRC_(ARMv7Context& context, const ARMv7Code code, const ARMv7 cn = (code.data & 0xf0000) >> 16; cm = (code.data & 0xf); - reject(cp - 10 < 2, "Advanced SIMD and VFP"); - reject(t == 13 && type == T1, "UNPREDICTABLE"); + reject(cp - 10 < 2 && (type == T1 || type == A1), "Advanced SIMD and VFP"); + reject(t == 13 && (type == T1 || type == T2), "UNPREDICTABLE"); break; } default: throw __FUNCTION__; @@ -340,6 +340,8 @@ void ARMv7_instrs::MRC_(ARMv7Context& context, const ARMv7Code code, const ARMv7 if (t < 15 && cp == 15 && opc1 == 0 && cn == 13 && cm == 0 && opc2 == 3) { + // Read CP15 User Read-only Thread ID Register (seems used as TLS address) + if (!context.TLS) { throw "TLS not initialized"; diff --git a/rpcs3/Emu/ARMv7/ARMv7Thread.cpp b/rpcs3/Emu/ARMv7/ARMv7Thread.cpp index 3495376c79..1a968dd858 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Thread.cpp +++ b/rpcs3/Emu/ARMv7/ARMv7Thread.cpp @@ -48,7 +48,7 @@ void armv7_init_tls() u32 armv7_get_tls(u32 thread) { - if (!Emu.GetTLSMemsz()) + if (!Emu.GetTLSMemsz() || !thread) { return 0; } @@ -67,8 +67,8 @@ u32 armv7_get_tls(u32 thread) if (g_armv7_tls_owners[i].compare_exchange_strong(old, thread)) { const u32 addr = g_armv7_tls_start + i * Emu.GetTLSMemsz(); // get TLS address - memset(vm::get_ptr(addr), 0, Emu.GetTLSMemsz()); // fill TLS area with zeros memcpy(vm::get_ptr(addr), vm::get_ptr(Emu.GetTLSAddr()), Emu.GetTLSFilesz()); // initialize from TLS image + memset(vm::get_ptr(addr + Emu.GetTLSFilesz()), 0, Emu.GetTLSMemsz() - Emu.GetTLSFilesz()); // fill the rest with zeros return addr; } } @@ -112,7 +112,7 @@ void ARMv7Thread::InitRegs() memset(context.GPR, 0, sizeof(context.GPR[0]) * 15); context.APSR.APSR = 0; context.IPSR.IPSR = 0; - context.ISET = Thumb; + //context.ISET = Thumb; context.ITSTATE.IT = 0; context.SP = m_stack_addr + m_stack_size; context.TLS = armv7_get_tls(GetId()); diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index c4cf028f8f..1c861da43c 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -99,6 +99,8 @@ void SPUThread::InitRegs() m_event_mask = 0; m_events = 0; + + R_ADDR = 0; } void SPUThread::DoRun() diff --git a/rpcs3/Emu/Memory/Memory.cpp b/rpcs3/Emu/Memory/Memory.cpp index 84f75c6fff..502694ff93 100644 --- a/rpcs3/Emu/Memory/Memory.cpp +++ b/rpcs3/Emu/Memory/Memory.cpp @@ -131,7 +131,7 @@ void MemoryBase::Init(MemoryType type) case Memory_PSV: MemoryBlocks.push_back(PSV.RAM.SetRange(0x81000000, 0x10000000)); - MemoryBlocks.push_back(UserMemory = PSV.Userspace.SetRange(0x91000000, 0x10000000)); + MemoryBlocks.push_back(UserMemory = PSV.Userspace.SetRange(0x91000000, 0x2F000000)); break; case Memory_PSP: diff --git a/rpcs3/Emu/Memory/vm_ref.h b/rpcs3/Emu/Memory/vm_ref.h index 5788457c3b..f7256cedff 100644 --- a/rpcs3/Emu/Memory/vm_ref.h +++ b/rpcs3/Emu/Memory/vm_ref.h @@ -10,6 +10,8 @@ namespace vm public: typedef T type; + static_assert(!std::is_pointer::value, "vm::_ref_base<> error: invalid type (pointer)"); + static_assert(!std::is_reference::value, "vm::_ref_base<> error: invalid type (reference)"); typedef typename remove_be_t::type le_type; typedef typename to_be_t::type be_type; diff --git a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp index 2a8d3cc699..3fc79e4256 100644 --- a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp @@ -42,6 +42,11 @@ u32 ppu_get_tls(u32 thread) sysPrxForUser->Notice("Thread Local Storage initialized (g_tls_start=0x%x, size = 0x%x)\n*** TLS segment addr: 0x%08x\n*** TLS segment size: 0x%08x", g_tls_start, Emu.GetTLSMemsz(), Emu.GetTLSAddr(), Emu.GetTLSFilesz()); } + + if (!thread) + { + return 0; + } for (u32 i = 0; i < TLS_MAX; i++) { @@ -57,8 +62,8 @@ u32 ppu_get_tls(u32 thread) if (g_tls_owners[i].compare_exchange_strong(old, thread)) { const u32 addr = g_tls_start + i * Emu.GetTLSMemsz(); // get TLS address - memset(vm::get_ptr(addr), 0, Emu.GetTLSMemsz()); // fill TLS area with zeros memcpy(vm::get_ptr(addr), vm::get_ptr(Emu.GetTLSAddr()), Emu.GetTLSFilesz()); // initialize from TLS image + memset(vm::get_ptr(addr + Emu.GetTLSFilesz()), 0, Emu.GetTLSMemsz() - Emu.GetTLSFilesz()); // fill the rest with zeros return addr; } } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp b/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp index 29cdb9bd39..f3fb23b383 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp @@ -85,10 +85,10 @@ SPUThread* spu_thread_initialize(std::shared_ptr& group, u32 spu_n sys_spu.Todo("Unsupported SPU Thread options (0x%x)", option); } - u32 spu_ep = (u32)img.entry_point; + const u32 spu_ep = img.entry_point; // Copy SPU image: // TODO: use segment info - u32 spu_offset = (u32)Memory.Alloc(256 * 1024, 4096); + const u32 spu_offset = vm::cast(Memory.MainMem.AllocAlign(256 * 1024, 4096)); memcpy(vm::get_ptr(spu_offset), vm::get_ptr(img.addr), 256 * 1024); SPUThread& new_thread = static_cast(Emu.GetCPU().AddThread(CPU_THREAD_SPU)); @@ -218,7 +218,7 @@ s32 sys_spu_thread_group_destroy(u32 id) std::shared_ptr t = Emu.GetCPU().GetThread(group_info->list[i]); if (t) { - Memory.Free(((SPUThread*)t.get())->GetOffset()); + Memory.MainMem.Free(((SPUThread*)t.get())->GetOffset()); Emu.GetCPU().RemoveThread(group_info->list[i]); } }