[HAL] Implement APIC-based profiling for x64.

This commit is contained in:
Ivan Labutin 2017-11-06 21:40:21 +03:00 committed by Thomas Faber
parent ad68422a7b
commit 5ae2750467
No known key found for this signature in database
GPG key ID: 076E7C3D44720826
4 changed files with 85 additions and 5 deletions

View file

@ -278,5 +278,9 @@ VOID
NTAPI
ApicInitializeTimer(ULONG Cpu);
VOID
NTAPI
HalInitializeProfiling(VOID);
VOID __cdecl ApicSpuriousService(VOID);

View file

@ -16,6 +16,12 @@
extern LARGE_INTEGER HalpCpuClockFrequency;
/* HAL profiling variables */
BOOLEAN HalIsProfiling = FALSE;
ULONGLONG HalCurProfileInterval = 10000000;
ULONGLONG HalMinProfileInterval = 1000;
ULONGLONG HalMaxProfileInterval = 10000000;
/* TIMER FUNCTIONS ************************************************************/
VOID
@ -59,26 +65,89 @@ ApicInitializeTimer(ULONG Cpu)
/* PUBLIC FUNCTIONS ***********************************************************/
VOID
NTAPI
HalInitializeProfiling(VOID)
{
KeGetPcr()->HalReserved[HAL_PROFILING_INTERVAL] = HalCurProfileInterval;
KeGetPcr()->HalReserved[HAL_PROFILING_MULTIPLIER] = 1; /* TODO: HACK */
}
VOID
NTAPI
HalStartProfileInterrupt(IN KPROFILE_SOURCE ProfileSource)
{
UNIMPLEMENTED;
return;
LVT_REGISTER LvtEntry;
/* Only handle ProfileTime */
if (ProfileSource == ProfileTime)
{
/* OK, we are profiling now */
HalIsProfiling = TRUE;
/* Set interrupt interval */
ApicWrite(APIC_TICR, KeGetPcr()->HalReserved[HAL_PROFILING_INTERVAL]);
/* Unmask it */
LvtEntry.Long = 0;
LvtEntry.TimerMode = 1;
LvtEntry.Vector = APIC_PROFILE_VECTOR;
LvtEntry.Mask = 0;
ApicWrite(APIC_TMRLVTR, LvtEntry.Long);
}
}
VOID
NTAPI
HalStopProfileInterrupt(IN KPROFILE_SOURCE ProfileSource)
{
UNIMPLEMENTED;
return;
LVT_REGISTER LvtEntry;
/* Only handle ProfileTime */
if (ProfileSource == ProfileTime)
{
/* We are not profiling */
HalIsProfiling = FALSE;
/* Mask interrupt */
LvtEntry.Long = 0;
LvtEntry.TimerMode = 1;
LvtEntry.Vector = APIC_PROFILE_VECTOR;
LvtEntry.Mask = 1;
ApicWrite(APIC_TMRLVTR, LvtEntry.Long);
}
}
ULONG_PTR
NTAPI
HalSetProfileInterval(IN ULONG_PTR Interval)
{
UNIMPLEMENTED;
ULONGLONG TimerInterval;
ULONGLONG FixedInterval;
FixedInterval = (ULONGLONG)Interval;
/* Check bounds */
if (FixedInterval < HalMinProfileInterval)
{
FixedInterval = HalMinProfileInterval;
}
else if (FixedInterval > HalMaxProfileInterval)
{
FixedInterval = HalMaxProfileInterval;
}
/* Remember interval */
HalCurProfileInterval = FixedInterval;
/* Recalculate interval for APIC */
TimerInterval = FixedInterval * KeGetPcr()->HalReserved[HAL_PROFILING_MULTIPLIER] / HalMaxProfileInterval;
/* Remember recalculated interval in PCR */
KeGetPcr()->HalReserved[HAL_PROFILING_INTERVAL] = (ULONG)TimerInterval;
/* And set it */
ApicWrite(APIC_TICR, (ULONG)TimerInterval);
return Interval;
}

View file

@ -32,6 +32,9 @@ HalpInitProcessor(
/* Initialize the local APIC for this cpu */
ApicInitializeLocalApic(ProcessorNumber);
/* Initialize profiling data (but don't start it) */
HalInitializeProfiling();
/* Initialize the timer */
//ApicInitializeTimer(ProcessorNumber);

View file

@ -49,6 +49,10 @@ VOID
#define HAL_APC_REQUEST 0
#define HAL_DPC_REQUEST 1
/* HAL profiling offsets in KeGetPcr()->HalReserved[] */
#define HAL_PROFILING_INTERVAL 0
#define HAL_PROFILING_MULTIPLIER 1
/* CMOS Registers and Ports */
#define CMOS_CONTROL_PORT (PUCHAR)0x70
#define CMOS_DATA_PORT (PUCHAR)0x71