summaryrefslogtreecommitdiffstats
path: root/qemu/roms/ipxe/src/arch/x86_64
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/roms/ipxe/src/arch/x86_64')
-rw-r--r--qemu/roms/ipxe/src/arch/x86_64/Makefile1
-rw-r--r--qemu/roms/ipxe/src/arch/x86_64/core/setjmp.S65
-rw-r--r--qemu/roms/ipxe/src/arch/x86_64/include/bits/byteswap.h2
-rw-r--r--qemu/roms/ipxe/src/arch/x86_64/include/bits/compiler.h3
-rw-r--r--qemu/roms/ipxe/src/arch/x86_64/include/bits/endian.h6
-rw-r--r--qemu/roms/ipxe/src/arch/x86_64/include/bits/entropy.h2
-rw-r--r--qemu/roms/ipxe/src/arch/x86_64/include/bits/hyperv.h75
-rw-r--r--qemu/roms/ipxe/src/arch/x86_64/include/bits/profile.h2
-rw-r--r--qemu/roms/ipxe/src/arch/x86_64/include/bits/reboot.h2
-rw-r--r--qemu/roms/ipxe/src/arch/x86_64/include/bits/sanboot.h2
-rw-r--r--qemu/roms/ipxe/src/arch/x86_64/include/bits/strings.h40
-rw-r--r--qemu/roms/ipxe/src/arch/x86_64/include/bits/time.h2
-rw-r--r--qemu/roms/ipxe/src/arch/x86_64/include/efi/ipxe/dhcp_arch.h11
-rw-r--r--qemu/roms/ipxe/src/arch/x86_64/include/ipxe/msr.h2
-rw-r--r--qemu/roms/ipxe/src/arch/x86_64/include/setjmp.h34
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 */