Beispiel #1
0
void __KernelMemoryDoState(PointerWrap &p)
{
	kernelMemory.DoState(p);
	userMemory.DoState(p);
	p.Do(vplWaitTimer);
	CoreTiming::RestoreRegisterEvent(vplWaitTimer, "VplTimeout", __KernelVplTimeout);
	p.DoMarker("sceKernelMemory");
}
Beispiel #2
0
void __KernelMemoryInit()
{
	kernelMemory.Init(PSP_GetKernelMemoryBase(), PSP_GetKernelMemoryEnd()-PSP_GetKernelMemoryBase());
	userMemory.Init(PSP_GetUserMemoryBase(), PSP_GetUserMemoryEnd()-PSP_GetUserMemoryBase());
	INFO_LOG(HLE, "Kernel and user memory pools initialized");

	vplWaitTimer = CoreTiming::RegisterEvent("VplTimeout", __KernelVplTimeout);
}
Beispiel #3
0
u32 FreeMemoryBlock(u32 uid) {
	INFO_LOG(HLE, "FreeMemoryBlock(%08x)", uid);
	u32 blockPtr = userMemory.GetBlockStartFromAddress(uid);
	if (!blockPtr) {
		return SCE_KERNEL_ERROR_UNKNOWN_UID;
	}
	userMemory.Free(blockPtr);
	return 0;
}
Beispiel #4
0
void __KernelMemoryShutdown()
{
	INFO_LOG(HLE,"Shutting down user memory pool: ");
	userMemory.ListBlocks();
	userMemory.Shutdown();
	INFO_LOG(HLE,"Shutting down \"kernel\" memory pool: ");
	kernelMemory.ListBlocks();
	kernelMemory.Shutdown();
}
Beispiel #5
0
void __KernelMemoryInit()
{
	kernelMemory.Init(PSP_GetKernelMemoryBase(), PSP_GetKernelMemoryEnd()-PSP_GetKernelMemoryBase());
	userMemory.Init(PSP_GetUserMemoryBase(), PSP_GetUserMemoryEnd()-PSP_GetUserMemoryBase());
	INFO_LOG(HLE, "Kernel and user memory pools initialized");

	vplWaitTimer = CoreTiming::RegisterEvent("VplTimeout", __KernelVplTimeout);

	flags_ = 0;
	sdkVersion_ = 0;
	compilerVersion_ = 0;
	memset(tlsUsedIndexes, 0, sizeof(tlsUsedIndexes));
}
Beispiel #6
0
void __KernelMemoryDoState(PointerWrap &p)
{
	kernelMemory.DoState(p);
	userMemory.DoState(p);

	p.Do(vplWaitTimer);
	CoreTiming::RestoreRegisterEvent(vplWaitTimer, "VplTimeout", __KernelVplTimeout);
	p.Do(flags_);
	p.Do(sdkVersion_);
	p.Do(compilerVersion_);
	p.DoArray(tlsUsedIndexes, ARRAY_SIZE(tlsUsedIndexes));
	p.DoMarker("sceKernelMemory");
}
Beispiel #7
0
void sceKernelMaxFreeMemSize() 
{
	// TODO: Fudge factor improvement
	u32 retVal = userMemory.GetLargestFreeBlockSize()-0x40000;
	DEBUG_LOG(HLE,"%08x (dec %i)=sceKernelMaxFreeMemSize",retVal,retVal);
	RETURN(retVal);
}
Beispiel #8
0
u32 GetMemoryBlockPtr(u32 uid, u32 addr) {
	INFO_LOG(HLE, "GetMemoryBlockPtr(%08x, %08x)", uid, addr);
	u32 blockPtr = userMemory.GetBlockStartFromAddress(uid);
	if (!blockPtr) {
		return SCE_KERNEL_ERROR_UNKNOWN_UID;
	}
	Memory::Write_U32(blockPtr, addr);
	return 0;
}
Beispiel #9
0
u32 AllocMemoryBlock(const char *pname, u32 type, u32 size, u32 paramsAddr) {

	// Just support allocating a block in the user region.

	u32 blockPtr = userMemory.Alloc(size, type == 1, pname);
	INFO_LOG(HLE,"%08x=AllocMemoryBlock(SysMemUserForUser_FE707FDF)(%s, %i, %08x, %08x)", blockPtr, pname, type, size, paramsAddr);

	// Create a UID object??? Nah, let's just us the UID itself (hack!)

	return blockPtr;
}
Beispiel #10
0
Fixture* Body::CreateFixture(const FixtureDef* def)
{
	assert(m_world->IsLocked() == false);
	if (m_world->IsLocked() == true)
	{
		return NULL;
	}

	BlockAllocator* allocator = &m_world->m_blockAllocator;

	void* memory = allocator->Allocate(sizeof(Fixture));
	Fixture* fixture = new (memory) Fixture;
	fixture->Create(allocator, this, def);

	if (m_flags & activeFlag)
	{
		BroadPhase* broadPhase = &m_world->m_contactManager.m_broadPhase;
		fixture->CreateProxies(broadPhase, m_xf);
	}

	fixture->m_next = m_fixtureList;
	m_fixtureList = fixture;
	++m_fixtureCount;

	fixture->m_body = this;

	// Adjust mass properties if needed.
	if (fixture->m_density > 0.0f)
	{
		ResetMassData();
	}

	// Let the world know we have a new fixture. This will cause new contacts
	// to be created at the beginning of the next time step.
	m_world->m_flags |= World::newFixture;

	return fixture;
}
Beispiel #11
0
// Parameters are an educated guess.
int sceKernelDeleteTls(SceUID uid)
{
	WARN_LOG(HLE, "sceKernelDeleteTls(%08x)", uid);
	u32 error;
	TLS *tls = kernelObjects.Get<TLS>(uid, error);
	if (tls)
	{
		// TODO: Wake waiting threads, probably?
		userMemory.Free(tls->address);
		tlsUsedIndexes[tls->ntls.index] = false;
		kernelObjects.Destroy<TLS>(uid);
	}
	return error;
}
Beispiel #12
0
void sceKernelDeleteFpl()
{
	SceUID id = PARAM(0);
	u32 error;
	FPL *fpl = kernelObjects.Get<FPL>(id, error);
	if (fpl)
	{
		userMemory.Free(fpl->address);
		DEBUG_LOG(HLE,"sceKernelDeleteFpl(%i)", id);
		RETURN(kernelObjects.Destroy<FPL>(id));
	}
	else
	{
		RETURN(error);
	}
}
Beispiel #13
0
int sceKernelDeleteVpl(SceUID uid)
{
	DEBUG_LOG(HLE, "sceKernelDeleteVpl(%i)", uid);
	u32 error;
	VPL *vpl = kernelObjects.Get<VPL>(uid, error);
	if (vpl)
	{
		bool wokeThreads = __KernelClearVplThreads(vpl, SCE_KERNEL_ERROR_WAIT_DELETE);
		if (wokeThreads)
			hleReSchedule("vpl deleted");

		userMemory.Free(vpl->address);
		kernelObjects.Destroy<VPL>(uid);
		return 0;
	}
	else
		return error;
}
Beispiel #14
0
//sceKernelCreateFpl(const char *name, SceUID mpid, SceUint attr, SceSize blocksize, int numBlocks, optparam)
void sceKernelCreateFpl()
{
	const char *name = Memory::GetCharPointer(PARAM(0));

	u32 mpid = PARAM(1);
	u32 attr = PARAM(2);
	u32 blockSize = PARAM(3);
	u32 numBlocks = PARAM(4);

	u32 totalSize = blockSize * numBlocks;

	bool atEnd = false;   // attr can change this I think

	u32 address = userMemory.Alloc(totalSize, atEnd, "FPL");
	if (address == (u32)-1)
	{
		DEBUG_LOG(HLE,"sceKernelCreateFpl(\"%s\", partition=%i, attr=%i, bsize=%i, nb=%i) FAILED - out of ram", 
			name, mpid, attr, blockSize, numBlocks);
		RETURN(SCE_KERNEL_ERROR_NO_MEMORY);
		return;
	}

	FPL *fpl = new FPL;
	SceUID id = kernelObjects.Create(fpl);
	strncpy(fpl->nf.name, name, 32);

	fpl->nf.size = sizeof(fpl->nf);
	fpl->nf.mpid = mpid;  // partition
	fpl->nf.attr = attr;
	fpl->nf.blocksize = blockSize;
	fpl->nf.numBlocks = numBlocks;
	fpl->nf.numWaitThreads = 0;
	fpl->blocks = new bool[fpl->nf.numBlocks];
	memset(fpl->blocks, 0, fpl->nf.numBlocks * sizeof(bool));
	fpl->address = address;

	DEBUG_LOG(HLE,"%i=sceKernelCreateFpl(\"%s\", partition=%i, attr=%i, bsize=%i, nb=%i)", 
		id, name, mpid, attr, blockSize, numBlocks);

	RETURN(id);
}
Beispiel #15
0
u32 AllocMemoryBlock(const char *pname, u32 type, u32 size, u32 paramsAddr) {

	// Just support allocating a block in the user region.
	if (paramsAddr) {
		u32 length = Memory::Read_U32(paramsAddr);
		if (length != 4) {
			WARN_LOG(HLE, "AllockMemoryBlock(SysMemUserForUser_FE707FDF) : unknown parameters with length %d", length);
		}
	}
	if (type < 0 || type > 1) {
		return SCE_KERNEL_ERROR_ILLEGAL_MEMBLOCKTYPE;
	}

	u32 blockPtr = userMemory.Alloc(size, type == 1, pname);
	if (!blockPtr) {
		return SCE_KERNEL_ERROR_MEMBLOCK_ALLOC_FAILED;
	}
	INFO_LOG(HLE,"%08x=AllocMemoryBlock(SysMemUserForUser_FE707FDF)(%s, %i, %08x, %08x)", blockPtr, pname, type, size, paramsAddr);

	// Create a UID object??? Nah, let's just us the UID itself (hack!)

	return blockPtr;
}
Beispiel #16
0
u32 sceKernelMaxFreeMemSize() 
{
	u32 retVal = userMemory.GetLargestFreeBlockSize();
	DEBUG_LOG(HLE, "%08x (dec %i)=sceKernelMaxFreeMemSize()", retVal, retVal);
	return retVal;
}
Beispiel #17
0
SceUID sceKernelCreateVpl(const char *name, int partition, u32 attr, u32 vplSize, u32 optPtr)
{
	if (!name)
	{
		WARN_LOG_REPORT(HLE, "%08x=sceKernelCreateVpl(): invalid name", SCE_KERNEL_ERROR_ERROR);
		return SCE_KERNEL_ERROR_ERROR;
	}
	if (partition < 1 || partition > 9 || partition == 7)
	{
		WARN_LOG_REPORT(HLE, "%08x=sceKernelCreateVpl(): invalid partition %d", SCE_KERNEL_ERROR_ILLEGAL_ARGUMENT, partition);
		return SCE_KERNEL_ERROR_ILLEGAL_ARGUMENT;
	}
	// We only support user right now.
	if (partition != 2 && partition != 6)
	{
		WARN_LOG_REPORT(HLE, "%08x=sceKernelCreateVpl(): invalid partition %d", SCE_KERNEL_ERROR_ILLEGAL_PERM, partition);
		return SCE_KERNEL_ERROR_ILLEGAL_PERM;
	}
	if (((attr & ~PSP_VPL_ATTR_KNOWN) & ~0xFF) != 0)
	{
		WARN_LOG_REPORT(HLE, "%08x=sceKernelCreateVpl(): invalid attr parameter: %08x", SCE_KERNEL_ERROR_ILLEGAL_ATTR, attr);
		return SCE_KERNEL_ERROR_ILLEGAL_ATTR;
	}
	if (vplSize == 0)
	{
		WARN_LOG_REPORT(HLE, "%08x=sceKernelCreateVpl(): invalid size", SCE_KERNEL_ERROR_ILLEGAL_MEMSIZE);
		return SCE_KERNEL_ERROR_ILLEGAL_MEMSIZE;
	}
	// Block Allocator seems to A-OK this, let's stop it here.
	if (vplSize >= 0x80000000)
	{
		WARN_LOG_REPORT(HLE, "%08x=sceKernelCreateVpl(): way too big size", SCE_KERNEL_ERROR_NO_MEMORY);
		return SCE_KERNEL_ERROR_NO_MEMORY;
	}

	// Can't have that little space in a Vpl, sorry.
	if (vplSize <= 0x30)
		vplSize = 0x1000;
	vplSize = (vplSize + 7) & ~7;

	// We ignore the upalign to 256 and do it ourselves by 8.
	u32 allocSize = vplSize;
	u32 memBlockPtr = userMemory.Alloc(allocSize, (attr & PSP_VPL_ATTR_HIGHMEM) != 0, "VPL");
	if (memBlockPtr == (u32)-1)
	{
		ERROR_LOG(HLE, "sceKernelCreateVpl: Failed to allocate %i bytes of pool data", vplSize);
		return SCE_KERNEL_ERROR_NO_MEMORY;
	}

	VPL *vpl = new VPL;
	SceUID id = kernelObjects.Create(vpl);

	strncpy(vpl->nv.name, name, KERNELOBJECT_MAX_NAME_LENGTH);
	vpl->nv.name[KERNELOBJECT_MAX_NAME_LENGTH] = 0;
	vpl->nv.attr = attr;
	vpl->nv.size = sizeof(vpl->nv);
	vpl->nv.poolSize = vplSize - 0x20;
	vpl->nv.numWaitThreads = 0;
	vpl->nv.freeSize = vpl->nv.poolSize;

	// A vpl normally has accounting stuff in the first 32 bytes.
	vpl->address = memBlockPtr + 0x20;
	vpl->alloc.Init(vpl->address, vpl->nv.poolSize);

	DEBUG_LOG(HLE, "%x=sceKernelCreateVpl(\"%s\", block=%i, attr=%i, size=%i)", 
		id, name, partition, vpl->nv.attr, vpl->nv.poolSize);

	return id;
}
Beispiel #18
0
void sceKernelTotalFreeMemSize()
{
	u32 retVal = userMemory.GetLargestFreeBlockSize()-0x8000;
	DEBUG_LOG(HLE,"%08x (dec %i)=sceKernelTotalFreeMemSize",retVal,retVal);
	RETURN(retVal);
}
Beispiel #19
0
void Body::DestroyFixture(Fixture* fixture)
{
	assert(m_world->IsLocked() == false);
	if (m_world->IsLocked() == true)
	{
		return;
	}

	assert(fixture->m_body == this);

	// Remove the fixture from this body's singly linked list.
	assert(m_fixtureCount > 0);
	Fixture** node = &m_fixtureList;
	bool found = false;
	while (*node != NULL)
	{
		if (*node == fixture)
		{
			*node = fixture->m_next;
			found = true;
			break;
		}

		node = &(*node)->m_next;
	}

	// You tried to remove a shape that is not attached to this body.
	assert(found);

	// Destroy any contacts associated with the fixture.
	ContactEdge* edge = m_contactList;
	while (edge)
	{
		Contact* c = edge->contact;
		edge = edge->next;

		Fixture* fixtureA = c->GetFixtureA();
		Fixture* fixtureB = c->GetFixtureB();

		if (fixture == fixtureA || fixture == fixtureB)
		{
			// This destroys the contact and removes it from
			// this body's contact list.
			m_world->m_contactManager.Destroy(c);
		}
	}

	BlockAllocator* allocator = &m_world->m_blockAllocator;

	if (m_flags & activeFlag)
	{
		BroadPhase* broadPhase = &m_world->m_contactManager.m_broadPhase;
		fixture->DestroyProxies(broadPhase);
	}

	fixture->Destroy(allocator);
	fixture->m_body = NULL;
	fixture->m_next = NULL;
	fixture->~Fixture();
	allocator->Free(fixture, sizeof(Fixture));

	--m_fixtureCount;

	// Reset the mass data.
	ResetMassData();
}
Beispiel #20
0
 void * operator new(size_t /* s */) 
 {
   return ball.Alloc();
 }
Beispiel #21
0
 void operator delete (void * p)
 {
   ball.Free (p);
 }
Beispiel #22
0
u32 FreeMemoryBlock(u32 uid) {
	INFO_LOG(HLE, "FreeMemoryBlock(%08x)", uid);
	userMemory.Free(uid);
	return 0;
}
Beispiel #23
0
u32 sceKernelTotalFreeMemSize()
{
	u32 retVal = userMemory.GetTotalFreeBytes();
	DEBUG_LOG(HLE, "%08x (dec %i)=sceKernelTotalFreeMemSize()", retVal, retVal);
	return retVal;
}
Beispiel #24
0
SceUID sceKernelCreateTls(const char *name, u32 partition, u32 attr, u32 blockSize, u32 count, u32 optionsPtr)
{
	if (!name)
	{
		WARN_LOG_REPORT(HLE, "%08x=sceKernelCreateTls(): invalid name", SCE_KERNEL_ERROR_NO_MEMORY);
		return SCE_KERNEL_ERROR_NO_MEMORY;
	}
	if ((attr & ~PSP_TLS_ATTR_KNOWN) >= 0x100)
	{
		WARN_LOG_REPORT(HLE, "%08x=sceKernelCreateTls(): invalid attr parameter: %08x", SCE_KERNEL_ERROR_ILLEGAL_ATTR, attr);
		return SCE_KERNEL_ERROR_ILLEGAL_ATTR;
	}
	if (partition < 1 || partition > 9 || partition == 7)
	{
		WARN_LOG_REPORT(HLE, "%08x=sceKernelCreateTls(): invalid partition %d", SCE_KERNEL_ERROR_ILLEGAL_ARGUMENT, partition);
		return SCE_KERNEL_ERROR_ILLEGAL_ARGUMENT;
	}
	// We only support user right now.
	if (partition != 2 && partition != 6)
	{
		WARN_LOG_REPORT(HLE, "%08x=sceKernelCreateTls(): invalid partition %d", SCE_KERNEL_ERROR_ILLEGAL_PERM, partition);
		return SCE_KERNEL_ERROR_ILLEGAL_PERM;
	}

	// There's probably a simpler way to get this same basic formula...
	// This is based on results from a PSP.
	bool illegalMemSize = blockSize == 0 || count == 0;
	if (!illegalMemSize && (u64) blockSize > ((0x100000000ULL / (u64) count) - 4ULL))
		illegalMemSize = true;
	if (!illegalMemSize && (u64) count >= 0x100000000ULL / (((u64) blockSize + 3ULL) & ~3ULL))
		illegalMemSize = true;
	if (illegalMemSize)
	{
		WARN_LOG_REPORT(HLE, "%08x=sceKernelCreateTls(): invalid blockSize/count", SCE_KERNEL_ERROR_ILLEGAL_MEMSIZE);
		return SCE_KERNEL_ERROR_ILLEGAL_MEMSIZE;
	}

	int index = -1;
	for (int i = 0; i < TLS_NUM_INDEXES; ++i)
		if (tlsUsedIndexes[i] == false)
		{
			index = i;
			break;
		}

	if (index == -1)
	{
		WARN_LOG_REPORT(HLE, "%08x=sceKernelCreateTls(): ran out of indexes for TLS objects", PSP_ERROR_TOO_MANY_TLS);
		return PSP_ERROR_TOO_MANY_TLS;
	}

	u32 totalSize = blockSize * count;
	u32 blockPtr = userMemory.Alloc(totalSize, (attr & PSP_TLS_ATTR_HIGHMEM) != 0, name);
	userMemory.ListBlocks();

	if (blockPtr == (u32) -1)
	{
		ERROR_LOG(HLE, "%08x=sceKernelCreateTls(%s, %d, %08x, %d, %d, %08x): failed to allocate memory", SCE_KERNEL_ERROR_NO_MEMORY, name, partition, attr, blockSize, count, optionsPtr);
		return SCE_KERNEL_ERROR_NO_MEMORY;
	}

	TLS *tls = new TLS();
	SceUID id = kernelObjects.Create(tls);

	tls->ntls.size = sizeof(tls->ntls);
	strncpy(tls->ntls.name, name, KERNELOBJECT_MAX_NAME_LENGTH);
	tls->ntls.name[KERNELOBJECT_MAX_NAME_LENGTH] = 0;
	tls->ntls.attr = attr;
	tls->ntls.index = index;
	tlsUsedIndexes[index] = true;
	tls->ntls.blockSize = blockSize;
	tls->ntls.totalBlocks = count;
	tls->ntls.freeBlocks = count;
	tls->ntls.numWaitThreads = 0;
	tls->address = blockPtr;
	tls->usage.resize(count, 0);

	WARN_LOG(HLE, "%08x=sceKernelCreateTls(%s, %d, %08x, %d, %d, %08x)", id, name, partition, attr, blockSize, count, optionsPtr);

	// TODO: just alignment?
	if (optionsPtr != 0)
		WARN_LOG(HLE, "sceKernelCreateTls(%s) unsupported options parameter: %08x", name, optionsPtr);
	if ((attr & PSP_TLS_ATTR_PRIORITY) != 0)
		WARN_LOG(HLE, "sceKernelCreateTls(%s) unsupported attr parameter: %08x", name, attr);

	return id;
}