2015-01-27 01:19:51 +01:00
|
|
|
#include "stdafx.h"
|
|
|
|
|
#include "Emu/System.h"
|
2016-05-13 12:17:26 +02:00
|
|
|
#include "Emu/PSP2/ARMv7Module.h"
|
2015-01-27 01:19:51 +01:00
|
|
|
|
2015-06-21 01:04:01 +02:00
|
|
|
#include "scePerf.h"
|
2015-02-01 22:12:40 +01:00
|
|
|
|
2017-05-13 20:30:37 +02:00
|
|
|
logs::channel scePerf("scePerf");
|
2016-02-01 22:53:16 +01:00
|
|
|
|
2015-06-21 01:04:01 +02:00
|
|
|
extern u64 get_system_time();
|
2015-02-01 22:12:40 +01:00
|
|
|
|
2016-08-16 17:46:24 +02:00
|
|
|
template<>
|
|
|
|
|
void fmt_class_string<ScePerfError>::format(std::string& out, u64 arg)
|
|
|
|
|
{
|
|
|
|
|
format_enum(out, arg, [](auto error)
|
|
|
|
|
{
|
|
|
|
|
switch (error)
|
|
|
|
|
{
|
|
|
|
|
STR_CASE(SCE_PERF_ERROR_INVALID_ARGUMENT);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return unknown;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
error_code scePerfArmPmonReset(ARMv7Thread& cpu, s32 threadId)
|
2015-02-01 22:12:40 +01:00
|
|
|
{
|
2016-01-12 22:57:16 +01:00
|
|
|
scePerf.warning("scePerfArmPmonReset(threadId=0x%x)", threadId);
|
2015-02-01 22:12:40 +01:00
|
|
|
|
2016-08-15 02:11:49 +02:00
|
|
|
verify(HERE), threadId == SCE_PERF_ARM_PMON_THREAD_ID_SELF;
|
2015-02-01 22:12:40 +01:00
|
|
|
|
2016-02-01 22:53:16 +01:00
|
|
|
cpu.counters = {};
|
2015-01-27 01:19:51 +01:00
|
|
|
|
|
|
|
|
return SCE_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-16 17:46:24 +02:00
|
|
|
error_code scePerfArmPmonSelectEvent(ARMv7Thread& cpu, s32 threadId, u32 counter, u8 eventCode)
|
2015-01-27 01:19:51 +01:00
|
|
|
{
|
2016-01-12 22:57:16 +01:00
|
|
|
scePerf.warning("scePerfArmPmonSelectEvent(threadId=0x%x, counter=0x%x, eventCode=0x%x)", threadId, counter, eventCode);
|
2015-02-01 22:12:40 +01:00
|
|
|
|
2016-08-15 02:11:49 +02:00
|
|
|
verify(HERE), threadId == SCE_PERF_ARM_PMON_THREAD_ID_SELF;
|
2015-02-01 22:12:40 +01:00
|
|
|
|
|
|
|
|
if (counter >= 6)
|
|
|
|
|
{
|
2015-06-21 01:04:01 +02:00
|
|
|
return SCE_PERF_ERROR_INVALID_ARGUMENT;
|
2015-02-01 22:12:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
u32 value = 0; // initial value
|
|
|
|
|
|
|
|
|
|
switch (eventCode)
|
|
|
|
|
{
|
|
|
|
|
case SCE_PERF_ARM_PMON_SOFT_INCREMENT: break;
|
|
|
|
|
|
|
|
|
|
case SCE_PERF_ARM_PMON_BRANCH_MISPREDICT:
|
|
|
|
|
case SCE_PERF_ARM_PMON_DCACHE_MISS:
|
2015-02-06 01:23:37 +01:00
|
|
|
case SCE_PERF_ARM_PMON_DCACHE_STALL:
|
|
|
|
|
case SCE_PERF_ARM_PMON_ICACHE_STALL:
|
|
|
|
|
case SCE_PERF_ARM_PMON_DATA_EVICTION:
|
|
|
|
|
case SCE_PERF_ARM_PMON_WRITE_STALL:
|
|
|
|
|
case SCE_PERF_ARM_PMON_MAINTLB_STALL:
|
2015-02-01 22:12:40 +01:00
|
|
|
case SCE_PERF_ARM_PMON_UNALIGNED:
|
|
|
|
|
{
|
|
|
|
|
value = 1; // these events will probably never be implemented
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case SCE_PERF_ARM_PMON_PREDICT_BRANCH:
|
|
|
|
|
case SCE_PERF_ARM_PMON_DCACHE_ACCESS:
|
|
|
|
|
{
|
|
|
|
|
value = 1000; // these events will probably never be implemented
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-02 03:54:36 +02:00
|
|
|
default:
|
|
|
|
|
{
|
2016-08-08 18:01:06 +02:00
|
|
|
fmt::throw_exception("Unknown event requested" HERE);
|
2015-07-02 03:54:36 +02:00
|
|
|
}
|
2015-02-01 22:12:40 +01:00
|
|
|
}
|
|
|
|
|
|
2016-02-01 22:53:16 +01:00
|
|
|
cpu.counters[counter].event = eventCode;
|
|
|
|
|
cpu.counters[counter].value = value;
|
2015-02-01 22:12:40 +01:00
|
|
|
|
|
|
|
|
return SCE_OK;
|
2015-01-27 01:19:51 +01:00
|
|
|
}
|
|
|
|
|
|
2016-08-16 17:46:24 +02:00
|
|
|
error_code scePerfArmPmonStart(ARMv7Thread& cpu, s32 threadId)
|
2015-01-27 01:19:51 +01:00
|
|
|
{
|
2016-01-12 22:57:16 +01:00
|
|
|
scePerf.warning("scePerfArmPmonStart(threadId=0x%x)", threadId);
|
2015-02-01 22:12:40 +01:00
|
|
|
|
2016-08-15 02:11:49 +02:00
|
|
|
verify(HERE), threadId == SCE_PERF_ARM_PMON_THREAD_ID_SELF;
|
2015-02-01 22:12:40 +01:00
|
|
|
|
|
|
|
|
return SCE_OK;
|
2015-01-27 01:19:51 +01:00
|
|
|
}
|
|
|
|
|
|
2016-08-16 17:46:24 +02:00
|
|
|
error_code scePerfArmPmonStop(ARMv7Thread& cpu, s32 threadId)
|
2015-01-27 01:19:51 +01:00
|
|
|
{
|
2016-01-12 22:57:16 +01:00
|
|
|
scePerf.warning("scePerfArmPmonStop(threadId=0x%x)");
|
2015-02-01 22:12:40 +01:00
|
|
|
|
2016-08-15 02:11:49 +02:00
|
|
|
verify(HERE), threadId == SCE_PERF_ARM_PMON_THREAD_ID_SELF;
|
2015-02-01 22:12:40 +01:00
|
|
|
|
|
|
|
|
return SCE_OK;
|
2015-01-27 01:19:51 +01:00
|
|
|
}
|
|
|
|
|
|
2016-08-16 17:46:24 +02:00
|
|
|
error_code scePerfArmPmonGetCounterValue(ARMv7Thread& cpu, s32 threadId, u32 counter, vm::ptr<u32> pValue)
|
2015-01-27 01:19:51 +01:00
|
|
|
{
|
2016-01-12 22:57:16 +01:00
|
|
|
scePerf.warning("scePerfArmPmonGetCounterValue(threadId=0x%x, counter=%d, pValue=*0x%x)", threadId, counter, pValue);
|
2015-02-01 22:12:40 +01:00
|
|
|
|
2016-08-15 02:11:49 +02:00
|
|
|
verify(HERE), threadId == SCE_PERF_ARM_PMON_THREAD_ID_SELF;
|
2015-02-01 22:12:40 +01:00
|
|
|
|
|
|
|
|
if (counter >= 6 && counter != SCE_PERF_ARM_PMON_CYCLE_COUNTER)
|
|
|
|
|
{
|
2015-06-21 01:04:01 +02:00
|
|
|
return SCE_PERF_ERROR_INVALID_ARGUMENT;
|
2015-02-01 22:12:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (counter < 6)
|
|
|
|
|
{
|
2016-02-01 22:53:16 +01:00
|
|
|
*pValue = cpu.counters[counter].value;
|
2015-02-01 22:12:40 +01:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2016-08-08 18:01:06 +02:00
|
|
|
fmt::throw_exception("Cycle counter requested" HERE);
|
2015-02-01 22:12:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return SCE_OK;
|
2015-01-27 01:19:51 +01:00
|
|
|
}
|
|
|
|
|
|
2016-08-16 17:46:24 +02:00
|
|
|
error_code scePerfArmPmonSoftwareIncrement(ARMv7Thread& cpu, u32 mask)
|
2015-01-27 01:19:51 +01:00
|
|
|
{
|
2016-01-12 22:57:16 +01:00
|
|
|
scePerf.warning("scePerfArmPmonSoftwareIncrement(mask=0x%x)", mask);
|
2015-02-01 22:12:40 +01:00
|
|
|
|
|
|
|
|
if (mask > SCE_PERF_ARM_PMON_COUNTER_MASK_ALL)
|
|
|
|
|
{
|
2015-06-21 01:04:01 +02:00
|
|
|
return SCE_PERF_ERROR_INVALID_ARGUMENT;
|
2015-02-01 22:12:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (u32 i = 0; i < 6; i++, mask >>= 1)
|
|
|
|
|
{
|
|
|
|
|
if (mask & 1)
|
|
|
|
|
{
|
2016-02-01 22:53:16 +01:00
|
|
|
cpu.counters[i].value++;
|
2015-02-01 22:12:40 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return SCE_OK;
|
2015-01-27 01:19:51 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
u64 scePerfGetTimebaseValue()
|
|
|
|
|
{
|
2016-01-12 22:57:16 +01:00
|
|
|
scePerf.warning("scePerfGetTimebaseValue()");
|
2015-02-01 22:12:40 +01:00
|
|
|
|
|
|
|
|
return get_system_time();
|
2015-01-27 01:19:51 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
u32 scePerfGetTimebaseFrequency()
|
|
|
|
|
{
|
2016-01-12 22:57:16 +01:00
|
|
|
scePerf.warning("scePerfGetTimebaseFrequency()");
|
2015-02-01 22:12:40 +01:00
|
|
|
|
|
|
|
|
return 1;
|
2015-01-27 01:19:51 +01:00
|
|
|
}
|
|
|
|
|
|
2015-06-21 01:04:01 +02:00
|
|
|
s32 _sceRazorCpuInit(vm::cptr<void> pBufferBase, u32 bufferSize, u32 numPerfCounters, vm::pptr<u32> psceRazorVars)
|
2015-01-27 01:19:51 +01:00
|
|
|
{
|
2016-08-08 18:01:06 +02:00
|
|
|
fmt::throw_exception("Unimplemented" HERE);
|
2015-01-27 01:19:51 +01:00
|
|
|
}
|
|
|
|
|
|
2015-06-21 01:04:01 +02:00
|
|
|
s32 sceRazorCpuPushMarker(vm::cptr<char> szLabel)
|
2015-01-27 01:19:51 +01:00
|
|
|
{
|
2016-08-08 18:01:06 +02:00
|
|
|
fmt::throw_exception("Unimplemented" HERE);
|
2015-01-27 01:19:51 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s32 sceRazorCpuPopMarker()
|
|
|
|
|
{
|
2016-08-08 18:01:06 +02:00
|
|
|
fmt::throw_exception("Unimplemented" HERE);
|
2015-01-27 01:19:51 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s32 sceRazorCpuSync()
|
|
|
|
|
{
|
2016-08-08 18:01:06 +02:00
|
|
|
fmt::throw_exception("Unimplemented" HERE);
|
2015-01-27 01:19:51 +01:00
|
|
|
}
|
|
|
|
|
|
2016-02-01 22:53:16 +01:00
|
|
|
#define REG_FUNC(nid, name) REG_FNID(ScePerf, nid, name)
|
2015-01-27 01:19:51 +01:00
|
|
|
|
2016-02-01 22:53:16 +01:00
|
|
|
DECLARE(arm_module_manager::ScePerf)("ScePerf", []()
|
2015-01-27 01:19:51 +01:00
|
|
|
{
|
|
|
|
|
REG_FUNC(0x35151735, scePerfArmPmonReset);
|
|
|
|
|
REG_FUNC(0x63CBEA8B, scePerfArmPmonSelectEvent);
|
|
|
|
|
REG_FUNC(0xC9D969D5, scePerfArmPmonStart);
|
|
|
|
|
REG_FUNC(0xD1A40F54, scePerfArmPmonStop);
|
|
|
|
|
REG_FUNC(0x6132A497, scePerfArmPmonGetCounterValue);
|
|
|
|
|
//REG_FUNC(0x12F6C708, scePerfArmPmonSetCounterValue);
|
|
|
|
|
REG_FUNC(0x4264B4E7, scePerfArmPmonSoftwareIncrement);
|
|
|
|
|
REG_FUNC(0xBD9615E5, scePerfGetTimebaseValue);
|
|
|
|
|
REG_FUNC(0x78EA4FFB, scePerfGetTimebaseFrequency);
|
|
|
|
|
REG_FUNC(0x7AD6AC30, _sceRazorCpuInit);
|
|
|
|
|
REG_FUNC(0xC3DE4C0A, sceRazorCpuPushMarker);
|
|
|
|
|
REG_FUNC(0xDC3224C3, sceRazorCpuPopMarker);
|
|
|
|
|
REG_FUNC(0x4F1385E3, sceRazorCpuSync);
|
2016-01-12 22:57:16 +01:00
|
|
|
});
|