mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-09 00:11:24 +12:00
Fixes
This commit is contained in:
parent
61a5459ccb
commit
8a945a1a52
8 changed files with 43 additions and 29 deletions
|
@ -37,6 +37,25 @@ struct ARMv7Context
|
||||||
};
|
};
|
||||||
|
|
||||||
u32 LR;
|
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
|
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
|
union
|
||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
|
|
|
@ -316,10 +316,10 @@ void ARMv7_instrs::MRC_(ARMv7Context& context, const ARMv7Code code, const ARMv7
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case T1:
|
case T1: case A1:
|
||||||
case A1:
|
case T2: case A2:
|
||||||
{
|
{
|
||||||
cond = context.ITSTATE.advance();
|
cond = type == A1 ? code.data >> 28 : context.ITSTATE.advance();
|
||||||
t = (code.data & 0xf000) >> 12;
|
t = (code.data & 0xf000) >> 12;
|
||||||
cp = (code.data & 0xf00) >> 8;
|
cp = (code.data & 0xf00) >> 8;
|
||||||
opc1 = (code.data & 0xe00000) >> 21;
|
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;
|
cn = (code.data & 0xf0000) >> 16;
|
||||||
cm = (code.data & 0xf);
|
cm = (code.data & 0xf);
|
||||||
|
|
||||||
reject(cp - 10 < 2, "Advanced SIMD and VFP");
|
reject(cp - 10 < 2 && (type == T1 || type == A1), "Advanced SIMD and VFP");
|
||||||
reject(t == 13 && type == T1, "UNPREDICTABLE");
|
reject(t == 13 && (type == T1 || type == T2), "UNPREDICTABLE");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: throw __FUNCTION__;
|
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)
|
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)
|
if (!context.TLS)
|
||||||
{
|
{
|
||||||
throw "TLS not initialized";
|
throw "TLS not initialized";
|
||||||
|
|
|
@ -48,7 +48,7 @@ void armv7_init_tls()
|
||||||
|
|
||||||
u32 armv7_get_tls(u32 thread)
|
u32 armv7_get_tls(u32 thread)
|
||||||
{
|
{
|
||||||
if (!Emu.GetTLSMemsz())
|
if (!Emu.GetTLSMemsz() || !thread)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -67,8 +67,8 @@ u32 armv7_get_tls(u32 thread)
|
||||||
if (g_armv7_tls_owners[i].compare_exchange_strong(old, 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
|
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
|
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;
|
return addr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,7 +112,7 @@ void ARMv7Thread::InitRegs()
|
||||||
memset(context.GPR, 0, sizeof(context.GPR[0]) * 15);
|
memset(context.GPR, 0, sizeof(context.GPR[0]) * 15);
|
||||||
context.APSR.APSR = 0;
|
context.APSR.APSR = 0;
|
||||||
context.IPSR.IPSR = 0;
|
context.IPSR.IPSR = 0;
|
||||||
context.ISET = Thumb;
|
//context.ISET = Thumb;
|
||||||
context.ITSTATE.IT = 0;
|
context.ITSTATE.IT = 0;
|
||||||
context.SP = m_stack_addr + m_stack_size;
|
context.SP = m_stack_addr + m_stack_size;
|
||||||
context.TLS = armv7_get_tls(GetId());
|
context.TLS = armv7_get_tls(GetId());
|
||||||
|
|
|
@ -99,6 +99,8 @@ void SPUThread::InitRegs()
|
||||||
|
|
||||||
m_event_mask = 0;
|
m_event_mask = 0;
|
||||||
m_events = 0;
|
m_events = 0;
|
||||||
|
|
||||||
|
R_ADDR = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SPUThread::DoRun()
|
void SPUThread::DoRun()
|
||||||
|
|
|
@ -131,7 +131,7 @@ void MemoryBase::Init(MemoryType type)
|
||||||
|
|
||||||
case Memory_PSV:
|
case Memory_PSV:
|
||||||
MemoryBlocks.push_back(PSV.RAM.SetRange(0x81000000, 0x10000000));
|
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;
|
break;
|
||||||
|
|
||||||
case Memory_PSP:
|
case Memory_PSP:
|
||||||
|
|
|
@ -10,6 +10,8 @@ namespace vm
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef T type;
|
typedef T type;
|
||||||
|
static_assert(!std::is_pointer<T>::value, "vm::_ref_base<> error: invalid type (pointer)");
|
||||||
|
static_assert(!std::is_reference<T>::value, "vm::_ref_base<> error: invalid type (reference)");
|
||||||
typedef typename remove_be_t<T>::type le_type;
|
typedef typename remove_be_t<T>::type le_type;
|
||||||
typedef typename to_be_t<T>::type be_type;
|
typedef typename to_be_t<T>::type be_type;
|
||||||
|
|
||||||
|
|
|
@ -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",
|
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());
|
g_tls_start, Emu.GetTLSMemsz(), Emu.GetTLSAddr(), Emu.GetTLSFilesz());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!thread)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
for (u32 i = 0; i < TLS_MAX; i++)
|
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))
|
if (g_tls_owners[i].compare_exchange_strong(old, thread))
|
||||||
{
|
{
|
||||||
const u32 addr = g_tls_start + i * Emu.GetTLSMemsz(); // get TLS address
|
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
|
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;
|
return addr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,10 +85,10 @@ SPUThread* spu_thread_initialize(std::shared_ptr<SpuGroupInfo>& group, u32 spu_n
|
||||||
sys_spu.Todo("Unsupported SPU Thread options (0x%x)", option);
|
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:
|
// Copy SPU image:
|
||||||
// TODO: use segment info
|
// 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<void>(spu_offset), vm::get_ptr<void>(img.addr), 256 * 1024);
|
memcpy(vm::get_ptr<void>(spu_offset), vm::get_ptr<void>(img.addr), 256 * 1024);
|
||||||
|
|
||||||
SPUThread& new_thread = static_cast<SPUThread&>(Emu.GetCPU().AddThread(CPU_THREAD_SPU));
|
SPUThread& new_thread = static_cast<SPUThread&>(Emu.GetCPU().AddThread(CPU_THREAD_SPU));
|
||||||
|
@ -218,7 +218,7 @@ s32 sys_spu_thread_group_destroy(u32 id)
|
||||||
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetThread(group_info->list[i]);
|
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetThread(group_info->list[i]);
|
||||||
if (t)
|
if (t)
|
||||||
{
|
{
|
||||||
Memory.Free(((SPUThread*)t.get())->GetOffset());
|
Memory.MainMem.Free(((SPUThread*)t.get())->GetOffset());
|
||||||
Emu.GetCPU().RemoveThread(group_info->list[i]);
|
Emu.GetCPU().RemoveThread(group_info->list[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue