void __KernelMemoryDoState(PointerWrap &p) { kernelMemory.DoState(p); userMemory.DoState(p); p.Do(vplWaitTimer); CoreTiming::RestoreRegisterEvent(vplWaitTimer, "VplTimeout", __KernelVplTimeout); p.DoMarker("sceKernelMemory"); }
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); }
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; }
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(); }
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)); }
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"); }
void sceKernelMaxFreeMemSize() { // TODO: Fudge factor improvement u32 retVal = userMemory.GetLargestFreeBlockSize()-0x40000; DEBUG_LOG(HLE,"%08x (dec %i)=sceKernelMaxFreeMemSize",retVal,retVal); RETURN(retVal); }
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; }
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; }
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; }
// 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; }
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); } }
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; }
//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); }
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; }
u32 sceKernelMaxFreeMemSize() { u32 retVal = userMemory.GetLargestFreeBlockSize(); DEBUG_LOG(HLE, "%08x (dec %i)=sceKernelMaxFreeMemSize()", retVal, retVal); return retVal; }
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; }
void sceKernelTotalFreeMemSize() { u32 retVal = userMemory.GetLargestFreeBlockSize()-0x8000; DEBUG_LOG(HLE,"%08x (dec %i)=sceKernelTotalFreeMemSize",retVal,retVal); RETURN(retVal); }
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(); }
void * operator new(size_t /* s */) { return ball.Alloc(); }
void operator delete (void * p) { ball.Free (p); }
u32 FreeMemoryBlock(u32 uid) { INFO_LOG(HLE, "FreeMemoryBlock(%08x)", uid); userMemory.Free(uid); return 0; }
u32 sceKernelTotalFreeMemSize() { u32 retVal = userMemory.GetTotalFreeBytes(); DEBUG_LOG(HLE, "%08x (dec %i)=sceKernelTotalFreeMemSize()", retVal, retVal); return retVal; }
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; }