NT4/private/ntos/nthals/haldti/mips/xxclock.c
2020-09-30 17:12:29 +02:00

172 lines
3.5 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1994 Microsoft Corporation
Module Name:
xxclock.c
Abstract:
This module implements the function necesssary to change the clock
interrupt rate.
Author:
David N. Cutler (davec) 7-Feb-1994
Environment:
Kernel mode only.
Revision History:
--*/
#include "halp.h"
#include "eisa.h"
//
// Define clock count and time table.
//
typedef struct _COUNT_ENTRY {
ULONG Count;
ULONG Time;
} COUNT_ENTRY, *PCOUNT_ENTRY;
COUNT_ENTRY TimeTable[] = {
{1197, 10032},
{2394, 20064},
{3591, 30096},
{4767, 39952},
{5964, 49984},
{7161, 60016},
{8358, 70048},
{9555, 80080},
{10731, 89936},
{11928, 99968}
};
//
// Define global data used to communicate new clock rates to the clock
// interrupt service routine.
//
ULONG HalpCurrentTimeIncrement;
ULONG HalpNextIntervalCount;
ULONG HalpNextTimeIncrement;
ULONG HalpNewTimeIncrement;
VOID
HalpProgramIntervalTimer(
IN ULONG IntervalCount
)
/*++
Routine Description:
This function is called to program the interval timer. It is used during
Phase 1 initialization to start the heartbeat timer. It also used by
the clock interrupt interrupt routine to change the hearbeat timer rate
when a call to HalSetTimeIncrement has been made in the previous time slice.
Arguments:
IntervalCount - Supplies cound value to be placed in the timer/counter.
Return Value:
None
--*/
{
PEISA_CONTROL controlBase;
TIMER_CONTROL timerControl;
//
// Set the system clock timer to the correct mode.
//
timerControl.BcdMode = 0;
timerControl.Mode = TM_SQUARE_WAVE;
timerControl.SelectByte = SB_LSB_THEN_MSB;
timerControl.SelectCounter = SELECT_COUNTER_0;
controlBase = HalpEisaControlBase;
WRITE_REGISTER_UCHAR(&controlBase->CommandMode1, *((PUCHAR) &timerControl));
//
// Set the system clock timer to the correct frequency.
//
WRITE_REGISTER_UCHAR(&controlBase->Timer1, (UCHAR)IntervalCount);
WRITE_REGISTER_UCHAR(&controlBase->Timer1, (UCHAR)(IntervalCount >> 8));
}
ULONG
HalSetTimeIncrement (
IN ULONG DesiredIncrement
)
/*++
Routine Description:
This function is called to set the clock interrupt rate to the frequency
required by the specified time increment value.
Arguments:
DesiredIncrement - Supplies desired number of 100ns units between clock
interrupts.
Return Value:
The actual time increment in 100ns units.
--*/
{
ULONG Index;
KIRQL OldIrql;
//
// Raise IRQL to the highest level, set the new clock interrupt
// parameters, lower IRQl, and return the new time increment value.
//
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
//
// The new clock count value is selected from a precomputed table of
// count/time pairs. The values in the table were selected for their
// accuracy and closeness to the values of 1ms, 2ms, 3ms, etc. to 10ms.
//
// N.B. The NT executive guarantees that this function will never
// be called with the desired incrment less than the minimum
// increment or greater than the maximum increment.
//
for (Index = 0; Index < sizeof(TimeTable) / sizeof(COUNT_ENTRY); Index += 1) {
if (DesiredIncrement <= TimeTable[Index].Time) {
break;
}
}
if (DesiredIncrement < TimeTable[Index].Time) {
Index -= 1;
}
HalpNextIntervalCount = TimeTable[Index].Count;
HalpNewTimeIncrement = TimeTable[Index].Time;
KeLowerIrql(OldIrql);
return TimeTable[Index].Time;
}