mirror of
https://github.com/ipxe/ipxe
synced 2026-06-29 00:07:28 +03:00
[s390x] Add optimised TCP/IP checksumming
Add an S/390 assembly language implementation of TCP/IP checksumming, using the hardware "cksm" instruction to first calculate the 32-bit one's complement checksum and then folding down to 16 bits. Use an inline function since the whole checksum calculation (including folding) requires only six instructions. Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
@@ -0,0 +1,41 @@
|
|||||||
|
#ifndef _BITS_TCPIP_H
|
||||||
|
#define _BITS_TCPIP_H
|
||||||
|
|
||||||
|
/** @file
|
||||||
|
*
|
||||||
|
* Transport-network layer interface
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate continued TCP/IP checkum
|
||||||
|
*
|
||||||
|
* @v partial Checksum of already-summed data, in network byte order
|
||||||
|
* @v data Data buffer
|
||||||
|
* @v len Length of data buffer
|
||||||
|
* @ret cksum Updated checksum, in network byte order
|
||||||
|
*/
|
||||||
|
static inline __attribute__ (( always_inline )) uint16_t
|
||||||
|
tcpip_continue_chksum ( uint16_t partial, const void *data, size_t len ) {
|
||||||
|
struct s390x_pointer_pair pair = { data, len };
|
||||||
|
unsigned int cksum;
|
||||||
|
|
||||||
|
__asm__ ( /* Calculate 32-bit checksum */
|
||||||
|
"\n1:\n\t"
|
||||||
|
"cksm %0, %1\n\t"
|
||||||
|
"jo 1b\n\t"
|
||||||
|
/* Fold down to 16 bits */
|
||||||
|
"risbgz %1, %0, 32, 47, 16\n\t"
|
||||||
|
"alr %0, %1\n\t"
|
||||||
|
"srl %0, 16\n\t"
|
||||||
|
"alcr %0, %N1\n\t"
|
||||||
|
: "=&r" ( cksum ),
|
||||||
|
"+r" ( pair )
|
||||||
|
: "0" ( ~partial ) );
|
||||||
|
|
||||||
|
return ~cksum;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _BITS_TCPIP_H */
|
||||||
Reference in New Issue
Block a user