This commit is contained in:
Nekotekina 2015-02-01 10:09:24 +03:00
parent 61a5459ccb
commit 8a945a1a52
8 changed files with 43 additions and 29 deletions

View file

@ -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

View file

@ -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";

View file

@ -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());

View file

@ -99,6 +99,8 @@ void SPUThread::InitRegs()
m_event_mask = 0;
m_events = 0;
R_ADDR = 0;
}
void SPUThread::DoRun()

View file

@ -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:

View file

@ -10,6 +10,8 @@ namespace vm
public:
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 to_be_t<T>::type be_type;

View file

@ -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;
}
}

View file

@ -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);
}
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<void>(spu_offset), vm::get_ptr<void>(img.addr), 256 * 1024);
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]);
if (t)
{
Memory.Free(((SPUThread*)t.get())->GetOffset());
Memory.MainMem.Free(((SPUThread*)t.get())->GetOffset());
Emu.GetCPU().RemoveThread(group_info->list[i]);
}
}