summaryrefslogtreecommitdiffstats
path: root/private/ntos/nthals/halflex/alpha/ev4ints.s
diff options
context:
space:
mode:
Diffstat (limited to 'private/ntos/nthals/halflex/alpha/ev4ints.s')
-rw-r--r--private/ntos/nthals/halflex/alpha/ev4ints.s300
1 files changed, 300 insertions, 0 deletions
diff --git a/private/ntos/nthals/halflex/alpha/ev4ints.s b/private/ntos/nthals/halflex/alpha/ev4ints.s
new file mode 100644
index 000000000..08fdaadc0
--- /dev/null
+++ b/private/ntos/nthals/halflex/alpha/ev4ints.s
@@ -0,0 +1,300 @@
+//++
+//
+// Copyright (C) 1994,1995 Microsoft Corporation
+//
+// Module Name:
+//
+// ev4ints.s
+//
+// Abstract:
+//
+// This module implements EV4-specific interrupt handlers.
+// (the performance counters)
+//
+//
+// Environment:
+//
+// Kernel mode only.
+//
+//
+//--
+#include "halalpha.h"
+
+#define PC0_SECONDARY_VECTOR 11
+#define PC1_SECONDARY_VECTOR 13
+#define PcProfileCount0 PcHalReserved+8
+#define PcProfileCount1 PcProfileCount0+4
+#define PcProfileCountReload0 PcProfileCount1+4
+#define PcProfileCountReload1 PcProfileCountReload0+4
+
+ .struct 0
+ .space 8 // reserved for alignment
+PrRa: .space 8 // space for return address
+PrFrameLength: //
+
+ SBTTL("Performance Counter 0 Interrupt")
+//++
+//
+// VOID
+// Halp21064PerformanceCounter0Interrupt
+// )
+//
+// Routine Description:
+//
+// This function is executed as the result of an interrupt from the
+// internal microprocessor performance counter 0. The interrupt
+// may be used to signal the completion of a profile event.
+// If profiling is current active, the function determines if the
+// profile interval has expired and if so dispatches to the standard
+// system routine to update the system profile time. If profiling
+// is not active then the function performs a secondary dispatch for
+// performance counter 0.
+//
+// Arguments:
+//
+// TrapFrame (fp/s6) - Supplies a pointer to the trap frame for
+// the interrupt.
+//
+// Return Value:
+//
+// TRUE is returned.
+//
+//--
+
+ NESTED_ENTRY(Halp21064PerformanceCounter0Interrupt, PrFrameLength, zero )
+
+ lda sp, -PrFrameLength(sp) // allocate a stack frame
+ stq ra, PrRa(sp) // save the return address
+
+ PROLOGUE_END //
+
+ call_pal rdpcr // v0 = pcr base address
+
+ ldl t0, PcProfileCount0(v0) // capture the current profile count
+ beq t0, 20f // if eq, profiling not active
+
+//
+// Profiling is active. Decrement the interval count and if it has
+// reached zero then call the kernel profile routine.
+//
+
+ subl t0, 1, t0 // decrement the interval count
+ bne t0, 10f // if ne, interval has not expired
+
+//
+// The profile interval has expired. Reset the profile interval count
+// and process the profile interrupt.
+//
+
+ ldl t0, PcProfileCountReload0(v0) // get the new tick count
+ stl t0, PcProfileCount0(v0) // reset the profile interval count
+
+ ldl a1, Halp21064ProfileSource0
+ bis fp, zero, a0 // pass trap frame pointer
+ ldl t1, __imp_KeProfileInterruptWithSource
+ jsr ra, (t1) // process the profile interrupt
+
+ br zero, 40f // common return
+
+//
+// The profile interval has not expired. Update the decremented count.
+//
+
+10:
+ stl t0, PcProfileCount0(v0) // update profile interval count
+ br zero, 40f // common return
+
+//
+// Profiling is not active. Therefore, this interrupt was caused by
+// a performance counter driver. Deliver a secondary dispatch.
+//
+
+20:
+
+ ldil a0, PC0_SECONDARY_VECTOR // get IDT vector for secondary
+ s4addl a0, v0, a0 // a0 = PCR + IDT index
+ ldl a0, PcInterruptRoutine(a0) // get service routine address
+ jsr ra, (a0) // call interrupt service routine
+
+//
+// Setup for return.
+//
+
+40:
+ ldil v0, TRUE // set return value = TRUE
+ ldq ra, PrRa(sp) // restore return address
+ lda sp, PrFrameLength(sp) // deallocate the stack frame
+ ret zero, (ra) // return
+
+ .end Halp21064PerformanceCounter0Interrupt
+
+
+ SBTTL("Performance Counter 1 Interrupt")
+//++
+//
+// VOID
+// Halp21064PerformanceCounter1Interrupt
+// )
+//
+// Routine Description:
+//
+// This function is executed as the result of an interrupt from the
+// internal microprocessor performance counter 1. The interrupt
+// may be used to signal the completion of a profile event.
+// If profiling is current active, the function determines if the
+// profile interval has expired and if so dispatches to the standard
+// system routine to update the system profile time. If profiling
+// is not active then the function performs a secondary dispatch for
+// performance counter 1.
+//
+// Arguments:
+//
+// TrapFrame (fp/s6) - Supplies a pointer to the trap frame for
+// the interrupt.
+//
+// Return Value:
+//
+// TRUE is returned.
+//
+//--
+
+ NESTED_ENTRY(Halp21064PerformanceCounter1Interrupt, PrFrameLength, zero )
+
+ lda sp, -PrFrameLength(sp) // allocate a stack frame
+ stq ra, PrRa(sp) // save the return address
+
+ PROLOGUE_END //
+
+ call_pal rdpcr // v0 = pcr base address
+
+ ldl t0, PcProfileCount1(v0) // capture the current profile count
+ beq t0, 20f // if eq, profiling not active
+
+//
+// Profiling is active. Decrement the interval count and if it has
+// reached zero then call the kernel profile routine.
+//
+
+ subl t0, 1, t0 // decrement the interval count
+ bne t0, 10f // if ne, interval has not expired
+
+//
+// The profile interval has expired. Reset the profile interval count
+// and process the profile interrupt.
+//
+
+ ldl t0, PcProfileCountReload1(v0) // get the new tick count
+ stl t0, PcProfileCount1(v0) // reset the profile interval count
+
+ ldl a1, Halp21064ProfileSource1
+ bis fp, zero, a0 // pass trap frame pointer
+ ldl t1, __imp_KeProfileInterruptWithSource
+ jsr ra, (t1) // process the profile interrupt
+
+ br zero, 40f // common return
+
+//
+// The profile interval has not expired. Update the decremented count.
+//
+
+10:
+ stl t0, PcProfileCount1(v0) // update profile interval count
+ br zero, 40f // common return
+
+//
+// Profiling is not active. Therefore, this interrupt was caused by
+// a performance counter driver. Deliver a secondary dispatch.
+//
+
+20:
+
+ ldil a0, PC1_SECONDARY_VECTOR // get IDT vector for secondary
+ s4addl a0, v0, a0 // a0 = PCR + IDT index
+ ldl a0, PcInterruptRoutine(a0) // get service routine address
+ jsr ra, (a0) // call interrupt service routine
+
+//
+// Setup for return.
+//
+
+40:
+ ldil v0, TRUE // set return value = TRUE
+ ldq ra, PrRa(sp) // restore return address
+ lda sp, PrFrameLength(sp) // deallocate the stack frame
+ ret zero, (ra) // return
+
+ .end Halp21064PerformanceCounter1Interrupt
+
+//++
+//
+// VOID
+// Halp21064WritePerformanceCounter(
+// IN ULONG PerformanceCounter,
+// IN BOOLEAN Enable,
+// IN ULONG MuxControl OPTIONAL,
+// IN ULONG EventCount OPTIONAL
+// )
+//
+// Routine Description:
+//
+// Write the specified microprocessor internal performance counter.
+//
+// Arguments:
+//
+// PerformanceCounter(a0) - Supplies the number of the performance counter
+// to write.
+//
+// Enable(a1) - Supplies a boolean that indicates if the performance
+// counter should be enabled or disabled.
+//
+// MuxControl(a2) - Supplies the mux control value which selects which
+// type of event to count when the counter is enabled.
+//
+// EventCount(a3) - Supplies the event interval when the counter is
+// enabled.
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+ LEAF_ENTRY(Halp21064WritePerformanceCounter)
+
+ call_pal wrperfmon // write the counter
+
+ ret zero, (ra) // return
+
+ .end Halp21064WritePerformanceCounter
+
+//++
+//
+// VOID
+// Halp21064ClearLockRegister(
+// PVOID LockAddress
+// )
+//
+// Routine Description:
+//
+// This function is called on every interrupt to clear the lock bit.
+//
+// Arguments:
+//
+// ClearLockAddress(a0) - Address in which to perform the conditional store.
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+ LEAF_ENTRY(Halp21064ClearLockRegister)
+
+ mb // Force all previous write off chip
+ stl_c zero, 0x0(a0) // Clear the lock register
+ mb // Force the write to clear the lock register off chip
+ ret zero, (ra) // return
+
+ .end Halp21064ClearLockRegister
+
+