Windows2000/private/ntos/ke/i386/mpipia.asm

469 lines
12 KiB
NASM
Raw Normal View History

2001-01-01 00:00:00 +01:00
title "mpipia"
; Copyright (c) 1989-1995 Microsoft Corporation
; Module Name:
; mpipia.asm
; Abstract:
; This module implements the x86 specific fucntions required to
; support multiprocessor systems.
; Author:
; David N. Cutler (davec) 5-Feb-1995
; Environment:
; Krnel mode only.
; Revision History:
.486p
.xlist
include ks386.inc
include mac386.inc
include callconv.inc
.list
EXTRNP HalRequestSoftwareInterrupt,1,IMPORT,FASTCALL
EXTRNP HalRequestSoftwareInterrupt,1,IMPORT,FASTCALL
EXTRNP _HalRequestIpi,1,IMPORT
EXTRNP _KiFreezeTargetExecution, 2
ifdef DBGMP
EXTRNP _KiPollDebugger
endif
extrn _KiProcessorBlock:DWORD
DELAYCOUNT equ 2000h
_DATA SEGMENT DWORD PUBLIC 'DATA'
public _KiSynchPacket
_KiSynchPacket dd 0
_DATA ENDS
_TEXT SEGMENT DWORD PUBLIC 'CODE'
ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
; BOOLEAN
; KiIpiServiceRoutine (
; IN PKTRAP_FRAME TrapFrame,
; IN PKEXCEPTION_FRAME ExceptionFrame
; )
; Routine Description:
; This routine is called at IPI level to process any outstanding
; interporcessor requests for the current processor.
; Arguments:
; TrapFrame - Supplies a pointer to a trap frame.
; ExceptionFrame - Not used.
; Return Value:
; A value of TRUE is returned, if one of more requests were service.
; Otherwise, FALSE is returned.
cPublicProc _KiIpiServiceRoutine, 2
ifndef NT_UP
cPublicFpo 2, 1
push ebx
mov ecx, PCR[PcPrcb] ; get current processor block address
xor ebx, ebx ; get request summary flags
cmp [ecx].PbRequestSummary, ebx
jz short isr10
xchg [ecx].PbRequestSummary, ebx
; Check for freeze request or synchronous request.
test bl, IPI_FREEZE+IPI_SYNCH_REQUEST
jnz short isr50 ; if nz, freeze or synch request
; For RequestSummary's other then IPI_FREEZE set return to TRUE
mov bh, 1
; Check for Packet ready.
; If a packet is ready, then get the address of the requested function
; and call the function passing the address of the packet address as a
; parameter.
isr10: mov eax, [ecx].PbSignalDone ; get source processor block address
or eax, eax ; check if packet ready
jz short isr20 ; if z set, no packet ready
mov edx, [esp + 8] ; Current trap frame
push [eax].PbCurrentPacket + 8 ; push parameters on stack
push [eax].PbCurrentPacket + 4 ;
push [eax].PbCurrentPacket + 0 ;
push eax ; push source processor block address
mov eax, [eax]+PbWorkerRoutine ; get worker routine address
mov [ecx].PbSignalDone, 0 ; clear packet address
mov [ecx].PbIpiFrame, edx ; Save frame address
call eax ; call worker routine
mov bh, 1 ; return TRUE
; Check for APC interrupt request.
isr20: test bl, IPI_APC ; check if APC interrupt requested
jz short isr30 ; if z, APC interrupt not requested
mov ecx, APC_LEVEL ; request APC interrupt
fstCall HalRequestSoftwareInterrupt
; Check for DPC interrupt request.
isr30: test bl, IPI_DPC ; check if DPC interrupt requested
jz short isr40 ; if z, DPC interrupt not requested
mov ecx, DISPATCH_LEVEL ; request DPC interrupt
fstCall HalRequestSoftwareInterrupt ;
isr40: mov al, bh ; return status
pop ebx
stdRET _KiIpiServiceRoutine
; Freeze or synchronous request
isr50: test bl, IPI_FREEZE
jz short isr60 ; if z, no freeze request
; Freeze request is requested
mov ecx, [esp] + 12 ; get exception frame address
mov edx, [esp] + 8 ; get trap frame address
stdCall _KiFreezeTargetExecution, <edx, ecx> ; freeze execution
mov ecx, PCR[PcPrcb] ; get current processor block address
test bl, not IPI_FREEZE ; Any other IPI RequestSummary?
setnz bh ; Set return code accordingly
test bl, IPI_SYNCH_REQUEST ; if z, no synch request
jz isr10
; Synchronous packet request. Pointer to requesting PRCB in KiSynchPacket.
isr60: mov eax, _KiSynchPacket ; get PRCB of requesting processor
mov edx, [esp + 8] ; Current trap frame
push [eax].PbCurrentPacket+8 ; push parameters on stack
push [eax].PbCurrentPacket+4 ;
push [eax].PbCurrentPacket+0 ;
push eax ; push source processor block address
mov eax, [eax]+PbWorkerRoutine ; get worker routine address
mov [ecx].PbIpiFrame, edx ; Save frame address
call eax ; call worker routine
mov ecx, PCR[PcPrcb] ; restore processor block address
mov bh, 1 ; return TRUE
jmp isr10
else
xor eax, eax ; return FALSE
stdRET _KiIpiServiceRoutine
endif
stdENDP _KiIpiServiceRoutine
; VOID
; FASTCALL
; KiIpiSend (
; IN KAFFINITY TargetProcessors,
; IN KIPI_REQUEST Request
; )
; Routine Description:
; This function requests the specified operation on the targt set of
; processors.
; Arguments:
; TargetProcessors (ecx) - Supplies the set of processors on which the
; specified operation is to be executed.
; IpiRequest (edx) - Supplies the request operation code.
; Return Value:
; None.
cPublicFastCall KiIpiSend, 2
ifndef NT_UP
cPublicFpo 0, 2
push esi ; save registers
push edi ;
mov esi, ecx ; save target processor set
shr ecx, 1 ; shift out first bit
lea edi, _KiProcessorBlock ; get processor block array address
jnc short is20 ; if nc, not in target set
is10: mov eax, [edi] ; get processor block address
lock or [eax].PbRequestSummary, edx ; set request summary bit
is20: shr ecx, 1 ; shift out next bit
lea edi, [edi+4] ; advance to next processor
jc short is10 ; if target, go set summary bit
jnz short is20 ; if more, check next
stdCall _HalRequestIpi, <esi> ; request IPI interrupts on targets
pop edi ; restore registers
pop esi ;
endif
fstRet KiIpiSend
fstENDP KiIpiSend
; VOID
; KiIpiSendPacket (
; IN KAFFINITY TargetProcessors,
; IN PKIPI_WORKER WorkerFunction,
; IN PVOID Parameter1,
; IN PVOID Parameter2,
; IN PVOID Parameter3
; )
; Routine Description:
; This routine executes the specified worker function on the specified
; set of processors.
; Arguments:
; TargetProcessors [esp + 4] - Supplies the set of processors on which the
; specfied operation is to be executed.
; WorkerFunction [esp + 8] - Supplies the address of the worker function.
; Parameter1 - Parameter3 [esp + 12] - Supplies worker function specific
; paramters.
; Return Value:
; None.
;--*/
cPublicProc _KiIpiSendPacket, 5
ifndef NT_UP
cPublicFpo 5, 2
push esi ; save registers
push edi ;
; Store function address and parameters in the packet area of the PRCB on
; the current processor.
mov edx, PCR[PcPrcb] ; get current processor block address
mov ecx, [esp] + 12 ; set target processor set
mov eax, [esp] + 16 ; set worker function address
mov edi, [esp] + 20 ; store worker function parameters
mov esi, [esp] + 24 ;
mov [edx].PbTargetSet, ecx
mov [edx].PbWorkerRoutine, eax
mov eax, [esp] + 28
mov [edx].PbCurrentPacket, edi
mov [edx].PbCurrentPacket + 4, esi
mov [edx].PbCurrentPacket + 8, eax
; Loop through the target processors and send the packet to the specified
; recipients.
shr ecx, 1 ; shift out first bit
lea edi, _KiProcessorBlock ; get processor block array address
jnc short isp30 ; if nc, not in target set
isp10: mov esi, [edi] ; get processor block address
isp20: mov eax, [esi].PbSignalDone ; check if packet being processed
or eax, eax ;
jne short isp20 ; if ne, packet being processed
lock cmpxchg [esi].PbSignalDone, edx ; compare and exchange
jnz short isp20 ; if nz, exchange failed
isp30: shr ecx, 1 ; shift out next bit
lea edi, [edi+4] ; advance to next processor
jc short isp10 ; if c, in target set
jnz short isp30 ; if nz, more target processors
mov ecx, [esp] + 12 ; set target processor set
stdCall _HalRequestIpi, <ecx> ; send IPI to targets
pop edi ; restore register
pop esi ;
endif
stdRet _KiIpiSendPacket
stdENDP _KiIpiSendPacket
; VOID
; FASTCALL
; KiIpiSignalPacketDone (
; IN PKIPI_CONTEXT Signaldone
; )
; Routine Description:
; This routine signals that a processor has completed a packet by
; clearing the calling processor's set member of the requesting
; processor's packet.
; Arguments:
; SignalDone (ecx) - Supplies a pointer to the processor block of the
; sending processor.
; Return Value:
; None.
cPublicFastCall KiIpiSignalPacketDone, 1
ifndef NT_UP
mov edx, PCR[PcPrcb] ; get current processor block address
mov eax, [edx].PbSetMember ; get processor bit
lock xor [ecx].PbTargetSet, eax ; clear processor set member
endif
fstRET KiIpiSignalPacketDone
fstENDP KiIpiSignalPacketDone
; VOID
; FASTCALL
; KiIpiSignalPacketDoneAndStall (
; IN PKIPI_CONTEXT Signaldone
; IN PULONG ReverseStall
; )
; Routine Description:
; This routine signals that a processor has completed a packet by
; clearing the calling processor's set member of the requesting
; processor's packet, and then stalls of the reverse stall value
; Arguments:
; SignalDone (ecx) - Supplies a pointer to the processor block of the
; sending processor.
; ReverseStall (edx) - Supplies a pointer to the reverse stall barrier
; Return Value:
; None.
cPublicFastCall KiIpiSignalPacketDoneAndStall, 2
cPublicFpo 0, 2
ifndef NT_UP
push ebx
push esi
mov esi, PCR[PcPrcb] ; get current processor block address
mov eax, [esi].PbSetMember ; get processor bit
mov ebx, dword ptr [edx] ; get current value of barrier
lock xor [ecx].PbTargetSet, eax ; clear processor set member
sps10: mov eax, DELAYCOUNT
sps20: cmp ebx, dword ptr [edx] ; barrier set?
jne short sps90 ; yes, all done
YIELD
dec eax ; P54C pre C2 workaround
jnz short sps20 ; if eax = 0, generate bus cycle
ifdef DBGMP
stdCall _KiPollDebugger ; Check for debugger ^C
endif
; There could be a freeze execution outstanding. Check and clear
; freeze flag.
.errnz IPI_FREEZE - 4
lock btr [esi].PbRequestSummary, 2 ; Generate bus cycle
jnc short sps10 ; Freeze pending?
cPublicFpo 0,4
push ecx ; save TargetSet address
push edx
stdCall _KiFreezeTargetExecution, <[esi].PbIpiFrame, 0>
pop edx
pop ecx
jmp short sps10
sps90: pop esi
pop ebx
endif
fstRET KiIpiSignalPacketDoneAndStall
fstENDP KiIpiSignalPacketDoneAndStall
_TEXT ends
end