rsx: Verify local memory offset

This commit is contained in:
Eladash 2020-01-14 15:50:53 +02:00 committed by kd-11
commit 1ccb3c4492
4 changed files with 39 additions and 8 deletions

View file

@ -428,6 +428,7 @@ s32 _cellGcmInitBody(ppu_thread& ppu, vm::pptr<CellGcmContextData> context, u32
render->isHLE = true;
render->label_addr = gcm_cfg->gcm_info.label_addr;
render->device_addr = gcm_cfg->gcm_info.context_addr;
render->local_mem_size = local_size;
render->init(gcm_cfg->gcm_info.control_addr - 0x40);
return CELL_OK;

View file

@ -210,6 +210,7 @@ error_code sys_rsx_context_allocate(vm::ptr<u32> context_id, vm::ptr<u64> lpar_d
render->current_display_buffer = 0;
render->label_addr = *lpar_reports;
render->device_addr = rsx_cfg->device_addr;
render->local_mem_size = rsx_cfg->memory_size;
render->init(*lpar_dma_control);
rsx_cfg->context_base = context_base;

View file

@ -48,13 +48,19 @@ namespace rsx
u32 get_address(u32 offset, u32 location)
{
const auto render = get_current_renderer();
switch (location)
{
case CELL_GCM_CONTEXT_DMA_MEMORY_FRAME_BUFFER:
case CELL_GCM_LOCATION_LOCAL:
{
return rsx::constants::local_mem_base + offset;
if (offset < render->local_mem_size)
{
return rsx::constants::local_mem_base + offset;
}
fmt::throw_exception("GetAddress(offset=0x%x, location=0x%x): Local RSX offset out of range" HERE, offset, location);
}
case CELL_GCM_CONTEXT_DMA_MEMORY_HOST_BUFFER:
@ -69,7 +75,14 @@ namespace rsx
}
case CELL_GCM_CONTEXT_DMA_REPORT_LOCATION_LOCAL:
return get_current_renderer()->label_addr + 0x1400 + offset;
{
if (offset < sizeof(RsxReports::report) /*&& (offset % 0x10) == 0*/)
{
return render->label_addr + 0x1400 + offset;
}
fmt::throw_exception("GetAddress(offset=0x%x, location=0x%x): Local RSX REPORT offset out of range" HERE, offset, location);
}
case CELL_GCM_CONTEXT_DMA_REPORT_LOCATION_MAIN:
{
@ -81,21 +94,36 @@ namespace rsx
fmt::throw_exception("GetAddress(offset=0x%x, location=0x%x): RSXIO memory not mapped" HERE, offset, location);
}
// They are handled elsewhere for targeted methods, so it's unexpected for them to be passed here
case CELL_GCM_CONTEXT_DMA_TO_MEMORY_GET_NOTIFY0:
fmt::throw_exception("Unimplemented CELL_GCM_CONTEXT_DMA_TO_MEMORY_GET_NOTIFY0 (offset=0x%x, location=0x%x)" HERE, offset, location);
fmt::throw_exception("Unexpected CELL_GCM_CONTEXT_DMA_TO_MEMORY_GET_NOTIFY0 (offset=0x%x, location=0x%x)" HERE, offset, location);
case CELL_GCM_CONTEXT_DMA_NOTIFY_MAIN_0:
fmt::throw_exception("Unimplemented CELL_GCM_CONTEXT_DMA_NOTIFY_MAIN_0 (offset=0x%x, location=0x%x)" HERE, offset, location);
fmt::throw_exception("Unexpected CELL_GCM_CONTEXT_DMA_NOTIFY_MAIN_0 (offset=0x%x, location=0x%x)" HERE, offset, location);
case CELL_GCM_CONTEXT_DMA_SEMAPHORE_RW:
case CELL_GCM_CONTEXT_DMA_SEMAPHORE_R:
return get_current_renderer()->label_addr + offset;
{
if (offset < sizeof(RsxReports::semaphore) /*&& (offset % 0x10) == 0*/)
{
return render->label_addr + offset;
}
fmt::throw_exception("GetAddress(offset=0x%x, location=0x%x): DMA SEMAPHORE offset out of range" HERE, offset, location);
}
case CELL_GCM_CONTEXT_DMA_DEVICE_RW:
return get_current_renderer()->device_addr + offset;
case CELL_GCM_CONTEXT_DMA_DEVICE_R:
return get_current_renderer()->device_addr + offset;
{
if (offset < 0x100000 /*&& (offset % 0x10) == 0*/)
{
return render->device_addr + offset;
}
// TODO: What happens here? It could wrap around or access other segments of rsx internal memory etc
// Or can simply throw access violation error
fmt::throw_exception("GetAddress(offset=0x%x, location=0x%x): DMA DEVICE offset out of range" HERE, offset, location);
}
default:
{

View file

@ -656,6 +656,7 @@ namespace rsx
u32 label_addr;
u32 main_mem_size{0};
u32 local_mem_size{0};
bool m_rtts_dirty;
bool m_textures_dirty[16];