summaryrefslogtreecommitdiffstats
path: root/private/ntos/nthals/haleagle/ppc/pxcalstl.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/ntos/nthals/haleagle/ppc/pxcalstl.c')
-rw-r--r--private/ntos/nthals/haleagle/ppc/pxcalstl.c184
1 files changed, 184 insertions, 0 deletions
diff --git a/private/ntos/nthals/haleagle/ppc/pxcalstl.c b/private/ntos/nthals/haleagle/ppc/pxcalstl.c
new file mode 100644
index 000000000..bc8044575
--- /dev/null
+++ b/private/ntos/nthals/haleagle/ppc/pxcalstl.c
@@ -0,0 +1,184 @@
+/*++
+
+Copyright (c) 1991-1993 Microsoft Corporation
+ Copyright 1994 MOTOROLA, INC. All Rights Reserved. This file
+ contains copyrighted material. Use of this file is restricted
+ by the provisions of a Motorola Software License Agreement.
+
+Module Name:
+
+ pxcalstl.c
+
+Abstract:
+
+
+ This module implements the calibration of the stall execution HAL
+ service for a PowerPC system.
+
+
+Author:
+
+ David N. Cutler (davec) 26-Apr-1991
+ Jim Wooldridge
+ Steve Johns (Motorola)
+
+Environment:
+
+ Kernel mode only.
+
+Revision History:
+
+--*/
+
+#include "halp.h"
+#include "pxsystyp.h"
+
+//
+// KeQueryPerformanceCounter & KeStallExecutionProcessor are called
+// before Phase 0 initialization, so initialize it to a reasonable value.
+//
+ULONG HalpPerformanceFrequency = 80000000/16;
+extern ULONG HalpClockCount;
+extern ULONG HalpFullTickClockCount;
+
+
+//
+// Put all code for HAL initialization in the INIT section. It will be
+// deallocated by memory management when phase 1 initialization is
+// completed.
+//
+
+#if defined(ALLOC_PRAGMA)
+
+#pragma alloc_text(INIT, HalpCalibrateStall)
+
+#endif
+
+
+
+ULONG
+HalpCalibrateTBPStack(
+ VOID
+ );
+
+
+BOOLEAN
+HalpCalibrateStall (
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This function calibrates the stall execution HAL service.
+
+ N.B. This routine is only called during phase 1 initialization.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ A value of TRUE is returned if the calibration is successfully
+ completed. Otherwise a value of FALSE is returned.
+
+--*/
+
+{ int i;
+ ULARGE_INTEGER BigNumber;
+ ULONG Variance;
+ ULONG BusSpeed;
+ static ULONG BusSpeeds [] = {
+ 25000000,
+ 33333333,
+ 40000000,
+ 41875000,
+ 50000000,
+ 55833333,
+ 60000000,
+ 66000000,
+ 66666666,
+ 67000000,
+ 75000000,
+ 80000000,
+ 83333333,
+ 83750000,
+ 90000000,
+ 99000000,
+ 100000000,
+ 111666666,
+ 120000000,
+ 132000000,
+ 133333332,
+ 134000000,
+ 150000000,
+ 160000000,
+ 166666666,
+ 167500000
+ };
+
+
+
+ //
+ // Set initial scale factor
+ //
+
+ PCR->StallScaleFactor = 1;
+
+ //
+ // Compute the clock frequency of the Time Base & Decrementer
+ //
+ // It's possible for reads from the CMOS RTC to return odd results.
+ // For this reason, We can use a do-while loop, to ensure the calibration
+ // function is called at least once and is returning a reasonable value.
+ //
+
+ do {
+ switch( HalpSystemType ) {
+
+ case MOTOROLA_POWERSTACK:
+ HalpPerformanceFrequency = HalpCalibrateTBPStack();
+ break;
+
+ default:
+ case MOTOROLA_BIG_BEND:
+ HalpPerformanceFrequency = HalpCalibrateTB();
+ break;
+ }
+ } while( HalpPerformanceFrequency < 1000000 );
+
+ //
+ // CPU bus runs at 4 times the DECREMENTER frequency
+ //
+ BusSpeed = HalpPerformanceFrequency * 4;
+
+ //
+ // Choose the bus speed which is closest to calculated value.
+ // If the bus speed is not "close enough", then it may be
+ // a new speed which we don't know about. For this case
+ // we will leave the Performance Frequency alone.
+ //
+ for (i=0; i< (sizeof(BusSpeeds)/sizeof(ULONG)); i++) {
+ //
+ // We are going to allow for a 0.1% variation
+ // in calibrated frequency of the system bus clock.
+ // Calculate the variance as 1/2048 the frequency.
+ //
+ Variance = BusSpeeds[i] >> 11;
+ if ((BusSpeeds[i] - Variance < BusSpeed) &&
+ (BusSpeeds[i] + Variance > BusSpeed)) {
+ HalpPerformanceFrequency = BusSpeeds[i] / 4;
+ break;
+ }
+ }
+
+ //
+ // Initialize the system clock variables
+ //
+ HalpClockCount = (HalpPerformanceFrequency * (MAXIMUM_INCREMENT/10000)) / 1000;
+ HalpFullTickClockCount = HalpClockCount;
+
+ return TRUE;
+}