1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-23 03:02:53 +01:00

Small changes in memory and RSXIOMem

Some bugs fixed, some other changes.
This commit is contained in:
Nekotekina 2014-10-04 18:43:46 +04:00
parent 6b0857dcff
commit 74007d5e5d
13 changed files with 95 additions and 92 deletions

View File

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

View File

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

View File

@ -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 ===== */

View File

@ -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<void(SPUThread& CPU)> m_custom_task;
std::function<void(SPUThread& SPU)> m_custom_task;
std::function<u32(SPUThread& SPU)> m_code3_func;
public:
SPUThread(CPUThreadType type = CPU_THREAD_SPU);

View File

@ -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.size(); ++i)
{
bool is_good_addr = true;
// check if address is already mapped
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) ||
(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<m_mapped_memory.size(); ++i)
{
if(m_mapped_memory[i].realAddress == realaddr && IsInMyRange(m_mapped_memory[i].addr, m_mapped_memory[i].size))
{
u32 size = m_mapped_memory[i].size;
size = m_mapped_memory[i].size;
m_mapped_memory.erase(m_mapped_memory.begin() + i);
return size;
return true;
}
}
return 0;
return false;
}
u32 VirtualMemoryBlock::UnmapAddress(u64 addr)
bool VirtualMemoryBlock::UnmapAddress(u64 addr, u32& size)
{
for(u32 i=0; i<m_mapped_memory.size(); ++i)
{
if(m_mapped_memory[i].addr == addr && IsInMyRange(m_mapped_memory[i].addr, m_mapped_memory[i].size))
{
u32 size = m_mapped_memory[i].size;
size = m_mapped_memory[i].size;
m_mapped_memory.erase(m_mapped_memory.begin() + i);
return size;
return true;
}
}
return 0;
return false;
}
bool VirtualMemoryBlock::Read32(const u64 addr, u32* value)

View File

@ -163,13 +163,14 @@ public:
// 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)
virtual u64 Map(u64 realaddr, u32 size, u64 addr = 0);
virtual bool Map(u64 realaddr, u32 size, u64 addr);
virtual u64 Map(u64 realaddr, u32 size);
// Unmap real address (please specify only starting point, no midway memory will be unmapped), returns the size of the unmapped area
virtual u32 UnmapRealAddress(u64 realaddr);
virtual bool UnmapRealAddress(u64 realaddr, u32& size);
// Unmap address (please specify only starting point, no midway memory will be unmapped), returns the size of the unmapped area
virtual u32 UnmapAddress(u64 addr);
virtual bool UnmapAddress(u64 addr, u32& size);
// Reserve a certain amount so no one can use it, returns true on succces, false on failure
virtual bool Reserve(u32 size);

View File

@ -12,12 +12,6 @@ namespace vm
{
return (T*)((u8*)g_base_addr + addr);
}
template<typename T>
T* const get_ptr(u64 addr)
{
return get_ptr<T>((u32)addr);
}
template<typename T>
T& get_ref(u32 addr)
@ -25,12 +19,6 @@ namespace vm
return *get_ptr<T>(addr);
}
template<typename T>
T& get_ref(u64 addr)
{
return get_ref<T>((u32)addr);
}
namespace ps3
{
static u8 read8(u32 addr)

View File

@ -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<u8>(GetAddress(offset, m_context_dma_img_src - 0xfeed0000));
u8* pixels_dst = vm::get_ptr<u8>(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<m_color_conv_in_h; ++y)
{
for(u16 x=0; x<m_color_format_src_pitch/4/*m_color_conv_in_w*/; ++x)
{
const u32 src_offset = (m_color_conv_in_y + y) * m_color_format_src_pitch + (m_color_conv_in_x + x) * 4;
const u32 dst_offset = (m_color_conv_out_y + y) * m_color_format_dst_pitch + (m_color_conv_out_x + x) * 4;
(u32&)pixels_dst[dst_offset] = (u32&)pixels_src[src_offset];
//(u32&)pixels_dst[dst_offset] = (u32&)pixels_src[src_offset];
}
}
}
@ -1981,9 +1986,10 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
{
const u32 cause = ARGS(0);
auto cb = m_user_handler;
Emu.GetCallbackManager().Async([cb, cause]()
Emu.GetCallbackManager().Register([cb, cause]()
{
cb(cause);
return 0;
});
}
break;
@ -2147,9 +2153,10 @@ void RSXThread::Task()
if (m_vblank_handler)
{
auto cb = m_vblank_handler;
Emu.GetCallbackManager().Async([cb]()
Emu.GetCallbackManager().Register([cb]()
{
cb(1);
return 0;
});
}
continue;
@ -2200,6 +2207,7 @@ void RSXThread::Task()
const u32 cmd = ReadIO32(get);
const u32 count = (cmd >> 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<be_t<u32>>::make((u32)Memory.RSXIOMem.RealAddr(Memory.RSXIOMem.GetStartAddr() + get + 4));
auto args = vm::ptr<be_t<u32>>::make((u32)Memory.RSXIOMem.RealAddr(get + 4));
for(u32 i=0; i<count; i++)
{
@ -2295,7 +2303,7 @@ void RSXThread::Init(const u32 ioAddress, const u32 ioSize, const u32 ctrlAddres
u32 RSXThread::ReadIO32(u32 addr)
{
u32 value;
if (!Memory.RSXIOMem.Read32(Memory.RSXIOMem.GetStartAddr() + addr, &value))
if (!Memory.RSXIOMem.Read32(addr, &value))
{
throw fmt::Format("%s(rsxio_addr=0x%x): RSXIO memory not mapped", __FUNCTION__, addr);
}
@ -2304,7 +2312,7 @@ u32 RSXThread::ReadIO32(u32 addr)
void RSXThread::WriteIO32(u32 addr, u32 value)
{
if (!Memory.RSXIOMem.Write32(Memory.RSXIOMem.GetStartAddr() + addr, value))
if (!Memory.RSXIOMem.Write32(addr, value))
{
throw fmt::Format("%s(rsxio_addr=0x%x): RSXIO memory not mapped", __FUNCTION__, addr);
}

View File

@ -338,12 +338,12 @@ s32 _cellGcmInitBody(vm::ptr<CellGcmContextData> 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<CellGcmOffsetTable> 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<be_t<u32>> 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;

View File

@ -106,11 +106,11 @@ s64 spursInit(
// default or system workload:
#ifdef PRX_DEBUG
spurs->m.wklSysG.pm.set(be_t<u64>::make(vm::read32(libsre_rtoc - 0x7EA4)));
spurs->m.wklSysG.size = 0x2200;
#else
spurs->m.wklSysG.pm.set(be_t<u64>::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<void>(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();

View File

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

View File

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

View File

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