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, ; ; 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, endif ; ; Dismiss interrupt and raise irq level to clock2 level ; push _CbusClockVector sub esp, 4 ; allocate space to save OldIrql stdCall _HalBeginSystemInterrupt, ; 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, INTERRUPT_EXIT stdENDP _CbusClockInterruptPx _TEXT ends ; end 32 bit code end