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)
|
|||
|
|