windows-nt/Source/XPSP1/NT/base/hals/halia64/ia64/i64itm.s
2020-09-26 16:20:57 +08:00

256 lines
5 KiB
ArmAsm
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.

// TITLE ("Memory Fences, Load Acquires and Store Acquires")
/*++
Copyright (c) 1995 Intel Corporation
Module Name:
i64itm.s assembly routines for updating ITM.
Abstract:
This module implements the I/O port access routines.
Author:
Bernard Lint, M. Jayakumar 17 Sep '97
Environment:
Kernel mode
Revision History:
--*/
#include "ksia64.h"
.file "i64itm.s"
.global HalpClockCount
.global HalpITMUpdateLatency
.global HalpITCTicksPer100ns
// Temp until compiler fixed
LEAF_ENTRY(HalpInitLINT)
LEAF_SETUP(1,0,0,0)
mov t0 = 0x10000
;;
mov cr.lrr0 = t0
mov cr.lrr1 = t0
;;
// Clear pending interrupts from irr's
// read ivr until spurious (0xf)
// set tpr level to zero to unmask all ints
mov t2 = cr.tpr
;;
mov cr.tpr = zero
;;
srlz.d
mov t0 = 0xf
;;
Hil_loop:
mov t1 = cr.ivr
;;
cmp.ne pt0 = t0, t1
;;
(pt0) mov cr.eoi = zero
(pt0) br.spnt Hil_loop
// Restore tpr
mov cr.tpr = t2
;;
srlz.d
LEAF_RETURN
LEAF_EXIT(HalpInitLINT)
/*++
BOOLEAN
HalpDisableInterrupts (
)
Routine Description:
This function disables interrupts.
Arguements:
None.
Return Value:
TRUE if interrupts were previously enabled else FALSE
--*/
LEAF_ENTRY(HalpDisableInterrupts)
mov t0 = psr
mov v0 = TRUE // set return value -- TRUE if enabled
;;
tbit.z pt1 = t0, PSR_I // pt1 = 1 if disabled
;;
FAST_DISABLE_INTERRUPTS
(pt1) mov v0 = FALSE // FALSE if disabled
br.ret.sptk brp
LEAF_EXIT(HalpDisableInterrupts)
/*++
VOID
HalpTurnOffInterrupts (
VOID
)
Routine Description:
This function turns off interrupts and interruption resources collection.
Arguements:
None.
Return Value:
None.
--*/
LEAF_ENTRY(HalpTurnOffInterrupts)
rsm 1 << PSR_I
;;
rsm 1 << PSR_IC
;;
srlz.d
LEAF_RETURN
LEAF_EXIT(HalpTurnOffInterrupts)
/*++
VOID
HalpTurnOnInterrupts (
VOID
)
Routine Description:
This function turns on interruption resources collection and interrupts.
Arguements:
None.
Return Value:
None.
--*/
LEAF_ENTRY(HalpTurnOnInterrupts)
ssm 1 << PSR_IC // set PSR.ic bit again
;;
srlz.i // serialize
;;
ssm 1 << PSR_I // set PSR.i bit again
LEAF_RETURN
LEAF_EXIT(HalpTurnOnInterrupts)
/*++
VOID
HalpSetNextClockInterrupts (
VOID
)
Routine Description:
This function reads the current ITC and updates accordingly the ITM
register with interruption resources collection and interrupts off.
The interruption resources collection and interrupts are turned on
returning to the caller.
Arguements:
None.
Return Value:
currentITCValue - previousITMValue.
--*/
LEAF_ENTRY(HalpSetNextClockInterrupt)
.regstk 0, 2, 0, 0
alloc r2 = 0, 2, 0, 0
addl r31 = @gprel(HalpClockCount),gp
movl r9 = KiPcr+PcHalReserved // CURRENT_ITM_VALUE_INDEX = 0
addl r30 = @gprel(HalpITMUpdateLatency),gp
;;
ld8.acq r11 = [r9] // r11 = currentITMValue
ld8 r10 = [r31] // r10 = HalpClockCount
;;
// 08/16/2000 TF
// We should check if r11 == cr.itm here...
//
add r32 = r11, r10 // r32 = compareITCValue = currentITMValue + HalpClockCount
;;
rsm 1 << PSR_I
;;
rsm 1 << PSR_IC
;;
srlz.d
retry_itm_read:
mov cr.itm = r32 // set itm with the most common scenario
;;
mov r30 = cr.itm
retry_itc_read:
mov r33 = ar.itc // r33 = currentITCValue
;;
cmp.ne pt2 = r30, r32
(pt2) br.cond.spnt retry_itm_read // this should not be taken,
// this just makes sure itm is actually written
#ifndef DISABLE_ITC_WORKAROUND
cmp4.eq pt1 = -1, r33 // if lower 32 bits equal 0xffffffff
(pt1) br.cond.spnt retry_itc_read
;;
#endif // DISABLE_ITC_WORKAROUND
sub r30 = r32, r33 // calculate a ITM/ITC delta
;;
cmp.lt pt0 = r30, r0 // if a delta is negative set pt0
;;
(pt0) add r32 = r32, r10 // r32 = updated currentITMValue + HalpClockCount
(pt0) br.cond.spnt retry_itm_read
;;
ssm 1 << PSR_IC // set PSR.ic bit again
;;
srlz.d // serialize
ssm 1 << PSR_I // set PSR.i bit again
st8 [r9] = r32
sub r8 = r33, r11 // r8 = currentITCValue - previousITMValue
LEAF_RETURN
LEAF_EXIT(HalpSetNextClockInterrupt)