NT4/private/ntos/nthals/haltyne/mips/x4clock.s
2020-09-30 17:12:29 +02:00

211 lines
6.2 KiB
ArmAsm
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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