185 lines
3.7 KiB
C
185 lines
3.7 KiB
C
|
/*++
|
|||
|
|
|||
|
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;
|
|||
|
}
|