421 lines
18 KiB
ArmAsm
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)
|