2020-09-30 17:12:29 +02:00

206 lines
5.8 KiB
ArmAsm
Raw Permalink 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.

// TITLE("Clock and Eisa Interrupt Handlers")
//++
//
// Copyright (c) 1993 Digital Equipment Corporation
//
// Module Name:
//
// jxintsup.s
//
// Abstract:
//
// This module implements the first level interrupt handlers
// for JENSEN.
//
// Author:
//
// Joe Notarangelo 08-Jul-1993
//
// Environment:
//
// Kernel mode only.
//
// Revision History:
//
//--
#include "ksalpha.h"
#include "jnsnrtc.h"
SBTTL("System Clock Interrupt")
//++
//
// VOID
// HalpClockInterrupt(
// )
//
// Routine Description:
//
// This function is executed for each interval timer interrupt on
// the JENSEN. The routine is responsible for acknowledging the
// interrupt and calling the kernel to update the system time.
// In addition, this routine checks for breakins from the kernel debugger
// and maintains the 64 bit performance counter based upon the
// processor cycle counter.
//
// Arguments:
//
// TrapFrame (fp/s6) - Supplies a pointer to the trap frame for
// the interrupt.
//
// Return Value:
//
// None.
//
//--
.struct 0
.space 8 // filler for octaword alignment
CiRa: .space 8 // space for return address
CiFrameLength: //
NESTED_ENTRY(HalpClockInterrupt, CiFrameLength, zero )
lda sp, -CiFrameLength(sp) // allocate stack frame
stq ra, CiRa(sp) // save return address
PROLOGUE_END
//
// Acknowledge the clock interrupt, by reading the control register c of
// the Real Time Clock in the 82C106 (VTI Combo Chip).
//
ldil a0, RTC_APORT // get the address port for rtc
ldil a1, RTC_CONTROL_REGISTERC // address for control register
bsr ra, HalpWriteVti // write the address port
ldil a0, RTC_DPORT // get the data port for the rtc
bsr ra, HalpReadVti // read the data port
//
// Call the kernel to update the system time.
//
ldl a1, HalpCurrentTimeIncrement
bis fp, zero, a0 // a0 = pointer to trap frame
ldl t0, __imp_KeUpdateSystemTime
jsr ra, (t0) // call kernel to update system time
ldl t0, HalpNextTimeIncrement // Get next time increment
stl t0, HalpCurrentTimeIncrement // Set CurrentTimeIncrement to NextTimeIncrement
ldl a0, HalpNextRateSelect // Get NextIntervalCount. If 0, no change required
beq a0, 5f
stl zero, HalpNextRateSelect // Set NextRateSelect to 0
bsr ra, HalpProgramIntervalTimer // Program timer with new rate select
ldl t0, HalpNewTimeIncrement // Get HalpNewTimeIncrement
stl t0, HalpNextTimeIncrement // Set HalpNextTimeIncrement to HalpNewTimeIncrement
5:
//
// Update the 64-bit performance counter.
//
// N.B. - This code is careful to update the 64-bit counter atomically.
//
lda t0, HalpRpccTime // get address of 64-bit rpcc global
ldq t4, 0(t0) // read rpcc global
rpcc t1 // read processor cycle counter
addl t1, zero, t1 // make t1 a longword
addl t4, 0, t2 // get low longword of rpcc global
cmpult t1, t2, t3 // is new rpcc < old rpcc
bne t3, 10f // if ne[true] rpcc wrapped
br zero, 20f // rpcc did not wrap
//
// The rpcc has wrapped, increment the high part of the 64-bit counter.
//
10:
lda t2, 1(zero) // t2 = 1
sll t2, 32, t2 // t2 = 1 0000 0000
addq t4, t2, t4 // increment high part by one
20:
zap t4, 0x0f, t4 // clean low part of rpcc global
zap t1, 0xf0, t1 // clean high part of rpcc
addq t4, t1, t4 // merge new rpcc as low part of global
stq t4, 0(t0) // store the updated counter
#if DEVL
//
// Check for a breakin request from the kernel debugger.
//
ldl t0, __imp_KdPollBreakIn
jsr ra, (t0) // check for breakin requested
beq v0, 30f // if eq[false], no breakin
ldl t0, __imp_DbgBreakPointWithStatus
lda a0, DBG_STATUS_CONTROL_C
jsr ra, (t0) // send status to debugger
30:
#endif //DEVL
//
// Return to the caller.
//
ldq ra, CiRa(sp) // restore return address
lda sp, CiFrameLength(sp) // deallocate stack frame
ret zero, (ra) // return to caller
.end HalpClockInterrupt
SBTTL("Eisa Interrupt")
//++
//
// VOID
// HalpEisaInterruptHandler
// IN PKINTERRUPT Interrupt,
// IN PVOID ServiceContext
// )
//
// Routine Description:
//
// This function is executed as the result of an interrupt on the EISA
// bus. The function is responsible for calling HalpEisaDispatch to
// appropriately dispatch the EISA interrupt.
//
// N.B. This function exists only to capture the trap frame and forward
// the interrupt to HalpEisaDispatch.
//
// Arguments:
//
// Interrupt (a0) - Supplies a pointer to the interrupt object.
//
// ServiceContext (a1) - Supplies a pointer to the service context for
// EISA interrupts.
//
// TrapFrame (fp/s6) - Supplies a pointer to the trap frame for
// the interrupt.
//
// Return Value:
//
// None.
//
//--
LEAF_ENTRY(HalpEisaInterruptHandler)
bis fp, zero, a2 // capture trap frame as argument
br zero, HalpEisaDispatch // dispatch the interrupt
ret zero, (ra) // will never get here
.end HalpEisaInterruptHandler