diff options
| author | fishsoupisgood <github@madingley.org> | 2019-04-29 01:17:54 +0100 | 
|---|---|---|
| committer | fishsoupisgood <github@madingley.org> | 2019-05-27 03:43:43 +0100 | 
| commit | 3f2546b2ef55b661fd8dd69682b38992225e86f6 (patch) | |
| tree | 65ca85f13617aee1dce474596800950f266a456c /roms/ipxe/src/arch/x86/include/bits | |
| download | qemu-master.tar.gz qemu-master.tar.bz2 qemu-master.zip | |
Diffstat (limited to 'roms/ipxe/src/arch/x86/include/bits')
| -rw-r--r-- | roms/ipxe/src/arch/x86/include/bits/bigint.h | 318 | ||||
| -rw-r--r-- | roms/ipxe/src/arch/x86/include/bits/errfile.h | 55 | ||||
| -rw-r--r-- | roms/ipxe/src/arch/x86/include/bits/io.h | 14 | ||||
| -rw-r--r-- | roms/ipxe/src/arch/x86/include/bits/linux_api_platform.h | 6 | ||||
| -rw-r--r-- | roms/ipxe/src/arch/x86/include/bits/pci_io.h | 15 | ||||
| -rw-r--r-- | roms/ipxe/src/arch/x86/include/bits/string.h | 232 | ||||
| -rw-r--r-- | roms/ipxe/src/arch/x86/include/bits/tcpip.h | 17 | ||||
| -rw-r--r-- | roms/ipxe/src/arch/x86/include/bits/xen.h | 164 | 
8 files changed, 821 insertions, 0 deletions
| diff --git a/roms/ipxe/src/arch/x86/include/bits/bigint.h b/roms/ipxe/src/arch/x86/include/bits/bigint.h new file mode 100644 index 00000000..d3449af5 --- /dev/null +++ b/roms/ipxe/src/arch/x86/include/bits/bigint.h @@ -0,0 +1,318 @@ +#ifndef _BITS_BIGINT_H +#define _BITS_BIGINT_H + +/** @file + * + * Big integer support + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <stdint.h> +#include <string.h> + +/** Element of a big integer */ +typedef uint32_t bigint_element_t; + +/** + * Initialise big integer + * + * @v value0		Element 0 of big integer to initialise + * @v size		Number of elements + * @v data		Raw data + * @v len		Length of raw data + */ +static inline __attribute__ (( always_inline )) void +bigint_init_raw ( uint32_t *value0, unsigned int size, +		  const void *data, size_t len ) { +	long pad_len = ( sizeof ( bigint_t ( size ) ) - len ); +	void *discard_D; +	long discard_c; + +	/* Copy raw data in reverse order, padding with zeros */ +	__asm__ __volatile__ ( "\n1:\n\t" +			       "movb -1(%2,%1), %%al\n\t" +			       "stosb\n\t" +			       "loop 1b\n\t" +			       "xorl %%eax, %%eax\n\t" +			       "mov %3, %1\n\t" +			       "rep stosb\n\t" +			       : "=&D" ( discard_D ), "=&c" ( discard_c ) +			       : "r" ( data ), "g" ( pad_len ), "0" ( value0 ), +				 "1" ( len ) +			       : "eax" ); +} + +/** + * Add big integers + * + * @v addend0		Element 0 of big integer to add + * @v value0		Element 0 of big integer to be added to + * @v size		Number of elements + */ +static inline __attribute__ (( always_inline )) void +bigint_add_raw ( const uint32_t *addend0, uint32_t *value0, +		 unsigned int size ) { +	long index; +	void *discard_S; +	long discard_c; + +	__asm__ __volatile__ ( "xor %0, %0\n\t" /* Zero %0 and clear CF */ +			       "\n1:\n\t" +			       "lodsl\n\t" +			       "adcl %%eax, (%3,%0,4)\n\t" +			       "inc %0\n\t" /* Does not affect CF */ +			       "loop 1b\n\t" +			       : "=&r" ( index ), "=&S" ( discard_S ), +				 "=&c" ( discard_c ) +			       : "r" ( value0 ), "1" ( addend0 ), "2" ( size ) +			       : "eax" ); +} + +/** + * Subtract big integers + * + * @v subtrahend0	Element 0 of big integer to subtract + * @v value0		Element 0 of big integer to be subtracted from + * @v size		Number of elements + */ +static inline __attribute__ (( always_inline )) void +bigint_subtract_raw ( const uint32_t *subtrahend0, uint32_t *value0, +		      unsigned int size ) { +	long index; +	void *discard_S; +	long discard_c; + +	__asm__ __volatile__ ( "xor %0, %0\n\t" /* Zero %0 and clear CF */ +			       "\n1:\n\t" +			       "lodsl\n\t" +			       "sbbl %%eax, (%3,%0,4)\n\t" +			       "inc %0\n\t" /* Does not affect CF */ +			       "loop 1b\n\t" +			       : "=&r" ( index ), "=&S" ( discard_S ), +				 "=&c" ( discard_c ) +			       : "r" ( value0 ), "1" ( subtrahend0 ), +				 "2" ( size ) +			       : "eax" ); +} + +/** + * Rotate big integer left + * + * @v value0		Element 0 of big integer + * @v size		Number of elements + */ +static inline __attribute__ (( always_inline )) void +bigint_rol_raw ( uint32_t *value0, unsigned int size ) { +	long index; +	long discard_c; + +	__asm__ __volatile__ ( "xor %0, %0\n\t" /* Zero %0 and clear CF */ +			       "\n1:\n\t" +			       "rcll $1, (%2,%0,4)\n\t" +			       "inc %0\n\t" /* Does not affect CF */ +			       "loop 1b\n\t" +			       : "=&r" ( index ), "=&c" ( discard_c ) +			       : "r" ( value0 ), "1" ( size ) ); +} + +/** + * Rotate big integer right + * + * @v value0		Element 0 of big integer + * @v size		Number of elements + */ +static inline __attribute__ (( always_inline )) void +bigint_ror_raw ( uint32_t *value0, unsigned int size ) { +	long discard_c; + +	__asm__ __volatile__ ( "clc\n\t" +			       "\n1:\n\t" +			       "rcrl $1, -4(%1,%0,4)\n\t" +			       "loop 1b\n\t" +			       : "=&c" ( discard_c ) +			       : "r" ( value0 ), "0" ( size ) ); +} + +/** + * Test if big integer is equal to zero + * + * @v value0		Element 0 of big integer + * @v size		Number of elements + * @ret is_zero		Big integer is equal to zero + */ +static inline __attribute__ (( always_inline, pure )) int +bigint_is_zero_raw ( const uint32_t *value0, unsigned int size ) { +	void *discard_D; +	long discard_c; +	int result; + +	__asm__ __volatile__ ( "xor %0, %0\n\t" /* Set ZF */ +			       "repe scasl\n\t" +			       "sete %b0\n\t" +			       : "=&a" ( result ), "=&D" ( discard_D ), +				 "=&c" ( discard_c ) +			       : "1" ( value0 ), "2" ( size ) ); +	return result; +} + +/** + * Compare big integers + * + * @v value0		Element 0 of big integer + * @v reference0	Element 0 of reference big integer + * @v size		Number of elements + * @ret geq		Big integer is greater than or equal to the reference + */ +static inline __attribute__ (( always_inline, pure )) int +bigint_is_geq_raw ( const uint32_t *value0, const uint32_t *reference0, +		    unsigned int size ) { +	const bigint_t ( size ) __attribute__ (( may_alias )) *value = +		( ( const void * ) value0 ); +	const bigint_t ( size ) __attribute__ (( may_alias )) *reference = +		( ( const void * ) reference0 ); +	void *discard_S; +	void *discard_D; +	long discard_c; +	int result; + +	__asm__ __volatile__ ( "std\n\t" +			       "\n1:\n\t" +			       "lodsl\n\t" +			       "scasl\n\t" +			       "loope 1b\n\t" +			       "setae %b0\n\t" +			       "cld\n\t" +			       : "=q" ( result ), "=&S" ( discard_S ), +				 "=&D" ( discard_D ), "=&c" ( discard_c ) +			       : "0" ( 0 ), "1" ( &value->element[ size - 1 ] ), +				 "2" ( &reference->element[ size - 1 ] ), +				 "3" ( size ) +			       : "eax" ); +	return result; +} + +/** + * Test if bit is set in big integer + * + * @v value0		Element 0 of big integer + * @v size		Number of elements + * @v bit		Bit to test + * @ret is_set		Bit is set + */ +static inline __attribute__ (( always_inline )) int +bigint_bit_is_set_raw ( const uint32_t *value0, unsigned int size, +			unsigned int bit ) { +	const bigint_t ( size ) __attribute__ (( may_alias )) *value = +		( ( const void * ) value0 ); +	unsigned int index = ( bit / ( 8 * sizeof ( value->element[0] ) ) ); +	unsigned int subindex = ( bit % ( 8 * sizeof ( value->element[0] ) ) ); + +	return ( value->element[index] & ( 1 << subindex ) ); +} + +/** + * Find highest bit set in big integer + * + * @v value0		Element 0 of big integer + * @v size		Number of elements + * @ret max_bit		Highest bit set + 1 (or 0 if no bits set) + */ +static inline __attribute__ (( always_inline )) int +bigint_max_set_bit_raw ( const uint32_t *value0, unsigned int size ) { +	long discard_c; +	int result; + +	__asm__ __volatile__ ( "\n1:\n\t" +			       "bsrl -4(%2,%1,4), %0\n\t" +			       "loopz 1b\n\t" +			       "rol %1\n\t" /* Does not affect ZF */ +			       "rol %1\n\t" +			       "leal 1(%k0,%k1,8), %k0\n\t" +			       "jnz 2f\n\t" +			       "xor %0, %0\n\t" +			       "\n2:\n\t" +			       : "=&r" ( result ), "=&c" ( discard_c ) +			       : "r" ( value0 ), "1" ( size ) ); +	return result; +} + +/** + * Grow big integer + * + * @v source0		Element 0 of source big integer + * @v source_size	Number of elements in source big integer + * @v dest0		Element 0 of destination big integer + * @v dest_size		Number of elements in destination big integer + */ +static inline __attribute__ (( always_inline )) void +bigint_grow_raw ( const uint32_t *source0, unsigned int source_size, +		  uint32_t *dest0, unsigned int dest_size ) { +	long pad_size = ( dest_size - source_size ); +	void *discard_D; +	void *discard_S; +	long discard_c; + +	__asm__ __volatile__ ( "rep movsl\n\t" +			       "xorl %%eax, %%eax\n\t" +			       "mov %3, %2\n\t" +			       "rep stosl\n\t" +			       : "=&D" ( discard_D ), "=&S" ( discard_S ), +				 "=&c" ( discard_c ) +			       : "g" ( pad_size ), "0" ( dest0 ), +				 "1" ( source0 ), "2" ( source_size ) +			       : "eax" ); +} + +/** + * Shrink big integer + * + * @v source0		Element 0 of source big integer + * @v source_size	Number of elements in source big integer + * @v dest0		Element 0 of destination big integer + * @v dest_size		Number of elements in destination big integer + */ +static inline __attribute__ (( always_inline )) void +bigint_shrink_raw ( const uint32_t *source0, unsigned int source_size __unused, +		    uint32_t *dest0, unsigned int dest_size ) { +	void *discard_D; +	void *discard_S; +	long discard_c; + +	__asm__ __volatile__ ( "rep movsl\n\t" +			       : "=&D" ( discard_D ), "=&S" ( discard_S ), +				 "=&c" ( discard_c ) +			       : "0" ( dest0 ), "1" ( source0 ), +				 "2" ( dest_size ) +			       : "eax" ); +} + +/** + * Finalise big integer + * + * @v value0		Element 0 of big integer to finalise + * @v size		Number of elements + * @v out		Output buffer + * @v len		Length of output buffer + */ +static inline __attribute__ (( always_inline )) void +bigint_done_raw ( const uint32_t *value0, unsigned int size __unused, +		  void *out, size_t len ) { +	void *discard_D; +	long discard_c; + +	/* Copy raw data in reverse order */ +	__asm__ __volatile__ ( "\n1:\n\t" +			       "movb -1(%2,%1), %%al\n\t" +			       "stosb\n\t" +			       "loop 1b\n\t" +			       : "=&D" ( discard_D ), "=&c" ( discard_c ) +			       : "r" ( value0 ), "0" ( out ), "1" ( len ) +			       : "eax" ); +} + +extern void bigint_multiply_raw ( const uint32_t *multiplicand0, +				  const uint32_t *multiplier0, +				  uint32_t *value0, unsigned int size ); + +#endif /* _BITS_BIGINT_H */ diff --git a/roms/ipxe/src/arch/x86/include/bits/errfile.h b/roms/ipxe/src/arch/x86/include/bits/errfile.h new file mode 100644 index 00000000..62457562 --- /dev/null +++ b/roms/ipxe/src/arch/x86/include/bits/errfile.h @@ -0,0 +1,55 @@ +#ifndef _BITS_ERRFILE_H +#define _BITS_ERRFILE_H + +FILE_LICENCE ( GPL2_OR_LATER ); + +/** + * @addtogroup errfile Error file identifiers + * @{ + */ + +#define ERRFILE_memtop_umalloc	( ERRFILE_ARCH | ERRFILE_CORE | 0x00000000 ) +#define ERRFILE_memmap		( ERRFILE_ARCH | ERRFILE_CORE | 0x00010000 ) +#define ERRFILE_pnpbios		( ERRFILE_ARCH | ERRFILE_CORE | 0x00020000 ) +#define ERRFILE_bios_smbios	( ERRFILE_ARCH | ERRFILE_CORE | 0x00030000 ) +#define ERRFILE_biosint		( ERRFILE_ARCH | ERRFILE_CORE | 0x00040000 ) +#define ERRFILE_int13		( ERRFILE_ARCH | ERRFILE_CORE | 0x00050000 ) +#define ERRFILE_pxeparent	( ERRFILE_ARCH | ERRFILE_CORE | 0x00060000 ) +#define ERRFILE_runtime		( ERRFILE_ARCH | ERRFILE_CORE | 0x00070000 ) +#define ERRFILE_vmware		( ERRFILE_ARCH | ERRFILE_CORE | 0x00080000 ) +#define ERRFILE_guestrpc	( ERRFILE_ARCH | ERRFILE_CORE | 0x00090000 ) +#define ERRFILE_guestinfo	( ERRFILE_ARCH | ERRFILE_CORE | 0x000a0000 ) +#define ERRFILE_apm		( ERRFILE_ARCH | ERRFILE_CORE | 0x000b0000 ) +#define ERRFILE_vesafb		( ERRFILE_ARCH | ERRFILE_CORE | 0x000c0000 ) + +#define ERRFILE_bootsector     ( ERRFILE_ARCH | ERRFILE_IMAGE | 0x00000000 ) +#define ERRFILE_bzimage	       ( ERRFILE_ARCH | ERRFILE_IMAGE | 0x00010000 ) +#define ERRFILE_eltorito       ( ERRFILE_ARCH | ERRFILE_IMAGE | 0x00020000 ) +#define ERRFILE_multiboot      ( ERRFILE_ARCH | ERRFILE_IMAGE | 0x00030000 ) +#define ERRFILE_nbi	       ( ERRFILE_ARCH | ERRFILE_IMAGE | 0x00040000 ) +#define ERRFILE_pxe_image      ( ERRFILE_ARCH | ERRFILE_IMAGE | 0x00050000 ) +#define ERRFILE_elfboot	       ( ERRFILE_ARCH | ERRFILE_IMAGE | 0x00060000 ) +#define ERRFILE_comboot        ( ERRFILE_ARCH | ERRFILE_IMAGE | 0x00070000 ) +#define ERRFILE_com32          ( ERRFILE_ARCH | ERRFILE_IMAGE | 0x00080000 ) +#define ERRFILE_comboot_resolv ( ERRFILE_ARCH | ERRFILE_IMAGE | 0x00090000 ) +#define ERRFILE_comboot_call   ( ERRFILE_ARCH | ERRFILE_IMAGE | 0x000a0000 ) +#define ERRFILE_sdi	       ( ERRFILE_ARCH | ERRFILE_IMAGE | 0x000b0000 ) +#define ERRFILE_initrd	       ( ERRFILE_ARCH | ERRFILE_IMAGE | 0x000c0000 ) +#define ERRFILE_pxe_call       ( ERRFILE_ARCH | ERRFILE_IMAGE | 0x000d0000 ) + +#define ERRFILE_undi		 ( ERRFILE_ARCH | ERRFILE_NET | 0x00000000 ) +#define ERRFILE_undiload	 ( ERRFILE_ARCH | ERRFILE_NET | 0x00010000 ) +#define ERRFILE_undinet		 ( ERRFILE_ARCH | ERRFILE_NET | 0x00020000 ) +#define ERRFILE_undionly	 ( ERRFILE_ARCH | ERRFILE_NET | 0x00030000 ) +#define ERRFILE_undirom		 ( ERRFILE_ARCH | ERRFILE_NET | 0x00040000 ) + +#define ERRFILE_timer_rdtsc   ( ERRFILE_ARCH | ERRFILE_DRIVER | 0x00000000 ) +#define ERRFILE_timer_bios    ( ERRFILE_ARCH | ERRFILE_DRIVER | 0x00010000 ) +#define ERRFILE_hvm	      ( ERRFILE_ARCH | ERRFILE_DRIVER | 0x00020000 ) + +#define ERRFILE_cpuid_cmd      ( ERRFILE_ARCH | ERRFILE_OTHER | 0x00000000 ) +#define ERRFILE_cpuid_settings ( ERRFILE_ARCH | ERRFILE_OTHER | 0x00010000 ) + +/** @} */ + +#endif /* _BITS_ERRFILE_H */ diff --git a/roms/ipxe/src/arch/x86/include/bits/io.h b/roms/ipxe/src/arch/x86/include/bits/io.h new file mode 100644 index 00000000..cb1b67a6 --- /dev/null +++ b/roms/ipxe/src/arch/x86/include/bits/io.h @@ -0,0 +1,14 @@ +#ifndef _BITS_IO_H +#define _BITS_IO_H + +/** @file + * + * x86-specific I/O API implementations + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <ipxe/x86_io.h> + +#endif /* _BITS_IO_H */ diff --git a/roms/ipxe/src/arch/x86/include/bits/linux_api_platform.h b/roms/ipxe/src/arch/x86/include/bits/linux_api_platform.h new file mode 100644 index 00000000..4a9ced5e --- /dev/null +++ b/roms/ipxe/src/arch/x86/include/bits/linux_api_platform.h @@ -0,0 +1,6 @@ +#ifndef _LINUX_API_PLATFORM_H +#define _LINUX_API_PLATFORM_H + +extern int linux_errno; + +#endif /* _LINUX_API_PLATFORM_H */ diff --git a/roms/ipxe/src/arch/x86/include/bits/pci_io.h b/roms/ipxe/src/arch/x86/include/bits/pci_io.h new file mode 100644 index 00000000..01b12326 --- /dev/null +++ b/roms/ipxe/src/arch/x86/include/bits/pci_io.h @@ -0,0 +1,15 @@ +#ifndef _BITS_PCI_IO_H +#define _BITS_PCI_IO_H + +/** @file + * + * i386-specific PCI I/O API implementations + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <ipxe/pcibios.h> +#include <ipxe/pcidirect.h> + +#endif /* _BITS_PCI_IO_H */ diff --git a/roms/ipxe/src/arch/x86/include/bits/string.h b/roms/ipxe/src/arch/x86/include/bits/string.h new file mode 100644 index 00000000..dce99498 --- /dev/null +++ b/roms/ipxe/src/arch/x86/include/bits/string.h @@ -0,0 +1,232 @@ +#ifndef X86_BITS_STRING_H +#define X86_BITS_STRING_H + +/* + * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +/** @file + * + * Optimised string operations + * + */ + +#define __HAVE_ARCH_MEMCPY + +extern void * __memcpy ( void *dest, const void *src, size_t len ); +extern void * __memcpy_reverse ( void *dest, const void *src, size_t len ); + +/** + * Copy memory area (where length is a compile-time constant) + * + * @v dest		Destination address + * @v src		Source address + * @v len		Length + * @ret dest		Destination address + */ +static inline __attribute__ (( always_inline )) void * +__constant_memcpy ( void *dest, const void *src, size_t len ) { +	union { +		uint32_t u32[2]; +		uint16_t u16[4]; +		uint8_t  u8[8]; +	} __attribute__ (( __may_alias__ )) *dest_u = dest; +	const union { +		uint32_t u32[2]; +		uint16_t u16[4]; +		uint8_t  u8[8]; +	} __attribute__ (( __may_alias__ )) *src_u = src; +	const void *esi; +	void *edi; + +	switch ( len ) { +	case 0 : /* 0 bytes */ +		return dest; +	/* +	 * Single-register moves; these are always better than a +	 * string operation.  We can clobber an arbitrary two +	 * registers (data, source, dest can re-use source register) +	 * instead of being restricted to esi and edi.  There's also a +	 * much greater potential for optimising with nearby code. +	 * +	 */ +	case 1 : /* 4 bytes */ +		dest_u->u8[0]  = src_u->u8[0]; +		return dest; +	case 2 : /* 6 bytes */ +		dest_u->u16[0] = src_u->u16[0]; +		return dest; +	case 4 : /* 4 bytes */ +		dest_u->u32[0] = src_u->u32[0]; +		return dest; +	/* +	 * Double-register moves; these are probably still a win. +	 * +	 */ +	case 3 : /* 12 bytes */ +		dest_u->u16[0] = src_u->u16[0]; +		dest_u->u8[2]  = src_u->u8[2]; +		return dest; +	case 5 : /* 10 bytes */ +		dest_u->u32[0] = src_u->u32[0]; +		dest_u->u8[4]  = src_u->u8[4]; +		return dest; +	case 6 : /* 12 bytes */ +		dest_u->u32[0] = src_u->u32[0]; +		dest_u->u16[2] = src_u->u16[2]; +		return dest; +	case 8 : /* 10 bytes */ +		dest_u->u32[0] = src_u->u32[0]; +		dest_u->u32[1] = src_u->u32[1]; +		return dest; +	} + +	/* Even if we have to load up esi and edi ready for a string +	 * operation, we can sometimes save space by using multiple +	 * single-byte "movs" operations instead of loading up ecx and +	 * using "rep movsb". +	 * +	 * "load ecx, rep movsb" is 7 bytes, plus an average of 1 byte +	 * to allow for saving/restoring ecx 50% of the time. +	 * +	 * "movsl" and "movsb" are 1 byte each, "movsw" is two bytes. +	 * (In 16-bit mode, "movsl" is 2 bytes and "movsw" is 1 byte, +	 * but "movsl" moves twice as much data, so it balances out). +	 * +	 * The cutoff point therefore occurs around 26 bytes; the byte +	 * requirements for each method are: +	 * +	 * len		   16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 +	 * #bytes (ecx)	    8  8  8  8  8  8  8  8  8  8  8  8  8  8  8  8 +	 * #bytes (no ecx)  4  5  6  7  5  6  7  8  6  7  8  9  7  8  9 10 +	 */ + +	esi = src; +	edi = dest; +	 +	if ( len >= 26 ) +		return __memcpy ( dest, src, len ); +	 +	if ( len >= 6*4 ) +		__asm__ __volatile__ ( "movsl" : "=&D" ( edi ), "=&S" ( esi ) +				       : "0" ( edi ), "1" ( esi ) : "memory" ); +	if ( len >= 5*4 ) +		__asm__ __volatile__ ( "movsl" : "=&D" ( edi ), "=&S" ( esi ) +				       : "0" ( edi ), "1" ( esi ) : "memory" ); +	if ( len >= 4*4 ) +		__asm__ __volatile__ ( "movsl" : "=&D" ( edi ), "=&S" ( esi ) +				       : "0" ( edi ), "1" ( esi ) : "memory" ); +	if ( len >= 3*4 ) +		__asm__ __volatile__ ( "movsl" : "=&D" ( edi ), "=&S" ( esi ) +				       : "0" ( edi ), "1" ( esi ) : "memory" ); +	if ( len >= 2*4 ) +		__asm__ __volatile__ ( "movsl" : "=&D" ( edi ), "=&S" ( esi ) +				       : "0" ( edi ), "1" ( esi ) : "memory" ); +	if ( len >= 1*4 ) +		__asm__ __volatile__ ( "movsl" : "=&D" ( edi ), "=&S" ( esi ) +				       : "0" ( edi ), "1" ( esi ) : "memory" ); +	if ( ( len % 4 ) >= 2 ) +		__asm__ __volatile__ ( "movsw" : "=&D" ( edi ), "=&S" ( esi ) +				       : "0" ( edi ), "1" ( esi ) : "memory" ); +	if ( ( len % 2 ) >= 1 ) +		__asm__ __volatile__ ( "movsb" : "=&D" ( edi ), "=&S" ( esi ) +				       : "0" ( edi ), "1" ( esi ) : "memory" ); + +	return dest; +} + +/** + * Copy memory area + * + * @v dest		Destination address + * @v src		Source address + * @v len		Length + * @ret dest		Destination address + */ +static inline __attribute__ (( always_inline )) void * +memcpy ( void *dest, const void *src, size_t len ) { +	if ( __builtin_constant_p ( len ) ) { +		return __constant_memcpy ( dest, src, len ); +	} else { +		return __memcpy ( dest, src, len ); +	} +} + +#define __HAVE_ARCH_MEMMOVE + +extern void * __memmove ( void *dest, const void *src, size_t len ); + +/** + * Copy (possibly overlapping) memory area + * + * @v dest		Destination address + * @v src		Source address + * @v len		Length + * @ret dest		Destination address + */ +static inline __attribute__ (( always_inline )) void * +memmove ( void *dest, const void *src, size_t len ) { +	ssize_t offset = ( dest - src ); + +	if ( __builtin_constant_p ( offset ) ) { +		if ( offset <= 0 ) { +			return memcpy ( dest, src, len ); +		} else { +			return __memcpy_reverse ( dest, src, len ); +		} +	} else { +		return __memmove ( dest, src, len ); +	} +} + +#define __HAVE_ARCH_MEMSET + +/** + * Fill memory region + * + * @v dest		Destination address + * @v fill		Fill pattern + * @v len		Length + * @ret dest		Destination address + */ +static inline void * memset ( void *dest, int fill, size_t len ) { +	void *discard_D; +	size_t discard_c; + +	__asm__ __volatile__ ( "rep stosb" +			       : "=&D" ( discard_D ), "=&c" ( discard_c ) +			       : "0" ( dest ), "1" ( len ), "a" ( fill ) +			       : "memory" ); +	return dest; +} + +#define __HAVE_ARCH_MEMSWAP + +extern void * memswap ( void *dest, void *src, size_t len ); + +#define __HAVE_ARCH_STRNCMP + +extern int strncmp ( const char *str1, const char *str2, size_t len ); + +#define __HAVE_ARCH_STRLEN + +extern size_t strlen ( const char *string ); + +#endif /* X86_BITS_STRING_H */ diff --git a/roms/ipxe/src/arch/x86/include/bits/tcpip.h b/roms/ipxe/src/arch/x86/include/bits/tcpip.h new file mode 100644 index 00000000..a4b335eb --- /dev/null +++ b/roms/ipxe/src/arch/x86/include/bits/tcpip.h @@ -0,0 +1,17 @@ +#ifndef _BITS_TCPIP_H +#define _BITS_TCPIP_H + +/** @file + * + * Transport-network layer interface + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +extern uint16_t x86_tcpip_continue_chksum ( uint16_t partial, +					    const void *data, size_t len ); + +#define tcpip_continue_chksum x86_tcpip_continue_chksum + +#endif /* _BITS_TCPIP_H */ diff --git a/roms/ipxe/src/arch/x86/include/bits/xen.h b/roms/ipxe/src/arch/x86/include/bits/xen.h new file mode 100644 index 00000000..dbccf1b7 --- /dev/null +++ b/roms/ipxe/src/arch/x86/include/bits/xen.h @@ -0,0 +1,164 @@ +#ifndef _BITS_XEN_H +#define _BITS_XEN_H + +/** @file + * + * Xen interface + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +/* Hypercall registers */ +#ifdef __x86_64__ +#define XEN_REG1 "rdi" +#define XEN_REG2 "rsi" +#define XEN_REG3 "rdx" +#define XEN_REG4 "r10" +#define XEN_REG5 "r8" +#else +#define XEN_REG1 "ebx" +#define XEN_REG2 "ecx" +#define XEN_REG3 "edx" +#define XEN_REG4 "esi" +#define XEN_REG5 "edi" +#endif + +/** A hypercall entry point */ +struct xen_hypercall { +	/** Code generated by hypervisor */ +	uint8_t code[32]; +} __attribute__ (( packed )); + +/** + * Issue hypercall with one argument + * + * @v xen		Xen hypervisor + * @v hypercall		Hypercall number + * @v arg1		First argument + * @ret retval		Return value + */ +static inline __attribute__ (( always_inline )) unsigned long +xen_hypercall_1 ( struct xen_hypervisor *xen, unsigned int hypercall, +		  unsigned long arg1 ) { +	register unsigned long reg1 asm ( XEN_REG1 ) = arg1; +	unsigned long retval; + +	__asm__ __volatile__ ( "call *%2" +			       : "=a" ( retval ), "+r" ( reg1 ) +			       : "r" ( &xen->hypercall[hypercall] ) +			       : XEN_REG2, XEN_REG3, XEN_REG4, XEN_REG5, +				 "memory" ); +	return retval; +} + +/** + * Issue hypercall with two arguments + * + * @v xen		Xen hypervisor + * @v hypercall		Hypercall number + * @v arg1		First argument + * @v arg2		Second argument + * @ret retval		Return value + */ +static inline __attribute__ (( always_inline )) unsigned long +xen_hypercall_2 ( struct xen_hypervisor *xen, unsigned int hypercall, +		  unsigned long arg1, unsigned long arg2 ) { +	register unsigned long reg1 asm ( XEN_REG1 ) = arg1; +	register unsigned long reg2 asm ( XEN_REG2 ) = arg2; +	unsigned long retval; + +	__asm__ __volatile__ ( "call *%3" +			       : "=a" ( retval ), "+r" ( reg1 ), "+r" ( reg2 ) +			       : "r" ( &xen->hypercall[hypercall] ) +			       : XEN_REG3, XEN_REG4, XEN_REG5, "memory" ); +	return retval; +} + +/** + * Issue hypercall with three arguments + * + * @v xen		Xen hypervisor + * @v hypercall		Hypercall number + * @v arg1		First argument + * @v arg2		Second argument + * @v arg3		Third argument + * @ret retval		Return value + */ +static inline __attribute__ (( always_inline )) unsigned long +xen_hypercall_3 ( struct xen_hypervisor *xen, unsigned int hypercall, +		  unsigned long arg1, unsigned long arg2, unsigned long arg3 ) { +	register unsigned long reg1 asm ( XEN_REG1 ) = arg1; +	register unsigned long reg2 asm ( XEN_REG2 ) = arg2; +	register unsigned long reg3 asm ( XEN_REG3 ) = arg3; +	unsigned long retval; + +	__asm__ __volatile__ ( "call *%4" +			       : "=a" ( retval ), "+r" ( reg1 ), "+r" ( reg2 ), +				 "+r" ( reg3 ) +			       : "r" ( &xen->hypercall[hypercall] ) +			       : XEN_REG4, XEN_REG5, "memory" ); +	return retval; +} + +/** + * Issue hypercall with four arguments + * + * @v xen		Xen hypervisor + * @v hypercall		Hypercall number + * @v arg1		First argument + * @v arg2		Second argument + * @v arg3		Third argument + * @v arg4		Fourth argument + * @ret retval		Return value + */ +static inline __attribute__ (( always_inline )) unsigned long +xen_hypercall_4 ( struct xen_hypervisor *xen, unsigned int hypercall, +		  unsigned long arg1, unsigned long arg2, unsigned long arg3, +		  unsigned long arg4 ) { +	register unsigned long reg1 asm ( XEN_REG1 ) = arg1; +	register unsigned long reg2 asm ( XEN_REG2 ) = arg2; +	register unsigned long reg3 asm ( XEN_REG3 ) = arg3; +	register unsigned long reg4 asm ( XEN_REG4 ) = arg4; +	unsigned long retval; + +	__asm__ __volatile__ ( "call *%5" +			       : "=a" ( retval ), "+r" ( reg1 ), "+r" ( reg2 ), +				 "+r" ( reg3 ), "+r" ( reg4 ) +			       : "r" ( &xen->hypercall[hypercall] ) +			       : XEN_REG5, "memory" ); +	return retval; +} + +/** + * Issue hypercall with five arguments + * + * @v xen		Xen hypervisor + * @v hypercall		Hypercall number + * @v arg1		First argument + * @v arg2		Second argument + * @v arg3		Third argument + * @v arg4		Fourth argument + * @v arg5		Fifth argument + * @ret retval		Return value + */ +static inline __attribute__ (( always_inline )) unsigned long +xen_hypercall_5 ( struct xen_hypervisor *xen, unsigned int hypercall, +		  unsigned long arg1, unsigned long arg2, unsigned long arg3, +		  unsigned long arg4, unsigned long arg5 ) { +	register unsigned long reg1 asm ( XEN_REG1 ) = arg1; +	register unsigned long reg2 asm ( XEN_REG2 ) = arg2; +	register unsigned long reg3 asm ( XEN_REG3 ) = arg3; +	register unsigned long reg4 asm ( XEN_REG4 ) = arg4; +	register unsigned long reg5 asm ( XEN_REG5 ) = arg5; +	unsigned long retval; + +	__asm__ __volatile__ ( "call *%6" +			       : "=a" ( retval ), "+r" ( reg1 ), "+r" ( reg2 ), +				 "+r" ( reg3 ), "+r" ( reg4 ), "+r" ( reg5 ) +			       : "r" ( &xen->hypercall[hypercall] ) +			       : "memory" ); +	return retval; +} + +#endif /* _BITS_XEN_H */ | 
