mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-26 12:42:41 +01:00
Memory cleanup: u64 -> u32, empty TLS fixed
cellGameContentPermit fixed
This commit is contained in:
parent
4d5bdf1419
commit
0eebfb0aaa
@ -19,9 +19,9 @@ RawSPUThread::~RawSPUThread()
|
|||||||
Memory.CloseRawSPU(this, m_index);
|
Memory.CloseRawSPU(this, m_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RawSPUThread::Read32(const u64 addr, u32* value)
|
bool RawSPUThread::Read32(const u32 addr, u32* value)
|
||||||
{
|
{
|
||||||
const u64 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET;
|
const u32 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET;
|
||||||
|
|
||||||
switch (offset)
|
switch (offset)
|
||||||
{
|
{
|
||||||
@ -68,9 +68,9 @@ bool RawSPUThread::Read32(const u64 addr, u32* value)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RawSPUThread::Write32(const u64 addr, const u32 value)
|
bool RawSPUThread::Write32(const u32 addr, const u32 value)
|
||||||
{
|
{
|
||||||
const u64 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET;
|
const u32 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET;
|
||||||
|
|
||||||
switch (offset)
|
switch (offset)
|
||||||
{
|
{
|
||||||
@ -198,7 +198,7 @@ bool RawSPUThread::Write32(const u64 addr, const u32 value)
|
|||||||
|
|
||||||
void RawSPUThread::InitRegs()
|
void RawSPUThread::InitRegs()
|
||||||
{
|
{
|
||||||
ls_offset = m_offset = (u32)GetStartAddr() + RAW_SPU_LS_OFFSET;
|
ls_offset = m_offset = GetStartAddr() + RAW_SPU_LS_OFFSET;
|
||||||
SPUThread::InitRegs();
|
SPUThread::InitRegs();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,5 +213,5 @@ void RawSPUThread::Task()
|
|||||||
|
|
||||||
SPUThread::Task();
|
SPUThread::Task();
|
||||||
|
|
||||||
SPU.NPC.SetValue((u32)PC);
|
SPU.NPC.SetValue(PC);
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,8 @@ public:
|
|||||||
RawSPUThread(CPUThreadType type = CPU_THREAD_RAW_SPU);
|
RawSPUThread(CPUThreadType type = CPU_THREAD_RAW_SPU);
|
||||||
virtual ~RawSPUThread();
|
virtual ~RawSPUThread();
|
||||||
|
|
||||||
bool Read32(const u64 addr, u32* value);
|
bool Read32(const u32 addr, u32* value);
|
||||||
|
bool Write32(const u32 addr, const u32 value);
|
||||||
bool Write32(const u64 addr, const u32 value);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void InitRegs();
|
virtual void InitRegs();
|
||||||
|
@ -17,42 +17,36 @@
|
|||||||
|
|
||||||
MemoryBase Memory;
|
MemoryBase Memory;
|
||||||
|
|
||||||
void MemoryBase::RegisterPages(u64 addr, u32 size)
|
void MemoryBase::RegisterPages(u32 addr, u32 size)
|
||||||
{
|
{
|
||||||
|
assert(size && (size | addr) % 4096 == 0);
|
||||||
|
|
||||||
LV2_LOCK(0);
|
LV2_LOCK(0);
|
||||||
|
|
||||||
//LOG_NOTICE(MEMORY, "RegisterPages(addr=0x%llx, size=0x%x)", addr, size);
|
//LOG_NOTICE(MEMORY, "RegisterPages(addr=0x%x, size=0x%x)", addr, size);
|
||||||
for (u64 i = addr / 4096; i < (addr + size) / 4096; i++)
|
for (u32 i = addr / 4096; i < addr / 4096 + size / 4096; i++)
|
||||||
{
|
{
|
||||||
if (i >= sizeof(m_pages) / sizeof(m_pages[0]))
|
|
||||||
{
|
|
||||||
LOG_ERROR(MEMORY, "%s(): invalid address 0x%llx", __FUNCTION__, i * 4096);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (m_pages[i])
|
if (m_pages[i])
|
||||||
{
|
{
|
||||||
LOG_ERROR(MEMORY, "Page already registered (addr=0x%llx)", i * 4096);
|
LOG_ERROR(MEMORY, "Page already registered (addr=0x%x)", i * 4096);
|
||||||
Emu.Pause();
|
Emu.Pause();
|
||||||
}
|
}
|
||||||
m_pages[i] = 1; // TODO: define page parameters
|
m_pages[i] = 1; // TODO: define page parameters
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryBase::UnregisterPages(u64 addr, u32 size)
|
void MemoryBase::UnregisterPages(u32 addr, u32 size)
|
||||||
{
|
{
|
||||||
|
assert(size && (size | addr) % 4096 == 0);
|
||||||
|
|
||||||
LV2_LOCK(0);
|
LV2_LOCK(0);
|
||||||
|
|
||||||
//LOG_NOTICE(MEMORY, "UnregisterPages(addr=0x%llx, size=0x%x)", addr, size);
|
//LOG_NOTICE(MEMORY, "UnregisterPages(addr=0x%x, size=0x%x)", addr, size);
|
||||||
for (u64 i = addr / 4096; i < (addr + size) / 4096; i++)
|
for (u32 i = addr / 4096; i < addr / 4096 + size / 4096; i++)
|
||||||
{
|
{
|
||||||
if (i >= sizeof(m_pages) / sizeof(m_pages[0]))
|
|
||||||
{
|
|
||||||
LOG_ERROR(MEMORY, "%s(): invalid address 0x%llx", __FUNCTION__, i * 4096);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!m_pages[i])
|
if (!m_pages[i])
|
||||||
{
|
{
|
||||||
LOG_ERROR(MEMORY, "Page not registered (addr=0x%llx)", i * 4096);
|
LOG_ERROR(MEMORY, "Page not registered (addr=0x%x)", i * 4096);
|
||||||
Emu.Pause();
|
Emu.Pause();
|
||||||
}
|
}
|
||||||
m_pages[i] = 0; // TODO: define page parameters
|
m_pages[i] = 0; // TODO: define page parameters
|
||||||
@ -187,29 +181,27 @@ u32 MemoryBase::ReadMMIO32(u32 addr)
|
|||||||
throw fmt::Format("%s(addr=0x%x) failed", __FUNCTION__, addr);
|
throw fmt::Format("%s(addr=0x%x) failed", __FUNCTION__, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MemoryBase::Map(const u64 addr, const u32 size)
|
bool MemoryBase::Map(const u32 addr, const u32 size)
|
||||||
{
|
{
|
||||||
|
assert(size && (size | addr) % 4096 == 0);
|
||||||
|
|
||||||
LV2_LOCK(0);
|
LV2_LOCK(0);
|
||||||
|
|
||||||
if ((addr | (addr + size)) & ~0xFFFFFFFFull)
|
for (u32 i = addr / 4096; i < addr / 4096 + size / 4096; i++)
|
||||||
{
|
{
|
||||||
return false;
|
if (m_pages[i])
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (u32 i = (u32)addr / 4096; i <= ((u32)addr + size - 1) / 4096; i++)
|
|
||||||
{
|
{
|
||||||
if (m_pages[i]) return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryBlocks.push_back((new MemoryBlock())->SetRange(addr, size));
|
MemoryBlocks.push_back((new MemoryBlock())->SetRange(addr, size));
|
||||||
|
|
||||||
LOG_WARNING(MEMORY, "Memory mapped at 0x%llx: size=0x%x", addr, size);
|
LOG_WARNING(MEMORY, "Memory mapped at 0x%x: size=0x%x", addr, size);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MemoryBase::Unmap(const u64 addr)
|
bool MemoryBase::Unmap(const u32 addr)
|
||||||
{
|
{
|
||||||
LV2_LOCK(0);
|
LV2_LOCK(0);
|
||||||
|
|
||||||
@ -225,11 +217,13 @@ bool MemoryBase::Unmap(const u64 addr)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
MemBlockInfo::MemBlockInfo(u64 _addr, u32 _size)
|
MemBlockInfo::MemBlockInfo(u32 addr, u32 size)
|
||||||
: MemInfo(_addr, PAGE_4K(_size))
|
: MemInfo(addr, size)
|
||||||
{
|
{
|
||||||
void* real_addr = vm::get_ptr(vm::cast(_addr));
|
assert(size && (size | addr) % 4096 == 0);
|
||||||
void* priv_addr = vm::get_priv_ptr(vm::cast(_addr));
|
|
||||||
|
void* real_addr = vm::get_ptr(addr);
|
||||||
|
void* priv_addr = vm::get_priv_ptr(addr);
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (!VirtualAlloc(priv_addr, size, MEM_COMMIT, PAGE_READWRITE) || !VirtualAlloc(real_addr, size, MEM_COMMIT, PAGE_READWRITE))
|
if (!VirtualAlloc(priv_addr, size, MEM_COMMIT, PAGE_READWRITE) || !VirtualAlloc(real_addr, size, MEM_COMMIT, PAGE_READWRITE))
|
||||||
@ -237,12 +231,12 @@ MemBlockInfo::MemBlockInfo(u64 _addr, u32 _size)
|
|||||||
if (mprotect(real_addr, size, PROT_READ | PROT_WRITE) || mprotect(priv_addr, size, PROT_READ | PROT_WRITE))
|
if (mprotect(real_addr, size, PROT_READ | PROT_WRITE) || mprotect(priv_addr, size, PROT_READ | PROT_WRITE))
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
LOG_ERROR(MEMORY, "Memory allocation failed (addr=0x%llx, size=0x%x)", addr, size);
|
LOG_ERROR(MEMORY, "Memory allocation failed (addr=0x%x, size=0x%x)", addr, size);
|
||||||
Emu.Pause();
|
Emu.Pause();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Memory.RegisterPages(_addr, PAGE_4K(_size));
|
Memory.RegisterPages(addr, size);
|
||||||
|
|
||||||
mem = real_addr;
|
mem = real_addr;
|
||||||
memset(mem, 0, size); // ???
|
memset(mem, 0, size); // ???
|
||||||
@ -257,12 +251,12 @@ void MemBlockInfo::Free()
|
|||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
DWORD old;
|
DWORD old;
|
||||||
|
|
||||||
if (!VirtualProtect(mem, size, PAGE_NOACCESS, &old) || !VirtualProtect(vm::get_priv_ptr(vm::cast(addr)), size, PAGE_NOACCESS, &old))
|
if (!VirtualProtect(mem, size, PAGE_NOACCESS, &old) || !VirtualProtect(vm::get_priv_ptr(addr), size, PAGE_NOACCESS, &old))
|
||||||
#else
|
#else
|
||||||
if (mprotect(mem, size, PROT_NONE) || mprotect(vm::get_priv_ptr(vm::cast(addr)), size, PROT_NONE))
|
if (mprotect(mem, size, PROT_NONE) || mprotect(vm::get_priv_ptr(addr), size, PROT_NONE))
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
LOG_ERROR(MEMORY, "Memory deallocation failed (addr=0x%llx, size=0x%x)", addr, size);
|
LOG_ERROR(MEMORY, "Memory deallocation failed (addr=0x%x, size=0x%x)", addr, size);
|
||||||
Emu.Pause();
|
Emu.Pause();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -316,15 +310,8 @@ void MemoryBlock::Delete()
|
|||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 MemoryBlock::FixAddr(const u64 addr) const
|
MemoryBlock* MemoryBlock::SetRange(const u32 start, const u32 size)
|
||||||
{
|
{
|
||||||
return addr - GetStartAddr();
|
|
||||||
}
|
|
||||||
|
|
||||||
MemoryBlock* MemoryBlock::SetRange(const u64 start, const u32 size)
|
|
||||||
{
|
|
||||||
if (start + size > 0x100000000) return nullptr;
|
|
||||||
|
|
||||||
range_start = start;
|
range_start = start;
|
||||||
range_size = size;
|
range_size = size;
|
||||||
|
|
||||||
@ -332,11 +319,6 @@ MemoryBlock* MemoryBlock::SetRange(const u64 start, const u32 size)
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MemoryBlock::IsMyAddress(const u64 addr)
|
|
||||||
{
|
|
||||||
return mem && addr >= GetStartAddr() && addr < GetEndAddr();
|
|
||||||
}
|
|
||||||
|
|
||||||
DynamicMemoryBlockBase::DynamicMemoryBlockBase()
|
DynamicMemoryBlockBase::DynamicMemoryBlockBase()
|
||||||
: MemoryBlock()
|
: MemoryBlock()
|
||||||
, m_max_size(0)
|
, m_max_size(0)
|
||||||
@ -357,22 +339,12 @@ const u32 DynamicMemoryBlockBase::GetUsedSize() const
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DynamicMemoryBlockBase::IsInMyRange(const u64 addr)
|
bool DynamicMemoryBlockBase::IsInMyRange(const u32 addr, const u32 size)
|
||||||
{
|
{
|
||||||
return addr >= MemoryBlock::GetStartAddr() && addr < MemoryBlock::GetStartAddr() + GetSize();
|
return addr >= MemoryBlock::GetStartAddr() && addr + size - 1 <= MemoryBlock::GetEndAddr();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DynamicMemoryBlockBase::IsInMyRange(const u64 addr, const u32 size)
|
MemoryBlock* DynamicMemoryBlockBase::SetRange(const u32 start, const u32 size)
|
||||||
{
|
|
||||||
return IsInMyRange(addr) && IsInMyRange(addr + size - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DynamicMemoryBlockBase::IsMyAddress(const u64 addr)
|
|
||||||
{
|
|
||||||
return IsInMyRange(addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
MemoryBlock* DynamicMemoryBlockBase::SetRange(const u64 start, const u32 size)
|
|
||||||
{
|
{
|
||||||
LV2_LOCK(0);
|
LV2_LOCK(0);
|
||||||
|
|
||||||
@ -396,8 +368,10 @@ void DynamicMemoryBlockBase::Delete()
|
|||||||
MemoryBlock::Delete();
|
MemoryBlock::Delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DynamicMemoryBlockBase::AllocFixed(u64 addr, u32 size)
|
bool DynamicMemoryBlockBase::AllocFixed(u32 addr, u32 size)
|
||||||
{
|
{
|
||||||
|
assert(size);
|
||||||
|
|
||||||
size = PAGE_4K(size + (addr & 4095)); // align size
|
size = PAGE_4K(size + (addr & 4095)); // align size
|
||||||
|
|
||||||
addr &= ~4095; // align start address
|
addr &= ~4095; // align start address
|
||||||
@ -420,13 +394,15 @@ bool DynamicMemoryBlockBase::AllocFixed(u64 addr, u32 size)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DynamicMemoryBlockBase::AppendMem(u64 addr, u32 size) /* private */
|
void DynamicMemoryBlockBase::AppendMem(u32 addr, u32 size) /* private */
|
||||||
{
|
{
|
||||||
m_allocated.emplace_back(addr, size);
|
m_allocated.emplace_back(addr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 DynamicMemoryBlockBase::AllocAlign(u32 size, u32 align)
|
u32 DynamicMemoryBlockBase::AllocAlign(u32 size, u32 align)
|
||||||
{
|
{
|
||||||
|
assert(size && align);
|
||||||
|
|
||||||
if (!MemoryBlock::GetStartAddr())
|
if (!MemoryBlock::GetStartAddr())
|
||||||
{
|
{
|
||||||
LOG_ERROR(MEMORY, "DynamicMemoryBlockBase::AllocAlign(size=0x%x, align=0x%x): memory block not initialized", size, align);
|
LOG_ERROR(MEMORY, "DynamicMemoryBlockBase::AllocAlign(size=0x%x, align=0x%x): memory block not initialized", size, align);
|
||||||
@ -449,7 +425,7 @@ u64 DynamicMemoryBlockBase::AllocAlign(u32 size, u32 align)
|
|||||||
|
|
||||||
LV2_LOCK(0);
|
LV2_LOCK(0);
|
||||||
|
|
||||||
for (u64 addr = MemoryBlock::GetStartAddr(); addr <= MemoryBlock::GetEndAddr() - exsize;)
|
for (u32 addr = MemoryBlock::GetStartAddr(); addr <= MemoryBlock::GetEndAddr() - exsize;)
|
||||||
{
|
{
|
||||||
bool is_good_addr = true;
|
bool is_good_addr = true;
|
||||||
|
|
||||||
@ -486,7 +462,7 @@ bool DynamicMemoryBlockBase::Alloc()
|
|||||||
return AllocAlign(GetSize() - GetUsedSize()) != 0;
|
return AllocAlign(GetSize() - GetUsedSize()) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DynamicMemoryBlockBase::Free(u64 addr)
|
bool DynamicMemoryBlockBase::Free(u32 addr)
|
||||||
{
|
{
|
||||||
LV2_LOCK(0);
|
LV2_LOCK(0);
|
||||||
|
|
||||||
@ -501,45 +477,19 @@ bool DynamicMemoryBlockBase::Free(u64 addr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_ERROR(MEMORY, "DynamicMemoryBlock::Free(addr=0x%llx): failed", addr);
|
LOG_ERROR(MEMORY, "DynamicMemoryBlock::Free(addr=0x%x): failed", addr);
|
||||||
for (u32 i = 0; i < m_allocated.size(); i++)
|
for (u32 i = 0; i < m_allocated.size(); i++)
|
||||||
{
|
{
|
||||||
LOG_NOTICE(MEMORY, "*** Memory Block: addr = 0x%llx, size = 0x%x", m_allocated[i].addr, m_allocated[i].size);
|
LOG_NOTICE(MEMORY, "*** Memory Block: addr = 0x%x, size = 0x%x", m_allocated[i].addr, m_allocated[i].size);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8* DynamicMemoryBlockBase::GetMem(u64 addr) const
|
|
||||||
{
|
|
||||||
return MemoryBlock::GetMem(addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DynamicMemoryBlockBase::IsLocked(u64 addr)
|
|
||||||
{
|
|
||||||
LOG_ERROR(MEMORY, "DynamicMemoryBlockBase::IsLocked() not implemented");
|
|
||||||
Emu.Pause();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DynamicMemoryBlockBase::Lock(u64 addr, u32 size)
|
|
||||||
{
|
|
||||||
LOG_ERROR(MEMORY, "DynamicMemoryBlockBase::Lock() not implemented");
|
|
||||||
Emu.Pause();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DynamicMemoryBlockBase::Unlock(u64 addr, u32 size)
|
|
||||||
{
|
|
||||||
LOG_ERROR(MEMORY, "DynamicMemoryBlockBase::Unlock() not implemented");
|
|
||||||
Emu.Pause();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
VirtualMemoryBlock::VirtualMemoryBlock() : MemoryBlock(), m_reserve_size(0)
|
VirtualMemoryBlock::VirtualMemoryBlock() : MemoryBlock(), m_reserve_size(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryBlock* VirtualMemoryBlock::SetRange(const u64 start, const u32 size)
|
MemoryBlock* VirtualMemoryBlock::SetRange(const u32 start, const u32 size)
|
||||||
{
|
{
|
||||||
range_start = start;
|
range_start = start;
|
||||||
range_size = size;
|
range_size = size;
|
||||||
@ -547,32 +497,16 @@ MemoryBlock* VirtualMemoryBlock::SetRange(const u64 start, const u32 size)
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VirtualMemoryBlock::IsInMyRange(const u64 addr)
|
bool VirtualMemoryBlock::IsInMyRange(const u32 addr, const u32 size)
|
||||||
{
|
{
|
||||||
return addr >= GetStartAddr() && addr < GetStartAddr() + GetSize() - GetReservedAmount();
|
return addr >= GetStartAddr() && addr + size - 1 <= GetEndAddr() - GetReservedAmount();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VirtualMemoryBlock::IsInMyRange(const u64 addr, const u32 size)
|
u32 VirtualMemoryBlock::Map(u32 realaddr, u32 size)
|
||||||
{
|
{
|
||||||
return IsInMyRange(addr) && IsInMyRange(addr + size - 1);
|
assert(size);
|
||||||
}
|
|
||||||
|
|
||||||
bool VirtualMemoryBlock::IsMyAddress(const u64 addr)
|
for (u32 addr = GetStartAddr(); addr <= GetEndAddr() - GetReservedAmount() - size;)
|
||||||
{
|
|
||||||
for (u32 i = 0; i<m_mapped_memory.size(); ++i)
|
|
||||||
{
|
|
||||||
if (addr >= m_mapped_memory[i].addr && addr < m_mapped_memory[i].addr + m_mapped_memory[i].size)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
u64 VirtualMemoryBlock::Map(u64 realaddr, u32 size)
|
|
||||||
{
|
|
||||||
for (u64 addr = GetStartAddr(); addr <= GetEndAddr() - GetReservedAmount() - size;)
|
|
||||||
{
|
{
|
||||||
bool is_good_addr = true;
|
bool is_good_addr = true;
|
||||||
|
|
||||||
@ -598,16 +532,28 @@ u64 VirtualMemoryBlock::Map(u64 realaddr, u32 size)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VirtualMemoryBlock::Map(u64 realaddr, u32 size, u64 addr)
|
bool VirtualMemoryBlock::Map(u32 realaddr, u32 size, u32 addr)
|
||||||
{
|
{
|
||||||
if (!IsInMyRange(addr, size) && (IsMyAddress(addr) || IsMyAddress(addr + size - 1)))
|
assert(size);
|
||||||
|
|
||||||
|
if (!IsInMyRange(addr, size))
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (u32 i = 0; i<m_mapped_memory.size(); ++i)
|
||||||
|
{
|
||||||
|
if (addr >= m_mapped_memory[i].addr && addr + size - 1 <= m_mapped_memory[i].addr + m_mapped_memory[i].size - 1)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_mapped_memory.emplace_back(addr, realaddr, size);
|
m_mapped_memory.emplace_back(addr, realaddr, size);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VirtualMemoryBlock::UnmapRealAddress(u64 realaddr, u32& size)
|
bool VirtualMemoryBlock::UnmapRealAddress(u32 realaddr, u32& size)
|
||||||
{
|
{
|
||||||
for (u32 i = 0; i<m_mapped_memory.size(); ++i)
|
for (u32 i = 0; i<m_mapped_memory.size(); ++i)
|
||||||
{
|
{
|
||||||
@ -622,7 +568,7 @@ bool VirtualMemoryBlock::UnmapRealAddress(u64 realaddr, u32& size)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VirtualMemoryBlock::UnmapAddress(u64 addr, u32& size)
|
bool VirtualMemoryBlock::UnmapAddress(u32 addr, u32& size)
|
||||||
{
|
{
|
||||||
for (u32 i = 0; i<m_mapped_memory.size(); ++i)
|
for (u32 i = 0; i<m_mapped_memory.size(); ++i)
|
||||||
{
|
{
|
||||||
@ -637,25 +583,25 @@ bool VirtualMemoryBlock::UnmapAddress(u64 addr, u32& size)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VirtualMemoryBlock::Read32(const u64 addr, u32* value)
|
bool VirtualMemoryBlock::Read32(const u32 addr, u32* value)
|
||||||
{
|
{
|
||||||
u64 realAddr;
|
u32 realAddr;
|
||||||
if (!getRealAddr(addr, realAddr))
|
if (!getRealAddr(addr, realAddr))
|
||||||
return false;
|
return false;
|
||||||
*value = vm::read32(realAddr);
|
*value = vm::read32(realAddr);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VirtualMemoryBlock::Write32(const u64 addr, const u32 value)
|
bool VirtualMemoryBlock::Write32(const u32 addr, const u32 value)
|
||||||
{
|
{
|
||||||
u64 realAddr;
|
u32 realAddr;
|
||||||
if (!getRealAddr(addr, realAddr))
|
if (!getRealAddr(addr, realAddr))
|
||||||
return false;
|
return false;
|
||||||
vm::write32(realAddr, value);
|
vm::write32(realAddr, value);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VirtualMemoryBlock::getRealAddr(u64 addr, u64& result)
|
bool VirtualMemoryBlock::getRealAddr(u32 addr, u32& result)
|
||||||
{
|
{
|
||||||
for (u32 i = 0; i<m_mapped_memory.size(); ++i)
|
for (u32 i = 0; i<m_mapped_memory.size(); ++i)
|
||||||
{
|
{
|
||||||
@ -669,7 +615,7 @@ bool VirtualMemoryBlock::getRealAddr(u64 addr, u64& result)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 VirtualMemoryBlock::getMappedAddress(u64 realAddress)
|
u32 VirtualMemoryBlock::getMappedAddress(u32 realAddress)
|
||||||
{
|
{
|
||||||
for (u32 i = 0; i<m_mapped_memory.size(); ++i)
|
for (u32 i = 0; i<m_mapped_memory.size(); ++i)
|
||||||
{
|
{
|
||||||
|
@ -72,9 +72,9 @@ public:
|
|||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegisterPages(u64 addr, u32 size);
|
void RegisterPages(u32 addr, u32 size);
|
||||||
|
|
||||||
void UnregisterPages(u64 addr, u32 size);
|
void UnregisterPages(u32 addr, u32 size);
|
||||||
|
|
||||||
u32 InitRawSPU(MemoryBlock* raw_spu);
|
u32 InitRawSPU(MemoryBlock* raw_spu);
|
||||||
|
|
||||||
@ -119,19 +119,19 @@ public:
|
|||||||
return UserMemory->GetSize() - UserMemory->GetUsedSize();
|
return UserMemory->GetSize() - UserMemory->GetUsedSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 Alloc(const u32 size, const u32 align)
|
u32 Alloc(const u32 size, const u32 align)
|
||||||
{
|
{
|
||||||
return UserMemory->AllocAlign(size, align);
|
return UserMemory->AllocAlign(size, align);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Free(const u64 addr)
|
bool Free(const u32 addr)
|
||||||
{
|
{
|
||||||
return UserMemory->Free(addr);
|
return UserMemory->Free(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Map(const u64 addr, const u32 size);
|
bool Map(const u32 addr, const u32 size);
|
||||||
|
|
||||||
bool Unmap(const u64 addr);
|
bool Unmap(const u32 addr);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern MemoryBase Memory;
|
extern MemoryBase Memory;
|
||||||
|
@ -2,20 +2,20 @@
|
|||||||
|
|
||||||
#define PAGE_4K(x) (x + 4095) & ~(4095)
|
#define PAGE_4K(x) (x + 4095) & ~(4095)
|
||||||
|
|
||||||
//#include <emmintrin.h>
|
|
||||||
|
|
||||||
struct MemInfo
|
struct MemInfo
|
||||||
{
|
{
|
||||||
u64 addr;
|
u32 addr;
|
||||||
u32 size;
|
u32 size;
|
||||||
|
|
||||||
MemInfo(u64 _addr, u32 _size)
|
MemInfo(u32 addr, u32 size)
|
||||||
: addr(_addr)
|
: addr(addr)
|
||||||
, size(_size)
|
, size(size)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
MemInfo() : addr(0), size(0)
|
MemInfo()
|
||||||
|
: addr(0)
|
||||||
|
, size(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -24,7 +24,7 @@ struct MemBlockInfo : public MemInfo
|
|||||||
{
|
{
|
||||||
void *mem;
|
void *mem;
|
||||||
|
|
||||||
MemBlockInfo(u64 _addr, u32 _size);
|
MemBlockInfo(u32 addr, u32 size);
|
||||||
|
|
||||||
void Free();
|
void Free();
|
||||||
|
|
||||||
@ -58,11 +58,11 @@ struct MemBlockInfo : public MemInfo
|
|||||||
|
|
||||||
struct VirtualMemInfo : public MemInfo
|
struct VirtualMemInfo : public MemInfo
|
||||||
{
|
{
|
||||||
u64 realAddress;
|
u32 realAddress;
|
||||||
|
|
||||||
VirtualMemInfo(u64 _addr, u64 _realaddr, u32 _size)
|
VirtualMemInfo(u32 addr, u32 realaddr, u32 size)
|
||||||
: MemInfo(_addr, _size)
|
: MemInfo(addr, size)
|
||||||
, realAddress(_realaddr)
|
, realAddress(realaddr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,7 +77,7 @@ class MemoryBlock
|
|||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
u8* mem;
|
u8* mem;
|
||||||
u64 range_start;
|
u32 range_start;
|
||||||
u32 range_size;
|
u32 range_size;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -93,25 +93,17 @@ private:
|
|||||||
public:
|
public:
|
||||||
virtual void Delete();
|
virtual void Delete();
|
||||||
|
|
||||||
u64 FixAddr(const u64 addr) const;
|
virtual MemoryBlock* SetRange(const u32 start, const u32 size);
|
||||||
|
|
||||||
virtual MemoryBlock* SetRange(const u64 start, const u32 size);
|
const u32 GetStartAddr() const { return range_start; }
|
||||||
virtual bool IsMyAddress(const u64 addr);
|
const u32 GetEndAddr() const { return GetStartAddr() + GetSize() - 1; }
|
||||||
virtual bool IsLocked(const u64 addr) { return false; }
|
|
||||||
|
|
||||||
const u64 GetStartAddr() const { return range_start; }
|
|
||||||
const u64 GetEndAddr() const { return GetStartAddr() + GetSize() - 1; }
|
|
||||||
virtual const u32 GetSize() const { return range_size; }
|
virtual const u32 GetSize() const { return range_size; }
|
||||||
virtual const u32 GetUsedSize() const { return GetSize(); }
|
virtual const u32 GetUsedSize() const { return GetSize(); }
|
||||||
u8* GetMem() const { return mem; }
|
|
||||||
virtual u8* GetMem(u64 addr) const { return mem + addr; }
|
|
||||||
|
|
||||||
virtual bool AllocFixed(u64 addr, u32 size) { return false; }
|
virtual bool AllocFixed(u32 addr, u32 size) { return false; }
|
||||||
virtual u64 AllocAlign(u32 size, u32 align = 1) { return 0; }
|
virtual u32 AllocAlign(u32 size, u32 align = 1) { return 0; }
|
||||||
virtual bool Alloc() { return false; }
|
virtual bool Alloc() { return false; }
|
||||||
virtual bool Free(u64 addr) { return false; }
|
virtual bool Free(u32 addr) { return false; }
|
||||||
virtual bool Lock(u64 addr, u32 size) { return false; }
|
|
||||||
virtual bool Unlock(u64 addr, u32 size) { return false; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class DynamicMemoryBlockBase : public MemoryBlock
|
class DynamicMemoryBlockBase : public MemoryBlock
|
||||||
@ -125,26 +117,19 @@ public:
|
|||||||
const u32 GetSize() const { return m_max_size; }
|
const u32 GetSize() const { return m_max_size; }
|
||||||
const u32 GetUsedSize() const;
|
const u32 GetUsedSize() const;
|
||||||
|
|
||||||
virtual bool IsInMyRange(const u64 addr);
|
virtual bool IsInMyRange(const u32 addr, const u32 size = 1);
|
||||||
virtual bool IsInMyRange(const u64 addr, const u32 size);
|
|
||||||
virtual bool IsMyAddress(const u64 addr);
|
|
||||||
virtual bool IsLocked(const u64 addr);
|
|
||||||
|
|
||||||
virtual MemoryBlock* SetRange(const u64 start, const u32 size);
|
virtual MemoryBlock* SetRange(const u32 start, const u32 size);
|
||||||
|
|
||||||
virtual void Delete();
|
virtual void Delete();
|
||||||
|
|
||||||
virtual bool AllocFixed(u64 addr, u32 size);
|
virtual bool AllocFixed(u32 addr, u32 size);
|
||||||
virtual u64 AllocAlign(u32 size, u32 align = 1);
|
virtual u32 AllocAlign(u32 size, u32 align = 1);
|
||||||
virtual bool Alloc();
|
virtual bool Alloc();
|
||||||
virtual bool Free(u64 addr);
|
virtual bool Free(u32 addr);
|
||||||
virtual bool Lock(u64 addr, u32 size);
|
|
||||||
virtual bool Unlock(u64 addr, u32 size);
|
|
||||||
|
|
||||||
virtual u8* GetMem(u64 addr) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void AppendMem(u64 addr, u32 size);
|
void AppendMem(u32 addr, u32 size);
|
||||||
};
|
};
|
||||||
|
|
||||||
class VirtualMemoryBlock : public MemoryBlock
|
class VirtualMemoryBlock : public MemoryBlock
|
||||||
@ -155,22 +140,20 @@ class VirtualMemoryBlock : public MemoryBlock
|
|||||||
public:
|
public:
|
||||||
VirtualMemoryBlock();
|
VirtualMemoryBlock();
|
||||||
|
|
||||||
virtual MemoryBlock* SetRange(const u64 start, const u32 size);
|
virtual MemoryBlock* SetRange(const u32 start, const u32 size);
|
||||||
virtual bool IsInMyRange(const u64 addr);
|
virtual bool IsInMyRange(const u32 addr, const u32 size = 1);
|
||||||
virtual bool IsInMyRange(const u64 addr, const u32 size);
|
|
||||||
virtual bool IsMyAddress(const u64 addr);
|
|
||||||
virtual void Delete();
|
virtual void Delete();
|
||||||
|
|
||||||
// maps real address to virtual address space, returns the mapped address or 0 on failure (if no address is specified the
|
// maps real address to virtual address space, returns the mapped address or 0 on failure (if no address is specified the
|
||||||
// first mappable space is used)
|
// first mappable space is used)
|
||||||
virtual bool Map(u64 realaddr, u32 size, u64 addr);
|
virtual bool Map(u32 realaddr, u32 size, u32 addr);
|
||||||
virtual u64 Map(u64 realaddr, u32 size);
|
virtual u32 Map(u32 realaddr, u32 size);
|
||||||
|
|
||||||
// Unmap real address (please specify only starting point, no midway memory will be unmapped), returns the size of the unmapped area
|
// Unmap real address (please specify only starting point, no midway memory will be unmapped), returns the size of the unmapped area
|
||||||
virtual bool UnmapRealAddress(u64 realaddr, u32& size);
|
virtual bool UnmapRealAddress(u32 realaddr, u32& size);
|
||||||
|
|
||||||
// Unmap address (please specify only starting point, no midway memory will be unmapped), returns the size of the unmapped area
|
// Unmap address (please specify only starting point, no midway memory will be unmapped), returns the size of the unmapped area
|
||||||
virtual bool UnmapAddress(u64 addr, u32& size);
|
virtual bool UnmapAddress(u32 addr, u32& size);
|
||||||
|
|
||||||
// Reserve a certain amount so no one can use it, returns true on succces, false on failure
|
// Reserve a certain amount so no one can use it, returns true on succces, false on failure
|
||||||
virtual bool Reserve(u32 size);
|
virtual bool Reserve(u32 size);
|
||||||
@ -181,24 +164,23 @@ public:
|
|||||||
// Return the total amount of reserved memory
|
// Return the total amount of reserved memory
|
||||||
virtual u32 GetReservedAmount();
|
virtual u32 GetReservedAmount();
|
||||||
|
|
||||||
bool Read32(const u64 addr, u32* value);
|
bool Read32(const u32 addr, u32* value);
|
||||||
|
|
||||||
bool Write32(const u64 addr, const u32 value);
|
bool Write32(const u32 addr, const u32 value);
|
||||||
|
|
||||||
// try to get the real address given a mapped address
|
// try to get the real address given a mapped address
|
||||||
// return true for success
|
// return true for success
|
||||||
bool getRealAddr(u64 addr, u64& result);
|
bool getRealAddr(u32 addr, u32& result);
|
||||||
|
|
||||||
u64 RealAddr(u64 addr)
|
u32 RealAddr(u32 addr)
|
||||||
{
|
{
|
||||||
u64 realAddr = 0;
|
u32 realAddr = 0;
|
||||||
getRealAddr(addr, realAddr);
|
getRealAddr(addr, realAddr);
|
||||||
return realAddr;
|
return realAddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return the mapped address given a real address, if not mapped return 0
|
// return the mapped address given a real address, if not mapped return 0
|
||||||
u64 getMappedAddress(u64 realAddress);
|
u32 getMappedAddress(u32 realAddress);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef DynamicMemoryBlockBase DynamicMemoryBlock;
|
typedef DynamicMemoryBlockBase DynamicMemoryBlock;
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ Module *cellGame = nullptr;
|
|||||||
|
|
||||||
std::string contentInfo = "";
|
std::string contentInfo = "";
|
||||||
std::string usrdir = "";
|
std::string usrdir = "";
|
||||||
|
bool path_set = false;
|
||||||
|
|
||||||
int cellGameBootCheck(vm::ptr<u32> type, vm::ptr<u32> attributes, vm::ptr<CellGameContentSize> size, vm::ptr<char[CELL_GAME_DIRNAME_SIZE]> dirName)
|
int cellGameBootCheck(vm::ptr<u32> type, vm::ptr<u32> attributes, vm::ptr<CellGameContentSize> size, vm::ptr<char[CELL_GAME_DIRNAME_SIZE]> dirName)
|
||||||
{
|
{
|
||||||
@ -52,6 +53,7 @@ int cellGameBootCheck(vm::ptr<u32> type, vm::ptr<u32> attributes, vm::ptr<CellGa
|
|||||||
if (dirName) strcpy_trunc(*dirName, ""); // ???
|
if (dirName) strcpy_trunc(*dirName, ""); // ???
|
||||||
contentInfo = "/dev_bdvd/PS3_GAME";
|
contentInfo = "/dev_bdvd/PS3_GAME";
|
||||||
usrdir = "/dev_bdvd/PS3_GAME/USRDIR";
|
usrdir = "/dev_bdvd/PS3_GAME/USRDIR";
|
||||||
|
path_set = true;
|
||||||
}
|
}
|
||||||
else if (category.substr(0, 2) == "HG")
|
else if (category.substr(0, 2) == "HG")
|
||||||
{
|
{
|
||||||
@ -61,6 +63,7 @@ int cellGameBootCheck(vm::ptr<u32> type, vm::ptr<u32> attributes, vm::ptr<CellGa
|
|||||||
if (dirName) strcpy_trunc(*dirName, titleId);
|
if (dirName) strcpy_trunc(*dirName, titleId);
|
||||||
contentInfo = "/dev_hdd0/game/" + titleId;
|
contentInfo = "/dev_hdd0/game/" + titleId;
|
||||||
usrdir = "/dev_hdd0/game/" + titleId + "/USRDIR";
|
usrdir = "/dev_hdd0/game/" + titleId + "/USRDIR";
|
||||||
|
path_set = true;
|
||||||
}
|
}
|
||||||
else if (category.substr(0, 2) == "GD")
|
else if (category.substr(0, 2) == "GD")
|
||||||
{
|
{
|
||||||
@ -70,6 +73,7 @@ int cellGameBootCheck(vm::ptr<u32> type, vm::ptr<u32> attributes, vm::ptr<CellGa
|
|||||||
if (dirName) strcpy_trunc(*dirName, titleId); // ???
|
if (dirName) strcpy_trunc(*dirName, titleId); // ???
|
||||||
contentInfo = "/dev_bdvd/PS3_GAME";
|
contentInfo = "/dev_bdvd/PS3_GAME";
|
||||||
usrdir = "/dev_bdvd/PS3_GAME/USRDIR";
|
usrdir = "/dev_bdvd/PS3_GAME/USRDIR";
|
||||||
|
path_set = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -124,6 +128,7 @@ int cellGamePatchCheck(vm::ptr<CellGameContentSize> size, u32 reserved_addr)
|
|||||||
std::string titleId = psf.GetString("TITLE_ID");
|
std::string titleId = psf.GetString("TITLE_ID");
|
||||||
contentInfo = "/dev_hdd0/game/" + titleId;
|
contentInfo = "/dev_hdd0/game/" + titleId;
|
||||||
usrdir = "/dev_hdd0/game/" + titleId + "/USRDIR";
|
usrdir = "/dev_hdd0/game/" + titleId + "/USRDIR";
|
||||||
|
path_set = true;
|
||||||
|
|
||||||
return CELL_GAME_RET_OK;
|
return CELL_GAME_RET_OK;
|
||||||
}
|
}
|
||||||
@ -155,10 +160,15 @@ int cellGameDataCheck(u32 type, vm::ptr<const char> dirName, vm::ptr<CellGameCon
|
|||||||
if (!Emu.GetVFS().ExistsDir("/dev_bdvd/PS3_GAME"))
|
if (!Emu.GetVFS().ExistsDir("/dev_bdvd/PS3_GAME"))
|
||||||
{
|
{
|
||||||
cellGame->Warning("cellGameDataCheck(): /dev_bdvd/PS3_GAME not found");
|
cellGame->Warning("cellGameDataCheck(): /dev_bdvd/PS3_GAME not found");
|
||||||
|
contentInfo = "";
|
||||||
|
usrdir = "";
|
||||||
|
path_set = true;
|
||||||
return CELL_GAME_RET_NONE;
|
return CELL_GAME_RET_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
contentInfo = "/dev_bdvd/PS3_GAME";
|
contentInfo = "/dev_bdvd/PS3_GAME";
|
||||||
usrdir = "/dev_bdvd/PS3_GAME/USRDIR";
|
usrdir = "/dev_bdvd/PS3_GAME/USRDIR";
|
||||||
|
path_set = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -167,10 +177,15 @@ int cellGameDataCheck(u32 type, vm::ptr<const char> dirName, vm::ptr<CellGameCon
|
|||||||
if (!Emu.GetVFS().ExistsDir(dir))
|
if (!Emu.GetVFS().ExistsDir(dir))
|
||||||
{
|
{
|
||||||
cellGame->Warning("cellGameDataCheck(): '%s' directory not found", dir.c_str());
|
cellGame->Warning("cellGameDataCheck(): '%s' directory not found", dir.c_str());
|
||||||
|
contentInfo = "";
|
||||||
|
usrdir = "";
|
||||||
|
path_set = true;
|
||||||
return CELL_GAME_RET_NONE;
|
return CELL_GAME_RET_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
contentInfo = dir;
|
contentInfo = dir;
|
||||||
usrdir = dir + "/USRDIR";
|
usrdir = dir + "/USRDIR";
|
||||||
|
path_set = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return CELL_GAME_RET_OK;
|
return CELL_GAME_RET_OK;
|
||||||
@ -186,9 +201,8 @@ int cellGameContentPermit(vm::ptr<char[CELL_GAME_PATH_MAX]> contentInfoPath, vm:
|
|||||||
return CELL_GAME_ERROR_PARAM;
|
return CELL_GAME_ERROR_PARAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (contentInfo == "" && usrdir == "")
|
if (!path_set)
|
||||||
{
|
{
|
||||||
cellGame->Warning("cellGameContentPermit(): CELL_GAME_ERROR_FAILURE (no permission given)");
|
|
||||||
return CELL_GAME_ERROR_FAILURE;
|
return CELL_GAME_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,6 +211,7 @@ int cellGameContentPermit(vm::ptr<char[CELL_GAME_PATH_MAX]> contentInfoPath, vm:
|
|||||||
|
|
||||||
contentInfo = "";
|
contentInfo = "";
|
||||||
usrdir = "";
|
usrdir = "";
|
||||||
|
path_set = false;
|
||||||
|
|
||||||
return CELL_GAME_RET_OK;
|
return CELL_GAME_RET_OK;
|
||||||
}
|
}
|
||||||
@ -476,6 +491,10 @@ void cellGame_init(Module *pxThis)
|
|||||||
{
|
{
|
||||||
cellGame = pxThis;
|
cellGame = pxThis;
|
||||||
|
|
||||||
|
contentInfo = "";
|
||||||
|
usrdir = "";
|
||||||
|
path_set = false;
|
||||||
|
|
||||||
// (TODO: Disc Exchange functions missing)
|
// (TODO: Disc Exchange functions missing)
|
||||||
|
|
||||||
cellGame->AddFunc(0xf52639ea, cellGameBootCheck);
|
cellGame->AddFunc(0xf52639ea, cellGameBootCheck);
|
||||||
|
@ -842,16 +842,16 @@ void cellGcmGetOffsetTable(vm::ptr<CellGcmOffsetTable> table)
|
|||||||
table->eaAddress = offsetTable.eaAddress;
|
table->eaAddress = offsetTable.eaAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 cellGcmIoOffsetToAddress(u32 ioOffset, u64 address)
|
s32 cellGcmIoOffsetToAddress(u32 ioOffset, vm::ptr<u32> address)
|
||||||
{
|
{
|
||||||
cellGcmSys->Log("cellGcmIoOffsetToAddress(ioOffset=0x%x, address=0x%llx)", ioOffset, address);
|
cellGcmSys->Log("cellGcmIoOffsetToAddress(ioOffset=0x%x, address=0x%llx)", ioOffset, address);
|
||||||
|
|
||||||
u64 realAddr;
|
u32 realAddr;
|
||||||
|
|
||||||
if (!Memory.RSXIOMem.getRealAddr(ioOffset, realAddr))
|
if (!Memory.RSXIOMem.getRealAddr(ioOffset, realAddr))
|
||||||
return CELL_GCM_ERROR_FAILURE;
|
return CELL_GCM_ERROR_FAILURE;
|
||||||
|
|
||||||
vm::write64(address, realAddr);
|
*address = realAddr;
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,6 @@ s32 cellGcmSetPrepareFlip(vm::ptr<CellGcmContextData> ctxt, u32 id);
|
|||||||
s32 cellGcmAddressToOffset(u64 address, vm::ptr<be_t<u32>> offset);
|
s32 cellGcmAddressToOffset(u64 address, vm::ptr<be_t<u32>> offset);
|
||||||
u32 cellGcmGetMaxIoMapSize();
|
u32 cellGcmGetMaxIoMapSize();
|
||||||
void cellGcmGetOffsetTable(vm::ptr<CellGcmOffsetTable> table);
|
void cellGcmGetOffsetTable(vm::ptr<CellGcmOffsetTable> table);
|
||||||
s32 cellGcmIoOffsetToAddress(u32 ioOffset, u64 address);
|
|
||||||
s32 cellGcmMapEaIoAddress(u32 ea, u32 io, u32 size);
|
s32 cellGcmMapEaIoAddress(u32 ea, u32 io, u32 size);
|
||||||
s32 cellGcmMapEaIoAddressWithFlags(u32 ea, u32 io, u32 size, u32 flags);
|
s32 cellGcmMapEaIoAddressWithFlags(u32 ea, u32 io, u32 size, u32 flags);
|
||||||
s32 cellGcmMapMainMemory(u32 ea, u32 size, vm::ptr<u32> offset);
|
s32 cellGcmMapMainMemory(u32 ea, u32 size, vm::ptr<u32> offset);
|
||||||
|
@ -24,8 +24,10 @@
|
|||||||
Module *sysPrxForUser = nullptr;
|
Module *sysPrxForUser = nullptr;
|
||||||
|
|
||||||
#define TLS_MAX 128
|
#define TLS_MAX 128
|
||||||
|
#define TLS_SYS 0x30
|
||||||
|
|
||||||
u32 g_tls_start; // start of TLS memory area
|
u32 g_tls_start; // start of TLS memory area
|
||||||
|
u32 g_tls_size;
|
||||||
|
|
||||||
std::array<std::atomic<u32>, TLS_MAX> g_tls_owners;
|
std::array<std::atomic<u32>, TLS_MAX> g_tls_owners;
|
||||||
|
|
||||||
@ -38,8 +40,9 @@ u32 ppu_get_tls(u32 thread)
|
|||||||
{
|
{
|
||||||
if (!g_tls_start)
|
if (!g_tls_start)
|
||||||
{
|
{
|
||||||
g_tls_start = vm::cast(Memory.MainMem.AllocAlign(Emu.GetTLSMemsz() * TLS_MAX, 4096)); // memory for up to TLS_MAX threads
|
g_tls_size = Emu.GetTLSMemsz() + TLS_SYS;
|
||||||
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 = vm::cast(Memory.MainMem.AllocAlign(g_tls_size * TLS_MAX, 4096)); // memory for up to TLS_MAX threads
|
||||||
|
sysPrxForUser->Notice("Thread Local Storage initialized (g_tls_start=0x%x, user_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());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,7 +55,7 @@ u32 ppu_get_tls(u32 thread)
|
|||||||
{
|
{
|
||||||
if (g_tls_owners[i] == thread)
|
if (g_tls_owners[i] == thread)
|
||||||
{
|
{
|
||||||
return g_tls_start + i * Emu.GetTLSMemsz(); // if already initialized, return TLS address
|
return g_tls_start + i * g_tls_size + TLS_SYS; // if already initialized, return TLS address
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,7 +64,8 @@ u32 ppu_get_tls(u32 thread)
|
|||||||
u32 old = 0;
|
u32 old = 0;
|
||||||
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 * g_tls_size + TLS_SYS; // get TLS address
|
||||||
|
memset(vm::get_ptr(addr - TLS_SYS), 0, TLS_SYS); // initialize system 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
|
memset(vm::get_ptr(addr + Emu.GetTLSFilesz()), 0, Emu.GetTLSMemsz() - Emu.GetTLSFilesz()); // fill the rest with zeros
|
||||||
return addr;
|
return addr;
|
||||||
|
@ -331,9 +331,9 @@ void RSXDebugger::GoToGet(wxCommandEvent& event)
|
|||||||
{
|
{
|
||||||
if (!RSXReady()) return;
|
if (!RSXReady()) return;
|
||||||
auto ctrl = vm::get_ptr<CellGcmControl>(Emu.GetGSManager().GetRender().m_ctrlAddress);
|
auto ctrl = vm::get_ptr<CellGcmControl>(Emu.GetGSManager().GetRender().m_ctrlAddress);
|
||||||
u64 realAddr;
|
u32 realAddr;
|
||||||
if (Memory.RSXIOMem.getRealAddr(ctrl->get.read_relaxed(), realAddr)) {
|
if (Memory.RSXIOMem.getRealAddr(ctrl->get.read_relaxed(), realAddr)) {
|
||||||
m_addr = realAddr; // WARNING: Potential Truncation? Cast from u64 to u32
|
m_addr = realAddr;
|
||||||
t_addr->SetValue(wxString::Format("%08x", m_addr));
|
t_addr->SetValue(wxString::Format("%08x", m_addr));
|
||||||
UpdateInformation();
|
UpdateInformation();
|
||||||
event.Skip();
|
event.Skip();
|
||||||
@ -345,9 +345,9 @@ void RSXDebugger::GoToPut(wxCommandEvent& event)
|
|||||||
{
|
{
|
||||||
if (!RSXReady()) return;
|
if (!RSXReady()) return;
|
||||||
auto ctrl = vm::get_ptr<CellGcmControl>(Emu.GetGSManager().GetRender().m_ctrlAddress);
|
auto ctrl = vm::get_ptr<CellGcmControl>(Emu.GetGSManager().GetRender().m_ctrlAddress);
|
||||||
u64 realAddr;
|
u32 realAddr;
|
||||||
if (Memory.RSXIOMem.getRealAddr(ctrl->put.read_relaxed(), realAddr)) {
|
if (Memory.RSXIOMem.getRealAddr(ctrl->put.read_relaxed(), realAddr)) {
|
||||||
m_addr = realAddr; // WARNING: Potential Truncation? Cast from u64 to u32
|
m_addr = realAddr;
|
||||||
t_addr->SetValue(wxString::Format("%08x", m_addr));
|
t_addr->SetValue(wxString::Format("%08x", m_addr));
|
||||||
UpdateInformation();
|
UpdateInformation();
|
||||||
event.Skip();
|
event.Skip();
|
||||||
|
Loading…
Reference in New Issue
Block a user