Merge pull request #4207 from xXPBSXx/fix/ampr-amm-usage-stats
feat(libSceAmpr): answer sceAmprAmmGetUsageStatsData
This commit is contained in:
commit
955f4fbffe
|
|
@ -228,6 +228,18 @@ static constexpr int ThrdError = 4;
|
|||
|
||||
static std::atomic_flag sharedPtrSpinLock;
|
||||
|
||||
struct AmmUsageStatsData {
|
||||
std::uint64_t sizeInBytes;
|
||||
std::uint16_t numPageTablePoolEntries;
|
||||
std::uint16_t allocatedPageTablePoolEntries;
|
||||
std::uint16_t highWatermarkAllocatedEntries;
|
||||
std::uint16_t reserved;
|
||||
std::uint32_t ringIdleFlags;
|
||||
};
|
||||
static_assert(sizeof(AmmUsageStatsData) == 0x18);
|
||||
static constexpr std::uint16_t AmmPageTablePoolEntries = 512;
|
||||
static constexpr std::uint32_t AmmRingIdleFlags = 0x7;
|
||||
|
||||
extern "C" {
|
||||
int APS5_VABI pthread_join_nid_postfix(Pthread thread, void** value);
|
||||
int APS5_VABI wcsrtombs_s_nid_postfix(std::size_t* result, char* destination, std::size_t capacity, const std::uint16_t** source, std::size_t limit, void* state);
|
||||
|
|
@ -1000,8 +1012,13 @@ int APS5_VABI sceAmprFpclassifyd(double value) {
|
|||
return SonyFpclassifyd(value);
|
||||
}
|
||||
|
||||
int APS5_VABI sceAmprAmmGetUsageStatsData() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
int APS5_VABI sceAmprAmmGetUsageStatsData(AmmUsageStatsData* stats) {
|
||||
if (!stats || stats->sizeInBytes > sizeof(AmmUsageStatsData)) return SCE_KERNEL_ERROR_EINVAL;
|
||||
AmmUsageStatsData out{};
|
||||
out.sizeInBytes = stats->sizeInBytes;
|
||||
out.numPageTablePoolEntries = AmmPageTablePoolEntries;
|
||||
out.ringIdleFlags = AmmRingIdleFlags;
|
||||
std::memcpy(stats, &out, static_cast<std::size_t>(stats->sizeInBytes));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ std::uint64_t APS5_VABI sceAmprMeasureCommandSizeReadFileScatter(void*, std::uin
|
|||
std::uint64_t APS5_VABI sceAmprMeasureCommandSizeReadFileGatherScatter(void*, std::uint64_t, std::uint64_t);
|
||||
std::uint64_t APS5_VABI sceAmprMeasureCommandSizeResetGatherScatterState();
|
||||
std::size_t APS5_VABI sceKernelGetDirectMemorySize();
|
||||
int APS5_VABI sceAmprAmmGetUsageStatsData(void*);
|
||||
int APS5_VABI sceAmprAmmCommandBufferConstructor(Apr::CommandBufferObject*);
|
||||
int APS5_VABI sceAmprAmmCommandBufferMap(Apr::CommandBufferObject*, std::uint64_t, std::uint64_t, std::int32_t, std::int32_t);
|
||||
int APS5_VABI sceAmprAmmCommandBufferMapWithGpuMaskId(Apr::CommandBufferObject*, std::uint64_t, std::uint64_t, std::int32_t, std::int32_t, std::uint8_t);
|
||||
|
|
@ -853,6 +854,24 @@ void TestAmmRangesAboveHintedMaps() {
|
|||
Require(sceKernelMunmap(span, page) == 0);
|
||||
}
|
||||
|
||||
void TestAmmUsageStats() {
|
||||
std::array<std::uint64_t, 4> stats{};
|
||||
Require(sceAmprAmmGetUsageStatsData(nullptr) == static_cast<int>(0x80020016));
|
||||
stats[0] = 0x19;
|
||||
Require(sceAmprAmmGetUsageStatsData(stats.data()) == static_cast<int>(0x80020016));
|
||||
stats = {0x18, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef};
|
||||
Require(sceAmprAmmGetUsageStatsData(stats.data()) == 0);
|
||||
Require(stats[0] == 0x18);
|
||||
Require((stats[1] & 0xffffu) == 512u && (stats[1] >> 16u) == 0u);
|
||||
Require((stats[2] & 0xffffffffu) == 7u && (stats[2] >> 32u) == 0u);
|
||||
stats = {0x8, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef};
|
||||
Require(sceAmprAmmGetUsageStatsData(stats.data()) == 0);
|
||||
Require(stats[0] == 0x8 && stats[1] == 0xdeadbeef && stats[2] == 0xdeadbeef);
|
||||
stats = {0x0, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef};
|
||||
Require(sceAmprAmmGetUsageStatsData(stats.data()) == 0);
|
||||
Require(stats[0] == 0 && stats[1] == 0xdeadbeef);
|
||||
}
|
||||
|
||||
void TestAmm() {
|
||||
std::uint64_t start = 0;
|
||||
std::uint64_t end = 0;
|
||||
|
|
@ -1293,6 +1312,7 @@ int main() {
|
|||
TestResolveSymbolicLink();
|
||||
TestGatherScatter();
|
||||
TestAmmRangesAboveHintedMaps();
|
||||
TestAmmUsageStats();
|
||||
TestAmm();
|
||||
TestAmmRemapAndProtect();
|
||||
TestAmmPrt();
|
||||
|
|
|
|||
|
|
@ -10,5 +10,6 @@
|
|||
|
||||
### Functional
|
||||
|
||||
- [sceAmprAmmGetUsageStatsData](../../../core/libs/prx/libSceAmpr/Export.cpp) (libSceAmpr) fills the caller-sized 24-byte statistics structure with 512 page-table pool entries, no allocated entries, a zero high watermark and ring idle flags 0x7, the constants of [KytyPS5](https://github.com/KytyPS5/KytyPS5/blob/main/src/libs/libAmpr.cpp); they are not measured on a console, and the real call is a pass-through to `sceKernelMapperGetUsageStatsData` per [drakmor/ampr_emu](https://github.com/drakmor/ampr_emu/blob/main/src/ampr_emu_amm.cpp), which this port has no kernel-side counterpart for.
|
||||
- [Dinkumware thread exports](../../../core/libs/prx/libSceAmpr/Export.cpp) (libSceAmpr) follow the Dinkumware threads library shipped with [Visual C++ 2013](https://github.com/adityaramesh/concurrency_runtime/tree/master/VS2013_SP2/crt/src/thr) (`cthread.c`) and its `atomic.c`, [microsoft/STL `cthread.cpp`](https://github.com/microsoft/STL/blob/main/stl/src/cthread.cpp) and C11 Annex K, without console verification. `_Thrd_t` is taken to be the guest `pthread_t`, as the `std::_Pad::_Launch(pthread**)` export suggests: `_Thrd_join` returns `_Thrd_error` (4) when `pthread_join` fails and stores the thread's return value truncated to `int`. `_Thrd_join` (32-bit store of the result, 0 or 4) and the spin lock (byte exchange loop, no yield) match that disassembly. The shared_ptr spin lock is one process-wide flag that yields while it spins. `wcstombs_s` is `wcsrtombs_s` with a fresh conversion state, so `*retval` excludes the terminating null as in Annex K, not as in the Microsoft CRT, and `_TRUNCATE` has no meaning.
|
||||
- [_Cnd_signal, _Cnd_init_with_name](../../../core/libs/prx/libSceAmpr/Export.cpp) (libSceAmpr) - take a pointer to the handle slot like the libc `_Cnd_*` exports from [#3079](https://github.com/boykopovar/AnyPS5/pull/3079) and act on the same conditions. `_Cnd_signal` wakes one waiter and returns `_Thrd_success` (0), as `_Cnd_broadcast` does; whether the console maps a failing internal signal to `_Thrd_error` is not known. The signature `_Cnd_init_with_name(_Cnd_t*, const char* name)` is inferred from [fpPS4 `ps4_mtx_internal.pas`](https://github.com/red-prig/fpPS4/blob/trunk/src/libcinternal/ps4_mtx_internal.pas), where the PS4 `_Mtx_init` is `_Mtx_init_with_name` with the name `SceLibcI_Mtx` and the name only reaches the pthread object; here it is `_Cnd_init` and the name, which may be null, is ignored. Neither is confirmed on a PS5 `libc.prx`. `_Thrd_id` still throws: microsoft/STL returns an `unsigned int` thread id, but whether the PS5 returns the `pthread_t` or a kernel thread id, and at what width, is not known
|
||||
|
|
|
|||
|
|
@ -8,5 +8,5 @@
|
|||
|
||||
### Functional
|
||||
|
||||
- PPSA30601 imports declared without parameters, signatures unknown, added without an implementation because the title fails to load without them: [six sce::Json::Object::Pair, sce::Json::Object and sce::Json::Array::iterator members](../../../core/libs/prx/libSceJson2/Export.cpp) (libSceJson2), [sceAmprAmmGetUsageStatsData](../../../core/libs/prx/libSceAmpr/Export.cpp) (libSceAmpr), [sceMouseResetAbsolutePosition](../../../core/libs/prx/libSceMouse/Export.cpp) (libSceMouse) and [sceSaveDataDirNameSearch2](../../../core/libs/prx/libSceSaveData.native/Export.cpp) (libSceSaveData.native)
|
||||
- PPSA30601 imports declared without parameters, signatures unknown, added without an implementation because the title fails to load without them: [six sce::Json::Object::Pair, sce::Json::Object and sce::Json::Array::iterator members](../../../core/libs/prx/libSceJson2/Export.cpp) (libSceJson2), [sceMouseResetAbsolutePosition](../../../core/libs/prx/libSceMouse/Export.cpp) (libSceMouse) and [sceSaveDataDirNameSearch2](../../../core/libs/prx/libSceSaveData.native/Export.cpp) (libSceSaveData.native)
|
||||
- [sce::Json::InitParameter2 base-object constructor](../../../core/libs/prx/libSceJson2/Export.cpp) (libSceJson2) - forwards to the complete-object constructor and uses its inferred layout and default field values; constructor equivalence and initialization bytes remain unverified on the console
|
||||
|
|
|
|||
Loading…
Reference in New Issue