diff options
author | 2016-06-03 03:33:22 +0000 | |
---|---|---|
committer | 2016-06-03 03:33:23 +0000 | |
commit | da27230f80795d0028333713f036d44c53cb0e68 (patch) | |
tree | b3d379eaf000adf72b36cb01cdf4d79c3e3f064c /qemu/roms/ipxe/src/arch/x86_64 | |
parent | 0e68cb048bb8aadb14675f5d4286d8ab2fc35449 (diff) | |
parent | 437fd90c0250dee670290f9b714253671a990160 (diff) |
Merge "These changes are the raw update to qemu-2.6."
Diffstat (limited to 'qemu/roms/ipxe/src/arch/x86_64')
15 files changed, 231 insertions, 18 deletions
diff --git a/qemu/roms/ipxe/src/arch/x86_64/Makefile b/qemu/roms/ipxe/src/arch/x86_64/Makefile index b687f3407..48c0aa1af 100644 --- a/qemu/roms/ipxe/src/arch/x86_64/Makefile +++ b/qemu/roms/ipxe/src/arch/x86_64/Makefile @@ -40,6 +40,7 @@ endif # x86_64-specific directories containing source files # +SRCDIRS += arch/x86_64/core SRCDIRS += arch/x86_64/prefix # Include common x86 Makefile diff --git a/qemu/roms/ipxe/src/arch/x86_64/core/setjmp.S b/qemu/roms/ipxe/src/arch/x86_64/core/setjmp.S new file mode 100644 index 000000000..e43200d7b --- /dev/null +++ b/qemu/roms/ipxe/src/arch/x86_64/core/setjmp.S @@ -0,0 +1,65 @@ +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) + + .text + .code64 + + /* Must match jmp_buf structure layout */ + .struct 0 +env_retaddr: .quad 0 +env_stack: .quad 0 +env_rbx: .quad 0 +env_rbp: .quad 0 +env_r12: .quad 0 +env_r13: .quad 0 +env_r14: .quad 0 +env_r15: .quad 0 + .previous + +/* + * Save stack context for non-local goto + */ + .globl setjmp +setjmp: + /* Save return address */ + movq 0(%rsp), %rax + movq %rax, env_retaddr(%rdi) + /* Save stack pointer */ + movq %rsp, env_stack(%rdi) + /* Save other registers */ + movq %rbx, env_rbx(%rdi) + movq %rbp, env_rbp(%rdi) + movq %r12, env_r12(%rdi) + movq %r13, env_r13(%rdi) + movq %r14, env_r14(%rdi) + movq %r15, env_r15(%rdi) + /* Return 0 when returning as setjmp() */ + xorq %rax, %rax + ret + .size setjmp, . - setjmp + +/* + * Non-local jump to a saved stack context + */ + .globl longjmp +longjmp: + /* Get result in %rax */ + movq %rsi, %rax + /* Force result to non-zero */ + testq %rax, %rax + jnz 1f + incq %rax +1: /* Restore stack pointer */ + movq env_stack(%rdi), %rsp + /* Restore other registers */ + movq env_rbx(%rdi), %rbx + movq env_rbp(%rdi), %rbp + movq env_r12(%rdi), %r12 + movq env_r13(%rdi), %r13 + movq env_r14(%rdi), %r14 + movq env_r15(%rdi), %r15 + /* Replace return address on the new stack */ + popq %rcx /* discard */ + pushq env_retaddr(%rdi) + /* Return to setjmp() caller */ + ret + .size longjmp, . - longjmp diff --git a/qemu/roms/ipxe/src/arch/x86_64/include/bits/byteswap.h b/qemu/roms/ipxe/src/arch/x86_64/include/bits/byteswap.h index 2e472d98a..d8c5098ef 100644 --- a/qemu/roms/ipxe/src/arch/x86_64/include/bits/byteswap.h +++ b/qemu/roms/ipxe/src/arch/x86_64/include/bits/byteswap.h @@ -9,7 +9,7 @@ #include <stdint.h> -FILE_LICENCE ( GPL2_OR_LATER ); +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); static inline __attribute__ (( always_inline, const )) uint16_t __bswap_variable_16 ( uint16_t x ) { diff --git a/qemu/roms/ipxe/src/arch/x86_64/include/bits/compiler.h b/qemu/roms/ipxe/src/arch/x86_64/include/bits/compiler.h index 51a7eaae2..f70b2e517 100644 --- a/qemu/roms/ipxe/src/arch/x86_64/include/bits/compiler.h +++ b/qemu/roms/ipxe/src/arch/x86_64/include/bits/compiler.h @@ -1,6 +1,9 @@ #ifndef _BITS_COMPILER_H #define _BITS_COMPILER_H +/** Dummy relocation type */ +#define RELOC_TYPE_NONE R_X86_64_NONE + #ifndef ASSEMBLY /** Declare a function with standard calling conventions */ diff --git a/qemu/roms/ipxe/src/arch/x86_64/include/bits/endian.h b/qemu/roms/ipxe/src/arch/x86_64/include/bits/endian.h deleted file mode 100644 index 413e702db..000000000 --- a/qemu/roms/ipxe/src/arch/x86_64/include/bits/endian.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef ETHERBOOT_BITS_ENDIAN_H -#define ETHERBOOT_BITS_ENDIAN_H - -#define __BYTE_ORDER __LITTLE_ENDIAN - -#endif /* ETHERBOOT_BITS_ENDIAN_H */ diff --git a/qemu/roms/ipxe/src/arch/x86_64/include/bits/entropy.h b/qemu/roms/ipxe/src/arch/x86_64/include/bits/entropy.h index 9c64c833b..a9b3bc10e 100644 --- a/qemu/roms/ipxe/src/arch/x86_64/include/bits/entropy.h +++ b/qemu/roms/ipxe/src/arch/x86_64/include/bits/entropy.h @@ -7,6 +7,6 @@ * */ -FILE_LICENCE ( GPL2_OR_LATER ); +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #endif /* _BITS_ENTROPY_H */ diff --git a/qemu/roms/ipxe/src/arch/x86_64/include/bits/hyperv.h b/qemu/roms/ipxe/src/arch/x86_64/include/bits/hyperv.h new file mode 100644 index 000000000..845c182f7 --- /dev/null +++ b/qemu/roms/ipxe/src/arch/x86_64/include/bits/hyperv.h @@ -0,0 +1,75 @@ +#ifndef _BITS_HYPERV_H +#define _BITS_HYPERV_H + +/** @file + * + * Hyper-V interface + * + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +#include <stddef.h> +#include <stdint.h> +#include <ipxe/io.h> + +/** + * Issue hypercall + * + * @v hv Hyper-V hypervisor + * @v code Call code + * @v in Input parameters + * @v out Output parameters + * @ret status Status code + */ +static inline __attribute__ (( always_inline )) int +hv_call ( struct hv_hypervisor *hv, unsigned int code, const void *in, + void *out ) { + void *hypercall = hv->hypercall; + register uint64_t rcx asm ( "rcx" ); + register uint64_t rdx asm ( "rdx" ); + register uint64_t r8 asm ( "r8" ); + uint64_t in_phys; + uint64_t out_phys; + uint16_t result; + + in_phys = ( ( __builtin_constant_p ( in ) && ( in == NULL ) ) + ? 0 : virt_to_phys ( in ) ); + out_phys = ( ( __builtin_constant_p ( out ) && ( out == NULL ) ) + ? 0 : virt_to_phys ( out ) ); + rcx = code; + rdx = in_phys; + r8 = out_phys; + __asm__ __volatile__ ( "call *%4" + : "=a" ( result ), "+r" ( rcx ), "+r" ( rdx ), + "+r" ( r8 ) + : "m" ( hypercall ) + : "r9", "r10", "r11", "xmm0", "xmm1", "xmm2", + "xmm3", "xmm4", "xmm5" ); + return result; +} + +/** + * Set bit atomically + * + * @v bits Bit field + * @v bit Bit to set + */ +static inline __attribute__ (( always_inline )) void +hv_set_bit ( void *bits, unsigned int bit ) { + struct { + uint64_t qword[ ( bit / 64 ) + 1 ]; + } *qwords = bits; + + /* Set bit using "lock bts". Inform compiler that any memory + * from the start of the bit field up to and including the + * qword containing this bit may be modified. (This is + * overkill but shouldn't matter in practice since we're + * unlikely to subsequently read other bits from the same bit + * field.) + */ + __asm__ __volatile__ ( "lock bts %1, %0" + : "+m" ( *qwords ) : "Ir" ( bit ) ); +} + +#endif /* _BITS_HYPERV_H */ diff --git a/qemu/roms/ipxe/src/arch/x86_64/include/bits/profile.h b/qemu/roms/ipxe/src/arch/x86_64/include/bits/profile.h index 6fc16d84b..b7c74fbe7 100644 --- a/qemu/roms/ipxe/src/arch/x86_64/include/bits/profile.h +++ b/qemu/roms/ipxe/src/arch/x86_64/include/bits/profile.h @@ -7,7 +7,7 @@ * */ -FILE_LICENCE ( GPL2_OR_LATER ); +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <stdint.h> diff --git a/qemu/roms/ipxe/src/arch/x86_64/include/bits/reboot.h b/qemu/roms/ipxe/src/arch/x86_64/include/bits/reboot.h index f1bce0540..f9bcd6a7b 100644 --- a/qemu/roms/ipxe/src/arch/x86_64/include/bits/reboot.h +++ b/qemu/roms/ipxe/src/arch/x86_64/include/bits/reboot.h @@ -7,6 +7,6 @@ * */ -FILE_LICENCE ( GPL2_OR_LATER ); +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #endif /* _BITS_REBOOT_H */ diff --git a/qemu/roms/ipxe/src/arch/x86_64/include/bits/sanboot.h b/qemu/roms/ipxe/src/arch/x86_64/include/bits/sanboot.h index d33d03cbe..dcab830f6 100644 --- a/qemu/roms/ipxe/src/arch/x86_64/include/bits/sanboot.h +++ b/qemu/roms/ipxe/src/arch/x86_64/include/bits/sanboot.h @@ -7,6 +7,6 @@ * */ -FILE_LICENCE ( GPL2_OR_LATER ); +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #endif /* _BITS_SANBOOT_H */ diff --git a/qemu/roms/ipxe/src/arch/x86_64/include/bits/strings.h b/qemu/roms/ipxe/src/arch/x86_64/include/bits/strings.h index 6ee99a500..3b7911f3b 100644 --- a/qemu/roms/ipxe/src/arch/x86_64/include/bits/strings.h +++ b/qemu/roms/ipxe/src/arch/x86_64/include/bits/strings.h @@ -1,7 +1,43 @@ #ifndef _BITS_STRINGS_H #define _BITS_STRINGS_H -FILE_LICENCE ( GPL2_OR_LATER ); +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +/** + * Find first (i.e. least significant) set bit + * + * @v value Value + * @ret lsb Least significant bit set in value (LSB=1), or zero + */ +static inline __attribute__ (( always_inline )) int __ffsll ( long long value ){ + long long lsb_minus_one; + + /* If the input value is zero, the BSF instruction returns + * ZF=0 and leaves an undefined value in the output register. + * Perform this check in C rather than asm so that it can be + * omitted in cases where the compiler is able to prove that + * the input is non-zero. + */ + if ( value ) { + __asm__ ( "bsfq %1, %0" + : "=r" ( lsb_minus_one ) + : "rm" ( value ) ); + return ( lsb_minus_one + 1 ); + } else { + return 0; + } +} + +/** + * Find first (i.e. least significant) set bit + * + * @v value Value + * @ret lsb Least significant bit set in value (LSB=1), or zero + */ +static inline __attribute__ (( always_inline )) int __ffsl ( long value ) { + + return __ffsll ( value ); +} /** * Find last (i.e. most significant) set bit @@ -13,7 +49,7 @@ static inline __attribute__ (( always_inline )) int __flsll ( long long value ){ long long msb_minus_one; /* If the input value is zero, the BSR instruction returns - * ZF=1 and leaves an undefined value in the output register. + * ZF=0 and leaves an undefined value in the output register. * Perform this check in C rather than asm so that it can be * omitted in cases where the compiler is able to prove that * the input is non-zero. diff --git a/qemu/roms/ipxe/src/arch/x86_64/include/bits/time.h b/qemu/roms/ipxe/src/arch/x86_64/include/bits/time.h index 59b355359..aa74fac8c 100644 --- a/qemu/roms/ipxe/src/arch/x86_64/include/bits/time.h +++ b/qemu/roms/ipxe/src/arch/x86_64/include/bits/time.h @@ -7,6 +7,6 @@ * */ -FILE_LICENCE ( GPL2_OR_LATER ); +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #endif /* _BITS_TIME_H */ diff --git a/qemu/roms/ipxe/src/arch/x86_64/include/efi/ipxe/dhcp_arch.h b/qemu/roms/ipxe/src/arch/x86_64/include/efi/ipxe/dhcp_arch.h index 9a4790fdc..6511c1ad3 100644 --- a/qemu/roms/ipxe/src/arch/x86_64/include/efi/ipxe/dhcp_arch.h +++ b/qemu/roms/ipxe/src/arch/x86_64/include/efi/ipxe/dhcp_arch.h @@ -4,7 +4,7 @@ * 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. + * License, or (at your option) 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 @@ -13,7 +13,12 @@ * * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. */ #ifndef _DHCP_ARCH_H @@ -24,7 +29,7 @@ * Architecture-specific DHCP options */ -FILE_LICENCE ( GPL2_OR_LATER ); +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <ipxe/dhcp.h> diff --git a/qemu/roms/ipxe/src/arch/x86_64/include/ipxe/msr.h b/qemu/roms/ipxe/src/arch/x86_64/include/ipxe/msr.h index a5816ac35..316243b69 100644 --- a/qemu/roms/ipxe/src/arch/x86_64/include/ipxe/msr.h +++ b/qemu/roms/ipxe/src/arch/x86_64/include/ipxe/msr.h @@ -7,7 +7,7 @@ * */ -FILE_LICENCE ( GPL2_OR_LATER ); +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); /** * Read model-specific register diff --git a/qemu/roms/ipxe/src/arch/x86_64/include/setjmp.h b/qemu/roms/ipxe/src/arch/x86_64/include/setjmp.h new file mode 100644 index 000000000..69835d9fa --- /dev/null +++ b/qemu/roms/ipxe/src/arch/x86_64/include/setjmp.h @@ -0,0 +1,34 @@ +#ifndef _SETJMP_H +#define _SETJMP_H + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +#include <stdint.h> + +/** A jump buffer */ +typedef struct { + /** Saved return address */ + uint64_t retaddr; + /** Saved stack pointer */ + uint64_t stack; + /** Saved %rbx */ + uint64_t rbx; + /** Saved %rbp */ + uint64_t rbp; + /** Saved %r12 */ + uint64_t r12; + /** Saved %r13 */ + uint64_t r13; + /** Saved %r14 */ + uint64_t r14; + /** Saved %r15 */ + uint64_t r15; +} jmp_buf[1]; + +extern int __asmcall __attribute__ (( returns_twice )) +setjmp ( jmp_buf env ); + +extern void __asmcall __attribute__ (( noreturn )) +longjmp ( jmp_buf env, int val ); + +#endif /* _SETJMP_H */ |