summaryrefslogtreecommitdiffstats
path: root/private/ntos/nthals/halsni4x/mips/xxclock.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/ntos/nthals/halsni4x/mips/xxclock.c')
-rw-r--r--private/ntos/nthals/halsni4x/mips/xxclock.c233
1 files changed, 233 insertions, 0 deletions
diff --git a/private/ntos/nthals/halsni4x/mips/xxclock.c b/private/ntos/nthals/halsni4x/mips/xxclock.c
new file mode 100644
index 000000000..0016c5194
--- /dev/null
+++ b/private/ntos/nthals/halsni4x/mips/xxclock.c
@@ -0,0 +1,233 @@
+//#pragma comment(exestr, "$Header: /usr4/winnt/SOURCES/ddk35/src/hal/halsni/mips/RCS/xxclock.c,v 1.3 1995/02/13 12:54:54 flo Exp $")
+
+/*++
+
+Copyright (c) 1993-94 Siemens Nixdorf Informationssysteme AG
+Copyright (c) 1985-94 Microsoft Corporation
+
+Module Name:
+
+ xxclock.c
+
+Abstract:
+
+
+ This module implements the function necesssary to change the clock
+ interrupt rate.
+
+Environment:
+
+ Kernel mode only.
+
+Revision History:
+
+--*/
+
+#include "halp.h"
+#include "eisa.h"
+#include "i82C54.h"
+
+
+//
+// Define global data used to communicate new clock rates to the clock
+// interrupt service routine.
+//
+
+ULONG HalpCurrentTimeIncrement;
+ULONG HalpNextTimeIncrement;
+ULONG HalpNewTimeIncrement;
+
+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.
+
+ N.B. This function is only executed on the processor that keeps the
+ system time.
+
+Arguments:
+
+ DesiredIncrement - Supplies desired number of 100ns units between clock
+ interrupts.
+
+Return Value:
+
+ The actual time increment in 100ns units.
+
+--*/
+
+{
+
+ ULONG NewTimeIncrement;
+ KIRQL OldIrql;
+
+ if (DesiredIncrement < MINIMUM_INCREMENT) {
+ DesiredIncrement = MINIMUM_INCREMENT;
+ }
+ if (DesiredIncrement > MAXIMUM_INCREMENT) {
+ DesiredIncrement = MAXIMUM_INCREMENT;
+ }
+
+ //
+ // 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);
+ NewTimeIncrement = DesiredIncrement / MINIMUM_INCREMENT;
+ NewTimeIncrement = NewTimeIncrement * MINIMUM_INCREMENT;
+ HalpNewTimeIncrement = NewTimeIncrement ;
+ KeLowerIrql(OldIrql);
+ return NewTimeIncrement;
+}
+
+VOID
+HalpProgramIntervalTimer (
+ IN ULONG Interval
+ )
+/*++
+
+Routine Description:
+
+ This function is called to program the System clock according to the frequency
+ required by the specified time increment value.
+
+ N.B. this information was found in the jenson (ALPHA) HAL
+ also valid for MIPS computer ???
+
+ There are four different rates that are used under NT
+ (see page 9-8 of KN121 System Module Programmer's Reference)
+
+ .976562 ms
+ 1.953125 ms
+ 3.90625 ms
+ 7.8125 ms
+
+
+Arguments:
+
+ Interval - Supplies desired number of 100ns units between clock
+ interrupts.
+
+Return Value:
+
+ none.
+
+--*/
+{
+ PEISA_CONTROL controlBase = (PEISA_CONTROL)HalpOnboardControlBase;
+ ULONG Count;
+ TIMER_CONTROL timerControl;
+ 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);
+
+ //
+ // Start the system clock to interrupt at the desired interval.
+ //
+ //
+
+ timerControl.BcdMode = 0;
+ timerControl.Mode = TM_SQUARE_WAVE;
+ timerControl.SelectByte = SB_LSB_THEN_MSB;
+ timerControl.SelectCounter = SELECT_COUNTER_0;
+
+ //
+ // use timer in the onboard PC core
+ //
+
+ Count = TIMER_CLOCK_IN / ( 10000000 / Interval );
+
+ WRITE_REGISTER_UCHAR(&controlBase->CommandMode1, *((PUCHAR) &timerControl));
+
+ //
+ // Set the system clock timer to the correct frequency.
+ //
+
+ WRITE_REGISTER_UCHAR(&controlBase->Timer1, (UCHAR)Count);
+ WRITE_REGISTER_UCHAR(&controlBase->Timer1, (UCHAR)(Count >> 8));
+
+ KeLowerIrql(OldIrql);
+}
+
+
+VOID
+HalpProgramExtraTimer (
+ IN ULONG Interval
+ )
+/*++
+
+Routine Description:
+
+ This function is called to program the second clock generator in a multiprocessor System
+ according to the frequency required by the specified Interval value (in 100ns units).
+
+
+Arguments:
+
+ Interval - Supplies desired number of 100ns units between clock
+ interrupts.
+
+Return Value:
+
+ none.
+
+--*/
+{
+
+ volatile PLOCAL_8254 pt = (PLOCAL_8254) RM400_EXTRA_TIMER_ADDR;
+ ULONG Count;
+ TIMER_CONTROL timerControl;
+ 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);
+
+ //
+ // Start the system clock to interrupt at the desired interval.
+ //
+ //
+
+ timerControl.BcdMode = 0;
+ timerControl.Mode = TM_SQUARE_WAVE;
+ timerControl.SelectByte = SB_LSB_THEN_MSB;
+ timerControl.SelectCounter = SELECT_COUNTER_0;
+
+ Count = EXTRA_TIMER_CLOCK_IN / (PRE_COUNT * 10000000 / Interval );
+
+ WRITE_REGISTER_UCHAR( &pt->control, *((PUCHAR) &timerControl));
+ WRITE_REGISTER_UCHAR(&(pt->counter0), (UCHAR)Count);
+ WRITE_REGISTER_UCHAR(&(pt->counter0), (UCHAR)(Count >> 8));
+
+ timerControl.BcdMode = 0;
+ timerControl.Mode = TM_RATE_GENERATOR;
+ timerControl.SelectByte = SB_LSB_THEN_MSB;
+ timerControl.SelectCounter = SELECT_COUNTER_2;
+
+ // the output of counter 2 is hardwired as input to counter 0/1
+ // so we use it as a pre-counter
+
+ WRITE_REGISTER_UCHAR( &pt->control, *((PUCHAR) &timerControl));
+ WRITE_REGISTER_UCHAR(&(pt->counter2), (UCHAR)PRE_COUNT);
+ WRITE_REGISTER_UCHAR(&(pt->counter2), (UCHAR)(PRE_COUNT >>8));
+
+ KeLowerIrql(OldIrql);
+
+}
+