#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