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