Kernel: Allow volatile for Tlspl objects.

This commit is contained in:
Unknown W. Brackets 2022-09-20 09:05:39 -07:00
parent 3c80bd94a2
commit 56f2d7cdac
2 changed files with 26 additions and 52 deletions

View file

@ -864,7 +864,7 @@ const HLEFunction ThreadManForUser[] =
{0XD8B299AE, &WrapU_IUUU<sceKernelSetVTimerHandler>, "sceKernelSetVTimerHandler", 'x', "ixxx" }, {0XD8B299AE, &WrapU_IUUU<sceKernelSetVTimerHandler>, "sceKernelSetVTimerHandler", 'x', "ixxx" },
{0X53B00E9A, &WrapU_IU64UU<sceKernelSetVTimerHandlerWide>, "sceKernelSetVTimerHandlerWide", 'x', "iXxx" }, {0X53B00E9A, &WrapU_IU64UU<sceKernelSetVTimerHandlerWide>, "sceKernelSetVTimerHandlerWide", 'x', "iXxx" },
{0X8DAFF657, &WrapI_CUUUUU<sceKernelCreateTlspl>, "sceKernelCreateTlspl", 'i', "sxxxxx" }, {0X8DAFF657, &WrapI_CUUUUU<sceKernelCreateTlspl>, "sceKernelCreateTlspl", 'i', "sixxxp" },
{0X32BF938E, &WrapI_I<sceKernelDeleteTlspl>, "sceKernelDeleteTlspl", 'i', "i" }, {0X32BF938E, &WrapI_I<sceKernelDeleteTlspl>, "sceKernelDeleteTlspl", 'i', "i" },
{0X721067F3, &WrapI_IU<sceKernelReferTlsplStatus>, "sceKernelReferTlsplStatus", 'i', "xp" }, {0X721067F3, &WrapI_IU<sceKernelReferTlsplStatus>, "sceKernelReferTlsplStatus", 'i', "xp" },
// Not completely certain about args. // Not completely certain about args.

View file

@ -2053,29 +2053,17 @@ void __KernelTlsplThreadEnd(SceUID threadID)
tlsplThreadEndChecks.erase(locked.first, locked.second); tlsplThreadEndChecks.erase(locked.first, locked.second);
} }
SceUID sceKernelCreateTlspl(const char *name, u32 partition, u32 attr, u32 blockSize, u32 count, u32 optionsPtr) SceUID sceKernelCreateTlspl(const char *name, u32 partition, u32 attr, u32 blockSize, u32 count, u32 optionsPtr) {
{
if (!name) if (!name)
{ return hleLogWarning(SCEKERNEL, SCE_KERNEL_ERROR_NO_MEMORY, "invalid name");
WARN_LOG_REPORT(SCEKERNEL, "%08x=sceKernelCreateTlspl(): invalid name", SCE_KERNEL_ERROR_NO_MEMORY);
return SCE_KERNEL_ERROR_NO_MEMORY;
}
if ((attr & ~PSP_TLSPL_ATTR_KNOWN) >= 0x100) if ((attr & ~PSP_TLSPL_ATTR_KNOWN) >= 0x100)
{ return hleLogWarning(SCEKERNEL, SCE_KERNEL_ERROR_ILLEGAL_ATTR, "invalid attr parameter: %08x", attr);
WARN_LOG_REPORT(SCEKERNEL, "%08x=sceKernelCreateTlspl(): invalid attr parameter: %08x", SCE_KERNEL_ERROR_ILLEGAL_ATTR, attr);
return SCE_KERNEL_ERROR_ILLEGAL_ATTR;
}
if (partition < 1 || partition > 9 || partition == 7) if (partition < 1 || partition > 9 || partition == 7)
{ return hleLogWarning(SCEKERNEL, SCE_KERNEL_ERROR_ILLEGAL_ARGUMENT, "invalid partition %d", partition);
WARN_LOG_REPORT(SCEKERNEL, "%08x=sceKernelCreateTlspl(): invalid partition %d", SCE_KERNEL_ERROR_ILLEGAL_ARGUMENT, partition);
return SCE_KERNEL_ERROR_ILLEGAL_ARGUMENT; BlockAllocator *allocator = BlockAllocatorFromID(partition);
} if (allocator == nullptr)
// We only support user right now. return hleLogWarning(SCEKERNEL, SCE_KERNEL_ERROR_ILLEGAL_PERM, "invalid partition %x", partition);
if (partition != 2 && partition != 6)
{
WARN_LOG_REPORT(SCEKERNEL, "%08x=sceKernelCreateTlspl(): 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... // There's probably a simpler way to get this same basic formula...
// This is based on results from a PSP. // This is based on results from a PSP.
@ -2085,41 +2073,29 @@ SceUID sceKernelCreateTlspl(const char *name, u32 partition, u32 attr, u32 block
if (!illegalMemSize && (u64) count >= 0x100000000ULL / (((u64) blockSize + 3ULL) & ~3ULL)) if (!illegalMemSize && (u64) count >= 0x100000000ULL / (((u64) blockSize + 3ULL) & ~3ULL))
illegalMemSize = true; illegalMemSize = true;
if (illegalMemSize) if (illegalMemSize)
{ return hleLogWarning(SCEKERNEL, SCE_KERNEL_ERROR_ILLEGAL_MEMSIZE, "invalid blockSize/count");
WARN_LOG_REPORT(SCEKERNEL, "%08x=sceKernelCreateTlspl(): invalid blockSize/count", SCE_KERNEL_ERROR_ILLEGAL_MEMSIZE);
return SCE_KERNEL_ERROR_ILLEGAL_MEMSIZE;
}
int index = -1; int index = -1;
for (int i = 0; i < TLSPL_NUM_INDEXES; ++i) for (int i = 0; i < TLSPL_NUM_INDEXES; ++i) {
if (tlsplUsedIndexes[i] == false) if (tlsplUsedIndexes[i] == false) {
{
index = i; index = i;
break; break;
} }
}
if (index == -1) if (index == -1)
{ return hleLogWarning(SCEKERNEL, PSP_ERROR_TOO_MANY_TLSPL, "ran out of indexes for TLS pools");
WARN_LOG_REPORT(SCEKERNEL, "%08x=sceKernelCreateTlspl(): ran out of indexes for TLS pools", PSP_ERROR_TOO_MANY_TLSPL);
return PSP_ERROR_TOO_MANY_TLSPL;
}
// Unless otherwise specified, we align to 4 bytes (a mips word.) // Unless otherwise specified, we align to 4 bytes (a mips word.)
u32 alignment = 4; u32 alignment = 4;
if (optionsPtr != 0) if (Memory::IsValidRange(optionsPtr, 4)) {
{ u32 size = Memory::ReadUnchecked_U32(optionsPtr);
u32 size = Memory::Read_U32(optionsPtr);
if (size > 8)
WARN_LOG_REPORT(SCEKERNEL, "sceKernelCreateTlspl(%s) unsupported options parameter, size = %d", name, size);
if (size >= 8) if (size >= 8)
alignment = Memory::Read_U32(optionsPtr + 4); alignment = Memory::Read_U32(optionsPtr + 4);
// Note that 0 intentionally is allowed. // Note that 0 intentionally is allowed.
if ((alignment & (alignment - 1)) != 0) if ((alignment & (alignment - 1)) != 0)
{ return hleLogError(SCEKERNEL, SCE_KERNEL_ERROR_ILLEGAL_ARGUMENT, "alignment is not a power of 2: %d", alignment);
ERROR_LOG_REPORT(SCEKERNEL, "sceKernelCreateTlspl(%s): alignment is not a power of 2: %d", name, alignment);
return SCE_KERNEL_ERROR_ILLEGAL_ARGUMENT;
}
// This goes for 0, 1, and 2. Can't have less than 4 byte alignment. // This goes for 0, 1, and 2. Can't have less than 4 byte alignment.
if (alignment < 4) if (alignment < 4)
alignment = 4; alignment = 4;
@ -2129,16 +2105,13 @@ SceUID sceKernelCreateTlspl(const char *name, u32 partition, u32 attr, u32 block
u32 alignedSize = (blockSize + alignment - 1) & ~(alignment - 1); u32 alignedSize = (blockSize + alignment - 1) & ~(alignment - 1);
u32 totalSize = alignedSize * count; u32 totalSize = alignedSize * count;
u32 blockPtr = userMemory.Alloc(totalSize, (attr & PSP_TLSPL_ATTR_HIGHMEM) != 0, name); u32 blockPtr = allocator->Alloc(totalSize, (attr & PSP_TLSPL_ATTR_HIGHMEM) != 0, name);
#ifdef _DEBUG #ifdef _DEBUG
userMemory.ListBlocks(); allocator->ListBlocks();
#endif #endif
if (blockPtr == (u32) -1) if (blockPtr == (u32)-1)
{ return hleLogError(SCEKERNEL, SCE_KERNEL_ERROR_NO_MEMORY, "failed to allocate memory");
ERROR_LOG(SCEKERNEL, "%08x=sceKernelCreateTlspl(%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;
}
TLSPL *tls = new TLSPL(); TLSPL *tls = new TLSPL();
SceUID id = kernelObjects.Create(tls); SceUID id = kernelObjects.Create(tls);
@ -2157,9 +2130,7 @@ SceUID sceKernelCreateTlspl(const char *name, u32 partition, u32 attr, u32 block
tls->alignment = alignment; tls->alignment = alignment;
tls->usage.resize(count, 0); tls->usage.resize(count, 0);
WARN_LOG(SCEKERNEL, "%08x=sceKernelCreateTlspl(%s, %d, %08x, %d, %d, %08x)", id, name, partition, attr, blockSize, count, optionsPtr); return hleLogSuccessInfoI(SCEKERNEL, id);
return id;
} }
int sceKernelDeleteTlspl(SceUID uid) int sceKernelDeleteTlspl(SceUID uid)
@ -2187,7 +2158,10 @@ int sceKernelDeleteTlspl(SceUID uid)
HLEKernel::ResumeFromWait(threadID, WAITTYPE_TLSPL, uid, 0); HLEKernel::ResumeFromWait(threadID, WAITTYPE_TLSPL, uid, 0);
hleReSchedule("deleted tlspl"); hleReSchedule("deleted tlspl");
userMemory.Free(tls->address); BlockAllocator *allocator = BlockAllocatorFromAddr(tls->address);
_assert_msg_(allocator != nullptr, "Should always have a valid allocator/address");
if (allocator)
allocator->Free(tls->address);
tlsplUsedIndexes[tls->ntls.index] = false; tlsplUsedIndexes[tls->ntls.index] = false;
kernelObjects.Destroy<TLSPL>(uid); kernelObjects.Destroy<TLSPL>(uid);
} }