summaryrefslogblamecommitdiffstats
path: root/private/ntos/nthals/haldti/mips/x4clock.s
blob: 9b20f0e03597da41230147761cee93ae95ecfb27 (plain) (tree)

















































































































































































































                                                                                                          
#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