Esempio n. 1
0
//190
int sys_spu_thread_write_spu_mb(u32 id, u32 value)
{
	sc_spu.Warning("sys_spu_thread_write_spu_mb(id=%d, value=0x%x)", id, value);

	CPUThread* thr = Emu.GetCPU().GetThread(id);

	if(!thr || (thr->GetType() != CPU_THREAD_SPU && thr->GetType() != CPU_THREAD_RAW_SPU))
	{
		return CELL_ESRCH;
	}

	(*(SPUThread*)thr).SPU.In_MBox.PushUncond(value);

	return CELL_OK;
}
Esempio n. 2
0
//188
int sys_spu_thread_get_spu_cfg(u32 id, mem64_t value)
{
	sc_spu.Warning("sys_spu_thread_get_spu_cfg(id=0x%x, value_addr=0x%x)", id, value.GetAddr());

	CPUThread* thr = Emu.GetCPU().GetThread(id);

	if(!thr || (thr->GetType() != CPU_THREAD_SPU && thr->GetType() != CPU_THREAD_RAW_SPU))
	{
		return CELL_ESRCH;
	}

	value = (*(SPUThread*)thr).cfg.value;

	return CELL_OK;
}
Esempio n. 3
0
//181
int sys_spu_thread_write_ls(u32 id, u32 address, u64 value, u32 type)
{
	sc_spu.Warning("sys_spu_thread_write_ls(id=0x%x, address=0x%x, value=0x%llx, type=0x%x)",
		id, address, value, type);

	CPUThread* thr = Emu.GetCPU().GetThread(id);

	if(!thr || (thr->GetType() != CPU_THREAD_SPU && thr->GetType() != CPU_THREAD_RAW_SPU))
	{
		return CELL_ESRCH;
	}

	(*(SPUThread*)thr).WriteLS64(address, value);

	return CELL_OK;
}
Esempio n. 4
0
s32 sys_spu_thread_connect_event(u32 id, u32 eq_id, u32 et, u8 spup)
{
	sc_spu.Warning("sys_spu_thread_connect_event(id=%d, eq_id=%d, event_type=0x%x, spup=%d)", id, eq_id, et, spup);

	CPUThread* thr = Emu.GetCPU().GetThread(id);

	if(!thr || (thr->GetType() != CPU_THREAD_SPU && thr->GetType() != CPU_THREAD_RAW_SPU))
	{
		return CELL_ESRCH;
	}

	EventQueue* eq;
	if (!Emu.GetIdManager().GetIDData(eq_id, eq))
	{
		return CELL_ESRCH;
	}

	if (spup > 63)
	{
		sc_spu.Error("sys_spu_thread_connect_event: invalid spup (%d)", spup);
		return CELL_EINVAL;
	}

	if (et != SYS_SPU_THREAD_EVENT_USER)
	{
		sc_spu.Error("sys_spu_thread_connect_event: unsupported event type (0x%x)", et);
		return CELL_EINVAL;
	}

	// TODO: check if can receive these events

	SPUThread& spu = *(SPUThread*)thr;

	EventPort& port = spu.SPUPs[spup];

	std::lock_guard<std::mutex> lock(port.m_mutex);

	if (port.eq)
	{
		return CELL_EISCONN;
	}

	eq->ports.add(&port);
	port.eq = eq;

	return CELL_OK;
}
Esempio n. 5
0
//182
int sys_spu_thread_read_ls(u32 id, u32 address, mem64_t value, u32 type)
{
    sc_spu.Log("sys_spu_thread_read_ls(id=%d, address=0x%x, value_addr=0x%x, type=0x%x)",
               id, address, value.GetAddr(), type);

    CPUThread* thr = Emu.GetCPU().GetThread(id);

    if(!thr || (thr->GetType() != CPU_THREAD_SPU && thr->GetType() != CPU_THREAD_RAW_SPU))
    {
        return CELL_ESRCH;
    }

    if (!thr->IsRunning())
    {
        return CELL_ESTAT;
    }

    if(!value.IsGood())
    {
        return CELL_EFAULT;
    }

    if (!(*(SPUThread*)thr).IsGoodLSA(address) || (address % type)) // +check alignment
    {
        return CELL_EINVAL;
    }

    switch (type)
    {
    case 1:
        value = (*(SPUThread*)thr).ReadLS8(address);
        return CELL_OK;
    case 2:
        value = (*(SPUThread*)thr).ReadLS16(address);
        return CELL_OK;
    case 4:
        value = (*(SPUThread*)thr).ReadLS32(address);
        return CELL_OK;
    case 8:
        value = (*(SPUThread*)thr).ReadLS64(address);
        return CELL_OK;
    default:
        return CELL_EINVAL;
    }
}
Esempio n. 6
0
s32 sys_spu_thread_unbind_queue(u32 id, u32 spuq_num)
{
	sc_spu.Warning("sys_spu_thread_unbind_queue(id=0x%x, spuq_num=0x%x)", id, spuq_num);

	CPUThread* thr = Emu.GetCPU().GetThread(id);

	if(!thr || (thr->GetType() != CPU_THREAD_SPU && thr->GetType() != CPU_THREAD_RAW_SPU))
	{
		return CELL_ESRCH;
	}

	if (!(*(SPUThread*)thr).SPUQs.UnregisterKey(FIX_SPUQ(spuq_num)))
	{
		return CELL_ESRCH; // may be CELL_EINVAL
	}

	return CELL_OK;
}
Esempio n. 7
0
//184
s32 sys_spu_thread_write_snr(u32 id, u32 number, u32 value)
{
	sc_spu.Log("sys_spu_thread_write_snr(id=%d, number=%d, value=0x%x)", id, number, value);
	CPUThread* thr = Emu.GetCPU().GetThread(id);

	if(!thr || (thr->GetType() != CPU_THREAD_SPU && thr->GetType() != CPU_THREAD_RAW_SPU))
	{
		return CELL_ESRCH;
	}

	if (number > 1)
	{
		return CELL_EINVAL;
	}

	(*(SPUThread*)thr).WriteSNR(number, value);

	return CELL_OK;
}
Esempio n. 8
0
//190
int sys_spu_thread_write_spu_mb(u32 id, u32 value)
{
	sc_spu.Warning("sys_spu_thread_write_spu_mb(id=0x%x, value=0x%x)", id, value);

	CPUThread* thr = Emu.GetCPU().GetThread(id);

	if(!thr || (thr->GetType() != CPU_THREAD_SPU && thr->GetType() != CPU_THREAD_RAW_SPU))
	{
		return CELL_ESRCH;
	}

	if(!(*(SPUThread*)thr).SPU.In_MBox.Push(value))
	{
		ConLog.Warning("sys_spu_thread_write_spu_mb(id=0x%x, value=0x%x): used all mbox items.");
		return CELL_EBUSY; //?
	}

	return CELL_OK;
}
Esempio n. 9
0
//187
s32 sys_spu_thread_set_spu_cfg(u32 id, u64 value)
{
	sc_spu.Warning("sys_spu_thread_set_spu_cfg(id=%d, value=0x%x)", id, value);

	CPUThread* thr = Emu.GetCPU().GetThread(id);

	if(!thr || (thr->GetType() != CPU_THREAD_SPU && thr->GetType() != CPU_THREAD_RAW_SPU))
	{
		return CELL_ESRCH;
	}

	if (value > 3)
	{
		return CELL_EINVAL;
	}

	(*(SPUThread*)thr).cfg.value = value;

	return CELL_OK;
}
Esempio n. 10
0
//182
int sys_spu_thread_read_ls(u32 id, u32 address, mem64_t value, u32 type)
{
	sc_spu.Warning("sys_spu_thread_read_ls(id=0x%x, address=0x%x, value_addr=0x%x, type=0x%x)",
		id, address, value.GetAddr(), type);

	CPUThread* thr = Emu.GetCPU().GetThread(id);

	if(!thr || (thr->GetType() != CPU_THREAD_SPU && thr->GetType() != CPU_THREAD_RAW_SPU))
	{
		return CELL_ESRCH;
	}

	if(!value.IsGood() || !(*(SPUThread*)thr).IsGoodLSA(address))
	{
		return CELL_EFAULT;
	}

	value = (*(SPUThread*)thr).ReadLS64(address);

	return CELL_OK;
}
Esempio n. 11
0
//181
int sys_spu_thread_write_ls(u32 id, u32 address, u64 value, u32 type)
{
    sc_spu.Log("sys_spu_thread_write_ls(id=%d, address=0x%x, value=0x%llx, type=0x%x)",
               id, address, value, type);

    CPUThread* thr = Emu.GetCPU().GetThread(id);

    if(!thr || (thr->GetType() != CPU_THREAD_SPU && thr->GetType() != CPU_THREAD_RAW_SPU))
    {
        return CELL_ESRCH;
    }

    if (!thr->IsRunning())
    {
        return CELL_ESTAT;
    }

    if (!(*(SPUThread*)thr).IsGoodLSA(address) || (address % type)) // +check alignment
    {
        return CELL_EINVAL;
    }

    switch (type)
    {
    case 1:
        (*(SPUThread*)thr).WriteLS8(address, value);
        return CELL_OK;
    case 2:
        (*(SPUThread*)thr).WriteLS16(address, value);
        return CELL_OK;
    case 4:
        (*(SPUThread*)thr).WriteLS32(address, value);
        return CELL_OK;
    case 8:
        (*(SPUThread*)thr).WriteLS64(address, value);
        return CELL_OK;
    default:
        return CELL_EINVAL;
    }
}
Esempio n. 12
0
s32 sys_spu_thread_disconnect_event(u32 id, u32 et, u8 spup)
{
	sc_spu.Warning("sys_spu_thread_disconnect_event(id=%d, event_type=0x%x, spup=%d)", id, et, spup);

	CPUThread* thr = Emu.GetCPU().GetThread(id);

	if(!thr || (thr->GetType() != CPU_THREAD_SPU && thr->GetType() != CPU_THREAD_RAW_SPU))
	{
		return CELL_ESRCH;
	}

	if (spup > 63)
	{
		sc_spu.Error("sys_spu_thread_connect_event: invalid spup (%d)", spup);
		return CELL_EINVAL;
	}

	if (et != SYS_SPU_THREAD_EVENT_USER)
	{
		sc_spu.Error("sys_spu_thread_connect_event: unsupported event type (0x%x)", et);
		return CELL_EINVAL;
	}

	SPUThread& spu = *(SPUThread*)thr;

	EventPort& port = spu.SPUPs[spup];

	std::lock_guard<std::mutex> lock(port.m_mutex);

	if (!port.eq)
	{
		return CELL_ENOTCONN;
	}

	port.eq->ports.remove(&port);
	port.eq = nullptr;

	return CELL_OK;
}
Esempio n. 13
0
//166
s32 sys_spu_thread_set_argument(u32 id, mem_ptr_t<sys_spu_thread_argument> arg)
{
	sc_spu.Warning("sys_spu_thread_set_argument(id=%d, arg_addr=0x%x)", id, arg.GetAddr());
	CPUThread* thr = Emu.GetCPU().GetThread(id);

	if(!thr || (thr->GetType() != CPU_THREAD_SPU && thr->GetType() != CPU_THREAD_RAW_SPU))
	{
		return CELL_ESRCH;
	}

	if(!arg.IsGood())
	{
		return CELL_EFAULT;
	}

	thr->SetArg(0, arg->arg1);
	thr->SetArg(1, arg->arg2);
	thr->SetArg(2, arg->arg3);
	thr->SetArg(3, arg->arg4);

	return CELL_OK;
}
Esempio n. 14
0
s32 sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq_id, u64 req, mem8_t spup)
{
	sc_spu.Warning("sys_spu_thread_group_connect_event_all_threads(id=%d, eq_id=%d, req=0x%llx, spup_addr=0x%x)",
		id, eq_id, req, spup.GetAddr());

	if (!spup.IsGood())
	{
		return CELL_EFAULT;
	}

	EventQueue* eq;
	if (!Emu.GetIdManager().GetIDData(eq_id, eq))
	{
		return CELL_ESRCH;
	}

	if (!req)
	{
		return CELL_EINVAL;
	}

	SpuGroupInfo* group;
	if (!Emu.GetIdManager().GetIDData(id, group))
	{
		return CELL_ESRCH;
	}

	std::vector<SPUThread*> threads;
	for (auto& v : group->list)
	{
		if (!v) continue;
		CPUThread* thr = Emu.GetCPU().GetThread(v);
		if (thr->GetType() != CPU_THREAD_SPU)
		{
			sc_spu.Error("sys_spu_thread_group_connect_event_all_threads(): CELL_ESTAT (wrong thread type)");
			return CELL_ESTAT;
		}
		threads.push_back((SPUThread*)thr);
	}

	if (threads.size() != group->m_count)
	{
		sc_spu.Error("sys_spu_thread_group_connect_event_all_threads(): CELL_ESTAT (%d from %d)", (u32)threads.size(), group->m_count);
		return CELL_ESTAT;
	}

	for (u32 i = 0; i < 64; i++) // port number
	{
		bool found = true;
		if (req & (1ull << i))
		{
			for (auto& t : threads) t->SPUPs[i].m_mutex.lock();

			for (auto& t : threads) if (t->SPUPs[i].eq) found = false;

			if (found)
			{
				for (auto& t : threads)
				{
					eq->ports.add(&(t->SPUPs[i]));
					t->SPUPs[i].eq = eq;
				}
				spup = (u8)i;
			}

			for (auto& t : threads) t->SPUPs[i].m_mutex.unlock();
		}
		else
		{
			found = false;
		}

		if (found) return CELL_OK;
	}

	return CELL_EISCONN;
}