Refactoring (#6143)

Prefer vm::ptr<>::ptr over vm::get_addr.
    Prefer vm::_ptr/base over vm::g_base_addr with offset.
    Added methods atomic_t<>::bts and atomic_t<>::btr .
    Removed obsolute rsx:🧵:Read/WriteIO32 methods.
    Removed wrong check in semaphore_release.
    Added handling for PUTRx commands for RawSPU MFC proxy.
    Prefer overloaded methods of v128 instead of _mm_... in VPKSHUS ppu interpreter precise.
    Fixed more potential overflows that may result in wrong behaviour.
    Added io/size alignment check for sys_rsx_context_iounmap.
    Added rsx::constants::local_mem_base which represents RSX local memory base address.
    Removed obsolute rsx:🧵:main_mem_addr/ioSize/ioAddress members.
This commit is contained in:
Eladash 2019-06-29 01:27:49 +03:00 committed by Ivan
parent e043412be4
commit 1ee7b91646
20 changed files with 64 additions and 81 deletions

View File

@ -1,4 +1,4 @@
#pragma once
#pragma once
#include "types.h"
#include <functional>
@ -1163,4 +1163,14 @@ public:
}
}
}
bool bts(uint bit)
{
return atomic_storage<type>::bts(m_data, bit);
}
bool btr(uint bit)
{
return atomic_storage<type>::btr(m_data, bit);
}
};

View File

@ -1,4 +1,4 @@
#pragma once
#pragma once
#ifdef _MSC_VER
#include <intrin.h>

View File

@ -374,8 +374,8 @@ s32 _cellGcmInitBody(ppu_thread& ppu, vm::pptr<CellGcmContextData> context, u32
if (!local_size && !local_addr)
{
local_size = 0xf900000; // TODO: Get sdk_version in _cellGcmFunc15 and pass it to gcmGetLocalMemorySize
local_addr = 0xC0000000;
vm::falloc(0xC0000000, local_size, vm::video);
local_addr = rsx::constants::local_mem_base;
vm::falloc(local_addr, local_size, vm::video);
}
cellGcmSys.warning("*** local memory(addr=0x%x, size=0x%x)", local_addr, local_size);
@ -446,11 +446,10 @@ s32 _cellGcmInitBody(ppu_thread& ppu, vm::pptr<CellGcmContextData> context, u32
ppu_execute<&sys_ppu_thread_create>(ppu, +_tid, 0x10000, 0, 1, 0x4000, SYS_PPU_THREAD_CREATE_INTERRUPT, +_name);
render->intr_thread = idm::get<named_thread<ppu_thread>>(*_tid);
render->intr_thread->state -= cpu_flag::stop;
render->main_mem_addr = 0;
render->isHLE = true;
render->label_addr = m_config->gcm_info.label_addr;
render->ctxt_addr = m_config->gcm_info.context_addr;
render->init(ioAddress, ioSize, m_config->gcm_info.control_addr - 0x40, local_addr);
render->init(m_config->gcm_info.control_addr - 0x40);
return CELL_OK;
}
@ -945,7 +944,7 @@ s32 cellGcmAddressToOffset(u32 address, vm::ptr<u32> offset)
// Address in local memory
if ((address >> 28) == 0xC)
{
result = address - 0xC0000000;
result = address - rsx::constants::local_mem_base;
}
// Address in main memory else check
else
@ -1046,7 +1045,7 @@ s32 cellGcmMapLocalMemory(vm::ptr<u32> address, vm::ptr<u32> size)
{
cellGcmSys.warning("cellGcmMapLocalMemory(address=*0x%x, size=*0x%x)", address, size);
if (!local_addr && !local_size && vm::falloc(local_addr = 0xC0000000, local_size = 0xf900000 /* TODO */, vm::video))
if (!local_addr && !local_size && vm::falloc(local_addr = rsx::constants::local_mem_base, local_size = 0xf900000 /* TODO */, vm::video))
{
*address = local_addr;
*size = local_size;

View File

@ -440,7 +440,7 @@ error_code cellPadPeriphGetData(u32 port_no, vm::ptr<CellPadPeriphData> data)
data->pclass_type = pad->m_class_type;
data->pclass_profile = 0x0;
return cellPadGetData(port_no, vm::get_addr(&data->cellpad_data));
return cellPadGetData(port_no, data.ptr(&CellPadPeriphData::cellpad_data));
}
error_code cellPadGetRawData(u32 port_no, vm::ptr<CellPadData> data)

View File

@ -1486,7 +1486,7 @@ bool ppu_interpreter_precise::VPKSHUS(ppu_thread& ppu, ppu_opcode_t op)
// Detect saturation
{
const u64 mask = 0xFF00FF00FF00FF00ULL;
const auto all_bits = v128::fromV(_mm_or_si128(a.vi, b.vi));
const auto all_bits = a | b;
if ((all_bits._u64[0] | all_bits._u64[1]) & mask)
{
ppu.sat = true;

View File

@ -142,6 +142,9 @@ bool spu_thread::write_reg(const u32 addr, const u32 value)
case MFC_PUTS_CMD:
case MFC_PUTBS_CMD:
case MFC_PUTFS_CMD:
case MFC_PUTR_CMD:
case MFC_PUTRB_CMD:
case MFC_PUTRF_CMD:
case MFC_GET_CMD:
case MFC_GETB_CMD:
case MFC_GETF_CMD:

View File

@ -1335,8 +1335,8 @@ void spu_thread::do_dma_transfer(const spu_mfc_cmd& args)
}
}
u8* dst = (u8*)vm::base(eal);
u8* src = (u8*)vm::base(offset + lsa);
u8* dst = vm::_ptr<u8>(eal);
u8* src = vm::_ptr<u8>(offset + lsa);
if (UNLIKELY(!is_get && !g_use_rtm))
{
@ -1603,7 +1603,7 @@ void spu_thread::do_putlluc(const spu_mfc_cmd& args)
cpu_thread::suspend_all cpu_lock(this);
// Try to obtain bit 7 (+64)
if (!atomic_storage<u64>::bts(vm::reservation_acquire(addr, 128).raw(), 6))
if (!vm::reservation_acquire(addr, 128).bts(6))
{
auto& data = vm::_ref<decltype(rdata)>(addr);
mov_rdata(data, to_write);

View File

@ -47,7 +47,7 @@ error_code sys_rsx_memory_allocate(vm::ptr<u32> mem_handle, vm::ptr<u64> mem_add
sys_rsx.warning("sys_rsx_memory_allocate(mem_handle=*0x%x, mem_addr=*0x%x, size=0x%x, flags=0x%llx, a5=0x%llx, a6=0x%llx, a7=0x%llx)", mem_handle, mem_addr, size, flags, a5, a6, a7);
*mem_handle = 0x5a5a5a5b;
*mem_addr = vm::falloc(0xC0000000, size, vm::video);
*mem_addr = vm::falloc(rsx::constants::local_mem_base, size, vm::video);
return CELL_OK;
}
@ -145,10 +145,9 @@ error_code sys_rsx_context_allocate(vm::ptr<u32> context_id, vm::ptr<u64> lpar_d
const auto render = rsx::get_current_renderer();
render->display_buffers_count = 0;
render->current_display_buffer = 0;
render->main_mem_addr = 0;
render->label_addr = *lpar_reports;
render->ctxt_addr = m_sysrsx->rsx_context_addr;
render->init(0, 0, *lpar_dma_control, 0xC0000000);
render->init(*lpar_dma_control);
return CELL_OK;
}
@ -176,8 +175,8 @@ error_code sys_rsx_context_iomap(u32 context_id, u32 io, u32 ea, u32 size, u64 f
{
sys_rsx.warning("sys_rsx_context_iomap(context_id=0x%x, io=0x%x, ea=0x%x, size=0x%x, flags=0x%llx)", context_id, io, ea, size, flags);
if (!size || io & 0xFFFFF || ea >= 0xC0000000 || ea & 0xFFFFF || size & 0xFFFFF ||
rsx::get_current_renderer()->main_mem_size < io + size)
if (!size || io & 0xFFFFF || ea + u64{size} >= rsx::constants::local_mem_base || ea & 0xFFFFF || size & 0xFFFFF ||
rsx::get_current_renderer()->main_mem_size < io + u64{size})
{
return CELL_EINVAL;
}
@ -213,7 +212,7 @@ error_code sys_rsx_context_iounmap(u32 context_id, u32 io, u32 size)
{
sys_rsx.warning("sys_rsx_context_iounmap(context_id=0x%x, io=0x%x, size=0x%x)", context_id, io, size);
if (!size || rsx::get_current_renderer()->main_mem_size < io + size)
if (!size || size & 0xFFFFF || io & 0xFFFFF || rsx::get_current_renderer()->main_mem_size < io + u64{size})
{
return CELL_EINVAL;
}

View File

@ -94,7 +94,7 @@ void sys_spu_image::deploy(u32 loc, sys_spu_segment* segs, u32 nsegs)
std::memcpy(vm::base(loc + seg.ls), vm::base(seg.addr), seg.size);
sha1_update(&sha, (uchar*)&seg.size, sizeof(seg.size));
sha1_update(&sha, (uchar*)&seg.ls, sizeof(seg.ls));
sha1_update(&sha, vm::g_base_addr + seg.addr, seg.size);
sha1_update(&sha, vm::_ptr<uchar>(seg.addr), seg.size);
}
else if (seg.type == SYS_SPU_SEGMENT_TYPE_FILL)
{
@ -127,12 +127,12 @@ void sys_spu_image::deploy(u32 loc, sys_spu_segment* segs, u32 nsegs)
}
// Apply the patch
auto applied = fxm::check_unlocked<patch_engine>()->apply(hash, vm::g_base_addr + loc);
auto applied = fxm::check_unlocked<patch_engine>()->apply(hash, vm::_ptr<u8>(loc));
if (!Emu.GetTitleID().empty())
{
// Alternative patch
applied += fxm::check_unlocked<patch_engine>()->apply(Emu.GetTitleID() + '-' + hash, vm::g_base_addr + loc);
applied += fxm::check_unlocked<patch_engine>()->apply(Emu.GetTitleID() + '-' + hash, vm::_ptr<u8>(loc));
}
LOG_NOTICE(LOADER, "Loaded SPU image: %s (<- %u)%s", hash, applied, dump);

View File

@ -310,7 +310,7 @@ namespace vm
{
for (u64 i = 0;; i++)
{
if (LIKELY(!atomic_storage<u64>::bts(res.raw(), 0)))
if (LIKELY(!res.bts(0)))
{
break;
}
@ -750,7 +750,7 @@ namespace vm
const u32 size = ::align(orig_size, min_page_size);
// return if addr or size is invalid
if (!size || size > this->size || addr < this->addr || addr + size - 1 > this->addr + this->size - 1 || flags & 0x10)
if (!size || addr < this->addr || addr + u64{size} > this->addr + this->size || flags & 0x10)
{
return 0;
}
@ -823,7 +823,7 @@ namespace vm
std::pair<u32, std::shared_ptr<utils::shm>> block_t::get(u32 addr, u32 size)
{
if (addr < this->addr || std::max<u32>(size, addr - this->addr + size) >= this->size)
if (addr < this->addr || addr + u64{size} > this->addr + this->size)
{
return {addr, nullptr};
}

View File

@ -36,7 +36,7 @@ namespace vm
{
auto& res = vm::reservation_acquire(addr, size);
if (UNLIKELY(atomic_storage<u64>::bts(res.raw(), 0)))
if (UNLIKELY(res.bts(0)))
{
reservation_lock_internal(res);
}

View File

@ -330,7 +330,7 @@ namespace rsx
rsx->read_barrier(src_addr, in_pitch * (line_count - 1) + line_length);
const u8* src = (u8*)vm::base(src_addr);
const u8* src = vm::_ptr<u8>(src_addr);
frame_capture_data::memory_block block;
block.offset = src_offset;

View File

@ -32,27 +32,27 @@ namespace rsx
const u32 contextAddr = vm::alloc(sizeof(rsx_context), vm::main);
if (contextAddr == 0)
fmt::throw_exception("Capture Replay: context alloc failed");
const auto& contextInfo = vm::_ref<rsx_context>(contextAddr);
const auto contextInfo = vm::ptr<rsx_context>::make(contextAddr);
// 'fake' initialize usermemory
sys_memory_allocate(buffer_size, SYS_MEMORY_PAGE_SIZE_1M, vm::get_addr(&contextInfo.user_addr));
verify(HERE), (user_mem_addr = contextInfo.user_addr) != 0;
sys_memory_allocate(buffer_size, SYS_MEMORY_PAGE_SIZE_1M, contextInfo.ptr(&rsx_context::user_addr));
verify(HERE), (user_mem_addr = contextInfo->user_addr) != 0;
if (sys_rsx_device_map(vm::get_addr(&contextInfo.dev_addr), vm::null, 0x8) != CELL_OK)
if (sys_rsx_device_map(contextInfo.ptr(&rsx_context::dev_addr), vm::null, 0x8) != CELL_OK)
fmt::throw_exception("Capture Replay: sys_rsx_device_map failed!");
if (sys_rsx_memory_allocate(vm::get_addr(&contextInfo.mem_handle), vm::get_addr(&contextInfo.mem_addr), 0x0F900000, 0, 0, 0, 0) != CELL_OK)
if (sys_rsx_memory_allocate(contextInfo.ptr(&rsx_context::mem_handle), contextInfo.ptr(&rsx_context::mem_addr), 0x0F900000, 0, 0, 0, 0) != CELL_OK)
fmt::throw_exception("Capture Replay: sys_rsx_memory_allocate failed!");
if (sys_rsx_context_allocate(vm::get_addr(&contextInfo.context_id), vm::get_addr(&contextInfo.dma_addr), vm::get_addr(&contextInfo.driver_info), vm::get_addr(&contextInfo.reports_addr), contextInfo.mem_handle, 0) != CELL_OK)
if (sys_rsx_context_allocate(contextInfo.ptr(&rsx_context::context_id), contextInfo.ptr(&rsx_context::dma_addr), contextInfo.ptr(&rsx_context::driver_info), contextInfo.ptr(&rsx_context::reports_addr), contextInfo->mem_handle, 0) != CELL_OK)
fmt::throw_exception("Capture Replay: sys_rsx_context_allocate failed!");
get_current_renderer()->main_mem_size = buffer_size;
if (sys_rsx_context_iomap(contextInfo.context_id, 0, user_mem_addr, buffer_size, 0) != CELL_OK)
if (sys_rsx_context_iomap(contextInfo->context_id, 0, user_mem_addr, buffer_size, 0) != CELL_OK)
fmt::throw_exception("Capture Replay: rsx io mapping failed!");
return contextInfo.context_id;
return contextInfo->context_id;
}
std::vector<u32> rsx_replay_thread::alloc_write_fifo(be_t<u32> context_id)

View File

@ -206,13 +206,13 @@ namespace rsx
}
// Memory partition check
if (mem_range.start >= 0xc0000000)
if (mem_range.start >= constants::local_mem_base)
{
if (e.first < 0xc0000000) continue;
if (e.first < constants::local_mem_base) continue;
}
else
{
if (e.first >= 0xc0000000) continue;
if (e.first >= constants::local_mem_base) continue;
}
// Pitch check

View File

@ -53,8 +53,7 @@ namespace rsx
case CELL_GCM_CONTEXT_DMA_MEMORY_FRAME_BUFFER:
case CELL_GCM_LOCATION_LOCAL:
{
// TODO: Don't use unnamed constants like 0xC0000000
return 0xC0000000 + offset;
return rsx::constants::local_mem_base + offset;
}
case CELL_GCM_CONTEXT_DMA_MEMORY_HOST_BUFFER:
@ -1747,12 +1746,9 @@ namespace rsx
rsx::method_registers.reset();
}
void thread::init(u32 ioAddress, u32 ioSize, u32 ctrlAddress, u32 localAddress)
void thread::init(u32 ctrlAddress)
{
ctrl = vm::_ptr<RsxDmaControl>(ctrlAddress);
this->ioAddress = ioAddress;
this->ioSize = ioSize;
local_mem_addr = localAddress;
flip_status = CELL_GCM_DISPLAY_FLIP_STATUS_DONE;
memset(display_buffers, 0, sizeof(display_buffers));
@ -1792,27 +1788,7 @@ namespace rsx
address = get_address(tile->offset, location);
}
return{ address, base, tile, (u8*)vm::base(address) };
}
u32 thread::ReadIO32(u32 addr)
{
if (u32 ea = RSXIOMem.RealAddr(addr))
{
return vm::read32(ea);
}
fmt::throw_exception("%s(addr=0x%x): RSXIO memory not mapped" HERE, __FUNCTION__, addr);
}
void thread::WriteIO32(u32 addr, u32 value)
{
if (u32 ea = RSXIOMem.RealAddr(addr))
{
return vm::write32(ea, value);
}
fmt::throw_exception("%s(addr=0x%x): RSXIO memory not mapped" HERE, __FUNCTION__, addr);
return{ address, base, tile, vm::_ptr<u8>(address) };
}
std::pair<u32, u32> thread::calculate_memory_requirements(const vertex_input_layout& layout, u32 first_vertex, u32 vertex_count)
@ -2294,7 +2270,7 @@ namespace rsx
void thread::on_notify_memory_unmapped(u32 address, u32 size)
{
if (!m_rsx_thread_exiting && address < 0xC0000000)
if (!m_rsx_thread_exiting && address < rsx::constants::local_mem_base)
{
u32 ea = address >> 20, io = RSXIOMem.io[ea];

View File

@ -489,7 +489,6 @@ namespace rsx
// I hate this flag, but until hle is closer to lle, its needed
bool isHLE{ false };
u32 ioAddress, ioSize;
u32 flip_status;
int debug_level;
@ -502,7 +501,7 @@ namespace rsx
u32 ctxt_addr;
u32 label_addr;
u32 local_mem_addr, main_mem_addr, main_mem_size{0};
u32 main_mem_size{0};
bool m_rtts_dirty;
bool m_textures_dirty[16];
@ -750,7 +749,7 @@ namespace rsx
public:
void reset();
void init(u32 ioAddress, u32 ioSize, u32 ctrlAddress, u32 localAddress);
void init(u32 ctrlAddress);
tiled_region get_tiled_address(u32 offset, u32 location);
GcmTileInfo *find_tile(u32 offset, u32 location);
@ -758,9 +757,6 @@ namespace rsx
// Emu App/Game flip, only immediately flips when called from rsxthread
void request_emu_flip(u32 buffer);
u32 ReadIO32(u32 addr);
void WriteIO32(u32 addr, u32 value);
void pause();
void unpause();

View File

@ -124,10 +124,7 @@ namespace rsx
res &= -128;
}
if (addr >> 28 != 0x4)
{
vm::reservation_notifier(addr, 4).notify_all();
}
vm::reservation_notifier(addr, 4).notify_all();
}
}
@ -1222,8 +1219,8 @@ namespace rsx
const auto read_address = get_address(src_offset, src_dma);
rsx->read_barrier(read_address, in_pitch * (line_count - 1) + line_length);
u8 *dst = (u8*)vm::base(get_address(dst_offset, dst_dma));
const u8 *src = (u8*)vm::base(read_address);
u8 *dst = vm::_ptr<u8>(get_address(dst_offset, dst_dma));
const u8 *src = vm::_ptr<u8>(read_address);
if (in_pitch == out_pitch && out_pitch == line_length)
{

View File

@ -96,6 +96,9 @@ namespace rsx
{
"vtex0", "vtex1", "vtex2", "vtex3",
};
// Local RSX memory base (known as constant)
static constexpr u32 local_mem_base = 0xC0000000;
}
/**

View File

@ -61,7 +61,7 @@ void breakpoint_list::AddBreakpoint(u32 pc)
const auto cpu = this->cpu.lock();
const u32 cpu_offset = cpu->id_type() != 1 ? static_cast<spu_thread&>(*cpu).offset : 0;
m_disasm->offset = (u8*)vm::base(cpu_offset);
m_disasm->offset = vm::_ptr<u8>(cpu_offset);
m_disasm->disasm(m_disasm->dump_pc = pc);

View File

@ -401,7 +401,7 @@ void Buffer::ShowWindowed()
// TODO: Is there any better way to choose the color buffers
#define SHOW_BUFFER(id) \
{ \
u32 addr = render->local_mem_addr + buffers[id].offset; \
u32 addr = rsx::constants::local_mem_base + buffers[id].offset; \
if (vm::check_addr(addr) && buffers[id].width && buffers[id].height) \
memory_viewer_panel::ShowImage(this, addr, 3, buffers[id].width, buffers[id].height, true); \
return; \
@ -690,7 +690,7 @@ void rsx_debugger::GetBuffers()
for (u32 bufferId=0; bufferId < render->display_buffers_count; bufferId++)
{
auto buffers = render->display_buffers;
u32 RSXbuffer_addr = render->local_mem_addr + buffers[bufferId].offset;
u32 RSXbuffer_addr = rsx::constants::local_mem_base + buffers[bufferId].offset;
if(!vm::check_addr(RSXbuffer_addr))
continue;