mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
175 lines
5.5 KiB
175 lines
5.5 KiB
// TITLE("Compute Timer Table Index")
|
|
//++
|
|
//
|
|
// Copyright (c) 1993 Microsoft Corporation
|
|
//
|
|
// Module Name:
|
|
//
|
|
// timindex.s
|
|
//
|
|
// Abstract:
|
|
//
|
|
// This module implements the code necessary to compute the timer table
|
|
// index for a timer.
|
|
//
|
|
// Author:
|
|
//
|
|
// David N. Cutler (davec) 17-May-1993
|
|
//
|
|
// Environment:
|
|
//
|
|
// Kernel mode only.
|
|
//
|
|
// Revision History:
|
|
//
|
|
// Sep 19, 1993 plj Conversion to IBM PowerPC
|
|
//
|
|
//--
|
|
|
|
#include "ksppc.h"
|
|
|
|
//
|
|
// Define external vsriables that can be addressed using GP.
|
|
//
|
|
|
|
.extern KiTimeIncrementReciprocal
|
|
.extern KiTimeIncrementShiftCount
|
|
|
|
SBTTL("Compute Timer Table Index")
|
|
//++
|
|
//
|
|
// ULONG
|
|
// KiComputeTimerTableIndex (
|
|
// IN LARGE_INTEGER Interval,
|
|
// IN LARGE_INTEGER CurrentTime,
|
|
// IN PKTIMER Timer
|
|
// )
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This function computes the timer table index for the specified timer
|
|
// object and stores the due time in the timer object.
|
|
//
|
|
// N.B. The interval parameter is guaranteed to be negative since it is
|
|
// expressed as relative time.
|
|
//
|
|
// The formula for due time calculation is:
|
|
//
|
|
// Due Time = Current time - Interval
|
|
//
|
|
// The formula for the index calculation is:
|
|
//
|
|
// Index = (Due Time / Maximum Time) & (Table Size - 1)
|
|
//
|
|
// The due time division is performed using reciprocal multiplication.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Interval (r.3, r.4) - Supplies the relative time at which the timer is
|
|
// to expire.
|
|
//
|
|
// CurrentTime (r.5, r.6) - Supplies the current interrupt time.
|
|
//
|
|
// Timer (r.7) - Supplies a pointer to a dispatch object of type timer.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// The time table index is returned as the function value and the due
|
|
// time is stored in the timer object.
|
|
//
|
|
//--
|
|
|
|
LEAF_ENTRY(KiComputeTimerTableIndex)
|
|
|
|
// Get addresses of KiTimeIncrementReciprocal and KiTimeIncrementShiftCounter
|
|
|
|
lwz r.11, [toc]KiTimeIncrementReciprocal(r.toc)
|
|
lwz r.10, [toc]KiTimeIncrementShiftCount(r.toc)
|
|
|
|
lwz r.12, 4(r.11) // get high part of magic divisor
|
|
lwz r.11, 0(r.11) // get low part of magic divisor
|
|
|
|
// Calculate DueTime = CurrentTime - Interval, result in {r.3,r.4}
|
|
|
|
subfc r.3, r.3, r.5 // subtract low parts (with carry)
|
|
subfe r.4, r.4, r.6 // subtract high parts (using carry)
|
|
|
|
lbz r.10, 0(r.10) // get shift count
|
|
|
|
stw r.3, TiDueTime(r.7) // set due time of timer object
|
|
stw r.4, TiDueTime+4(r.7)
|
|
|
|
//
|
|
// Compute low 32-bits of dividend times low 32-bits of divisor.
|
|
//
|
|
mulhwu r.0, r.3, r.11
|
|
|
|
//
|
|
// Compute low 32-bits of dividend times high 32-bits of divisor.
|
|
//
|
|
mullw r.6, r.3, r.12 // low 32-bits to r.6
|
|
mulhwu r.7, r.3, r.12 // high 32-bits to r.7
|
|
|
|
//
|
|
// Compute high 32-bits of dividend times low 32-bits of divisor.
|
|
//
|
|
mullw r.8, r.4, r.11 // low 32-bits to r.8
|
|
mulhwu r.9, r.4, r.11 // high 32-bits to r.9
|
|
|
|
//
|
|
// Compute high 32-bits of dividend times high 32-bits of divisor.
|
|
//
|
|
mullw r.3, r.4, r.12 // low 32-bits to r.3
|
|
mulhwu r.4, r.4, r.12 // high 32-bits to r.4
|
|
|
|
//
|
|
// On the grounds that I can't do more than double precision arithmetic
|
|
// without visual aids, I will attempt to draw a picture of what is
|
|
// going on here,.... my apologies to those who don't need the pic.
|
|
//
|
|
//
|
|
// _________________________________________________________________
|
|
// | | | | |
|
|
// | | | Due Time Low * Recip Low |
|
|
// | | | r.0 - |
|
|
// |---------------------------------------------------------------|
|
|
// | | Due Time Low * Recip High | |
|
|
// | | r.7 r.6 | |
|
|
// |------------------------------------------------ |
|
|
// | | Due Time High * Recip Low | |
|
|
// | | r.9 r.8 | |
|
|
// |------------------------------------------------ |
|
|
// | Due Time High * Recip High | | |
|
|
// | r.4 r.3 | | |
|
|
// |---------------------------------------------------------------|
|
|
// | | | | |
|
|
// | x | y | z | |
|
|
// |----------------------------------------------------------------
|
|
//
|
|
|
|
//
|
|
// Add partial results to form high 64-bits of result.
|
|
//
|
|
// (add 3 low parts together (r.0, r.6 and r.8) generating carries.
|
|
// the carries are added to the sum of the high parts (r.7, r.9 and r.3),
|
|
// the sum of the low parts is discarded).
|
|
//
|
|
addc r.0, r.6, r.0 // z = r.0 + r.6
|
|
adde r.7, r.9, r.7 // y = r.7 + r.9 + carry from z
|
|
addze r.4, r.4 // x += carry from y
|
|
addc r.0, r.8, r.0 // z += r.8
|
|
adde r.3, r.3, r.7 // y += r.3 + carry from z
|
|
addze r.4, r.4 // x += carry from y
|
|
|
|
//
|
|
// Combine low part of x with high part of y
|
|
//
|
|
// N.B. It is assumed that the shift count is less than 32-bits and not zero.
|
|
//
|
|
subfic r.11, r.10, 32 // compute left shift count
|
|
srw r.3, r.3, r.10 // get high part of low part
|
|
slw r.4, r.4, r.11 // get low part of high word
|
|
or r.3, r.4, r.3 // combine upper low and lower high
|
|
rlwinm r.3, r.3, 0, TIMER_TABLE_SIZE - 1
|
|
|
|
LEAF_EXIT(KiComputeTimerTableIndex)
|