|
|
#if defined(R4000)
// TITLE("Interval and Profile Clock Interrupts") //++ // // Copyright (c) 1991 Microsoft Corporation // // Module Name: // // x4clock.s // // Abstract: // // This module implements the code necessary to field and process the // interval and profile clock interrupts on a MIPS R4000 system. // // Author: // // David N. Cutler (davec) 26-Apr-1991 // // Environment: // // Kernel mode only. // // Revision History: // //--
#include "halmips.h"
SBTTL("System Clock Interrupt") //++ // // Routine Description: // // This routine is entered as the result of an interrupt generated by // the interval timer. Its function is to acknowledge the interrupt and // transfer control to the standard system routine to update the system // time and the execution time of the current thread and process. // // Arguments: // // s8 - Supplies a pointer to a trap frame. // // Return Value: // // None. // //--
.struct 0 CiArgs: .space 4 * 4 // saved arguments .space 3 * 4 // fill CiRa: .space 4 // saved return address CiFrameLength: //
NESTED_ENTRY(HalpClockInterrupt, CiFrameLength, zero)
subu sp,sp,CiFrameLength // allocate stack frame sw ra,CiRa(sp) // save return address
PROLOGUE_END
move a0,s8 // set address of trap frame lw a1,HalpCurrentTimeIncrement // Get current time increment jal KeUpdateSystemTime // update system time lw t0,HalpNextTimeIncrement // Get NextTimeIncrement sw t0,HalpCurrentTimeIncrement // Set CurrentTimeIncrement to NextTimeIncrement lw a0,HalpNextIntervalCount // Get Next Interval Count. If 0, then no change required beq zero,a0,5f // See if time increment is to be changed jal HalpProgramIntervalTimer // Program timer with new interval count value lw t0,HalpNewTimeIncrement // Get HalpNewTimeIncrement sw t0,HalpNextTimeIncrement // Set HalpNextTimeIncrement to HalpNewTimeIncrement sw zero,HalpNextIntervalCount // Set HalpNextIntervalCount to 0 5: lw t0,KdDebuggerEnabled // check if debugger enabled lbu t0,0(t0) // beq zero,t0,10f // if eq, debugger not enabled jal KdPollBreakIn // check if breakin is requested beq zero,v0,10f // if eq, no breakin requested li a0,DBG_STATUS_CONTROL_C // break in and send jal DbgBreakPointWithStatus // status to debugger 10: lw ra,CiRa(sp) // restore return address addu sp,sp,CiFrameLength // deallocate stack frame j ra // return
.end HalpClockInterrupt
SBTTL("Profile Clock Interrupt") //++ // // Routine Description: // // This routine is entered as the result of an interrupt generated by the // profile clock. Its function is to acknowledge the profile interrupt, // compute the next compare value, update the performance counter, and // transfer control to the standard system routine to process any active // profiles. // // Arguments: // // s8 - Supplies a pointer to a trap frame. // // Return Value: // // None. // //--
LEAF_ENTRY(HalpProfileInterrupt)
.set noreorder .set noat mfc0 t1,count // get current count value mfc0 t0,compare // get current comparison value addu t1,t1,8 // factor in lost cycles subu t1,t1,t0 // compute initial count value mtc0 t0,compare // dismiss interrupt mtc0 t1,count // set new count register value .set at .set reorder
la t1,HalpPerformanceCounter // get performance counter address lw t2,LiLowPart(t1) // get low part of performance count lw t3,LiHighPart(t1) // get high part of performance count addu t2,t2,t0 // update low part of performance count sw t2,LiLowPart(t1) // store low part of performance count sltu t4,t2,t0 // generate carry into high part addu t3,t3,t4 // update high part of performance count sw t3,LiHighPart(t1) // store high part of performance count move a0,s8 // set address of trap frame j KeProfileInterrupt // process profile entries
.end HalpProfileInterrupt
SBTTL("Read Count Register") //++ // // ULONG // HalpReadCountRegister ( // VOID // );
// // Routine Description: // // This routine reads the current value of the count register and // returns the value. // // Arguments: // // None. // // Return Value: // // Current value of the count register. // //--
LEAF_ENTRY(HalpReadCountRegister)
.set noreorder .set noat mfc0 v0,count // get count register value .set at .set reorder
j ra // return
.end HalpReadCountRegister
SBTTL("Write Compare Register And Clear") //++ // // ULONG // HalpWriteCompareRegisterAndClear ( // IN ULONG Value // );
// // Routine Description: // // This routine reads the current value of the count register, writes // the value of the compare register, clears the count register, and // returns the previous value of the count register. // // Arguments: // // Value - Supplies the value written to the compare register. // // Return Value: // // Previous value of the count register. // //--
LEAF_ENTRY(HalpWriteCompareRegisterAndClear)
.set noreorder .set noat mfc0 v0,count // get count register value mtc0 a0,compare // set compare register value li t0,7 // set lost cycle count mtc0 t0,count // set count register to zero .set at .set reorder
j ra // return
.end HalpWriteCompareRegisterAndClear
#endif
|