windows-nt/Source/XPSP1/NT/base/ntos/ke/ia64/ivtlog.s
2020-09-26 16:20:57 +08:00

421 lines
18 KiB
ArmAsm

// shadow IVT
// logs and then branches to the original vector code at KiIvtBase
//
#include "ksia64.h"
// For Conditional Interrupt Logging
#define KiVhptTransVectorBit 0
#define KiInstTlbVectorBit 1
#define KiDataTlbVectorBit 2
#define KiAltInstTlbVectorBit 3
#define KiAltDataTlbVectorBit 4
#define KiNestedTlbVectorBit 5
#define KiInstKeyMissVectorBit 6
#define KiDataKeyMissVectorBit 7
#define KiDirtyBitVectorBit 8
#define KiInstAccessBitVectorBit 9
#define KiDataAccessBitVectorBit 10
#define KiBreakVectorBit 11
#define KiExternalInterruptVectorBit 12
#define KiPageNotPresentVectorBit 13
#define KiKeyPermVectorBit 14
#define KiInstAccessRightsVectorBit 15
#define KiDataAccessRightsVectorBit 16
#define KiGeneralExceptionsVectorBit 17
#define KiDisabledFpRegisterVectorBit 18
#define KiNatConsumptionVectorBit 19
#define KiSpeculationVectorBit 20
#define KiDebugFaultVectorBit 21
#define KiUnalignedFaultVectorBit 22
#define KiFloatFaultVectorBit 23
#define KiFloatTrapVectorBit 24
#define KiLowerPrivilegeVectorBit 25
#define KiTakenBranchVectorBit 26
#define KiSingleStepVectorBit 27
#define KiIA32ExceptionVectorBit 28
#define KiIA32InterceptionVectorBit 29
#define KiIA32InterruptionVectorBit 30
// #define UserSystemcallBit 61
// #define ExternalInterruptBit 62
// #define ContextSwitchBit 63
// reserve bit 13 in ConfigFlag to indicate which IVT to use
#define DISABLE_TRACE_LOG 13
.file "ivtilog.s"
.explicit
.global KiVectorLogMask
#define VECTOR_ENTRY(Offset, Name, Extra0) \
.##global Name; \
.##type Name,@function; \
.##org Offset; \
.##global Name##ILog; \
.##proc Name##ILog; \
\
Name##ILog:: ;\
mov h30 = pr ;\
mov h27 = gp ;\
;; ;\
movl gp = _gp ;\
;; ;\
add h28 = @gprel(KiVectorLogMask), gp ;\
;; ;\
ld8 h29 = [h28] ;\
;; ;\
mov gp = h27 ;\
;; ;\
tbit.z pt1 = h29, Name##Bit ;\
(pt1) br.cond.sptk Name##ILogEnd ;\
;; ;\
\
mov h28 = cr.iip ;\
movl h25 = KiPcr+PcInterruptionCount ;\
;; ;\
mov h29 = cr.ipsr ;\
ld4.nt1 h26 = [h25] ;\
mov h24 = MAX_NUMBER_OF_IHISTORY_RECORDS - 1 ;\
;; ;\
add h27 = 1, h26 ;\
and h26 = h24, h26 ;\
add h24 = 0x1000-PcInterruptionCount, h25 ;\
;; ;\
st4.nta [h25] = h27 ;\
shl h26 = h26, 5 ;\
;; ;\
add h27 = h26, h24 ;\
mov h31 = (Offset >> 8) ;\
;; ;\
st8 [h27] = h31, 8 ;\
;; ;\
st8 [h27] = h28, 8 ;\
mov h31 = Extra0 ;\
;; ;\
st8 [h27] = h29, 8 ;\
;; ;\
st8 [h27] = h31; ;\
\
Name##ILogEnd:: ;\
\
mov pr = h30, -1 ;\
br.sptk Name
#define VECTOR_EXIT(Name) \
.##endp Name##ILog
#define VECTOR_ENTRY_HB_DUMP(Offset, Name, Extra0) \
.##global Name; \
.##type Name,@function; \
.##org Offset; \
.##global Name##ILog; \
.##proc Name##ILog; \
\
Name##ILog:: \
/* h30 = pr */ ;\
/* b0 = Name##ILogStart */ ;\
/* h29 = cpuid3 */ ;\
/* h28 = b0 */ ;\
{ .mmi ;\
mov ar.k1 = h24 ;\
mov ar.k2 = h25 ;\
nop.i 0 ;\
} ;\
{ .mmi ;\
mov ar.k4 = h27 ;\
mov ar.k5 = h28 ;\
nop.i 0 ;\
} ;\
{ .mii ;\
mov h29 = 3 ;\
mov h30 = pr ;\
mov h28 = b0;; ;\
} ;\
{ .mli ;\
mov h29 = cpuid[h29] ;\
movl h31 = Name##ILogStart;; ;\
} ;\
{ .mii ;\
mov h26 = 675 ;\
mov b0 = h31 /* set return address */ ;\
extr.u h24 = h29, 24, 8 ;; ;\
} ;\
{ .mib ;\
nop.m 0 ;\
cmp.ne pt0 = 7, h24 ;\
(pt0) br.cond.spnt Name##ILogStart ;\
} ;\
{ .mmi ;\
mov h27 = msr[h26] ;; ;\
nop.m 0 ;\
tbit.nz pt2 = r27, 8 /* skip if HB is disabled */ ;\
} ;\
{ .mib ;\
nop.m 0 ;\
dep h27 = 1, r27, 8, 1 /* disable HB */ ;\
(pt2) br.cond.spnt Name##ILogStart ;; ;\
} ;\
{ .mib ;\
mov msr[h26] = h27 ;\
nop.i 0 ;\
br.sptk KiDumpHistoryBuffer ;\
} ;\
;\
Name##ILogStart:: ;\
{ .mli ;\
mov h27 = gp ;\
movl h31 = Name##ILogEnd ;; ;\
} ;\
{ .mli ;\
nop.m 0 ;\
movl gp = _gp ;; ;\
} ;\
{ .mmi ;\
add h25 = @gprel(KiVectorLogMask), gp ;; ;\
ld8 h25 = [h25] ;\
mov b0 = r31 ;\
} ;\
{ .mmi ;\
mov h29 = (Offset >> 8) ;\
mov h31 = Extra0 ;\
mov gp = h27 ;; ;\
} ;\
{ .mib ;\
nop.m 0 ;\
tbit.nz pt1 = h25, Name##Bit ;\
(pt1) br.sptk KiLogInterruptEvent ;; ;\
} ;\
Name##ILogEnd:: ;\
{ .mii ;\
nop.m 0 ;\
mov b0 = h28 ;\
mov pr = h30, -1 ;\
} ;\
{ .mib ;\
nop.m 0 ;\
nop.i 0 ;\
br.sptk Name ;; ;\
}
.section .drectve, "MI", "progbits"
string "-section:.ivtilog,,align=0x8000"
.section .ivtilog = "ax", "progbits"
KiIvtBaseILog:: // symbol for start of shadow IVT
VECTOR_ENTRY(0x0000, KiVhptTransVector, cr.ifa)
VECTOR_EXIT(KiVhptTransVector)
VECTOR_ENTRY(0x0400, KiInstTlbVector, cr.iipa)
VECTOR_EXIT(KiInstTlbVector)
VECTOR_ENTRY(0x0800, KiDataTlbVector, cr.ifa)
VECTOR_EXIT(KiDataTlbVector)
VECTOR_ENTRY(0x0c00, KiAltInstTlbVector, cr.iipa)
VECTOR_EXIT(KiAltInstTlbVector)
VECTOR_ENTRY(0x1000, KiAltDataTlbVector, cr.ifa)
VECTOR_EXIT(KiAltDataTlbVector)
VECTOR_ENTRY(0x1400, KiNestedTlbVector, cr.ifa)
VECTOR_EXIT(KiNestedTlbVector)
VECTOR_ENTRY(0x1800, KiInstKeyMissVector, cr.iipa)
VECTOR_EXIT(KiInstKeyMissVector)
VECTOR_ENTRY(0x1c00, KiDataKeyMissVector, cr.ifa)
VECTOR_EXIT(KiDataKeyMissVector)
VECTOR_ENTRY(0x2000, KiDirtyBitVector, cr.ifa)
VECTOR_EXIT(KiDirtyBitVector)
VECTOR_ENTRY(0x2400, KiInstAccessBitVector, cr.iipa)
VECTOR_EXIT(KiInstAccessBitVector)
VECTOR_ENTRY(0x2800, KiDataAccessBitVector, cr.ifa)
VECTOR_EXIT(KiDataAccessBitVector)
VECTOR_ENTRY(0x2C00, KiBreakVector, cr.iim)
VECTOR_EXIT(KiBreakVector)
VECTOR_ENTRY(0x3000, KiExternalInterruptVector, r0)
VECTOR_EXIT(KiExternalInterruptVector)
VECTOR_ENTRY(0x5000, KiPageNotPresentVector, cr.ifa)
VECTOR_EXIT(KiPageNotPresentVector)
VECTOR_ENTRY(0x5100, KiKeyPermVector, cr.ifa)
VECTOR_EXIT(KiKeyPermVector)
VECTOR_ENTRY(0x5200, KiInstAccessRightsVector, cr.iipa)
VECTOR_EXIT(KiInstAccessRightsVector)
VECTOR_ENTRY(0x5300, KiDataAccessRightsVector, cr.ifa)
VECTOR_EXIT(KiDataAccessRightsVector)
VECTOR_ENTRY_HB_DUMP(0x5400, KiGeneralExceptionsVector, cr.isr)
// VECTOR_ENTRY(0x5400, KiGeneralExceptionsVector, cr.isr)
VECTOR_EXIT(KiGeneralExceptionsVector)
VECTOR_ENTRY(0x5500, KiDisabledFpRegisterVector, cr.isr)
VECTOR_EXIT(KiDisabledFpRegisterVector)
VECTOR_ENTRY(0x5600, KiNatConsumptionVector, cr.isr)
VECTOR_EXIT(KiNatConsumptionVector)
VECTOR_ENTRY(0x5700, KiSpeculationVector, cr.iim)
VECTOR_EXIT(KiSpeculationVector)
VECTOR_ENTRY(0x5900, KiDebugFaultVector, cr.isr)
VECTOR_EXIT(KiDebugFaultVector)
VECTOR_ENTRY(0x5a00, KiUnalignedFaultVector, cr.ifa)
VECTOR_EXIT(KiUnalignedFaultVector)
VECTOR_ENTRY(0x5c00, KiFloatFaultVector, cr.isr)
VECTOR_EXIT(KiFloatFaultVector)
VECTOR_ENTRY(0x5d00, KiFloatTrapVector, cr.isr)
VECTOR_EXIT(KiFloatTrapVector)
VECTOR_ENTRY(0x5e00, KiLowerPrivilegeVector, cr.iipa)
VECTOR_EXIT(KiLowerPrivilegeVector)
VECTOR_ENTRY(0x5f00, KiTakenBranchVector, cr.iipa)
VECTOR_EXIT(KiTakenBranchVector)
VECTOR_ENTRY(0x6000, KiSingleStepVector, cr.iipa)
VECTOR_EXIT(KiSingleStepVector)
VECTOR_ENTRY(0x6900, KiIA32ExceptionVector, r0)
VECTOR_EXIT(KiIA32ExceptionVector)
VECTOR_ENTRY(0x6a00, KiIA32InterceptionVector, r0)
VECTOR_EXIT(KiIA32InterceptionVector)
VECTOR_ENTRY(0x6b00, KiIA32InterruptionVector, r0)
VECTOR_EXIT(KiIA32InterruptionVector)
.org 0x7ff0
{ .mii
break.m 0
break.i 0
break.i 0}
.text
.global KiIvtBaseILog
LEAF_ENTRY (KiSwitchToLogVector)
movl t0 = KiIvtBaseILog
;;
mov cr.iva = t0 // switch IVT to no log IVT
;;
srlz.i
LEAF_RETURN
LEAF_EXIT (KiSwitchToLogVector)
LEAF_ENTRY (KiDumpHistoryBuffer)
mov h25 = 681
movl h31 = KiPcr+ProcessorControlRegisterLength + 8
mov h24 = 680
movl h29 = KiPcr+ProcessorControlRegisterLength ;
;;
.reg.val h24, 680
mov h26 = msr[h24]
.reg.val h25, 681
mov h27 = msr[h25]
add h24 = 2, h24
;;
st8 [h29] = h26, 16
st8 [h31] = h27, 16
add h25 = 2, h25
;;
.reg.val h24, 682
mov h26 = msr[h24]
.reg.val h25, 683
mov h27 = msr[h25]
add h24 = 2, h24
;;
st8 [h29] = h26, 16
st8 [h31] = h27, 16
add h25 = 2, h25
;;
.reg.val h24, 684
mov h26 = msr[h24]
.reg.val h24, 685
mov h27 = msr[h25]
add h24 = 2, h24
;;
st8 [h29] = h26, 16
st8 [h31] = h27, 16
add h25 = 2, h25
;;
.reg.val h24, 686
mov h26 = msr[h24]
.reg.val h25, 687
mov h27 = msr[h25]
mov h24 = 674
;;
st8 [h29] = h26
st8 [h31] = h27, 8
;;
mov h25 = msr[h24]
mov h26 = 675
;;
st8 [h31] = h25
mov h27 = msr[h26]
;;
dep h27 = 0, r27, 8, 1 // enable HB
;;
mov msr[h26] = h27
br.sptk b0
LEAF_EXIT (KiDumpHistoryBuffer)
//
// save it to the IH buffer
//
LEAF_ENTRY (KiLogInterruptEvent)
// h29 Offset
// h31 Extra
// h28,h30 should not be used
movl h25 = KiPcr+PcInterruptionCount
;;
ld4.nt1 h26 = [h25]
mov h24 = MAX_NUMBER_OF_IHISTORY_RECORDS - 1
;;
add h27 = 1, h26
and h26 = h24, h26
add h24 = 0x1000-PcInterruptionCount, h25
;;
st4.nta [h25] = h27
shl h26 = h26, 5
;;
add h27 = h26, h24
mov h24 = cr.iip
;;
mov h25 = cr.ipsr
st8 [h27] = h29, 8 // Log Offset with h29
;;
st8 [h27] = h24, 8 // Log IIP
;;
st8 [h27] = h25, 8 // Log IPSR
;;
st8 [h27] = h31 // Log Extra with h31
br.sptk b0
LEAF_EXIT (KiLogInterruptEvent)