Example #1
0
int UTF16stoUTF8s(mem16_ptr_t utf16, mem64_t utf16_len, mem8_ptr_t utf8, mem64_t utf8_len)
{
	cellL10n.Warning("UTF16stoUTF8s(utf16_addr=0x%x, utf16_len_addr=0x%x, utf8_addr=0x%x, utf8_len_addr=0x%x)",
		utf16.GetAddr(), utf16_len.GetAddr(), utf8.GetAddr(), utf8_len.GetAddr());

	if (!utf16.IsGood() || !utf16_len.IsGood() || !utf8_len.IsGood())
		return SRCIllegal;

	std::u16string wstr =(char16_t*)Memory.VirtualToRealAddr(utf16);
	wstr.resize(utf16_len.GetValue()); // TODO: Is this really the role of utf16_len in this function?
#ifdef _MSC_VER
	std::wstring_convert<std::codecvt_utf8_utf16<char16_t>,char16_t> convert;
	std::string str = convert.to_bytes(wstr);

	if (!utf8.IsGood() || utf8_len.GetValue() < str.size())
	{
		utf8_len = str.size();
		return DSTExhausted;
	}

	utf8_len = str.size();
	Memory.WriteString(utf8, str.c_str());
#endif
	return ConversionOK;
}
Example #2
0
int UTF16stoUTF8s(mem16_ptr_t utf16, mem64_t utf16_len, mem8_ptr_t utf8, mem64_t utf8_len)
{
	cellL10n.Warning("UTF16stoUTF8s(utf16_addr=0x%x, utf16_len_addr=0x%x, utf8_addr=0x%x, utf8_len_addr=0x%x)",
		utf16.GetAddr(), utf16_len.GetAddr(), utf8.GetAddr(), utf8_len.GetAddr());

	if (!utf16.IsGood() || !utf16_len.IsGood() || !utf8_len.IsGood())
		return SRCIllegal;

	std::wstring wstr = (wchar_t*)Memory.VirtualToRealAddr(utf16);
	std::string str;

	int len = min((int)utf16_len.GetValue(), (int)wstr.size());
	int size = (int)WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), len, 0, 0, NULL, NULL);

	if (!utf8.IsGood())
		utf8_len = size;
	if (utf8_len.GetValue() < size)
		return DSTExhausted;

#ifdef WIN32
	WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), len, &str[0], size, NULL, NULL);
#else
	// TODO
#endif

	Memory.WriteString(utf8, str);
	return ConversionOK;
}
Example #3
0
int sys_event_flag_trywait(u32 eflag_id, u64 bitptn, u32 mode, mem64_t result)
{
	sys_event_flag.Warning("sys_event_flag_trywait(eflag_id=%d, bitptn=0x%llx, mode=0x%x, result_addr=0x%x)",
		eflag_id, bitptn, mode, result.GetAddr());

	if (result.IsGood()) result = 0;

	switch (mode & 0xf)
	{
	case SYS_EVENT_FLAG_WAIT_AND: break;
	case SYS_EVENT_FLAG_WAIT_OR: break;
	default: return CELL_EINVAL;
	}

	switch (mode & ~0xf)
	{
	case 0: break; // ???
	case SYS_EVENT_FLAG_WAIT_CLEAR: break;
	case SYS_EVENT_FLAG_WAIT_CLEAR_ALL: break;
	default: return CELL_EINVAL;
	}

	EventFlag* ef;
	if(!sys_event_flag.CheckId(eflag_id, ef)) return CELL_ESRCH;

	SMutexLocker lock(ef->m_mutex);

	u64 flags = ef->flags;

	if (((mode & SYS_EVENT_FLAG_WAIT_AND) && (flags & bitptn) == bitptn) ||
		((mode & SYS_EVENT_FLAG_WAIT_OR) && (flags & bitptn)))
	{
		if (mode & SYS_EVENT_FLAG_WAIT_CLEAR)
		{
			ef->flags &= ~bitptn;
		}
		else if (mode & SYS_EVENT_FLAG_WAIT_CLEAR_ALL)
		{
			ef->flags = 0;
		}

		if (result.IsGood())
		{
			result = flags;
			return CELL_OK;
		}

		if (!result.GetAddr())
		{
			return CELL_OK;
		}
		return CELL_EFAULT;
	}

	return CELL_EBUSY;
}
Example #4
0
int cellFsRead(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nread)
{
	sys_fs.Log("cellFsRead(fd=%d, buf_addr=0x%x, nbytes=0x%llx, nread_addr=0x%x)",
		fd, buf_addr, nbytes, nread.GetAddr());
	vfsStream* file;
	if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH;

	if (nread.GetAddr() && !nread.IsGood()) return CELL_EFAULT;

	u32 res = 0;
	u32 count = nbytes;
	if (nbytes != (u64)count) return CELL_ENOMEM;

	if (!Memory.IsGoodAddr(buf_addr)) return CELL_EFAULT;

	if (count) if (u32 frag = buf_addr & 4095) // memory page fragment
	{
		u32 req = min(count, 4096 - frag);
		u32 read = file->Read(Memory + buf_addr, req);
		buf_addr += req;
		res += read;
		count -= req;
		if (read < req) goto fin;
	}

	for (u32 pages = count / 4096; pages > 0; pages--) // full pages
	{
		if (!Memory.IsGoodAddr(buf_addr)) goto fin; // ??? (probably EFAULT)
		u32 read = file->Read(Memory + buf_addr, 4096);
		buf_addr += 4096;
		res += read;
		count -= 4096;
		if (read < 4096) goto fin;
	}

	if (count) // last fragment
	{
		if (!Memory.IsGoodAddr(buf_addr)) goto fin;
		res += file->Read(Memory + buf_addr, count);
	}

fin:

	if (nread.GetAddr()) nread = res; // write value if not NULL

	return CELL_OK;
}
Example #5
0
File: lv2Fs.cpp Project: Subv/rpcs3
s32 cellFsWrite(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nwrite)
{
	sys_fs->Log("cellFsWrite(fd=%d, buf_addr=0x%x, nbytes=0x%llx, nwrite_addr=0x%x)",
		fd, buf_addr, nbytes, nwrite.GetAddr());
	vfsStream* file;
	if(!sys_fs->CheckId(fd, file)) return CELL_ESRCH;

	if (nbytes != (u32)nbytes) return CELL_ENOMEM;

	// TODO: checks

	const u64 res = nbytes ? file->Write(Memory.GetMemFromAddr(buf_addr), nbytes) : 0;

	if (nwrite.GetAddr()) nwrite = res; // write value if not NULL

	return CELL_OK;
}
Example #6
0
int cellPamfGetStreamOffsetAndSize(mem_ptr_t<PamfHeader> pAddr, u64 fileSize, mem64_t pOffset, mem64_t pSize)
{
	cellPamf.Warning("cellPamfGetStreamOffsetAndSize(pAddr=0x%x, fileSize=%d, pOffset_addr=0x%x, pSize_addr=0x%x)",
		pAddr.GetAddr(), fileSize, pOffset.GetAddr(), pSize.GetAddr());

	if (!pAddr.IsGood() || !pOffset.IsGood() || !pSize.IsGood())
		return CELL_PAMF_ERROR_INVALID_ARG;

	//if ((u32)pAddr->magic != 0x464d4150)
		//return CELL_PAMF_ERROR_UNKNOWN_TYPE;

	const u64 offset = (u64)pAddr->data_offset << 11;
	pOffset = offset;
	const u64 size = (u64)pAddr->data_size << 11;
	pSize = size;
	return CELL_OK;
}
Example #7
0
int cellFsReadWithOffset(u32 fd, u64 offset, u32 buf_addr, u64 buffer_size, mem64_t nread)
{
	sys_fs.Warning("cellFsReadWithOffset(fd=%d, offset=0x%llx, buf_addr=0x%x, buffer_size=%lld nread=0x%llx)",
		fd, offset, buf_addr, buffer_size, nread.GetAddr());

	int ret;
	MemoryAllocator<be_t<u64>> oldPos, newPos;
	ret = cellFsLseek(fd, 0, CELL_SEEK_CUR, oldPos.GetAddr());       // Save the current position
	if (ret) return ret;
	ret = cellFsLseek(fd, offset, CELL_SEEK_SET, newPos.GetAddr());  // Move to the specified offset
	if (ret) return ret;
	ret = cellFsRead(fd, buf_addr, buffer_size, nread.GetAddr());    // Read the file
	if (ret) return ret;
	ret = cellFsLseek(fd, Memory.Read64(oldPos.GetAddr()), CELL_SEEK_SET, newPos.GetAddr());  // Return to the old position
	if (ret) return ret;

	return CELL_OK;
}
Example #8
0
int cellFsStReadGetStatus(u32 fd, mem64_t status)
{
	sys_fs.Warning("cellFsStReadGetRingBuf(fd=%d, status_addr=0x%x)", fd, status.GetAddr());

	vfsStream* file;
	if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH;

	status = m_fs_config.m_fs_status;

	return CELL_OK;
}
Example #9
0
int cellFsStReadGetRegid(u32 fd, mem64_t regid)
{
	sys_fs.Warning("cellFsStReadGetRingBuf(fd=%d, regid_addr=0x%x)", fd, regid.GetAddr());

	vfsStream* file;
	if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH;

	regid = m_fs_config.m_regid;

	return CELL_OK;
}
Example #10
0
int cellFsStRead(u32 fd, u32 buf_addr, u64 size, mem64_t rsize)
{
	sys_fs.Warning("TODO: cellFsStRead(fd=%d, buf_addr=0x%x, size=0x%llx, rsize_addr = 0x%x)", fd, buf_addr, size, rsize.GetAddr());
	
	vfsStream* file;
	if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH;

	if (rsize.GetAddr() && !rsize.IsGood()) return CELL_EFAULT;

	m_fs_config.m_regid += size;
	rsize = m_fs_config.m_regid;

	return CELL_OK;
}
Example #11
0
s32 cellFsRead(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nread)
{
	sys_fs->Log("cellFsRead(fd=%d, buf_addr=0x%x, nbytes=0x%llx, nread_addr=0x%x)",
		fd, buf_addr, nbytes, nread.GetAddr());
	vfsStream* file;
	if(!sys_fs->CheckId(fd, file)) return CELL_ESRCH;

	if (nread.GetAddr() && !nread.IsGood())
	{
		sys_fs->Error("cellFsRead(): bad nread_addr(0x%x)", nread.GetAddr());
		return CELL_EFAULT;
	}

	if (nbytes != (u32)nbytes) return CELL_ENOMEM;

	// TODO: checks

	const u64 res = nbytes ? file->Read(Memory.GetMemFromAddr(buf_addr), nbytes) : 0;

	if (nread.GetAddr()) nread = res; // write value if not NULL

	return CELL_OK;
}
Example #12
0
//188
s32 sys_spu_thread_get_spu_cfg(u32 id, mem64_t value)
{
	sc_spu.Warning("sys_spu_thread_get_spu_cfg(id=%d, 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;
}
Example #13
0
int cellPamfGetHeaderSize2(mem_ptr_t<PamfHeader> pAddr, u64 fileSize, u32 attribute, mem64_t pSize)
{
	cellPamf.Warning("cellPamfGetHeaderSize2(pAddr=0x%x, fileSize=%d, attribute=0x%x, pSize_addr=0x%x)",
		pAddr.GetAddr(), fileSize, attribute, pSize.GetAddr());

	if (!pAddr.IsGood() || !pSize.IsGood())
		return CELL_PAMF_ERROR_INVALID_ARG;

	//if ((u32)pAddr->magic != 0x464d4150)
		//return CELL_PAMF_ERROR_UNKNOWN_TYPE;

	const u64 offset = (u64)pAddr->data_offset << 11;
	pSize = offset;
	return CELL_OK;
}
Example #14
0
File: lv2Fs.cpp Project: Subv/rpcs3
s32 cellFsGetFreeSize(u32 path_addr, mem32_t block_size, mem64_t block_count)
{
	const std::string& ps3_path = Memory.ReadString(path_addr);
	sys_fs->Warning("cellFsGetFreeSize(path=\"%s\", block_size_addr=0x%x, block_count_addr=0x%x)",
		ps3_path.c_str(), block_size.GetAddr(), block_count.GetAddr());

	if (ps3_path.empty())
		return CELL_EINVAL;

	// TODO: Get real values. Currently, it always returns 40 GB of free space divided in 4 KB blocks
	block_size = 4096; // ?
	block_count = 10485760; // ?

	return CELL_OK;
}
Example #15
0
int sceNpTrophyGetRequiredDiskSpace(u32 context, u32 handle, mem64_t reqspace, u64 options)
{
	sceNpTrophy.Warning("sceNpTrophyGetRequiredDiskSpace(context=%d, handle=%d, reqspace_addr=0x%x, options=0x%llx)",
		context, handle, reqspace.GetAddr(), options);

	if (!s_npTrophyInstance.m_bInitialized)
		return SCE_NP_TROPHY_ERROR_NOT_INITIALIZED;
	if (!reqspace.IsGood())
		return SCE_NP_TROPHY_ERROR_INVALID_ARGUMENT;
	// TODO: There are other possible errors

	sceNpTrophyInternalContext& ctxt = s_npTrophyInstance.contexts[context];
	reqspace = ctxt.trp_stream->GetSize(); // TODO: This is not accurate. It's just an approximation of the real value

	return CELL_OK;
}
Example #16
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;
    }
}
Example #17
0
int cellFsRead(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nread)
{
	sys_fs.Log("cellFsRead(fd: %d, buf_addr: 0x%x, nbytes: 0x%llx, nread_addr: 0x%x)",
		fd, buf_addr, nbytes, nread.GetAddr());
	vfsStream* file;
	if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH;

	if(Memory.IsGoodAddr(buf_addr) && !Memory.IsGoodAddr(buf_addr, nbytes))
	{
		MemoryBlock& block = Memory.GetMemByAddr(buf_addr);
		nbytes = block.GetSize() - (buf_addr - block.GetStartAddr());
	}

	const u64 res = nbytes ? file->Read(Memory.GetMemFromAddr(buf_addr), nbytes) : 0;

	if(nread.IsGood())
		nread = res;

	return CELL_OK;
}
Example #18
0
int cellFsWrite(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nwrite)
{
	sys_fs.Log("cellFsWrite(fd=%d, buf_addr=0x%x, nbytes=0x%llx, nwrite_addr=0x%x)",
		fd, buf_addr, nbytes, nwrite.GetAddr());
	vfsStream* file;
	if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH;

	if(Memory.IsGoodAddr(buf_addr) && !Memory.IsGoodAddr(buf_addr, nbytes))
	{
		MemoryBlock& block = Memory.GetMemByAddr(buf_addr);
		nbytes = block.GetSize() - (buf_addr - block.GetStartAddr());
	}

	const u64 res = nbytes ? file->Write(Memory.GetMemFromAddr(buf_addr), nbytes) : 0;

	if(nwrite.IsGood())
		nwrite = res;

	return CELL_OK;
}
Example #19
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;
}
Example #20
0
s32 sys_raw_spu_get_int_mask(u32 id, u32 class_id, mem64_t mask)
{
	sc_spu.Log("sys_raw_spu_get_int_mask(id=%d, class_id=%d, mask_addr=0x%x)", id, class_id, mask.GetAddr());

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

	RawSPUThread* t = Emu.GetCPU().GetRawSPUThread(id);
	if (!t)
	{
		return CELL_ESRCH;
	}

	if (class_id != 0 && class_id != 2)
	{
		return CELL_EINVAL;
	}

	mask = t->m_intrtag[class_id].mask;
	return CELL_OK;
}
Example #21
0
int sys_event_flag_get(u32 eflag_id, mem64_t flags)
{
	sys_event_flag.Warning("sys_event_flag_get(eflag_id=%d, flags_addr=0x%x)", eflag_id, flags.GetAddr());
	
	EventFlag* ef;
	if(!sys_event_flag.CheckId(eflag_id, ef)) return CELL_ESRCH;

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

	flags = ef->flags; // ???

	return CELL_OK;
}
Example #22
0
int cellFsGetBlockSize(u32 path_addr, mem64_t sector_size, mem64_t block_size)
{
	sys_fs.Log("cellFsGetBlockSize(file: %s, sector_size_addr: 0x%x, block_size_addr: 0x%x)", Memory.ReadString(path_addr).wx_str(), sector_size.GetAddr(), block_size.GetAddr());

	sector_size = 4096; // ?
	block_size = 4096; // ?

	return CELL_OK;
}
Example #23
0
int cellFsFGetBlockSize(u32 fd, mem64_t sector_size, mem64_t block_size)
{
	sys_fs.Log("cellFsFGetBlockSize(fd=%d, sector_size_addr: 0x%x, block_size_addr: 0x%x)", fd, sector_size.GetAddr(), block_size.GetAddr());

	vfsStream* file;
	if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH;

	sector_size = 4096; // ?
	block_size = 4096; // ?

	return CELL_OK;
}
Example #24
0
int cellFsLseek(u32 fd, s64 offset, u32 whence, mem64_t pos)
{
	vfsSeekMode seek_mode;
	sys_fs.Log("cellFsLseek(fd=%d, offset=0x%llx, whence=0x%x, pos_addr=0x%x)", fd, offset, whence, pos.GetAddr());
	switch(whence)
	{
	case CELL_SEEK_SET: seek_mode = vfsSeekSet; break;
	case CELL_SEEK_CUR: seek_mode = vfsSeekCur; break;
	case CELL_SEEK_END: seek_mode = vfsSeekEnd; break;
	default:
		sys_fs.Error(fd, "Unknown seek whence! (0x%x)", whence);
	return CELL_EINVAL;
	}

	u32 attr;
	vfsStream* file;
	if(!sys_fs.CheckId(fd, file, attr) || attr != IDFlag_File) return CELL_ESRCH;
	pos = file->Seek(offset, seek_mode);
	return CELL_OK;
}
Example #25
0
int cellFsReaddir(u32 fd, mem_ptr_t<CellFsDirent> dir, mem64_t nread)
{
	sys_fs.Log("cellFsReaddir(fd=%d, dir_addr=0x%x, nread_addr=0x%x)", fd, dir.GetAddr(), nread.GetAddr());

	vfsDirBase* directory;
	if(!sys_fs.CheckId(fd, directory))
		return CELL_ESRCH;
	if(!dir.IsGood() || !nread.IsGood())
		return CELL_EFAULT;

	const DirEntryInfo* info = directory->Read();
	if(info)
	{
		nread = 1;
		Memory.WriteString(dir.GetAddr()+2, info->name.wx_str());
		dir->d_namlen = info->name.Length();
		dir->d_type = (info->flags & DirEntry_TypeFile) ? CELL_FS_TYPE_REGULAR : CELL_FS_TYPE_DIRECTORY;
	}
	else
	{
		nread = 0;
	}

	return CELL_OK;
}
Example #26
0
int sys_event_flag_wait(u32 eflag_id, u64 bitptn, u32 mode, mem64_t result, u64 timeout)
{
	sys_event_flag.Warning("sys_event_flag_wait(eflag_id=%d, bitptn=0x%llx, mode=0x%x, result_addr=0x%x, timeout=%lld)",
		eflag_id, bitptn, mode, result.GetAddr(), timeout);

	if (result.IsGood()) result = 0;

	switch (mode & 0xf)
	{
	case SYS_EVENT_FLAG_WAIT_AND: break;
	case SYS_EVENT_FLAG_WAIT_OR: break;
	default: return CELL_EINVAL;
	}

	switch (mode & ~0xf)
	{
	case 0: break; // ???
	case SYS_EVENT_FLAG_WAIT_CLEAR: break;
	case SYS_EVENT_FLAG_WAIT_CLEAR_ALL: break;
	default: return CELL_EINVAL;
	}

	EventFlag* ef;
	if(!sys_event_flag.CheckId(eflag_id, ef)) return CELL_ESRCH;

	u32 tid = GetCurrentPPUThread().GetId();

	{
		SMutexLocker lock(ef->m_mutex);
		if (ef->m_type == SYS_SYNC_WAITER_SINGLE && ef->waiters.GetCount() > 0)
		{
			return CELL_EPERM;
		}
		EventFlagWaiter rec;
		rec.bitptn = bitptn;
		rec.mode = mode;
		rec.tid = tid;
		ef->waiters.AddCpy(rec);

		if (ef->check() == tid)
		{
			u64 flags = ef->flags;

			ef->waiters.RemoveAt(ef->waiters.GetCount() - 1);

			if (mode & SYS_EVENT_FLAG_WAIT_CLEAR)
			{
				ef->flags &= ~bitptn;
			}
			else if (mode & SYS_EVENT_FLAG_WAIT_CLEAR_ALL)
			{
				ef->flags = 0;
			}

			if (result.IsGood())
			{
				result = flags;
				return CELL_OK;
			}

			if (!result.GetAddr())
			{
				return CELL_OK;
			}
			return CELL_EFAULT;
		}
	}

	u32 counter = 0;
	const u32 max_counter = timeout ? (timeout / 1000) : ~0;

	while (true)
	{
		if (ef->signal.GetOwner() == tid)
		{
			SMutexLocker lock(ef->m_mutex);

			ef->signal.unlock(tid);

			u64 flags = ef->flags;

			for (u32 i = 0; i < ef->waiters.GetCount(); i++)
			{
				if (ef->waiters[i].tid == tid)
				{
					ef->waiters.RemoveAt(i);

					if (mode & SYS_EVENT_FLAG_WAIT_CLEAR)
					{
						ef->flags &= ~bitptn;
					}
					else if (mode & SYS_EVENT_FLAG_WAIT_CLEAR_ALL)
					{
						ef->flags = 0;
					}

					if (result.IsGood())
					{
						result = flags;
						return CELL_OK;
					}

					if (!result.GetAddr())
					{
						return CELL_OK;
					}
					return CELL_EFAULT;
				}
			}

			return CELL_ECANCELED;
		}

		Sleep(1);

		if (counter++ > max_counter)
		{
			SMutexLocker lock(ef->m_mutex);

			for (u32 i = 0; i < ef->waiters.GetCount(); i++)
			{
				if (ef->waiters[i].tid == tid)
				{
					ef->waiters.RemoveAt(i);
					break;
				}
			}
			
			return CELL_ETIMEDOUT;
		}
		if (Emu.IsStopped())
		{
			ConLog.Warning("sys_event_flag_wait(id=%d) aborted", eflag_id);
			return CELL_OK;
		}
	}
}
Example #27
0
s32 sys_ppu_thread_join(u64 thread_id, mem64_t vptr)
{
	sysPrxForUser->Warning("sys_ppu_thread_join(thread_id=%lld, vptr_addr=0x%x)", thread_id, vptr.GetAddr());

	CPUThread* thr = Emu.GetCPU().GetThread(thread_id);
	if(!thr) return CELL_ESRCH;

	while (thr->IsAlive())
	{
		if (Emu.IsStopped())
		{
			LOG_WARNING(PPU, "sys_ppu_thread_join(%d) aborted", thread_id);
			return CELL_OK;
		}
		std::this_thread::sleep_for(std::chrono::milliseconds(1));
	}

	vptr = thr->GetExitStatus();
	return CELL_OK;
}
Example #28
0
s32 sys_ppu_thread_create(mem64_t thread_id, u32 entry, u64 arg, s32 prio, u32 stacksize, u64 flags, u32 threadname_addr)
{
	std::string threadname = "";
	if (Memory.IsGoodAddr(threadname_addr))
	{
		threadname = Memory.ReadString(threadname_addr);
		sysPrxForUser->Log("sys_ppu_thread_create(thread_id_addr=0x%x, entry=0x%x, arg=0x%llx, prio=%d, stacksize=0x%x, flags=0x%llx, threadname_addr=0x%x('%s'))",
			thread_id.GetAddr(), entry, arg, prio, stacksize, flags, threadname_addr, threadname.c_str());
	}
	else
	{
		sysPrxForUser->Log("sys_ppu_thread_create(thread_id_addr=0x%x, entry=0x%x, arg=0x%llx, prio=%d, stacksize=0x%x, flags=0x%llx, threadname_addr=0x%x)",
			thread_id.GetAddr(), entry, arg, prio, stacksize, flags, threadname_addr);
		if (threadname_addr != 0) return CELL_EFAULT;
	}

	if (!Memory.IsGoodAddr(entry) || !thread_id.IsGood())
	{
		return CELL_EFAULT;
	}

	bool is_joinable = false;
	bool is_interrupt = false;

	switch (flags)
	{
	case 0: break;
	case SYS_PPU_THREAD_CREATE_JOINABLE:
	{
		is_joinable = true;
		break;
	}
	case SYS_PPU_THREAD_CREATE_INTERRUPT:
	{
		is_interrupt = true;
		break;
	}
	default: sysPrxForUser->Error("sys_ppu_thread_create(): unknown flags value (0x%llx)", flags); return CELL_EPERM;
	}

	CPUThread& new_thread = Emu.GetCPU().AddThread(CPU_THREAD_PPU);

	thread_id = new_thread.GetId();
	new_thread.SetEntry(entry);
	new_thread.SetArg(0, arg);
	new_thread.SetPrio(prio);
	new_thread.SetStackSize(stacksize);
	//new_thread.flags = flags;
	new_thread.m_has_interrupt = false;
	new_thread.m_is_interrupt = is_interrupt;
	new_thread.SetName(threadname);

	LOG_NOTICE(PPU, "*** New PPU Thread [%s] (flags=0x%llx, entry=0x%x): id = %d", new_thread.GetName().c_str(), flags, entry, new_thread.GetId());

	if (!is_interrupt)
	{
		new_thread.Run();
		new_thread.Exec();
	}

	return CELL_OK;
}
Example #29
0
int cellFsStReadGetCurrentAddr(u32 fd, mem32_t addr_addr, mem64_t size)
{
	sys_fs.Warning("TODO: cellFsStReadGetCurrentAddr(fd=%d, addr_addr=0x%x, size_addr = 0x%x)", fd, addr_addr.GetAddr(), size.GetAddr());

	vfsStream* file;
	if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH;

	if (!addr_addr.IsGood() && !size.IsGood()) return CELL_EFAULT;
	
	return CELL_OK;
}
Example #30
0
s32 sys_raw_spu_get_int_stat(u32 id, u32 class_id, mem64_t stat)
{
	sc_spu.Log("sys_raw_spu_get_int_stat(id=%d, class_id=%d, stat_addr=0xx)", id, class_id, stat.GetAddr());

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

	RawSPUThread* t = Emu.GetCPU().GetRawSPUThread(id);
	if (!t)
	{
		return CELL_ESRCH;
	}

	if (class_id != 0 && class_id != 2)
	{
		return CELL_EINVAL;
	}

	stat = t->m_intrtag[class_id].stat;
	return CELL_OK;
}