mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 16:43:04 +00:00
[HAL] Implement APIC-based profiling for x64.
This commit is contained in:
parent
ad68422a7b
commit
5ae2750467
4 changed files with 85 additions and 5 deletions
|
@ -278,5 +278,9 @@ VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
ApicInitializeTimer(ULONG Cpu);
|
ApicInitializeTimer(ULONG Cpu);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
HalInitializeProfiling(VOID);
|
||||||
|
|
||||||
VOID __cdecl ApicSpuriousService(VOID);
|
VOID __cdecl ApicSpuriousService(VOID);
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,12 @@
|
||||||
|
|
||||||
extern LARGE_INTEGER HalpCpuClockFrequency;
|
extern LARGE_INTEGER HalpCpuClockFrequency;
|
||||||
|
|
||||||
|
/* HAL profiling variables */
|
||||||
|
BOOLEAN HalIsProfiling = FALSE;
|
||||||
|
ULONGLONG HalCurProfileInterval = 10000000;
|
||||||
|
ULONGLONG HalMinProfileInterval = 1000;
|
||||||
|
ULONGLONG HalMaxProfileInterval = 10000000;
|
||||||
|
|
||||||
/* TIMER FUNCTIONS ************************************************************/
|
/* TIMER FUNCTIONS ************************************************************/
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -59,26 +65,89 @@ ApicInitializeTimer(ULONG Cpu)
|
||||||
|
|
||||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
HalInitializeProfiling(VOID)
|
||||||
|
{
|
||||||
|
KeGetPcr()->HalReserved[HAL_PROFILING_INTERVAL] = HalCurProfileInterval;
|
||||||
|
KeGetPcr()->HalReserved[HAL_PROFILING_MULTIPLIER] = 1; /* TODO: HACK */
|
||||||
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
HalStartProfileInterrupt(IN KPROFILE_SOURCE ProfileSource)
|
HalStartProfileInterrupt(IN KPROFILE_SOURCE ProfileSource)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
LVT_REGISTER LvtEntry;
|
||||||
return;
|
|
||||||
|
/* 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
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
HalStopProfileInterrupt(IN KPROFILE_SOURCE ProfileSource)
|
HalStopProfileInterrupt(IN KPROFILE_SOURCE ProfileSource)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
LVT_REGISTER LvtEntry;
|
||||||
return;
|
|
||||||
|
/* 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
|
ULONG_PTR
|
||||||
NTAPI
|
NTAPI
|
||||||
HalSetProfileInterval(IN ULONG_PTR Interval)
|
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;
|
return Interval;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,9 @@ HalpInitProcessor(
|
||||||
/* Initialize the local APIC for this cpu */
|
/* Initialize the local APIC for this cpu */
|
||||||
ApicInitializeLocalApic(ProcessorNumber);
|
ApicInitializeLocalApic(ProcessorNumber);
|
||||||
|
|
||||||
|
/* Initialize profiling data (but don't start it) */
|
||||||
|
HalInitializeProfiling();
|
||||||
|
|
||||||
/* Initialize the timer */
|
/* Initialize the timer */
|
||||||
//ApicInitializeTimer(ProcessorNumber);
|
//ApicInitializeTimer(ProcessorNumber);
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,10 @@ VOID
|
||||||
#define HAL_APC_REQUEST 0
|
#define HAL_APC_REQUEST 0
|
||||||
#define HAL_DPC_REQUEST 1
|
#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 */
|
/* CMOS Registers and Ports */
|
||||||
#define CMOS_CONTROL_PORT (PUCHAR)0x70
|
#define CMOS_CONTROL_PORT (PUCHAR)0x70
|
||||||
#define CMOS_DATA_PORT (PUCHAR)0x71
|
#define CMOS_DATA_PORT (PUCHAR)0x71
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue