mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-25 20:22:30 +01:00
Implement lv2_spu_image
- Improved sys_spu_image_.. error checking - sys_process SYS_SPUIMAGE_OBJECT handling implemented
This commit is contained in:
parent
80827aa31a
commit
0dce6be8cb
@ -23,6 +23,7 @@
|
||||
#include "sys_timer.h"
|
||||
#include "sys_trace.h"
|
||||
#include "sys_fs.h"
|
||||
#include "sys_spu.h"
|
||||
|
||||
|
||||
|
||||
@ -69,7 +70,7 @@ s32 sys_process_get_number_of_object(u32 object, vm::ptr<u32> nump)
|
||||
case SYS_EVENT_QUEUE_OBJECT: *nump = idm_get_count<lv2_obj, lv2_event_queue>(); break;
|
||||
case SYS_EVENT_PORT_OBJECT: *nump = idm_get_count<lv2_obj, lv2_event_port>(); break;
|
||||
case SYS_TRACE_OBJECT: sys_process.error("sys_process_get_number_of_object: object = SYS_TRACE_OBJECT"); *nump = 0; break;
|
||||
case SYS_SPUIMAGE_OBJECT: fmt::throw_exception("SYS_SPUIMAGE_OBJECT" HERE);
|
||||
case SYS_SPUIMAGE_OBJECT: *nump = idm_get_count<lv2_obj, lv2_spu_image>(); break;
|
||||
case SYS_PRX_OBJECT: *nump = idm_get_count<lv2_obj, lv2_prx>(); break;
|
||||
case SYS_SPUPORT_OBJECT: fmt::throw_exception("SYS_SPUPORT_OBJECT" HERE);
|
||||
case SYS_OVERLAY_OBJECT: *nump = idm_get_count<lv2_obj, lv2_overlay>(); break;
|
||||
@ -117,7 +118,7 @@ s32 sys_process_get_id(u32 object, vm::ptr<u32> buffer, u32 size, vm::ptr<u32> s
|
||||
case SYS_EVENT_QUEUE_OBJECT: idm_get_set<lv2_obj, lv2_event_queue>(objects); break;
|
||||
case SYS_EVENT_PORT_OBJECT: idm_get_set<lv2_obj, lv2_event_port>(objects); break;
|
||||
case SYS_TRACE_OBJECT: fmt::throw_exception("SYS_TRACE_OBJECT" HERE);
|
||||
case SYS_SPUIMAGE_OBJECT: fmt::throw_exception("SYS_SPUIMAGE_OBJECT" HERE);
|
||||
case SYS_SPUIMAGE_OBJECT: idm_get_set<lv2_obj, lv2_spu_image>(objects); break;
|
||||
case SYS_PRX_OBJECT: idm_get_set<lv2_obj, lv2_prx>(objects); break;
|
||||
case SYS_SPUPORT_OBJECT: fmt::throw_exception("SYS_SPUPORT_OBJECT" HERE);
|
||||
case SYS_OVERLAY_OBJECT: idm_get_set<lv2_obj, lv2_overlay>(objects); break;
|
||||
|
@ -43,12 +43,15 @@ void sys_spu_image::load(const fs::file& stream)
|
||||
}
|
||||
|
||||
type = SYS_SPU_IMAGE_TYPE_KERNEL;
|
||||
entry_point = obj.header.e_entry;
|
||||
|
||||
nsegs = sys_spu_image::get_nsegs(obj.progs);
|
||||
|
||||
const u32 mem_size = nsegs * sizeof(sys_spu_segment) + ::size32(stream);
|
||||
segs = vm::cast(vm::alloc(mem_size, vm::main));
|
||||
|
||||
// Write ID and save entry
|
||||
entry_point = idm::make<lv2_obj, lv2_spu_image>(+obj.header.e_entry);
|
||||
|
||||
const u32 src = segs.addr() + nsegs * sizeof(sys_spu_segment);
|
||||
|
||||
stream.seek(0);
|
||||
@ -158,7 +161,19 @@ error_code _sys_spu_image_get_information(ppu_thread& ppu, vm::ptr<sys_spu_image
|
||||
|
||||
sys_spu.warning("_sys_spu_image_get_information(img=*0x%x, entry_point=*0x%x, nsegs=*0x%x)", img, entry_point, nsegs);
|
||||
|
||||
*entry_point = img->entry_point;
|
||||
if (img->type != SYS_SPU_IMAGE_TYPE_KERNEL)
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
const auto image = idm::get<lv2_obj, lv2_spu_image>(img->entry_point);
|
||||
|
||||
if (!image)
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
*entry_point = image->e_entry;
|
||||
*nsegs = img->nsegs;
|
||||
return CELL_OK;
|
||||
}
|
||||
@ -178,7 +193,6 @@ error_code sys_spu_image_open(ppu_thread& ppu, vm::ptr<sys_spu_image> img, vm::c
|
||||
}
|
||||
|
||||
img->load(elf_file);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@ -198,6 +212,16 @@ error_code _sys_spu_image_close(ppu_thread& ppu, vm::ptr<sys_spu_image> img)
|
||||
|
||||
sys_spu.warning("_sys_spu_image_close(img=*0x%x)", img);
|
||||
|
||||
if (img->type != SYS_SPU_IMAGE_TYPE_KERNEL)
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
if (!idm::remove<lv2_obj, lv2_spu_image>(img->entry_point))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
vm::dealloc(img->segs.addr(), vm::main);
|
||||
return CELL_OK;
|
||||
}
|
||||
@ -236,11 +260,31 @@ error_code sys_spu_thread_initialize(ppu_thread& ppu, vm::ptr<u32> thread, u32 g
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
if (img->type != SYS_SPU_IMAGE_TYPE_KERNEL && img->type != SYS_SPU_IMAGE_TYPE_USER)
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
if (group->threads[spu_num] || group->run_state != SPU_THREAD_GROUP_STATUS_NOT_INITIALIZED)
|
||||
{
|
||||
return CELL_EBUSY;
|
||||
}
|
||||
|
||||
sys_spu_image image = *img;
|
||||
|
||||
if (img->type == SYS_SPU_IMAGE_TYPE_KERNEL)
|
||||
{
|
||||
const auto handle = idm::get<lv2_obj, lv2_spu_image>(img->entry_point);
|
||||
|
||||
if (!handle)
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
// Save actual entry point
|
||||
image.entry_point = handle->e_entry;
|
||||
}
|
||||
|
||||
if (u32 option = attr->option)
|
||||
{
|
||||
sys_spu.todo("Unimplemented SPU Thread options (0x%x)", option);
|
||||
@ -266,7 +310,7 @@ error_code sys_spu_thread_initialize(ppu_thread& ppu, vm::ptr<u32> thread, u32 g
|
||||
*thread = tid;
|
||||
|
||||
group->args[spu_num] = {arg->arg1, arg->arg2, arg->arg3, arg->arg4};
|
||||
group->imgs[spu_num] = std::make_pair(*img, std::vector<sys_spu_segment>());
|
||||
group->imgs[spu_num] = std::make_pair(image, std::vector<sys_spu_segment>());
|
||||
group->imgs[spu_num].second.assign(img->segs.get_ptr(), img->segs.get_ptr() + img->nsegs);
|
||||
|
||||
if (++group->init == group->max_num)
|
||||
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "sys_sync.h"
|
||||
#include "sys_event.h"
|
||||
#include "Emu/Cell/SPUThread.h"
|
||||
|
||||
@ -112,7 +113,7 @@ enum : u32
|
||||
struct sys_spu_image
|
||||
{
|
||||
be_t<u32> type; // user, kernel
|
||||
be_t<u32> entry_point;
|
||||
be_t<u32> entry_point; // Note: in kernel mode it's used to store id
|
||||
vm::bptr<sys_spu_segment> segs;
|
||||
be_t<s32> nsegs;
|
||||
|
||||
@ -210,6 +211,18 @@ enum : u32
|
||||
SYS_SPU_IMAGE_DIRECT = 1,
|
||||
};
|
||||
|
||||
struct lv2_spu_image : lv2_obj
|
||||
{
|
||||
static const u32 id_base = 0x22000000;
|
||||
|
||||
const u32 e_entry;
|
||||
|
||||
lv2_spu_image(u32 entry)
|
||||
: e_entry(entry)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct lv2_spu_group
|
||||
{
|
||||
static const u32 id_base = 0x04000100;
|
||||
|
Loading…
Reference in New Issue
Block a user