194 lines
4.5 KiB
NASM
194 lines
4.5 KiB
NASM
title "profile interrupt handler for the Corollary MP machines"
|
|
;++
|
|
;
|
|
;Copyright (c) 1992, 1993, 1994 Corollary Inc
|
|
;
|
|
;Module Name:
|
|
;
|
|
; cbusprof.asm
|
|
;
|
|
;Abstract:
|
|
;
|
|
; This module contains the profile interrupt handler for the
|
|
; non-boot processors in the Corollary MP machines. This is
|
|
; only needed because only one processor should ack the CMOS
|
|
; for each profile interrupt.
|
|
;
|
|
;Author:
|
|
;
|
|
; Landy Wang (landy@corollary.com) 26-Mar-1992
|
|
;
|
|
;Revision History:
|
|
;
|
|
;--
|
|
|
|
|
|
|
|
.386p
|
|
.xlist
|
|
include hal386.inc
|
|
include callconv.inc ; calling convention macros
|
|
include i386\kimacro.inc
|
|
include cbus.inc
|
|
|
|
EXTRNP _HalBeginSystemInterrupt,3
|
|
EXTRNP _HalEndSystemInterrupt,2
|
|
ifdef CBC_REV1
|
|
EXTRNP _Cbus2RequestSoftwareInterrupt,1
|
|
endif
|
|
|
|
.list
|
|
|
|
|
|
_TEXT SEGMENT DWORD PUBLIC 'CODE' ; Start 32 bit code
|
|
ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
|
|
|
|
|
|
page ,132
|
|
subttl "System Profile Interrupt for Additional Processors"
|
|
;++
|
|
;
|
|
; Routine Description:
|
|
;
|
|
; This routine is entered as the result of a profile interrupt.
|
|
; This routine is only entered by the non-boot processors.
|
|
;
|
|
; The CMOS will be acked by the boot processor (only one CPU can
|
|
; do this - which one is arbitrary, but it must only be ONE!).
|
|
;
|
|
; This function thus, just raises system Irql to PROFILE_LEVEL
|
|
; and transfers control to the standard system routine to process
|
|
; any active profiles.
|
|
;
|
|
; Arguments:
|
|
;
|
|
; None
|
|
; Interrupt is disabled
|
|
;
|
|
; Return Value:
|
|
;
|
|
; Does not return, jumps directly to KeProfileInterrupt, which returns
|
|
;
|
|
; Sets Irql = PROFILE_LEVEL
|
|
;
|
|
;--
|
|
ENTER_DR_ASSIST Hpx_a, Hpx_t
|
|
|
|
cPublicProc _HalpProfileInterruptPx ,0
|
|
|
|
;
|
|
; Save machine state in trap frame
|
|
;
|
|
|
|
ENTER_INTERRUPT Hpx_a, Hpx_t
|
|
|
|
;
|
|
; (esp) - base of trap frame
|
|
;
|
|
|
|
push _ProfileVector
|
|
sub esp, 4 ; allocate space to save OldIrql
|
|
stdCall _HalBeginSystemInterrupt, <PROFILE_LEVEL,_ProfileVector,esp>
|
|
|
|
;
|
|
; if this is C-bus II, modify the vector so the interrupt
|
|
; will not be EOI'd.
|
|
;
|
|
cmp _Cbus2BridgesFound, 0
|
|
je short cbus1
|
|
mov eax, [_CbusClockVector]
|
|
mov [esp+4], eax
|
|
cbus1:
|
|
|
|
;
|
|
; The boot processor has already cleared (or is about to clear)
|
|
; the interrupt flag on the RTC, so we don't do that here.
|
|
;
|
|
|
|
jmp _HalpProfileInterrupt2ndEntry@0
|
|
|
|
stdENDP _HalpProfileInterruptPx
|
|
|
|
|
|
page ,132
|
|
subttl "System Clock Interrupt for Additional Processors"
|
|
;++
|
|
;
|
|
; Routine Description:
|
|
;
|
|
; This routine is entered as the result of an interrupt generated by CLOCK.
|
|
; This routine is entered only by additional (non-boot) processors, so it
|
|
; must NOT update the performance counter or update the system time.
|
|
;
|
|
; instead, it just dismisses the interrupt, raises system Irql to
|
|
; CLOCK2_LEVEL and transfers control to the standard system routine
|
|
; to update the execution time of the current thread and process.
|
|
;
|
|
; Arguments:
|
|
;
|
|
; None
|
|
; Interrupt is disabled
|
|
;
|
|
; Return Value:
|
|
;
|
|
; Does not return, jumps directly to KeUpdateRunTime, which returns
|
|
;
|
|
; Sets Irql = CLOCK2_LEVEL and dismisses the interrupt
|
|
;
|
|
;--
|
|
ENTER_DR_ASSIST Hcix_a, Hcix_t
|
|
|
|
cPublicProc _CbusClockInterruptPx ,0
|
|
|
|
;
|
|
; Save machine state in trap frame
|
|
; (esp) - base of trap frame
|
|
;
|
|
|
|
ENTER_INTERRUPT Hcix_a, Hcix_t
|
|
|
|
ifdef CBC_REV1
|
|
;
|
|
; because we can miss an interrupt due to a hardware bug in the
|
|
; CBC rev 1 silicon, send ourselves an IPI on every clock.
|
|
; since we don't know when we've missed one, this will ensure
|
|
; we don't cause lock timeouts if nothing else!
|
|
;
|
|
|
|
stdCall _Cbus2RequestSoftwareInterrupt, <IPI_LEVEL>
|
|
endif
|
|
|
|
;
|
|
; Dismiss interrupt and raise irq level to clock2 level
|
|
;
|
|
|
|
push _CbusClockVector
|
|
sub esp, 4 ; allocate space to save OldIrql
|
|
stdCall _HalBeginSystemInterrupt, <CLOCK2_LEVEL, _CbusClockVector, esp>
|
|
|
|
; Spurious interrupts on Corollary hardware are
|
|
; directed to a different interrupt gate, so no need
|
|
; to check return value above.
|
|
|
|
POKE_LEDS eax, edx
|
|
|
|
mov eax, dword ptr [_CbusTimeStamp]
|
|
mov dword ptr [eax], 0
|
|
|
|
;
|
|
; (esp) = OldIrql
|
|
; (esp+4) = Vector
|
|
; (esp+8) = base of trap frame
|
|
;
|
|
; (ebp) = base of trap frame for KeUpdateRunTime, this was set
|
|
; up by the ENTER_INTERRUPT macro above
|
|
|
|
stdCall _KeUpdateRunTime,<dword ptr [esp]>
|
|
|
|
INTERRUPT_EXIT
|
|
|
|
stdENDP _CbusClockInterruptPx
|
|
|
|
_TEXT ends ; end 32 bit code
|
|
end
|