160 lines
4.9 KiB
ArmAsm
160 lines
4.9 KiB
ArmAsm
// TITLE("LPC Move Message Support")
|
||
//++
|
||
//
|
||
// Copyright (c) 1990 Microsoft Corporation
|
||
//
|
||
// Module Name:
|
||
//
|
||
// lpcmove.s
|
||
//
|
||
// Abstract:
|
||
//
|
||
// This module implements functions to support the efficient movement of
|
||
// LPC Message blocks
|
||
//
|
||
// Author:
|
||
//
|
||
// Chuck Bauman (cbauman@vnet.ibm.com) 20-Mar-1993
|
||
//
|
||
// Environment:
|
||
//
|
||
// Kernel mode only.
|
||
//
|
||
// Revision History:
|
||
//
|
||
// July 5th, 1994 plj@vnet.ibm.com slight performance optimization
|
||
// and updated C code to be correct
|
||
// again (I think).
|
||
//
|
||
// N.B. Structures of type PPORT_MESSAGE are assumed to be 8 byte aligned.
|
||
//
|
||
//--
|
||
|
||
#include "ksppc.h"
|
||
|
||
// SBTTL("Move Message")
|
||
//++
|
||
//
|
||
// VOID
|
||
// LpcpMoveMessage (
|
||
// OUT PPORT_MESSAGE DstMsg
|
||
// IN PPORT_MESSAGE SrcMsg
|
||
// IN PUCHAR SrcMsgData
|
||
// IN ULONG MsgType OPTIONAL,
|
||
// IN PCLIENT_ID ClientId OPTIONAL
|
||
// )
|
||
//
|
||
// Routine Description:
|
||
//
|
||
// This function moves an LPC message block and optionally sets the message
|
||
// type and client id to the specified values.
|
||
//
|
||
// Arguments:
|
||
//
|
||
// DstMsg (r.3) - Supplies a pointer to the destination message.
|
||
//
|
||
// SrcMsg (r.4) - Supplies a pointer to the source message.
|
||
//
|
||
// SrcMsgData (r.5) - Supplies a pointer to the source message data to
|
||
// copy to destination.
|
||
//
|
||
// MsgType (r.6) - If non-zero, then store in type field of the
|
||
// destination message.
|
||
//
|
||
// ClientId (r.7) - If non-NULL, then points to a ClientId to copy to
|
||
// the destination message.
|
||
//
|
||
// Return Value:
|
||
//
|
||
// None
|
||
//
|
||
//--
|
||
// The following is a possible C implementation of this routine, shown for
|
||
// (hopefully) clarity.
|
||
//--
|
||
// VOID
|
||
// LpcpMoveMessage (
|
||
// OUT PULONG DstMsg PPORT_MESSAGE
|
||
// IN PULONG SrcMsg PPORT_MESSAGE
|
||
// IN PULONG SrcMsgData PUCHAR
|
||
// IN ULONG MsgType OPTIONAL,
|
||
// IN PULONG ClientId OPTIONAL PCLIENT_ID
|
||
// )
|
||
// {
|
||
// ULONG NumberWords;
|
||
//
|
||
// *DstMsg++ = NumberWords = *SrcMsg++;
|
||
// NumberWords = (NumberWords + 3) >> 2;
|
||
// if (MsgType != 0) {
|
||
// *DstMsg++ = (*SrcMsg++ & 0xffff0000) | (MsgType & 0xffff);
|
||
// } else {
|
||
// *DstMsg++ = *SrcMsg++;
|
||
// }
|
||
// if (ClientId == NULL) {
|
||
// *DstMsg++ = *SrcMsg++;
|
||
// *DstMsg++ = *SrcMsg++;
|
||
// } else {
|
||
// *DstMsg++ = *ClientId++;
|
||
// *DstMsg++ = *ClientId;
|
||
// SrcMsg += 2;
|
||
// }
|
||
// *DstMsg++ = *SrcMsg++;
|
||
// *DstMsg++ = *SrcMsg++;
|
||
// while (NumberWords--) {
|
||
// *DstMsg++ = *SrcMsgData++;
|
||
// }
|
||
// }
|
||
|
||
LEAF_ENTRY(LpcpMoveMessage)
|
||
lwz r.10,0(r.4) // load first longword of source
|
||
cmpwi cr.1,r.6,0 // message type specified?
|
||
cmpwi cr.6,r.7,0 // client id specified?
|
||
subi r.5,r.5,4 // Prepare for lwzu in copymsg loop
|
||
lwz r.8,4(r.4) // load second longword of source
|
||
addi r.9,r.10,3 // round length to 4-byte multiple
|
||
rlwinm. r.11,r.9,29,0x1fff // get number of quadwords
|
||
lfd f.0,16(r.4) // get message id and view size
|
||
beq cr.1,nomsgtype // if eq, message type not specified
|
||
rlwimi r.8,r.6, 0, 0xffff // insert specified message type
|
||
|
||
nomsgtype:
|
||
stw r.10,0(r.3) // store first longword of destination
|
||
stw r.8,4(r.3) // store second longword of destination
|
||
beq cr.6,noclientid// if eq, client id not specified
|
||
lwz r.10,0(r.7) // load first longword of client id
|
||
lwz r.8,4(r.7) // load second longword if client id
|
||
b storeclient //
|
||
|
||
noclientid:
|
||
lwz r.10,8(r.4) // get third longword of source
|
||
lwz r.8,12(r.4) // get fourth longword of source
|
||
|
||
storeclient:
|
||
mtcrf 0x01,r.9 // set cr bit 29 if odd number longwords
|
||
stw r.10,8(r.3) // store client id (first half)
|
||
stw r.8,12(r.3) // (second half)
|
||
stfdu f.0,16(r.3) // store message id and view size
|
||
|
||
//
|
||
// At this point, the next byte to be stored in the destination (if any)
|
||
// goes at (r.3) + 8.
|
||
//
|
||
beq cr.0,noquad // if 0 length, no quadwords
|
||
mtctr r.11 // set count register with loop count
|
||
|
||
copymsg:
|
||
lwz r.10,4(r.5) // get longword of source
|
||
lwzu r.11,8(r.5) // get longword of source
|
||
stwu r.10,8(r.3) // store next longword of destination
|
||
stw r.11,4(r.3) // store next longword of destination
|
||
bdnz copymsg // if nz, more longwords to move
|
||
|
||
noquad:
|
||
bflr 29 // return if no odd longword to move
|
||
|
||
lwz r.10,4(r.5) // get last longword
|
||
stw r.10,8(r.3) // store last longword
|
||
|
||
LEAF_EXIT(LpcpMoveMessage) // return
|
||
|