예제 #1
0
//128
int sys_event_queue_create(mem32_t equeue_id, mem_ptr_t<sys_event_queue_attr> attr, u64 event_queue_key, int size)
{
	sys_event.Warning("sys_event_queue_create(equeue_id_addr=0x%x, attr_addr=0x%x, event_queue_key=0x%llx, size=%d)",
		equeue_id.GetAddr(), attr.GetAddr(), event_queue_key, size);

	if(size <= 0 || size > 127)
	{
		return CELL_EINVAL;
	}

	if(!equeue_id.IsGood() || !attr.IsGood())
	{
		return CELL_EFAULT;
	}

	switch (attr->protocol.ToBE())
	{
	case se32(SYS_SYNC_PRIORITY): break;
	case se32(SYS_SYNC_RETRY): sys_event.Error("Invalid SYS_SYNC_RETRY protocol attr"); return CELL_EINVAL;
	case se32(SYS_SYNC_PRIORITY_INHERIT): sys_event.Error("Invalid SYS_SYNC_PRIORITY_INHERIT protocol attr"); return CELL_EINVAL;
	case se32(SYS_SYNC_FIFO): break;
	default: sys_event.Error("Unknown 0x%x protocol attr", (u32)attr->protocol); return CELL_EINVAL;
	}

	switch (attr->type.ToBE())
	{
	case se32(SYS_PPU_QUEUE): break;
	case se32(SYS_SPU_QUEUE): break;
	default: sys_event.Error("Unknown 0x%x type attr", (u32)attr->type); return CELL_EINVAL;
	}

	if (event_queue_key && Emu.GetEventManager().CheckKey(event_queue_key))
	{
		return CELL_EEXIST;
	}

	EventQueue* eq = new EventQueue((u32)attr->protocol, (int)attr->type, attr->name_u64, event_queue_key, size);

	if (event_queue_key && !Emu.GetEventManager().RegisterKey(eq, event_queue_key))
	{
		delete eq;
		return CELL_EAGAIN;
	}

	equeue_id = sys_event.GetNewId(eq);
	sys_event.Warning("*** event_queue created [%s] (protocol=0x%x, type=0x%x): id = %d",
		wxString(attr->name, 8).wx_str(), (u32)attr->protocol, (int)attr->type, equeue_id.GetValue());

	return CELL_OK;
}
예제 #2
0
s32 sys_mutex_create(mem32_t mutex_id, mem_ptr_t<sys_mutex_attribute> attr)
{
	sys_mutex.Log("sys_mutex_create(mutex_id_addr=0x%x, attr_addr=0x%x)", mutex_id.GetAddr(), attr.GetAddr());

	switch (attr->protocol.ToBE())
	{
	case se32(SYS_SYNC_FIFO): break;
	case se32(SYS_SYNC_PRIORITY): break;
	case se32(SYS_SYNC_PRIORITY_INHERIT): sys_mutex.Todo("sys_mutex_create(): SYS_SYNC_PRIORITY_INHERIT"); break;
	case se32(SYS_SYNC_RETRY): sys_mutex.Error("sys_mutex_create(): SYS_SYNC_RETRY"); return CELL_EINVAL;
	default: sys_mutex.Error("Unknown protocol attribute(0x%x)", (u32)attr->protocol); return CELL_EINVAL;
	}

	bool is_recursive;
	switch (attr->recursive.ToBE())
	{
	case se32(SYS_SYNC_RECURSIVE): is_recursive = true; break;
	case se32(SYS_SYNC_NOT_RECURSIVE): is_recursive = false; break;
	default: sys_mutex.Error("Unknown recursive attribute(0x%x)", (u32)attr->recursive); return CELL_EINVAL;
	}

	if (attr->pshared.ToBE() != se32(0x200))
	{
		sys_mutex.Error("Unknown pshared attribute(0x%x)", (u32)attr->pshared);
		return CELL_EINVAL;
	}

	u32 tid = GetCurrentPPUThread().GetId();
	Mutex* mutex = new Mutex((u32)attr->protocol, is_recursive, attr->name_u64);
	u32 id = sys_mutex.GetNewId(mutex, TYPE_MUTEX);
	mutex->m_mutex.lock(tid);
	mutex->id = id;
	mutex_id = id;
	mutex->m_mutex.unlock(tid);
	sys_mutex.Warning("*** mutex created [%s] (protocol=0x%x, recursive=%s): id = %d",
		std::string(attr->name, 8).c_str(), (u32) attr->protocol,
		(is_recursive ? "true" : "false"), mutex_id.GetValue());

	// TODO: unlock mutex when owner thread does exit

	return CELL_OK;
}
예제 #3
0
int sys_mutex_create(mem32_t mutex_id, mem_ptr_t<sys_mutex_attribute> attr)
{
	sys_mtx.Log("sys_mutex_create(mutex_id_addr=0x%x, attr_addr=0x%x)", mutex_id.GetAddr(), attr.GetAddr());

	if (!mutex_id.IsGood() || !attr.IsGood())
	{
		return CELL_EFAULT;
	}

	switch (attr->protocol.ToBE())
	{
	case se32(SYS_SYNC_FIFO): break;
	case se32(SYS_SYNC_PRIORITY): break;
	case se32(SYS_SYNC_PRIORITY_INHERIT): sys_mtx.Warning("TODO: SYS_SYNC_PRIORITY_INHERIT protocol"); break;
	case se32(SYS_SYNC_RETRY): sys_mtx.Error("Invalid SYS_SYNC_RETRY protocol"); return CELL_EINVAL;
	default: sys_mtx.Error("Unknown protocol attribute(0x%x)", (u32)attr->protocol); return CELL_EINVAL;
	}

	bool is_recursive;
	switch (attr->recursive.ToBE())
	{
	case se32(SYS_SYNC_RECURSIVE): is_recursive = true; break;
	case se32(SYS_SYNC_NOT_RECURSIVE): is_recursive = false; break;
	default: sys_mtx.Error("Unknown recursive attribute(0x%x)", (u32)attr->recursive); return CELL_EINVAL;
	}

	if (attr->pshared.ToBE() != se32(0x200))
	{
		sys_mtx.Error("Unknown pshared attribute(0x%x)", (u32)attr->pshared);
		return CELL_EINVAL;
	}

	mutex_id = sys_mtx.GetNewId(new Mutex((u32)attr->protocol, is_recursive, attr->name_u64));
	sys_mtx.Warning("*** mutex created [%s] (protocol=0x%x, recursive=%s): id = %d",
		wxString(attr->name, 8).wx_str(), (u32)attr->protocol,
		wxString(is_recursive ? "true" : "false").wx_str(), mutex_id.GetValue());

	// TODO: unlock mutex when owner thread does exit

	return CELL_OK;
}
예제 #4
0
int sys_memory_container_create(mem32_t cid, u32 yield_size)
{
	sc_mem.Warning("sys_memory_container_create(cid_addr=0x%x, yield_size=0x%x)", cid.GetAddr(), yield_size);

	if (!cid.IsGood())
		return CELL_EFAULT;

	yield_size &= ~0xfffff; //round down to 1 MB granularity
	u64 addr = Memory.Alloc(yield_size, 0x100000); //1 MB alignment

	if(!addr)
		return CELL_ENOMEM;

	// Wrap the allocated memory in a memory container.
	MemoryContainerInfo *ct = new MemoryContainerInfo(addr, yield_size);
	cid = sc_mem.GetNewId(ct);

	sc_mem.Warning("*** memory_container created(addr=0x%llx): id = %d", addr, cid.GetValue());

	return CELL_OK;
}
예제 #5
0
파일: sys_spu.cpp 프로젝트: Smprvrd/rpcs3
//170
s32 sys_spu_thread_group_create(mem32_t id, u32 num, int prio, mem_ptr_t<sys_spu_thread_group_attribute> attr)
{
	sc_spu.Warning("sys_spu_thread_group_create(id_addr=0x%x, num=%d, prio=%d, attr_addr=0x%x)",
		id.GetAddr(), num, prio, attr.GetAddr());

	if (!id.IsGood() || !attr.IsGood()) return CELL_EFAULT;

	if (!Memory.IsGoodAddr(attr->name_addr, attr->name_len)) return CELL_EFAULT;

	if (num > 256) return CELL_EINVAL;

	if (prio < 16 || prio > 255) return CELL_EINVAL;

	const std::string name = Memory.ReadString(attr->name_addr, attr->name_len);

	id = sc_spu.GetNewId(new SpuGroupInfo(name, num, prio, attr->type, attr->ct));

	sc_spu.Warning("*** SPU Thread Group created [%s] (type=0x%x, option.ct=0x%x): id=%d", 
		name.c_str(), (int)attr->type, (u32)attr->ct, id.GetValue());

	return CELL_OK;
}
예제 #6
0
int sys_event_flag_create(mem32_t eflag_id, mem_ptr_t<sys_event_flag_attr> attr, u64 init)
{
	sys_event_flag.Warning("sys_event_flag_create(eflag_id_addr=0x%x, attr_addr=0x%x, init=0x%llx)",
		eflag_id.GetAddr(), attr.GetAddr(), init);

	if(!eflag_id.IsGood() || !attr.IsGood())
	{
		return CELL_EFAULT;
	}

	switch (attr->protocol.ToBE())
	{
	case se32(SYS_SYNC_PRIORITY): break;
	case se32(SYS_SYNC_RETRY): sys_event_flag.Warning("TODO: SYS_SYNC_RETRY attr"); break;
	case se32(SYS_SYNC_PRIORITY_INHERIT): sys_event_flag.Warning("TODO: SYS_SYNC_PRIORITY_INHERIT attr"); break;
	case se32(SYS_SYNC_FIFO): break;
	default: return CELL_EINVAL;
	}

	if (attr->pshared.ToBE() != se32(0x200))
	{
		return CELL_EINVAL;
	}

	switch (attr->type.ToBE())
	{
	case se32(SYS_SYNC_WAITER_SINGLE): break;
	case se32(SYS_SYNC_WAITER_MULTIPLE): break;
	default: return CELL_EINVAL;
	}

	eflag_id = sys_event_flag.GetNewId(new EventFlag(init, (u32)attr->protocol, (int)attr->type));

	sys_event_flag.Warning("*** event_flag created [%s] (protocol=0x%x, type=0x%x): id = %d",
		std::string(attr->name, 8).c_str(), (u32)attr->protocol, (int)attr->type, eflag_id.GetValue());

	return CELL_OK;
}
예제 #7
0
int sys_semaphore_create(mem32_t sem, mem_ptr_t<sys_semaphore_attribute> attr, int initial_count, int max_count)
{
	sys_sem.Warning("sys_semaphore_create(sem_addr=0x%x, attr_addr=0x%x, initial_count=%d, max_count=%d)",
		sem.GetAddr(), attr.GetAddr(), initial_count, max_count);

	if (!sem.IsGood() || !attr.IsGood())
	{
		return CELL_EFAULT;
	}

	if (max_count <= 0 || initial_count > max_count || initial_count < 0)
	{
		sys_sem.Error("sys_semaphore_create(): invalid parameters (initial_count=%d, max_count=%d)", initial_count, max_count);
		return CELL_EINVAL;
	}
	
	if (attr->pshared.ToBE() != se32(0x200))
	{
		sys_sem.Error("sys_semaphore_create(): invalid pshared value(0x%x)", (u32)attr->pshared);
		return CELL_EINVAL;
	}

	switch (attr->protocol.ToBE())
	{
	case se32(SYS_SYNC_FIFO): break;
	case se32(SYS_SYNC_PRIORITY): break;
	case se32(SYS_SYNC_PRIORITY_INHERIT): sys_sem.Warning("TODO: SYS_SYNC_PRIORITY_INHERIT protocol"); break;
	case se32(SYS_SYNC_RETRY): sys_sem.Error("Invalid SYS_SYNC_RETRY protocol"); return CELL_EINVAL;
	default: sys_sem.Error("Unknown protocol attribute(0x%x)", (u32)attr->protocol); return CELL_EINVAL;
	}

	sem = sys_sem.GetNewId(new Semaphore(initial_count, max_count, attr->protocol, attr->name_u64));
	ConLog.Write("*** semaphore created [%s] (protocol=0x%x): id = %d",
		std::string(attr->name, 8).c_str(), (u32)attr->protocol, sem.GetValue());

	return CELL_OK;
}
예제 #8
0
int cellFsOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size)
{
	const wxString& path = Memory.ReadString(path_addr);
	sys_fs.Log("cellFsOpen(path=\"%s\", flags=0x%x, fd_addr=0x%x, arg_addr=0x%x, size=0x%llx)",
		path.wx_str(), flags, fd.GetAddr(), arg.GetAddr(), size);

	const wxString& ppath = path;
	//ConLog.Warning("path: %s [%s]", ppath.wx_str(), path.wx_str());

	s32 _oflags = flags;
	if(flags & CELL_O_CREAT)
	{
		_oflags &= ~CELL_O_CREAT;
		Emu.GetVFS().CreateFile(ppath);
	}

	vfsOpenMode o_mode;

	switch(flags & CELL_O_ACCMODE)
	{
	case CELL_O_RDONLY:
		_oflags &= ~CELL_O_RDONLY;
		o_mode = vfsRead;
	break;

	case CELL_O_WRONLY:
		_oflags &= ~CELL_O_WRONLY;

		if(flags & CELL_O_APPEND)
		{
			_oflags &= ~CELL_O_APPEND;
			o_mode = vfsWriteAppend;
		}
		else if(flags & CELL_O_EXCL)
		{
			_oflags &= ~CELL_O_EXCL;
			o_mode = vfsWriteExcl;
		}
		else //if (flags & CELL_O_TRUNC)
		{
			_oflags &= ~CELL_O_TRUNC;
			o_mode = vfsWrite;
		}
	break;

	case CELL_O_RDWR:
		_oflags &= ~CELL_O_RDWR;
		if (flags & CELL_O_TRUNC)
		{
			_oflags &= ~CELL_O_TRUNC;
			//truncate file before opening it as read/write
			Emu.GetVFS().OpenFile(ppath, vfsWrite);
		}
		o_mode = vfsReadWrite;
	break;
	}

	if(_oflags != 0)
	{
		sys_fs.Error("\"%s\" has unknown flags! flags: 0x%08x", ppath.wx_str(), flags);
		return CELL_EINVAL;
	}

	vfsFileBase* stream = Emu.GetVFS().OpenFile(ppath, o_mode);

	if(!stream || !stream->IsOpened())
	{
		sys_fs.Error("\"%s\" not found! flags: 0x%08x", ppath.wx_str(), flags);
		return CELL_ENOENT;
	}

	fd = sys_fs.GetNewId(stream, IDFlag_File);
	ConLog.Warning("*** cellFsOpen(path=\"%s\"): fd = %d", path.wx_str(), fd.GetValue());

	return CELL_OK;
}
예제 #9
0
파일: sys_spu.cpp 프로젝트: Smprvrd/rpcs3
//172
s32 sys_spu_thread_initialize(mem32_t thread, u32 group, u32 spu_num, mem_ptr_t<sys_spu_image> img, mem_ptr_t<sys_spu_thread_attribute> attr, mem_ptr_t<sys_spu_thread_argument> arg)
{
	sc_spu.Warning("sys_spu_thread_initialize(thread_addr=0x%x, group=0x%x, spu_num=%d, img_addr=0x%x, attr_addr=0x%x, arg_addr=0x%x)",
		thread.GetAddr(), group, spu_num, img.GetAddr(), attr.GetAddr(), arg.GetAddr());

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

	if(!thread.IsGood() || !img.IsGood() || !attr.IsGood() || !arg.IsGood())
	{
		return CELL_EFAULT;
	}

	if (attr->name_addr)
	{
		if(!Memory.IsGoodAddr(attr->name_addr, attr->name_len))
		{
			return CELL_EFAULT;
		}
	}

	if(spu_num >= group_info->list.size())
	{
		return CELL_EINVAL;
	}
	
	if(group_info->list[spu_num])
	{
		return CELL_EBUSY;
	}

	u32 spu_ep = (u32)img->entry_point;

	std::string name = "SPUThread";
	if (attr->name_addr)
	{
		name = Memory.ReadString(attr->name_addr, attr->name_len);
	}

	u64 a1 = arg->arg1;
	u64 a2 = arg->arg2;
	u64 a3 = arg->arg3;
	u64 a4 = arg->arg4;

	//copy SPU image:
	auto spu_offset = Memory.MainMem.AllocAlign(256 * 1024);
	if (!Memory.Copy(spu_offset, (u32)img->segs_addr, 256 * 1024))
	{
		return CELL_EFAULT;
	}

	CPUThread& new_thread = Emu.GetCPU().AddThread(CPU_THREAD_SPU);
	//initialize from new place:
	new_thread.SetOffset(spu_offset);
	new_thread.SetEntry(spu_ep);
	new_thread.SetName(name);
	new_thread.SetArg(0, a1);
	new_thread.SetArg(1, a2);
	new_thread.SetArg(2, a3);
	new_thread.SetArg(3, a4);
	new_thread.Run();

	thread = group_info->list[spu_num] = new_thread.GetId();
	(*(SPUThread*)&new_thread).group = group_info;

	sc_spu.Warning("*** New SPU Thread [%s] (img_offset=0x%x, ls_offset=0x%x, ep=0x%x, a1=0x%llx, a2=0x%llx, a3=0x%llx, a4=0x%llx): id=%d",
		(attr->name_addr ? name.c_str() : ""), (u32) img->segs_addr, ((SPUThread&) new_thread).dmac.ls_offset, spu_ep, a1, a2, a3, a4, thread.GetValue());

	return CELL_OK;
}
예제 #10
0
int sys_cond_create(mem32_t cond_id, u32 mutex_id, mem_ptr_t<sys_cond_attribute> attr)
{
	sys_cond.Log("sys_cond_create(cond_id_addr=0x%x, mutex_id=%d, attr_addr=0x%x)",
		cond_id.GetAddr(), mutex_id, attr.GetAddr());

	if (!cond_id.IsGood() || !attr.IsGood())
	{
		return CELL_EFAULT;
	}

	if (attr->pshared.ToBE() != se32(0x200))
	{
		sys_cond.Error("Invalid pshared attribute(0x%x)", (u32)attr->pshared);
		return CELL_EINVAL;
	}

	Mutex* mutex;
	if (!Emu.GetIdManager().GetIDData(mutex_id, mutex))
	{
		return CELL_ESRCH;
	}

	if (mutex->is_recursive)
	{
		sys_cond.Warning("*** condition on recursive mutex(%d)", mutex_id);
	}

	Cond* cond = new Cond(mutex, attr->name_u64);
	u32 id = sys_cond.GetNewId(cond);
	cond_id = id;
	mutex->cond_count++;
	sys_cond.Warning("*** condition created [%s] (mutex_id=%d): id = %d", wxString(attr->name, 8).wx_str(), mutex_id, cond_id.GetValue());

	return CELL_OK;
}