summaryrefslogtreecommitdiffstats
path: root/contrib/syslinux-4.02/gpxe/src/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/syslinux-4.02/gpxe/src/arch/x86')
-rw-r--r--contrib/syslinux-4.02/gpxe/src/arch/x86/Makefile9
-rw-r--r--contrib/syslinux-4.02/gpxe/src/arch/x86/Makefile.efi28
-rw-r--r--contrib/syslinux-4.02/gpxe/src/arch/x86/core/pcidirect.c47
-rw-r--r--contrib/syslinux-4.02/gpxe/src/arch/x86/core/x86_string.c63
-rw-r--r--contrib/syslinux-4.02/gpxe/src/arch/x86/include/bits/pci_io.h15
-rw-r--r--contrib/syslinux-4.02/gpxe/src/arch/x86/include/bits/string.h252
-rw-r--r--contrib/syslinux-4.02/gpxe/src/arch/x86/include/gpxe/efi/efix86_nap.h18
-rw-r--r--contrib/syslinux-4.02/gpxe/src/arch/x86/include/gpxe/pcibios.h135
-rw-r--r--contrib/syslinux-4.02/gpxe/src/arch/x86/include/gpxe/pcidirect.h141
-rw-r--r--contrib/syslinux-4.02/gpxe/src/arch/x86/interface/efi/efix86_nap.c48
-rw-r--r--contrib/syslinux-4.02/gpxe/src/arch/x86/prefix/efidrvprefix.c46
-rw-r--r--contrib/syslinux-4.02/gpxe/src/arch/x86/prefix/efiprefix.c41
-rw-r--r--contrib/syslinux-4.02/gpxe/src/arch/x86/scripts/efi.lds106
13 files changed, 949 insertions, 0 deletions
diff --git a/contrib/syslinux-4.02/gpxe/src/arch/x86/Makefile b/contrib/syslinux-4.02/gpxe/src/arch/x86/Makefile
new file mode 100644
index 0000000..f5f67ac
--- /dev/null
+++ b/contrib/syslinux-4.02/gpxe/src/arch/x86/Makefile
@@ -0,0 +1,9 @@
+# Include common x86 headers
+#
+INCDIRS += arch/x86/include
+
+# x86-specific directories containing source files
+#
+SRCDIRS += arch/x86/core
+SRCDIRS += arch/x86/interface/efi
+SRCDIRS += arch/x86/prefix
diff --git a/contrib/syslinux-4.02/gpxe/src/arch/x86/Makefile.efi b/contrib/syslinux-4.02/gpxe/src/arch/x86/Makefile.efi
new file mode 100644
index 0000000..bef8d59
--- /dev/null
+++ b/contrib/syslinux-4.02/gpxe/src/arch/x86/Makefile.efi
@@ -0,0 +1,28 @@
+# -*- makefile -*- : Force emacs to use Makefile mode
+
+# The EFI linker script
+#
+LDSCRIPT = arch/x86/scripts/efi.lds
+
+# Retain relocation information for elf2efi
+#
+LDFLAGS += -q -S
+
+# Media types.
+#
+NON_AUTO_MEDIA += efi
+NON_AUTO_MEDIA += efidrv
+
+# Rules for building EFI files
+#
+$(BIN)/%.efi : $(BIN)/%.efi.tmp $(ELF2EFI)
+ $(QM)$(ECHO) " [FINISH] $@"
+ $(Q)$(ELF2EFI) --subsystem=10 $< $@
+
+$(BIN)/%.efidrv : $(BIN)/%.efidrv.tmp $(ELF2EFI)
+ $(QM)$(ECHO) " [FINISH] $@"
+ $(Q)$(ELF2EFI) --subsystem=11 $< $@
+
+$(BIN)/%.efirom : $(BIN)/%.efidrv $(EFIROM)
+ $(QM)$(ECHO) " [FINISH] $@"
+ $(Q)$(EFIROM) -v $(TGT_PCI_VENDOR) -d $(TGT_PCI_DEVICE) $< $@
diff --git a/contrib/syslinux-4.02/gpxe/src/arch/x86/core/pcidirect.c b/contrib/syslinux-4.02/gpxe/src/arch/x86/core/pcidirect.c
new file mode 100644
index 0000000..2c61d9c
--- /dev/null
+++ b/contrib/syslinux-4.02/gpxe/src/arch/x86/core/pcidirect.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2006 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <gpxe/io.h>
+#include <gpxe/pci.h>
+
+/** @file
+ *
+ * PCI configuration space access via Type 1 accesses
+ *
+ */
+
+/**
+ * Prepare for Type 1 PCI configuration space access
+ *
+ * @v pci PCI device
+ * @v where Location within PCI configuration space
+ */
+void pcidirect_prepare ( struct pci_device *pci, int where ) {
+ outl ( ( 0x80000000 | ( pci->bus << 16 ) | ( pci->devfn << 8 ) |
+ ( where & ~3 ) ), PCIDIRECT_CONFIG_ADDRESS );
+}
+
+PROVIDE_PCIAPI_INLINE ( direct, pci_max_bus );
+PROVIDE_PCIAPI_INLINE ( direct, pci_read_config_byte );
+PROVIDE_PCIAPI_INLINE ( direct, pci_read_config_word );
+PROVIDE_PCIAPI_INLINE ( direct, pci_read_config_dword );
+PROVIDE_PCIAPI_INLINE ( direct, pci_write_config_byte );
+PROVIDE_PCIAPI_INLINE ( direct, pci_write_config_word );
+PROVIDE_PCIAPI_INLINE ( direct, pci_write_config_dword );
diff --git a/contrib/syslinux-4.02/gpxe/src/arch/x86/core/x86_string.c b/contrib/syslinux-4.02/gpxe/src/arch/x86/core/x86_string.c
new file mode 100644
index 0000000..5838eba
--- /dev/null
+++ b/contrib/syslinux-4.02/gpxe/src/arch/x86/core/x86_string.c
@@ -0,0 +1,63 @@
+/*
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/** @file
+ *
+ * Optimised string operations
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <string.h>
+
+/**
+ * Copy memory area
+ *
+ * @v dest Destination address
+ * @v src Source address
+ * @v len Length
+ * @ret dest Destination address
+ */
+void * __memcpy ( void *dest, const void *src, size_t len ) {
+ void *edi = dest;
+ const void *esi = src;
+ int discard_ecx;
+
+ /* We often do large dword-aligned and dword-length block
+ * moves. Using movsl rather than movsb speeds these up by
+ * around 32%.
+ */
+ if ( len >> 2 ) {
+ __asm__ __volatile__ ( "rep movsl"
+ : "=&D" ( edi ), "=&S" ( esi ),
+ "=&c" ( discard_ecx )
+ : "0" ( edi ), "1" ( esi ),
+ "2" ( len >> 2 )
+ : "memory" );
+ }
+ if ( len & 0x02 ) {
+ __asm__ __volatile__ ( "movsw" : "=&D" ( edi ), "=&S" ( esi )
+ : "0" ( edi ), "1" ( esi ) : "memory" );
+ }
+ if ( len & 0x01 ) {
+ __asm__ __volatile__ ( "movsb" : "=&D" ( edi ), "=&S" ( esi )
+ : "0" ( edi ), "1" ( esi ) : "memory" );
+ }
+ return dest;
+}
diff --git a/contrib/syslinux-4.02/gpxe/src/arch/x86/include/bits/pci_io.h b/contrib/syslinux-4.02/gpxe/src/arch/x86/include/bits/pci_io.h
new file mode 100644
index 0000000..f6efcda
--- /dev/null
+++ b/contrib/syslinux-4.02/gpxe/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 <gpxe/pcibios.h>
+#include <gpxe/pcidirect.h>
+
+#endif /* _BITS_PCI_IO_H */
diff --git a/contrib/syslinux-4.02/gpxe/src/arch/x86/include/bits/string.h b/contrib/syslinux-4.02/gpxe/src/arch/x86/include/bits/string.h
new file mode 100644
index 0000000..a68868a
--- /dev/null
+++ b/contrib/syslinux-4.02/gpxe/src/arch/x86/include/bits/string.h
@@ -0,0 +1,252 @@
+#ifndef ETHERBOOT_BITS_STRING_H
+#define ETHERBOOT_BITS_STRING_H
+/*
+ * Taken from Linux /usr/include/asm/string.h
+ * All except memcpy, memmove, memset and memcmp removed.
+ *
+ * Non-standard memswap() function added because it saves quite a bit
+ * of code (mbrown@fensystems.co.uk).
+ */
+
+/*
+ * This string-include defines all string functions as inline
+ * functions. Use gcc. It also assumes ds=es=data space, this should be
+ * normal. Most of the string-functions are rather heavily hand-optimized,
+ * see especially strtok,strstr,str[c]spn. They should work, but are not
+ * very easy to understand. Everything is done entirely within the register
+ * set, making the functions fast and clean. String instructions have been
+ * used through-out, making for "slightly" unclear code :-)
+ *
+ * NO Copyright (C) 1991, 1992 Linus Torvalds,
+ * consider these trivial functions to be PD.
+ */
+
+FILE_LICENCE ( PUBLIC_DOMAIN );
+
+#define __HAVE_ARCH_MEMCPY
+
+extern void * __memcpy ( void *dest, const void *src, size_t len );
+
+#if 0
+static inline __attribute__ (( always_inline )) void *
+__memcpy ( void *dest, const void *src, size_t len ) {
+ int d0, d1, d2;
+ __asm__ __volatile__ ( "rep ; movsb"
+ : "=&c" ( d0 ), "=&S" ( d1 ), "=&D" ( d2 )
+ : "0" ( len ), "1" ( src ), "2" ( dest )
+ : "memory" );
+ return dest;
+}
+#endif
+
+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;
+}
+
+#define memcpy( dest, src, len ) \
+ ( __builtin_constant_p ( (len) ) ? \
+ __constant_memcpy ( (dest), (src), (len) ) : \
+ __memcpy ( (dest), (src), (len) ) )
+
+#define __HAVE_ARCH_MEMMOVE
+static inline void * memmove(void * dest,const void * src, size_t n)
+{
+int d0, d1, d2;
+if (dest<src)
+__asm__ __volatile__(
+ "cld\n\t"
+ "rep\n\t"
+ "movsb"
+ : "=&c" (d0), "=&S" (d1), "=&D" (d2)
+ :"0" (n),"1" (src),"2" (dest)
+ : "memory");
+else
+__asm__ __volatile__(
+ "std\n\t"
+ "rep\n\t"
+ "movsb\n\t"
+ "cld"
+ : "=&c" (d0), "=&S" (d1), "=&D" (d2)
+ :"0" (n),
+ "1" (n-1+(const char *)src),
+ "2" (n-1+(char *)dest)
+ :"memory");
+return dest;
+}
+
+#define __HAVE_ARCH_MEMSET
+static inline void * memset(void *s, int c,size_t count)
+{
+int d0, d1;
+__asm__ __volatile__(
+ "cld\n\t"
+ "rep\n\t"
+ "stosb"
+ : "=&c" (d0), "=&D" (d1)
+ :"a" (c),"1" (s),"0" (count)
+ :"memory");
+return s;
+}
+
+#define __HAVE_ARCH_MEMSWAP
+static inline void * memswap(void *dest, void *src, size_t n)
+{
+int d0, d1, d2, d3;
+__asm__ __volatile__(
+ "\n1:\t"
+ "movb (%%edi),%%al\n\t"
+ "xchgb (%%esi),%%al\n\t"
+ "incl %%esi\n\t"
+ "stosb\n\t"
+ "loop 1b"
+ : "=&c" (d0), "=&S" (d1), "=&D" (d2), "=&a" (d3)
+ : "0" (n), "1" (src), "2" (dest)
+ : "memory" );
+return dest;
+}
+
+#define __HAVE_ARCH_STRNCMP
+static inline int strncmp(const char * cs,const char * ct,size_t count)
+{
+register int __res;
+int d0, d1, d2;
+__asm__ __volatile__(
+ "1:\tdecl %3\n\t"
+ "js 2f\n\t"
+ "lodsb\n\t"
+ "scasb\n\t"
+ "jne 3f\n\t"
+ "testb %%al,%%al\n\t"
+ "jne 1b\n"
+ "2:\txorl %%eax,%%eax\n\t"
+ "jmp 4f\n"
+ "3:\tsbbl %%eax,%%eax\n\t"
+ "orb $1,%%al\n"
+ "4:"
+ :"=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2)
+ :"1" (cs),"2" (ct),"3" (count));
+return __res;
+}
+
+#define __HAVE_ARCH_STRLEN
+static inline size_t strlen(const char * s)
+{
+int d0;
+register int __res;
+__asm__ __volatile__(
+ "repne\n\t"
+ "scasb\n\t"
+ "notl %0\n\t"
+ "decl %0"
+ :"=c" (__res), "=&D" (d0) :"1" (s),"a" (0), "0" (0xffffffff));
+return __res;
+}
+
+#endif /* ETHERBOOT_BITS_STRING_H */
diff --git a/contrib/syslinux-4.02/gpxe/src/arch/x86/include/gpxe/efi/efix86_nap.h b/contrib/syslinux-4.02/gpxe/src/arch/x86/include/gpxe/efi/efix86_nap.h
new file mode 100644
index 0000000..833c922
--- /dev/null
+++ b/contrib/syslinux-4.02/gpxe/src/arch/x86/include/gpxe/efi/efix86_nap.h
@@ -0,0 +1,18 @@
+#ifndef _GPXE_EFIX86_NAP_H
+#define _GPXE_EFIX86_NAP_H
+
+/** @file
+ *
+ * EFI CPU sleeping
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#ifdef NAP_EFIX86
+#define NAP_PREFIX_efix86
+#else
+#define NAP_PREFIX_efix86 __efix86_
+#endif
+
+#endif /* _GPXE_EFIX86_NAP_H */
diff --git a/contrib/syslinux-4.02/gpxe/src/arch/x86/include/gpxe/pcibios.h b/contrib/syslinux-4.02/gpxe/src/arch/x86/include/gpxe/pcibios.h
new file mode 100644
index 0000000..93a6eb8
--- /dev/null
+++ b/contrib/syslinux-4.02/gpxe/src/arch/x86/include/gpxe/pcibios.h
@@ -0,0 +1,135 @@
+#ifndef _GPXE_PCIBIOS_H
+#define _GPXE_PCIBIOS_H
+
+#include <stdint.h>
+
+/** @file
+ *
+ * PCI configuration space access via PCI BIOS
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#ifdef PCIAPI_PCBIOS
+#define PCIAPI_PREFIX_pcbios
+#else
+#define PCIAPI_PREFIX_pcbios __pcbios_
+#endif
+
+struct pci_device;
+
+#define PCIBIOS_INSTALLATION_CHECK 0xb1010000
+#define PCIBIOS_READ_CONFIG_BYTE 0xb1080000
+#define PCIBIOS_READ_CONFIG_WORD 0xb1090000
+#define PCIBIOS_READ_CONFIG_DWORD 0xb10a0000
+#define PCIBIOS_WRITE_CONFIG_BYTE 0xb10b0000
+#define PCIBIOS_WRITE_CONFIG_WORD 0xb10c0000
+#define PCIBIOS_WRITE_CONFIG_DWORD 0xb10d0000
+
+extern int pcibios_read ( struct pci_device *pci, uint32_t command,
+ uint32_t *value );
+extern int pcibios_write ( struct pci_device *pci, uint32_t command,
+ uint32_t value );
+
+/**
+ * Read byte from PCI configuration space via PCI BIOS
+ *
+ * @v pci PCI device
+ * @v where Location within PCI configuration space
+ * @v value Value read
+ * @ret rc Return status code
+ */
+static inline __always_inline int
+PCIAPI_INLINE ( pcbios, pci_read_config_byte ) ( struct pci_device *pci,
+ unsigned int where,
+ uint8_t *value ) {
+ uint32_t tmp;
+ int rc;
+
+ rc = pcibios_read ( pci, PCIBIOS_READ_CONFIG_BYTE | where, &tmp );
+ *value = tmp;
+ return rc;
+}
+
+/**
+ * Read word from PCI configuration space via PCI BIOS
+ *
+ * @v pci PCI device
+ * @v where Location within PCI configuration space
+ * @v value Value read
+ * @ret rc Return status code
+ */
+static inline __always_inline int
+PCIAPI_INLINE ( pcbios, pci_read_config_word ) ( struct pci_device *pci,
+ unsigned int where,
+ uint16_t *value ) {
+ uint32_t tmp;
+ int rc;
+
+ rc = pcibios_read ( pci, PCIBIOS_READ_CONFIG_WORD | where, &tmp );
+ *value = tmp;
+ return rc;
+}
+
+/**
+ * Read dword from PCI configuration space via PCI BIOS
+ *
+ * @v pci PCI device
+ * @v where Location within PCI configuration space
+ * @v value Value read
+ * @ret rc Return status code
+ */
+static inline __always_inline int
+PCIAPI_INLINE ( pcbios, pci_read_config_dword ) ( struct pci_device *pci,
+ unsigned int where,
+ uint32_t *value ) {
+ return pcibios_read ( pci, PCIBIOS_READ_CONFIG_DWORD | where, value );
+}
+
+/**
+ * Write byte to PCI configuration space via PCI BIOS
+ *
+ * @v pci PCI device
+ * @v where Location within PCI configuration space
+ * @v value Value to be written
+ * @ret rc Return status code
+ */
+static inline __always_inline int
+PCIAPI_INLINE ( pcbios, pci_write_config_byte ) ( struct pci_device *pci,
+ unsigned int where,
+ uint8_t value ) {
+ return pcibios_write ( pci, PCIBIOS_WRITE_CONFIG_BYTE | where, value );
+}
+
+/**
+ * Write word to PCI configuration space via PCI BIOS
+ *
+ * @v pci PCI device
+ * @v where Location within PCI configuration space
+ * @v value Value to be written
+ * @ret rc Return status code
+ */
+static inline __always_inline int
+PCIAPI_INLINE ( pcbios, pci_write_config_word ) ( struct pci_device *pci,
+ unsigned int where,
+ uint16_t value ) {
+ return pcibios_write ( pci, PCIBIOS_WRITE_CONFIG_WORD | where, value );
+}
+
+/**
+ * Write dword to PCI configuration space via PCI BIOS
+ *
+ * @v pci PCI device
+ * @v where Location within PCI configuration space
+ * @v value Value to be written
+ * @ret rc Return status code
+ */
+static inline __always_inline int
+PCIAPI_INLINE ( pcbios, pci_write_config_dword ) ( struct pci_device *pci,
+ unsigned int where,
+ uint32_t value ) {
+ return pcibios_write ( pci, PCIBIOS_WRITE_CONFIG_DWORD | where, value);
+}
+
+#endif /* _GPXE_PCIBIOS_H */
diff --git a/contrib/syslinux-4.02/gpxe/src/arch/x86/include/gpxe/pcidirect.h b/contrib/syslinux-4.02/gpxe/src/arch/x86/include/gpxe/pcidirect.h
new file mode 100644
index 0000000..8b705fb
--- /dev/null
+++ b/contrib/syslinux-4.02/gpxe/src/arch/x86/include/gpxe/pcidirect.h
@@ -0,0 +1,141 @@
+#ifndef _PCIDIRECT_H
+#define _PCIDIRECT_H
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <stdint.h>
+#include <gpxe/io.h>
+
+#ifdef PCIAPI_DIRECT
+#define PCIAPI_PREFIX_direct
+#else
+#define PCIAPI_PREFIX_direct __direct_
+#endif
+
+/** @file
+ *
+ * PCI configuration space access via Type 1 accesses
+ *
+ */
+
+#define PCIDIRECT_CONFIG_ADDRESS 0xcf8
+#define PCIDIRECT_CONFIG_DATA 0xcfc
+
+struct pci_device;
+
+extern void pcidirect_prepare ( struct pci_device *pci, int where );
+
+/**
+ * Determine maximum PCI bus number within system
+ *
+ * @ret max_bus Maximum bus number
+ */
+static inline __always_inline int
+PCIAPI_INLINE ( direct, pci_max_bus ) ( void ) {
+ /* No way to work this out via Type 1 accesses */
+ return 0xff;
+}
+
+/**
+ * Read byte from PCI configuration space via Type 1 access
+ *
+ * @v pci PCI device
+ * @v where Location within PCI configuration space
+ * @v value Value read
+ * @ret rc Return status code
+ */
+static inline __always_inline int
+PCIAPI_INLINE ( direct, pci_read_config_byte ) ( struct pci_device *pci,
+ unsigned int where,
+ uint8_t *value ) {
+ pcidirect_prepare ( pci, where );
+ *value = inb ( PCIDIRECT_CONFIG_DATA + ( where & 3 ) );
+ return 0;
+}
+
+/**
+ * Read word from PCI configuration space via Type 1 access
+ *
+ * @v pci PCI device
+ * @v where Location within PCI configuration space
+ * @v value Value read
+ * @ret rc Return status code
+ */
+static inline __always_inline int
+PCIAPI_INLINE ( direct, pci_read_config_word ) ( struct pci_device *pci,
+ unsigned int where,
+ uint16_t *value ) {
+ pcidirect_prepare ( pci, where );
+ *value = inw ( PCIDIRECT_CONFIG_DATA + ( where & 2 ) );
+ return 0;
+}
+
+/**
+ * Read dword from PCI configuration space via Type 1 access
+ *
+ * @v pci PCI device
+ * @v where Location within PCI configuration space
+ * @v value Value read
+ * @ret rc Return status code
+ */
+static inline __always_inline int
+PCIAPI_INLINE ( direct, pci_read_config_dword ) ( struct pci_device *pci,
+ unsigned int where,
+ uint32_t *value ) {
+ pcidirect_prepare ( pci, where );
+ *value = inl ( PCIDIRECT_CONFIG_DATA );
+ return 0;
+}
+
+/**
+ * Write byte to PCI configuration space via Type 1 access
+ *
+ * @v pci PCI device
+ * @v where Location within PCI configuration space
+ * @v value Value to be written
+ * @ret rc Return status code
+ */
+static inline __always_inline int
+PCIAPI_INLINE ( direct, pci_write_config_byte ) ( struct pci_device *pci,
+ unsigned int where,
+ uint8_t value ) {
+ pcidirect_prepare ( pci, where );
+ outb ( value, PCIDIRECT_CONFIG_DATA + ( where & 3 ) );
+ return 0;
+}
+
+/**
+ * Write word to PCI configuration space via Type 1 access
+ *
+ * @v pci PCI device
+ * @v where Location within PCI configuration space
+ * @v value Value to be written
+ * @ret rc Return status code
+ */
+static inline __always_inline int
+PCIAPI_INLINE ( direct, pci_write_config_word ) ( struct pci_device *pci,
+ unsigned int where,
+ uint16_t value ) {
+ pcidirect_prepare ( pci, where );
+ outw ( value, PCIDIRECT_CONFIG_DATA + ( where & 2 ) );
+ return 0;
+}
+
+/**
+ * Write dword to PCI configuration space via Type 1 access
+ *
+ * @v pci PCI device
+ * @v where Location within PCI configuration space
+ * @v value Value to be written
+ * @ret rc Return status code
+ */
+static inline __always_inline int
+PCIAPI_INLINE ( direct, pci_write_config_dword ) ( struct pci_device *pci,
+ unsigned int where,
+ uint32_t value ) {
+ pcidirect_prepare ( pci, where );
+ outl ( value, PCIDIRECT_CONFIG_DATA );
+ return 0;
+}
+
+#endif /* _PCIDIRECT_H */
diff --git a/contrib/syslinux-4.02/gpxe/src/arch/x86/interface/efi/efix86_nap.c b/contrib/syslinux-4.02/gpxe/src/arch/x86/interface/efi/efix86_nap.c
new file mode 100644
index 0000000..89a4e3b
--- /dev/null
+++ b/contrib/syslinux-4.02/gpxe/src/arch/x86/interface/efi/efix86_nap.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2008 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <gpxe/nap.h>
+#include <gpxe/efi/efi.h>
+
+/** @file
+ *
+ * gPXE CPU sleeping API for EFI
+ *
+ */
+
+/**
+ * Sleep until next interrupt
+ *
+ */
+static void efix86_cpu_nap ( void ) {
+ /*
+ * I can't find any EFI API that allows us to put the CPU to
+ * sleep. The CpuSleep() function is defined in CpuLib.h, but
+ * isn't part of any exposed protocol so we have no way to
+ * call it.
+ *
+ * The EFI shell doesn't seem to bother sleeping the CPU; it
+ * just sits there idly burning power.
+ *
+ */
+ __asm__ __volatile__ ( "hlt" );
+}
+
+PROVIDE_NAP ( efix86, cpu_nap, efix86_cpu_nap );
diff --git a/contrib/syslinux-4.02/gpxe/src/arch/x86/prefix/efidrvprefix.c b/contrib/syslinux-4.02/gpxe/src/arch/x86/prefix/efidrvprefix.c
new file mode 100644
index 0000000..36d5650
--- /dev/null
+++ b/contrib/syslinux-4.02/gpxe/src/arch/x86/prefix/efidrvprefix.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2009 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <stdlib.h>
+#include <gpxe/init.h>
+#include <gpxe/efi/efi.h>
+
+/**
+ * EFI entry point
+ *
+ * @v image_handle Image handle
+ * @v systab System table
+ * @ret efirc EFI return status code
+ */
+EFI_STATUS EFIAPI _start ( EFI_HANDLE image_handle,
+ EFI_SYSTEM_TABLE *systab ) {
+ EFI_STATUS efirc;
+
+ /* Initialise EFI environment */
+ if ( ( efirc = efi_init ( image_handle, systab ) ) != 0 )
+ return efirc;
+
+ /* Initialise gPXE environment */
+ initialise();
+ startup();
+
+ /* Install SNP driver and return */
+ return RC_TO_EFIRC ( efi_snp_install () );
+}
diff --git a/contrib/syslinux-4.02/gpxe/src/arch/x86/prefix/efiprefix.c b/contrib/syslinux-4.02/gpxe/src/arch/x86/prefix/efiprefix.c
new file mode 100644
index 0000000..4cc9e04
--- /dev/null
+++ b/contrib/syslinux-4.02/gpxe/src/arch/x86/prefix/efiprefix.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2009 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <stdlib.h>
+#include <gpxe/efi/efi.h>
+
+/**
+ * EFI entry point
+ *
+ * @v image_handle Image handle
+ * @v systab System table
+ * @ret efirc EFI return status code
+ */
+EFI_STATUS EFIAPI _start ( EFI_HANDLE image_handle,
+ EFI_SYSTEM_TABLE *systab ) {
+ EFI_STATUS efirc;
+
+ /* Initialise EFI environment */
+ if ( ( efirc = efi_init ( image_handle, systab ) ) != 0 )
+ return efirc;
+
+ /* Call to main() */
+ return RC_TO_EFIRC ( main () );
+}
diff --git a/contrib/syslinux-4.02/gpxe/src/arch/x86/scripts/efi.lds b/contrib/syslinux-4.02/gpxe/src/arch/x86/scripts/efi.lds
new file mode 100644
index 0000000..7525b81
--- /dev/null
+++ b/contrib/syslinux-4.02/gpxe/src/arch/x86/scripts/efi.lds
@@ -0,0 +1,106 @@
+/* -*- sh -*- */
+
+/*
+ * Linker script for EFI images
+ *
+ */
+
+ENTRY ( _start )
+
+SECTIONS {
+
+ /* The file starts at a virtual address of zero, and sections are
+ * contiguous. Each section is aligned to at least _max_align,
+ * which defaults to 32. Load addresses are equal to virtual
+ * addresses.
+ */
+
+ _max_align = 32;
+
+ /* Allow plenty of space for file headers */
+ . = 0x1000;
+
+ /*
+ * The text section
+ *
+ */
+
+ . = ALIGN ( _max_align );
+ .text : {
+ _text = .;
+ *(.text)
+ *(.text.*)
+ _etext = .;
+ }
+
+ /*
+ * The rodata section
+ *
+ */
+
+ . = ALIGN ( _max_align );
+ .rodata : {
+ _rodata = .;
+ *(.rodata)
+ *(.rodata.*)
+ _erodata = .;
+ }
+
+ /*
+ * The data section
+ *
+ */
+
+ . = ALIGN ( _max_align );
+ .data : {
+ _data = .;
+ *(.data)
+ *(.data.*)
+ *(SORT(.tbl.*)) /* Various tables. See include/tables.h */
+ _edata = .;
+ }
+
+ /*
+ * The bss section
+ *
+ */
+
+ . = ALIGN ( _max_align );
+ .bss : {
+ _bss = .;
+ *(.bss)
+ *(.bss.*)
+ *(COMMON)
+ _ebss = .;
+ }
+
+ /*
+ * Weak symbols that need zero values if not otherwise defined
+ *
+ */
+
+ .weak 0x0 : {
+ _weak = .;
+ *(.weak)
+ _eweak = .;
+ }
+ _assert = ASSERT ( ( _weak == _eweak ), ".weak is non-zero length" );
+
+ /*
+ * Dispose of the comment and note sections to make the link map
+ * easier to read
+ *
+ */
+
+ /DISCARD/ : {
+ *(.comment)
+ *(.comment.*)
+ *(.note)
+ *(.note.*)
+ *(.eh_frame)
+ *(.eh_frame.*)
+ *(.rel)
+ *(.rel.*)
+ *(.discard)
+ }
+}