Ejemplo n.º 1
0
s32 sys_spu_thread_group_start(u32 id)
{
	sys_spu.warning("sys_spu_thread_group_start(id=0x%x)", id);

	LV2_LOCK;

	const auto group = idm::get<lv2_spu_group_t>(id);

	if (!group)
	{
		return CELL_ESRCH;
	}

	if (group->state != SPU_THREAD_GROUP_STATUS_INITIALIZED)
	{
		return CELL_ESTAT;
	}

	// SPU_THREAD_GROUP_STATUS_READY state is not used

	group->state = SPU_THREAD_GROUP_STATUS_RUNNING;
	group->join_state = 0;

	for (auto& t : group->threads)
	{
		if (t)
		{
			if (t->index >= group->threads.size())
			{
				throw EXCEPTION("Unexpected SPU thread index (%d)", t->index);
			}

			auto& args = group->args[t->index];
			auto& image = group->images[t->index];

			// Copy SPU image:
			// TODO: use segment info
			std::memcpy(vm::base(t->offset), image->segs.get_ptr(), 256 * 1024);

			t->pc = image->entry_point;
			t->cpu_init();
			t->gpr[3] = v128::from64(0, args.arg1);
			t->gpr[4] = v128::from64(0, args.arg2);
			t->gpr[5] = v128::from64(0, args.arg3);
			t->gpr[6] = v128::from64(0, args.arg4);

			t->status.exchange(SPU_STATUS_RUNNING);
		}
	}

	// because SPU_THREAD_GROUP_STATUS_READY is not possible, run event is delivered immediately

	group->send_run_event(lv2_lock, id, 0, 0); // TODO: check data2 and data3

	for (auto& thread : group->threads)
	{
		if (thread)
		{
			thread->state -= cpu_state::stop;
			(*thread)->lock_notify();
		}
	}

	return CELL_OK;
}
Ejemplo n.º 2
0
s32 sys_spu_thread_group_start(u32 id)
{
    sys_spu.Warning("sys_spu_thread_group_start(id=0x%x)", id);

    LV2_LOCK;

    const auto group = Emu.GetIdManager().get<spu_group_t>(id);

    if (!group)
    {
        return CELL_ESRCH;
    }

    if (group->state != SPU_THREAD_GROUP_STATUS_INITIALIZED)
    {
        return CELL_ESTAT;
    }

    // SPU_THREAD_GROUP_STATUS_READY state is not used

    group->state = SPU_THREAD_GROUP_STATUS_RUNNING;
    group->join_state = 0;

    for (auto& t : group->threads)
    {
        if (t)
        {
            if (t->index >= group->threads.size())
            {
                throw EXCEPTION("Unexpected SPU thread index (%d)", t->index);
            }

            auto& args = group->args[t->index];
            auto& image = group->images[t->index];

            // Copy SPU image:
            // TODO: use segment info
            std::memcpy(vm::get_ptr<void>(t->offset), vm::get_ptr<void>(image->addr), 256 * 1024);

            t->PC = image->entry_point;
            t->Run();
            t->GPR[3] = u128::from64(0, args.arg1);
            t->GPR[4] = u128::from64(0, args.arg2);
            t->GPR[5] = u128::from64(0, args.arg3);
            t->GPR[6] = u128::from64(0, args.arg4);

            t->status.exchange(SPU_STATUS_RUNNING);
        }
    }

    // because SPU_THREAD_GROUP_STATUS_READY is not possible, run event is delivered immediately

    group->send_run_event(lv2_lock, id, 0, 0); // TODO: check data2 and data3

    for (auto& t : group->threads)
    {
        if (t) t->Exec();
    }

    return CELL_OK;
}