summaryrefslogtreecommitdiffstats
path: root/src/arch
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/arm64/Makefile.efi4
-rw-r--r--src/arch/i386/Makefile16
-rw-r--r--src/arch/i386/Makefile.linux10
-rw-r--r--src/arch/i386/core/linux/linux_syscall.S45
-rw-r--r--src/arch/i386/core/linux/linuxprefix.S28
-rw-r--r--src/arch/i386/include/bits/compiler.h2
-rw-r--r--src/arch/i386/include/bits/linux_api.h6
-rw-r--r--src/arch/x86/Makefile.linux17
-rw-r--r--src/arch/x86/Makefile.pcbios54
-rw-r--r--src/arch/x86/core/cachedhcp.c179
-rw-r--r--src/arch/x86/core/linux/linux_api.c149
-rw-r--r--src/arch/x86/core/linux/linux_strerror.c169
-rw-r--r--src/arch/x86/core/pcidirect.c1
-rw-r--r--src/arch/x86/core/runtime.c47
-rw-r--r--src/arch/x86/core/stack.S2
-rw-r--r--src/arch/x86/core/stack16.S2
-rw-r--r--src/arch/x86/drivers/hyperv/hyperv.c12
-rw-r--r--src/arch/x86/drivers/xen/hvm.c10
-rw-r--r--src/arch/x86/drivers/xen/hvm.h2
-rw-r--r--src/arch/x86/image/initrd.c12
-rw-r--r--src/arch/x86/include/bits/bitops.h8
-rw-r--r--src/arch/x86/include/bits/linux_api_platform.h6
-rw-r--r--src/arch/x86/include/ipxe/cpuid.h3
-rw-r--r--src/arch/x86/include/ipxe/pcibios.h13
-rw-r--r--src/arch/x86/include/ipxe/pcidirect.h13
-rw-r--r--src/arch/x86/include/ipxe/rsdp.h13
-rw-r--r--src/arch/x86/interface/pcbios/bios_cachedhcp.c76
-rw-r--r--src/arch/x86/interface/pcbios/bios_console.c2
-rw-r--r--src/arch/x86/interface/pcbios/e820mangler.S2
-rw-r--r--src/arch/x86/interface/pcbios/int13.c2
-rw-r--r--src/arch/x86/interface/pcbios/pcibios.c1
-rw-r--r--src/arch/x86/interface/pcbios/rsdp.c1
-rw-r--r--src/arch/x86/interface/pxe/pxe_entry.S4
-rw-r--r--src/arch/x86/interface/syslinux/comboot_call.c6
-rw-r--r--src/arch/x86/prefix/exeprefix.S2
-rw-r--r--src/arch/x86/prefix/mromprefix.S2
-rw-r--r--src/arch/x86/prefix/rawprefix.S53
-rw-r--r--src/arch/x86/prefix/romprefix.S8
-rw-r--r--src/arch/x86/prefix/unlzma.S2
-rw-r--r--src/arch/x86/scripts/pcbios.lds63
-rw-r--r--src/arch/x86/scripts/prefixonly.lds29
-rw-r--r--src/arch/x86/transitions/liba20.S2
-rw-r--r--src/arch/x86/transitions/librm.S29
-rw-r--r--src/arch/x86/transitions/librm_mgmt.c18
-rw-r--r--src/arch/x86/transitions/librm_test.c3
-rw-r--r--src/arch/x86_64/Makefile.linux8
-rw-r--r--src/arch/x86_64/core/linux/linux_syscall.S33
-rw-r--r--src/arch/x86_64/core/linux/linuxprefix.S25
-rw-r--r--src/arch/x86_64/include/bits/compiler.h2
-rw-r--r--src/arch/x86_64/include/bits/linux_api.h6
50 files changed, 370 insertions, 832 deletions
diff --git a/src/arch/arm64/Makefile.efi b/src/arch/arm64/Makefile.efi
index eb04c0e2f..998a64d03 100644
--- a/src/arch/arm64/Makefile.efi
+++ b/src/arch/arm64/Makefile.efi
@@ -1,9 +1,5 @@
# -*- makefile -*- : Force emacs to use Makefile mode
-# Avoid untranslatable relocations
-#
-CFLAGS += -fno-pic
-
# Specify EFI image builder
#
ELF2EFI = $(ELF2EFI64)
diff --git a/src/arch/i386/Makefile b/src/arch/i386/Makefile
index b7c2792d9..e59f05fc8 100644
--- a/src/arch/i386/Makefile
+++ b/src/arch/i386/Makefile
@@ -69,22 +69,6 @@ CFLAGS += -fshort-wchar
#
CFLAGS += -Ui386
-# Some widespread patched versions of gcc include -fPIE -Wl,-pie by
-# default. Note that gcc will exit *successfully* if it fails to
-# recognise an option that starts with "no", so we have to test for
-# output on stderr instead of checking the exit status.
-#
-# Current versions of gcc require -no-pie; older versions require
-# -nopie. We therefore test for both.
-#
-ifeq ($(CCTYPE),gcc)
-PIE_TEST = [ -z "`$(CC) -fno-PIE -no-pie -x c -c /dev/null -o /dev/null 2>&1`" ]
-PIE_FLAGS := $(shell $(PIE_TEST) && $(ECHO) '-fno-PIE -no-pie')
-PIE_TEST2 = [ -z "`$(CC) -fno-PIE -nopie -x c -c /dev/null -o /dev/null 2>&1`" ]
-PIE_FLAGS2 := $(shell $(PIE_TEST2) && $(ECHO) '-fno-PIE -nopie')
-WORKAROUND_CFLAGS += $(PIE_FLAGS) $(PIE_FLAGS2)
-endif
-
# i386-specific directories containing source files
#
SRCDIRS += arch/i386/core
diff --git a/src/arch/i386/Makefile.linux b/src/arch/i386/Makefile.linux
index 46328c83b..fe4229e94 100644
--- a/src/arch/i386/Makefile.linux
+++ b/src/arch/i386/Makefile.linux
@@ -1,6 +1,14 @@
+# -*- makefile -*- : Force emacs to use Makefile mode
+
+# Linker script
+#
LDSCRIPT = arch/i386/scripts/linux.lds
-SRCDIRS += arch/i386/core/linux
+# Compiler flags for building host API wrapper
+#
+LINUX_CFLAGS += -m32
+# Include generic Linux Makefile
+#
MAKEDEPS += arch/x86/Makefile.linux
include arch/x86/Makefile.linux
diff --git a/src/arch/i386/core/linux/linux_syscall.S b/src/arch/i386/core/linux/linux_syscall.S
deleted file mode 100644
index 38a3e74bd..000000000
--- a/src/arch/i386/core/linux/linux_syscall.S
+++ /dev/null
@@ -1,45 +0,0 @@
-
- .section ".data"
- .globl linux_errno
-
-linux_errno: .int 0
-
- .section ".text"
- .code32
- .globl linux_syscall
- .type linux_syscall, @function
-
-linux_syscall:
- /* Save registers */
- pushl %ebx
- pushl %esi
- pushl %edi
- pushl %ebp
-
- movl 20(%esp), %eax // C arg1 -> syscall number
- movl 24(%esp), %ebx // C arg2 -> syscall arg1
- movl 28(%esp), %ecx // C arg3 -> syscall arg2
- movl 32(%esp), %edx // C arg4 -> syscall arg3
- movl 36(%esp), %esi // C arg5 -> syscall arg4
- movl 40(%esp), %edi // C arg6 -> syscall arg5
- movl 44(%esp), %ebp // C arg7 -> syscall arg6
-
- int $0x80
-
- /* Restore registers */
- popl %ebp
- popl %edi
- popl %esi
- popl %ebx
-
- cmpl $-4095, %eax
- jae 1f
- ret
-
-1:
- negl %eax
- movl %eax, linux_errno
- movl $-1, %eax
- ret
-
- .size linux_syscall, . - linux_syscall
diff --git a/src/arch/i386/core/linux/linuxprefix.S b/src/arch/i386/core/linux/linuxprefix.S
deleted file mode 100644
index 398d3cb21..000000000
--- a/src/arch/i386/core/linux/linuxprefix.S
+++ /dev/null
@@ -1,28 +0,0 @@
-#include <linux/unistd.h>
-
- .section ".text"
- .code32
- .globl _linux_start
- .type _linux_start, @function
-
-_linux_start:
- xorl %ebp, %ebp
-
- popl %esi // save argc
- movl %esp, %edi // save argv
-
- andl $~15, %esp // 16-byte align the stack
-
- pushl %edi // argv -> C arg2
- pushl %esi // argc -> C arg1
-
- call save_args
-
- /* Our main doesn't use any arguments */
- call main
-
- movl %eax, %ebx // rc -> syscall arg1
- movl $__NR_exit, %eax
- int $0x80
-
- .size _linux_start, . - _linux_start
diff --git a/src/arch/i386/include/bits/compiler.h b/src/arch/i386/include/bits/compiler.h
index 7c4a09396..87201135f 100644
--- a/src/arch/i386/include/bits/compiler.h
+++ b/src/arch/i386/include/bits/compiler.h
@@ -9,7 +9,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#ifndef ASSEMBLY
/** Declare a function with standard calling conventions */
-#define __asmcall __attribute__ (( used, cdecl, regparm(0) ))
+#define __asmcall __attribute__ (( cdecl, regparm(0) ))
/**
* Declare a function with libgcc implicit linkage
diff --git a/src/arch/i386/include/bits/linux_api.h b/src/arch/i386/include/bits/linux_api.h
deleted file mode 100644
index dc6e7416e..000000000
--- a/src/arch/i386/include/bits/linux_api.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _I386_LINUX_API_H
-#define _I386_LINUX_API_H
-
-#define __SYSCALL_mmap __NR_mmap2
-
-#endif /* _I386_LINUX_API_H */
diff --git a/src/arch/x86/Makefile.linux b/src/arch/x86/Makefile.linux
index 1faf84753..b60065567 100644
--- a/src/arch/x86/Makefile.linux
+++ b/src/arch/x86/Makefile.linux
@@ -1,13 +1,10 @@
-MEDIA = linux
-
-# enable valgrind
-CFLAGS += -UNVALGRIND
+# -*- makefile -*- : Force emacs to use Makefile mode
+# Include x86 Linux headers
+#
INCDIRS += arch/x86/include/linux
-SRCDIRS += interface/linux
-SRCDIRS += drivers/linux
-SRCDIRS += arch/x86/core/linux
-$(BIN)/%.linux : $(BIN)/%.linux.tmp
- $(QM)$(ECHO) " [FINISH] $@"
- $(Q)$(CP) $< $@
+# Include generic Linux Makefile
+#
+MAKEDEPS += Makefile.linux
+include Makefile.linux
diff --git a/src/arch/x86/Makefile.pcbios b/src/arch/x86/Makefile.pcbios
index c44eefc1f..ed8d554a7 100644
--- a/src/arch/x86/Makefile.pcbios
+++ b/src/arch/x86/Makefile.pcbios
@@ -4,18 +4,15 @@
#
SRCDIRS += arch/x86/drivers/net
-# The i386 linker script
+# The linker scripts
#
LDSCRIPT = arch/x86/scripts/pcbios.lds
+LDSCRIPT_PREFIX = arch/x86/scripts/prefixonly.lds
# Stop ld from complaining about our customised linker script
#
LDFLAGS += -N --no-check-sections
-# Prefix always starts at address zero
-#
-LDFLAGS += --section-start=.prefix=0
-
# Media types.
#
MEDIA += rom
@@ -57,46 +54,11 @@ LIST_NAME_mrom := ROMS
LIST_NAME_pcirom := ROMS
LIST_NAME_isarom := ROMS
-# Locations of isolinux files
-#
-SYSLINUX_DIR_LIST := \
- /usr/lib/syslinux \
- /usr/lib/syslinux/bios \
- /usr/lib/syslinux/modules/bios \
- /usr/share/syslinux \
- /usr/share/syslinux/bios \
- /usr/share/syslinux/modules/bios \
- /usr/local/share/syslinux \
- /usr/local/share/syslinux/bios \
- /usr/local/share/syslinux/modules/bios \
- /usr/lib/ISOLINUX
-ISOLINUX_BIN_LIST := \
- $(ISOLINUX_BIN) \
- $(patsubst %,%/isolinux.bin,$(SYSLINUX_DIR_LIST))
-LDLINUX_C32_LIST := \
- $(LDLINUX_C32) \
- $(patsubst %,%/ldlinux.c32,$(SYSLINUX_DIR_LIST))
-ISOLINUX_BIN = $(firstword $(wildcard $(ISOLINUX_BIN_LIST)))
-LDLINUX_C32 = $(firstword $(wildcard $(LDLINUX_C32_LIST)))
-
-# rule to make a non-emulation ISO boot image
+# ISO or FAT filesystem images
NON_AUTO_MEDIA += iso
-%iso: %lkrn util/geniso
- $(QM)$(ECHO) " [GENISO] $@"
- $(Q)ISOLINUX_BIN=$(ISOLINUX_BIN) LDLINUX_C32=$(LDLINUX_C32) \
- VERSION="$(VERSION)" bash util/geniso -o $@ $<
-
-# rule to make a floppy emulation ISO boot image
-NON_AUTO_MEDIA += liso
-%liso: %lkrn util/geniso
- $(QM)$(ECHO) " [GENISO] $@"
- $(Q)VERSION="$(VERSION)" bash util/geniso -l -o $@ $<
-
-# rule to make a syslinux floppy image (mountable, bootable)
-NON_AUTO_MEDIA += sdsk
-%sdsk: %lkrn util/gensdsk
- $(QM)$(ECHO) " [GENSDSK] $@"
- $(Q)bash util/gensdsk $@ $<
+$(BIN)/%.iso $(BIN)/%.sdsk: $(BIN)/%.lkrn util/genfsimg
+ $(QM)$(ECHO) " [GENFSIMG] $@"
+ $(Q)util/genfsimg -o $@ $<
# rule to write disk images to /dev/fd0
NON_AUTO_MEDIA += fd0
@@ -108,12 +70,12 @@ NON_AUTO_MEDIA += fd0
# Special target for building Master Boot Record binary
$(BIN)/mbr.tmp : $(BIN)/mbr.o
$(QM)$(ECHO) " [LD] $@"
- $(Q)$(LD) $(LDFLAGS) -o $@ -e mbr $<
+ $(Q)$(LD) $(LDFLAGS) -T $(LDSCRIPT_PREFIX) -o $@ -e mbr $<
# rule to make a USB disk image
$(BIN)/usbdisk.tmp : $(BIN)/usbdisk.o
$(QM)$(ECHO) " [LD] $@"
- $(Q)$(LD) $(LDFLAGS) -o $@ -e mbr $<
+ $(Q)$(LD) $(LDFLAGS) -T $(LDSCRIPT_PREFIX) -o $@ -e mbr $<
NON_AUTO_MEDIA += usb
%usb: $(BIN)/usbdisk.bin %hd
diff --git a/src/arch/x86/core/cachedhcp.c b/src/arch/x86/core/cachedhcp.c
deleted file mode 100644
index dffafe3c9..000000000
--- a/src/arch/x86/core/cachedhcp.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (C) 2013 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.
- *
- * 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.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <ipxe/dhcppkt.h>
-#include <ipxe/init.h>
-#include <ipxe/netdevice.h>
-#include <realmode.h>
-#include <pxe_api.h>
-
-/** @file
- *
- * Cached DHCP packet
- *
- */
-
-/** Cached DHCPACK physical address
- *
- * This can be set by the prefix.
- */
-uint32_t __bss16 ( cached_dhcpack_phys );
-#define cached_dhcpack_phys __use_data16 ( cached_dhcpack_phys )
-
-/** Colour for debug messages */
-#define colour &cached_dhcpack_phys
-
-/** Cached DHCPACK */
-static struct dhcp_packet *cached_dhcpack;
-
-/**
- * Cached DHCPACK startup function
- *
- */
-static void cachedhcp_init ( void ) {
- struct dhcp_packet *dhcppkt;
- struct dhcp_packet *tmp;
- struct dhcphdr *dhcphdr;
- size_t max_len;
- size_t len;
-
- /* Do nothing if no cached DHCPACK is present */
- if ( ! cached_dhcpack_phys ) {
- DBGC ( colour, "CACHEDHCP found no cached DHCPACK\n" );
- return;
- }
-
- /* No reliable way to determine length before parsing packet;
- * start by assuming maximum length permitted by PXE.
- */
- max_len = sizeof ( BOOTPLAYER_t );
-
- /* Allocate and populate DHCP packet */
- dhcppkt = zalloc ( sizeof ( *dhcppkt ) + max_len );
- if ( ! dhcppkt ) {
- DBGC ( colour, "CACHEDHCP could not allocate copy\n" );
- return;
- }
- dhcphdr = ( ( ( void * ) dhcppkt ) + sizeof ( *dhcppkt ) );
- copy_from_user ( dhcphdr, phys_to_user ( cached_dhcpack_phys ), 0,
- max_len );
- dhcppkt_init ( dhcppkt, dhcphdr, max_len );
-
- /* Shrink packet to required length. If reallocation fails,
- * just continue to use the original packet and waste the
- * unused space.
- */
- len = dhcppkt_len ( dhcppkt );
- assert ( len <= max_len );
- tmp = realloc ( dhcppkt, ( sizeof ( *dhcppkt ) + len ) );
- if ( tmp )
- dhcppkt = tmp;
-
- /* Reinitialise packet at new address */
- dhcphdr = ( ( ( void * ) dhcppkt ) + sizeof ( *dhcppkt ) );
- dhcppkt_init ( dhcppkt, dhcphdr, len );
-
- /* Store as cached DHCPACK, and mark original copy as consumed */
- DBGC ( colour, "CACHEDHCP found cached DHCPACK at %08x+%zx\n",
- cached_dhcpack_phys, len );
- cached_dhcpack = dhcppkt;
- cached_dhcpack_phys = 0;
-}
-
-/**
- * Cached DHCPACK startup function
- *
- */
-static void cachedhcp_startup ( void ) {
-
- /* If cached DHCP packet was not claimed by any network device
- * during startup, then free it.
- */
- if ( cached_dhcpack ) {
- DBGC ( colour, "CACHEDHCP freeing unclaimed cached DHCPACK\n" );
- dhcppkt_put ( cached_dhcpack );
- cached_dhcpack = NULL;
- }
-}
-
-/** Cached DHCPACK initialisation function */
-struct init_fn cachedhcp_init_fn __init_fn ( INIT_NORMAL ) = {
- .initialise = cachedhcp_init,
-};
-
-/** Cached DHCPACK startup function */
-struct startup_fn cachedhcp_startup_fn __startup_fn ( STARTUP_LATE ) = {
- .name = "cachedhcp",
- .startup = cachedhcp_startup,
-};
-
-/**
- * Apply cached DHCPACK to network device, if applicable
- *
- * @v netdev Network device
- * @ret rc Return status code
- */
-static int cachedhcp_probe ( struct net_device *netdev ) {
- struct ll_protocol *ll_protocol = netdev->ll_protocol;
- int rc;
-
- /* Do nothing unless we have a cached DHCPACK */
- if ( ! cached_dhcpack )
- return 0;
-
- /* Do nothing unless cached DHCPACK's MAC address matches this
- * network device.
- */
- if ( memcmp ( netdev->ll_addr, cached_dhcpack->dhcphdr->chaddr,
- ll_protocol->ll_addr_len ) != 0 ) {
- DBGC ( colour, "CACHEDHCP cached DHCPACK does not match %s\n",
- netdev->name );
- return 0;
- }
- DBGC ( colour, "CACHEDHCP cached DHCPACK is for %s\n", netdev->name );
-
- /* Register as DHCP settings for this network device */
- if ( ( rc = register_settings ( &cached_dhcpack->settings,
- netdev_settings ( netdev ),
- DHCP_SETTINGS_NAME ) ) != 0 ) {
- DBGC ( colour, "CACHEDHCP could not register settings: %s\n",
- strerror ( rc ) );
- return rc;
- }
-
- /* Claim cached DHCPACK */
- dhcppkt_put ( cached_dhcpack );
- cached_dhcpack = NULL;
-
- return 0;
-}
-
-/** Cached DHCP packet network device driver */
-struct net_driver cachedhcp_driver __net_driver = {
- .name = "cachedhcp",
- .probe = cachedhcp_probe,
-};
diff --git a/src/arch/x86/core/linux/linux_api.c b/src/arch/x86/core/linux/linux_api.c
deleted file mode 100644
index 17b1f3fd4..000000000
--- a/src/arch/x86/core/linux/linux_api.c
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2010 Piotr Jaroszyński <p.jaroszynski@gmail.com>
- *
- * 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 St, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-/** @file
- *
- * Implementation of most of the linux API.
- */
-
-#include <linux_api.h>
-
-#include <stdarg.h>
-#include <asm/unistd.h>
-#include <string.h>
-
-int linux_open ( const char *pathname, int flags ) {
- return linux_syscall ( __NR_open, pathname, flags );
-}
-
-int linux_close ( int fd ) {
- return linux_syscall ( __NR_close, fd );
-}
-
-off_t linux_lseek ( int fd, off_t offset, int whence ) {
- return linux_syscall ( __NR_lseek, fd, offset, whence );
-}
-
-__kernel_ssize_t linux_read ( int fd, void *buf, __kernel_size_t count ) {
- return linux_syscall ( __NR_read, fd, buf, count );
-}
-
-__kernel_ssize_t linux_write ( int fd, const void *buf,
- __kernel_size_t count ) {
- return linux_syscall ( __NR_write, fd, buf, count );
-}
-
-int linux_fcntl ( int fd, int cmd, ... ) {
- long arg;
- va_list list;
-
- va_start ( list, cmd );
- arg = va_arg ( list, long );
- va_end ( list );
-
- return linux_syscall ( __NR_fcntl, fd, cmd, arg );
-}
-
-int linux_ioctl ( int fd, int request, ... ) {
- void *arg;
- va_list list;
-
- va_start ( list, request );
- arg = va_arg ( list, void * );
- va_end ( list );
-
- return linux_syscall ( __NR_ioctl, fd, request, arg );
-}
-
-int linux_poll ( struct pollfd *fds, nfds_t nfds, int timeout ) {
- return linux_syscall ( __NR_poll, fds, nfds, timeout );
-}
-
-int linux_nanosleep ( const struct timespec *req, struct timespec *rem ) {
- return linux_syscall ( __NR_nanosleep, req, rem );
-}
-
-int linux_usleep ( useconds_t usec ) {
- struct timespec ts = {
- .tv_sec = ( ( long ) ( usec / 1000000 ) ),
- .tv_nsec = ( ( long ) ( usec % 1000000 ) * 1000UL ),
- };
-
- return linux_nanosleep ( &ts, NULL );
-}
-
-int linux_gettimeofday ( struct timeval *tv, struct timezone *tz ) {
- return linux_syscall ( __NR_gettimeofday, tv, tz );
-}
-
-void * linux_mmap ( void *addr, __kernel_size_t length, int prot, int flags,
- int fd, __kernel_off_t offset ) {
- return ( void * ) linux_syscall ( __SYSCALL_mmap, addr, length, prot,
- flags, fd, offset );
-}
-
-void * linux_mremap ( void *old_address, __kernel_size_t old_size,
- __kernel_size_t new_size, int flags ) {
- return ( void * ) linux_syscall ( __NR_mremap, old_address, old_size,
- new_size, flags );
-}
-
-int linux_munmap ( void *addr, __kernel_size_t length ) {
- return linux_syscall ( __NR_munmap, addr, length );
-}
-
-int linux_socket ( int domain, int type_, int protocol ) {
-#ifdef __NR_socket
- return linux_syscall ( __NR_socket, domain, type_, protocol );
-#else
-#ifndef SOCKOP_socket
-# define SOCKOP_socket 1
-#endif
- unsigned long sc_args[] = { domain, type_, protocol };
- return linux_syscall ( __NR_socketcall, SOCKOP_socket, sc_args );
-#endif
-}
-
-int linux_bind ( int fd, const struct sockaddr *addr, socklen_t addrlen ) {
-#ifdef __NR_bind
- return linux_syscall ( __NR_bind, fd, addr, addrlen );
-#else
-#ifndef SOCKOP_bind
-# define SOCKOP_bind 2
-#endif
- unsigned long sc_args[] = { fd, (unsigned long)addr, addrlen };
- return linux_syscall ( __NR_socketcall, SOCKOP_bind, sc_args );
-#endif
-}
-
-ssize_t linux_sendto ( int fd, const void *buf, size_t len, int flags,
- const struct sockaddr *daddr, socklen_t addrlen ) {
-#ifdef __NR_sendto
- return linux_syscall ( __NR_sendto, fd, buf, len, flags,
- daddr, addrlen );
-#else
-#ifndef SOCKOP_sendto
-# define SOCKOP_sendto 11
-#endif
- unsigned long sc_args[] = { fd, (unsigned long)buf, len,
- flags, (unsigned long)daddr, addrlen };
- return linux_syscall ( __NR_socketcall, SOCKOP_sendto, sc_args );
-#endif
-}
diff --git a/src/arch/x86/core/linux/linux_strerror.c b/src/arch/x86/core/linux/linux_strerror.c
deleted file mode 100644
index 24c9b7738..000000000
--- a/src/arch/x86/core/linux/linux_strerror.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) 2010 Piotr Jaroszyński <p.jaroszynski@gmail.com>
- *
- * 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 St, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-FILE_LICENCE(GPL2_OR_LATER);
-
-/** @file
- *
- * linux_strerror implementation
- */
-
-#include <linux_api.h>
-#include <stdio.h>
-
-/** Error names from glibc */
-static const char *errors[] = {
- "Success",
- "Operation not permitted",
- "No such file or directory",
- "No such process",
- "Interrupted system call",
- "Input/output error",
- "No such device or address",
- "Argument list too long",
- "Exec format error",
- "Bad file descriptor",
- "No child processes",
- "Resource temporarily unavailable",
- "Cannot allocate memory",
- "Permission denied",
- "Bad address",
- "Block device required",
- "Device or resource busy",
- "File exists",
- "Invalid cross-device link",
- "No such device",
- "Not a directory",
- "Is a directory",
- "Invalid argument",
- "Too many open files in system",
- "Too many open files",
- "Inappropriate ioctl for device",
- "Text file busy",
- "File too large",
- "No space left on device",
- "Illegal seek",
- "Read-only file system",
- "Too many links",
- "Broken pipe",
- "Numerical argument out of domain",
- "Numerical result out of range",
- "Resource deadlock avoided",
- "File name too long",
- "No locks available",
- "Function not implemented",
- "Directory not empty",
- "Too many levels of symbolic links",
- "",
- "No message of desired type",
- "Identifier removed",
- "Channel number out of range",
- "Level 2 not synchronized",
- "Level 3 halted",
- "Level 3 reset",
- "Link number out of range",
- "Protocol driver not attached",
- "No CSI structure available",
- "Level 2 halted",
- "Invalid exchange",
- "Invalid request descriptor",
- "Exchange full",
- "No anode",
- "Invalid request code",
- "Invalid slot",
- "",
- "Bad font file format",
- "Device not a stream",
- "No data available",
- "Timer expired",
- "Out of streams resources",
- "Machine is not on the network",
- "Package not installed",
- "Object is remote",
- "Link has been severed",
- "Advertise error",
- "Srmount error",
- "Communication error on send",
- "Protocol error",
- "Multihop attempted",
- "RFS specific error",
- "Bad message",
- "Value too large for defined data type",
- "Name not unique on network",
- "File descriptor in bad state",
- "Remote address changed",
- "Can not access a needed shared library",
- "Accessing a corrupted shared library",
- ".lib section in a.out corrupted",
- "Attempting to link in too many shared libraries",
- "Cannot exec a shared library directly",
- "Invalid or incomplete multibyte or wide character",
- "Interrupted system call should be restarted",
- "Streams pipe error",
- "Too many users",
- "Socket operation on non-socket",
- "Destination address required",
- "Message too long",
- "Protocol wrong type for socket",
- "Protocol not available",
- "Protocol not supported",
- "Socket type not supported",
- "Operation not supported",
- "Protocol family not supported",
- "Address family not supported by protocol",
- "Address already in use",
- "Cannot assign requested address",
- "Network is down",
- "Network is unreachable",
- "Network dropped connection on reset",
- "Software caused connection abort",
- "Connection reset by peer",
- "No buffer space available",
- "Transport endpoint is already connected",
- "Transport endpoint is not connected",
- "Cannot send after transport endpoint shutdown",
- "Too many references: cannot splice",
- "Connection timed out",
- "Connection refused",
- "Host is down",
- "No route to host",
- "Operation already in progress",
- "Operation now in progress",
- "Stale NFS file handle",
- "Structure needs cleaning",
- "Not a XENIX named type file",
- "No XENIX semaphores available",
- "Is a named type file",
- "Remote I/O error",
- "Disk quota exceeded",
- "No medium found",
- "Wrong medium type",
-};
-
-const char *linux_strerror(int errnum)
-{
- static char errbuf[64];
- static int errors_size = sizeof(errors) / sizeof(*errors);
-
- if (errnum >= errors_size || errnum < 0) {
- snprintf(errbuf, sizeof(errbuf), "Error %#08x", errnum);
- return errbuf;
- } else {
- return errors[errnum];
- }
-}
diff --git a/src/arch/x86/core/pcidirect.c b/src/arch/x86/core/pcidirect.c
index 0d09be84b..9b8226fea 100644
--- a/src/arch/x86/core/pcidirect.c
+++ b/src/arch/x86/core/pcidirect.c
@@ -52,3 +52,4 @@ 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 );
+PROVIDE_PCIAPI_INLINE ( direct, pci_ioremap );
diff --git a/src/arch/x86/core/runtime.c b/src/arch/x86/core/runtime.c
index f96b23af4..02072b5bf 100644
--- a/src/arch/x86/core/runtime.c
+++ b/src/arch/x86/core/runtime.c
@@ -38,7 +38,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/init.h>
#include <ipxe/image.h>
#include <ipxe/script.h>
-#include <ipxe/umalloc.h>
#include <realmode.h>
/** Command line physical address
@@ -180,7 +179,6 @@ static int cmdline_init ( void ) {
*/
static int initrd_init ( void ) {
struct image *image;
- int rc;
/* Do nothing if no initrd was specified */
if ( ! initrd_phys ) {
@@ -194,53 +192,18 @@ static int initrd_init ( void ) {
DBGC ( colour, "RUNTIME found initrd at [%x,%x)\n",
initrd_phys, ( initrd_phys + initrd_len ) );
- /* Allocate image */
- image = alloc_image ( NULL );
+ /* Create initrd image */
+ image = image_memory ( "<INITRD>", phys_to_user ( initrd_phys ),
+ initrd_len );
if ( ! image ) {
- DBGC ( colour, "RUNTIME could not allocate image for "
- "initrd\n" );
- rc = -ENOMEM;
- goto err_alloc_image;
- }
- if ( ( rc = image_set_name ( image, "<INITRD>" ) ) != 0 ) {
- DBGC ( colour, "RUNTIME could not set image name: %s\n",
- strerror ( rc ) );
- goto err_set_name;
+ DBGC ( colour, "RUNTIME could not create initrd image\n" );
+ return -ENOMEM;
}
- /* Allocate and copy initrd content */
- image->data = umalloc ( initrd_len );
- if ( ! image->data ) {
- DBGC ( colour, "RUNTIME could not allocate %d bytes for "
- "initrd\n", initrd_len );
- rc = -ENOMEM;
- goto err_umalloc;
- }
- image->len = initrd_len;
- memcpy_user ( image->data, 0, phys_to_user ( initrd_phys ), 0,
- initrd_len );
-
/* Mark initrd as consumed */
initrd_phys = 0;
- /* Register image */
- if ( ( rc = register_image ( image ) ) != 0 ) {
- DBGC ( colour, "RUNTIME could not register initrd: %s\n",
- strerror ( rc ) );
- goto err_register_image;
- }
-
- /* Drop our reference to the image */
- image_put ( image );
-
return 0;
-
- err_register_image:
- err_umalloc:
- err_set_name:
- image_put ( image );
- err_alloc_image:
- return rc;
}
/**
diff --git a/src/arch/x86/core/stack.S b/src/arch/x86/core/stack.S
index 995c397ca..baa19ff84 100644
--- a/src/arch/x86/core/stack.S
+++ b/src/arch/x86/core/stack.S
@@ -13,7 +13,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
****************************************************************************
*/
.section ".stack", "aw", @nobits
- .align 8
+ .balign 8
.globl _stack
_stack:
.space STACK_SIZE
diff --git a/src/arch/x86/core/stack16.S b/src/arch/x86/core/stack16.S
index 4bc6f081a..ad67e4f2d 100644
--- a/src/arch/x86/core/stack16.S
+++ b/src/arch/x86/core/stack16.S
@@ -7,7 +7,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
****************************************************************************
*/
.section ".stack16", "aw", @nobits
- .align 8
+ .balign 8
.globl _stack16
_stack16:
.space 4096
diff --git a/src/arch/x86/drivers/hyperv/hyperv.c b/src/arch/x86/drivers/hyperv/hyperv.c
index 1903d1db2..9d3a42da0 100644
--- a/src/arch/x86/drivers/hyperv/hyperv.c
+++ b/src/arch/x86/drivers/hyperv/hyperv.c
@@ -83,7 +83,7 @@ hv_alloc_pages ( struct hv_hypervisor *hv, ... ) {
/* Allocate and zero pages */
va_start ( args, hv );
for ( i = 0 ; ( ( page = va_arg ( args, void ** ) ) != NULL ); i++ ) {
- *page = malloc_dma ( PAGE_SIZE, PAGE_SIZE );
+ *page = malloc_phys ( PAGE_SIZE, PAGE_SIZE );
if ( ! *page )
goto err_alloc;
memset ( *page, 0, PAGE_SIZE );
@@ -97,7 +97,7 @@ hv_alloc_pages ( struct hv_hypervisor *hv, ... ) {
va_start ( args, hv );
for ( ; i >= 0 ; i-- ) {
page = va_arg ( args, void ** );
- free_dma ( *page, PAGE_SIZE );
+ free_phys ( *page, PAGE_SIZE );
}
va_end ( args );
return -ENOMEM;
@@ -116,7 +116,7 @@ hv_free_pages ( struct hv_hypervisor *hv, ... ) {
va_start ( args, hv );
while ( ( page = va_arg ( args, void * ) ) != NULL )
- free_dma ( page, PAGE_SIZE );
+ free_phys ( page, PAGE_SIZE );
va_end ( args );
}
@@ -131,8 +131,8 @@ static int hv_alloc_message ( struct hv_hypervisor *hv ) {
/* Allocate buffer. Must be aligned to at least 8 bytes and
* must not cross a page boundary, so align on its own size.
*/
- hv->message = malloc_dma ( sizeof ( *hv->message ),
- sizeof ( *hv->message ) );
+ hv->message = malloc_phys ( sizeof ( *hv->message ),
+ sizeof ( *hv->message ) );
if ( ! hv->message )
return -ENOMEM;
@@ -147,7 +147,7 @@ static int hv_alloc_message ( struct hv_hypervisor *hv ) {
static void hv_free_message ( struct hv_hypervisor *hv ) {
/* Free buffer */
- free_dma ( hv->message, sizeof ( *hv->message ) );
+ free_phys ( hv->message, sizeof ( *hv->message ) );
}
/**
diff --git a/src/arch/x86/drivers/xen/hvm.c b/src/arch/x86/drivers/xen/hvm.c
index 57196f555..b77cdd14c 100644
--- a/src/arch/x86/drivers/xen/hvm.c
+++ b/src/arch/x86/drivers/xen/hvm.c
@@ -106,7 +106,7 @@ static int hvm_map_hypercall ( struct hvm_device *hvm ) {
/* Allocate pages */
hvm->hypercall_len = ( pages * PAGE_SIZE );
- hvm->xen.hypercall = malloc_dma ( hvm->hypercall_len, PAGE_SIZE );
+ hvm->xen.hypercall = malloc_phys ( hvm->hypercall_len, PAGE_SIZE );
if ( ! hvm->xen.hypercall ) {
DBGC ( hvm, "HVM could not allocate %d hypercall page(s)\n",
pages );
@@ -141,7 +141,7 @@ static int hvm_map_hypercall ( struct hvm_device *hvm ) {
static void hvm_unmap_hypercall ( struct hvm_device *hvm ) {
/* Free pages */
- free_dma ( hvm->xen.hypercall, hvm->hypercall_len );
+ free_phys ( hvm->xen.hypercall, hvm->hypercall_len );
}
/**
@@ -175,7 +175,7 @@ static void * hvm_ioremap ( struct hvm_device *hvm, unsigned int space,
}
/* Map this space */
- mmio = ioremap ( ( hvm->mmio + hvm->mmio_offset ), len );
+ mmio = pci_ioremap ( hvm->pci, ( hvm->mmio + hvm->mmio_offset ), len );
if ( ! mmio ) {
DBGC ( hvm, "HVM could not map MMIO space [%08lx,%08lx)\n",
( hvm->mmio + hvm->mmio_offset ),
@@ -371,7 +371,8 @@ static int hvm_map_xenstore ( struct hvm_device *hvm ) {
xenstore_phys = ( xenstore_pfn * PAGE_SIZE );
/* Map XenStore */
- hvm->xen.store.intf = ioremap ( xenstore_phys, PAGE_SIZE );
+ hvm->xen.store.intf = pci_ioremap ( hvm->pci, xenstore_phys,
+ PAGE_SIZE );
if ( ! hvm->xen.store.intf ) {
DBGC ( hvm, "HVM could not map XenStore at [%08lx,%08lx)\n",
xenstore_phys, ( xenstore_phys + PAGE_SIZE ) );
@@ -420,6 +421,7 @@ static int hvm_probe ( struct pci_device *pci ) {
rc = -ENOMEM;
goto err_alloc;
}
+ hvm->pci = pci;
hvm->mmio = pci_bar_start ( pci, HVM_MMIO_BAR );
hvm->mmio_len = pci_bar_size ( pci, HVM_MMIO_BAR );
DBGC2 ( hvm, "HVM has MMIO space [%08lx,%08lx)\n",
diff --git a/src/arch/x86/drivers/xen/hvm.h b/src/arch/x86/drivers/xen/hvm.h
index 72ed94f6d..88e490815 100644
--- a/src/arch/x86/drivers/xen/hvm.h
+++ b/src/arch/x86/drivers/xen/hvm.h
@@ -39,6 +39,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
struct hvm_device {
/** Xen hypervisor */
struct xen_hypervisor xen;
+ /** PCI device */
+ struct pci_device *pci;
/** CPUID base */
uint32_t cpuid_base;
/** Length of hypercall table */
diff --git a/src/arch/x86/image/initrd.c b/src/arch/x86/image/initrd.c
index 8f6366d3d..49b959a91 100644
--- a/src/arch/x86/image/initrd.c
+++ b/src/arch/x86/image/initrd.c
@@ -175,18 +175,18 @@ static int initrd_swap_any ( userptr_t free, size_t free_len ) {
/* Search for adjacent image */
for_each_image ( high ) {
- /* If we have found the adjacent image, swap and exit */
- if ( high->data == adjacent ) {
- initrd_swap ( low, high, free, free_len );
- return 1;
- }
-
/* Stop search if all remaining potential
* adjacent images are already in the correct
* order.
*/
if ( high == low )
break;
+
+ /* If we have found the adjacent image, swap and exit */
+ if ( high->data == adjacent ) {
+ initrd_swap ( low, high, free, free_len );
+ return 1;
+ }
}
}
diff --git a/src/arch/x86/include/bits/bitops.h b/src/arch/x86/include/bits/bitops.h
index 17dcf1024..f697b8c8f 100644
--- a/src/arch/x86/include/bits/bitops.h
+++ b/src/arch/x86/include/bits/bitops.h
@@ -29,7 +29,7 @@ set_bit ( unsigned int bit, volatile void *bits ) {
uint8_t byte[ ( bit / 8 ) + 1 ];
} *bytes = bits;
- __asm__ __volatile__ ( "lock bts %1, %0"
+ __asm__ __volatile__ ( "lock btsl %k1, %0"
: "+m" ( *bytes ) : "Ir" ( bit ) );
}
@@ -45,7 +45,7 @@ clear_bit ( unsigned int bit, volatile void *bits ) {
uint8_t byte[ ( bit / 8 ) + 1 ];
} *bytes = bits;
- __asm__ __volatile__ ( "lock btr %1, %0"
+ __asm__ __volatile__ ( "lock btrl %k1, %0"
: "+m" ( *bytes ) : "Ir" ( bit ) );
}
@@ -63,7 +63,7 @@ test_and_set_bit ( unsigned int bit, volatile void *bits ) {
} *bytes = bits;
int old;
- __asm__ __volatile__ ( "lock bts %2, %0\n\t"
+ __asm__ __volatile__ ( "lock btsl %k2, %0\n\t"
"sbb %1, %1\n\t"
: "+m" ( *bytes ), "=r" ( old )
: "Ir" ( bit ) );
@@ -84,7 +84,7 @@ test_and_clear_bit ( unsigned int bit, volatile void *bits ) {
} *bytes = bits;
int old;
- __asm__ __volatile__ ( "lock btr %2, %0\n\t"
+ __asm__ __volatile__ ( "lock btrl %k2, %0\n\t"
"sbb %1, %1\n\t"
: "+m" ( *bytes ), "=r" ( old )
: "Ir" ( bit ) );
diff --git a/src/arch/x86/include/bits/linux_api_platform.h b/src/arch/x86/include/bits/linux_api_platform.h
deleted file mode 100644
index 4a9ced5e2..000000000
--- a/src/arch/x86/include/bits/linux_api_platform.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _LINUX_API_PLATFORM_H
-#define _LINUX_API_PLATFORM_H
-
-extern int linux_errno;
-
-#endif /* _LINUX_API_PLATFORM_H */
diff --git a/src/arch/x86/include/ipxe/cpuid.h b/src/arch/x86/include/ipxe/cpuid.h
index 0ae572da4..b5403bd9d 100644
--- a/src/arch/x86/include/ipxe/cpuid.h
+++ b/src/arch/x86/include/ipxe/cpuid.h
@@ -42,6 +42,9 @@ struct x86_features {
/** Hypervisor is present */
#define CPUID_FEATURES_INTEL_ECX_HYPERVISOR 0x80000000UL
+/** FXSAVE and FXRSTOR are supported */
+#define CPUID_FEATURES_INTEL_EDX_FXSR 0x01000000UL
+
/** Get largest extended function */
#define CPUID_AMD_MAX_FN 0x80000000UL
diff --git a/src/arch/x86/include/ipxe/pcibios.h b/src/arch/x86/include/ipxe/pcibios.h
index 7e1bcd814..bae4eede1 100644
--- a/src/arch/x86/include/ipxe/pcibios.h
+++ b/src/arch/x86/include/ipxe/pcibios.h
@@ -132,4 +132,17 @@ PCIAPI_INLINE ( pcbios, pci_write_config_dword ) ( struct pci_device *pci,
return pcibios_write ( pci, PCIBIOS_WRITE_CONFIG_DWORD | where, value);
}
+/**
+ * Map PCI bus address as an I/O address
+ *
+ * @v bus_addr PCI bus address
+ * @v len Length of region
+ * @ret io_addr I/O address, or NULL on error
+ */
+static inline __always_inline void *
+PCIAPI_INLINE ( pcbios, pci_ioremap ) ( struct pci_device *pci __unused,
+ unsigned long bus_addr, size_t len ) {
+ return ioremap ( bus_addr, len );
+}
+
#endif /* _IPXE_PCIBIOS_H */
diff --git a/src/arch/x86/include/ipxe/pcidirect.h b/src/arch/x86/include/ipxe/pcidirect.h
index d924f2f20..9570fd7d6 100644
--- a/src/arch/x86/include/ipxe/pcidirect.h
+++ b/src/arch/x86/include/ipxe/pcidirect.h
@@ -138,4 +138,17 @@ PCIAPI_INLINE ( direct, pci_write_config_dword ) ( struct pci_device *pci,
return 0;
}
+/**
+ * Map PCI bus address as an I/O address
+ *
+ * @v bus_addr PCI bus address
+ * @v len Length of region
+ * @ret io_addr I/O address, or NULL on error
+ */
+static inline __always_inline void *
+PCIAPI_INLINE ( direct, pci_ioremap ) ( struct pci_device *pci __unused,
+ unsigned long bus_addr, size_t len ) {
+ return ioremap ( bus_addr, len );
+}
+
#endif /* _PCIDIRECT_H */
diff --git a/src/arch/x86/include/ipxe/rsdp.h b/src/arch/x86/include/ipxe/rsdp.h
index 7e32c0011..14afcd774 100644
--- a/src/arch/x86/include/ipxe/rsdp.h
+++ b/src/arch/x86/include/ipxe/rsdp.h
@@ -15,4 +15,17 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#define ACPI_PREFIX_rsdp __rsdp_
#endif
+/**
+ * Locate ACPI table
+ *
+ * @v signature Requested table signature
+ * @v index Requested index of table with this signature
+ * @ret table Table, or UNULL if not found
+ */
+static inline __attribute__ (( always_inline )) userptr_t
+ACPI_INLINE ( rsdp, acpi_find ) ( uint32_t signature, unsigned int index ) {
+
+ return acpi_find_via_rsdt ( signature, index );
+}
+
#endif /* _IPXE_RSDP_H */
diff --git a/src/arch/x86/interface/pcbios/bios_cachedhcp.c b/src/arch/x86/interface/pcbios/bios_cachedhcp.c
new file mode 100644
index 000000000..3d38699f7
--- /dev/null
+++ b/src/arch/x86/interface/pcbios/bios_cachedhcp.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2013 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.
+ *
+ * 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.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <stdint.h>
+#include <ipxe/init.h>
+#include <ipxe/cachedhcp.h>
+#include <realmode.h>
+#include <pxe_api.h>
+
+/** @file
+ *
+ * Cached DHCP packet
+ *
+ */
+
+/** Cached DHCPACK physical address
+ *
+ * This can be set by the prefix.
+ */
+uint32_t __bss16 ( cached_dhcpack_phys );
+#define cached_dhcpack_phys __use_data16 ( cached_dhcpack_phys )
+
+/** Colour for debug messages */
+#define colour &cached_dhcpack_phys
+
+/**
+ * Cached DHCPACK initialisation function
+ *
+ */
+static void cachedhcp_init ( void ) {
+ int rc;
+
+ /* Do nothing if no cached DHCPACK is present */
+ if ( ! cached_dhcpack_phys ) {
+ DBGC ( colour, "CACHEDHCP found no cached DHCPACK\n" );
+ return;
+ }
+
+ /* Record cached DHCPACK */
+ if ( ( rc = cachedhcp_record ( phys_to_user ( cached_dhcpack_phys ),
+ sizeof ( BOOTPLAYER_t ) ) ) != 0 ) {
+ DBGC ( colour, "CACHEDHCP could not record DHCPACK: %s\n",
+ strerror ( rc ) );
+ return;
+ }
+
+ /* Mark as consumed */
+ cached_dhcpack_phys = 0;
+}
+
+/** Cached DHCPACK initialisation function */
+struct init_fn cachedhcp_init_fn __init_fn ( INIT_NORMAL ) = {
+ .initialise = cachedhcp_init,
+};
diff --git a/src/arch/x86/interface/pcbios/bios_console.c b/src/arch/x86/interface/pcbios/bios_console.c
index 52a02fba5..80ebf330e 100644
--- a/src/arch/x86/interface/pcbios/bios_console.c
+++ b/src/arch/x86/interface/pcbios/bios_console.c
@@ -443,7 +443,7 @@ struct console_driver bios_console __console_driver = {
*
* @v ix86 Registers as passed to INT 16
*/
-static __asmcall void bios_inject ( struct i386_all_regs *ix86 ) {
+static __asmcall __used void bios_inject ( struct i386_all_regs *ix86 ) {
unsigned int discard_a;
unsigned int scancode;
unsigned int i;
diff --git a/src/arch/x86/interface/pcbios/e820mangler.S b/src/arch/x86/interface/pcbios/e820mangler.S
index d5d97b482..296a6488b 100644
--- a/src/arch/x86/interface/pcbios/e820mangler.S
+++ b/src/arch/x86/interface/pcbios/e820mangler.S
@@ -67,7 +67,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
****************************************************************************
*/
.section ".data16", "aw", @progbits
- .align 16
+ .balign 16
.globl hidemem_base
.globl hidemem_umalloc
.globl hidemem_textdata
diff --git a/src/arch/x86/interface/pcbios/int13.c b/src/arch/x86/interface/pcbios/int13.c
index ca789a0d1..30530e197 100644
--- a/src/arch/x86/interface/pcbios/int13.c
+++ b/src/arch/x86/interface/pcbios/int13.c
@@ -1064,7 +1064,7 @@ static int int13_cdrom_read_boot_catalog ( struct san_device *sandev,
* INT 13 handler
*
*/
-static __asmcall void int13 ( struct i386_all_regs *ix86 ) {
+static __asmcall __used void int13 ( struct i386_all_regs *ix86 ) {
int command = ix86->regs.ah;
unsigned int bios_drive = ix86->regs.dl;
struct san_device *sandev;
diff --git a/src/arch/x86/interface/pcbios/pcibios.c b/src/arch/x86/interface/pcbios/pcibios.c
index 07ac0c18d..bf812f77f 100644
--- a/src/arch/x86/interface/pcbios/pcibios.c
+++ b/src/arch/x86/interface/pcbios/pcibios.c
@@ -121,3 +121,4 @@ PROVIDE_PCIAPI_INLINE ( pcbios, pci_read_config_dword );
PROVIDE_PCIAPI_INLINE ( pcbios, pci_write_config_byte );
PROVIDE_PCIAPI_INLINE ( pcbios, pci_write_config_word );
PROVIDE_PCIAPI_INLINE ( pcbios, pci_write_config_dword );
+PROVIDE_PCIAPI_INLINE ( pcbios, pci_ioremap );
diff --git a/src/arch/x86/interface/pcbios/rsdp.c b/src/arch/x86/interface/pcbios/rsdp.c
index 8da0b5588..3c67b7525 100644
--- a/src/arch/x86/interface/pcbios/rsdp.c
+++ b/src/arch/x86/interface/pcbios/rsdp.c
@@ -123,3 +123,4 @@ static userptr_t rsdp_find_rsdt ( void ) {
}
PROVIDE_ACPI ( rsdp, acpi_find_rsdt, rsdp_find_rsdt );
+PROVIDE_ACPI_INLINE ( rsdp, acpi_find );
diff --git a/src/arch/x86/interface/pxe/pxe_entry.S b/src/arch/x86/interface/pxe/pxe_entry.S
index 663aa842e..3a5a100e3 100644
--- a/src/arch/x86/interface/pxe/pxe_entry.S
+++ b/src/arch/x86/interface/pxe/pxe_entry.S
@@ -34,7 +34,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
*/
.section ".text16.data", "aw", @progbits
.globl ppxe
- .align 16
+ .balign 16
ppxe:
.ascii "!PXE" /* Signature */
.byte pxe_length /* StructLength */
@@ -72,7 +72,7 @@ undiheader:
*/
.section ".text16.data", "aw", @progbits
.globl pxenv
- .align 16
+ .balign 16
pxenv:
.ascii "PXENV+" /* Signature */
.word 0x0201 /* Version */
diff --git a/src/arch/x86/interface/syslinux/comboot_call.c b/src/arch/x86/interface/syslinux/comboot_call.c
index e70f200e3..dc308dafe 100644
--- a/src/arch/x86/interface/syslinux/comboot_call.c
+++ b/src/arch/x86/interface/syslinux/comboot_call.c
@@ -220,7 +220,7 @@ static int comboot_fetch_kernel ( char *kernel_file, char *cmdline ) {
/**
* Terminate program interrupt handler
*/
-static __asmcall void int20 ( struct i386_all_regs *ix86 __unused ) {
+static __asmcall __used void int20 ( struct i386_all_regs *ix86 __unused ) {
rmlongjmp ( comboot_return, COMBOOT_EXIT );
}
@@ -228,7 +228,7 @@ static __asmcall void int20 ( struct i386_all_regs *ix86 __unused ) {
/**
* DOS-compatible API
*/
-static __asmcall void int21 ( struct i386_all_regs *ix86 ) {
+static __asmcall __used void int21 ( struct i386_all_regs *ix86 ) {
ix86->flags |= CF;
switch ( ix86->regs.ah ) {
@@ -311,7 +311,7 @@ __weak int pxe_api_call_weak ( struct i386_all_regs *ix86 __unused ) {
/**
* SYSLINUX API
*/
-static __asmcall void int22 ( struct i386_all_regs *ix86 ) {
+static __asmcall __used void int22 ( struct i386_all_regs *ix86 ) {
ix86->flags |= CF;
switch ( ix86->regs.ax ) {
diff --git a/src/arch/x86/prefix/exeprefix.S b/src/arch/x86/prefix/exeprefix.S
index c351456e2..0eab8c12a 100644
--- a/src/arch/x86/prefix/exeprefix.S
+++ b/src/arch/x86/prefix/exeprefix.S
@@ -110,7 +110,7 @@ overlay:
/* Overlay number */
.word 0
- .align 16, 0
+ .balign 16, 0
.globl _exe_start
_exe_start:
diff --git a/src/arch/x86/prefix/mromprefix.S b/src/arch/x86/prefix/mromprefix.S
index 2b5c6bf64..d08284d7a 100644
--- a/src/arch/x86/prefix/mromprefix.S
+++ b/src/arch/x86/prefix/mromprefix.S
@@ -492,7 +492,7 @@ mromheader:
.word 0
.size mromheader, . - mromheader
- .align 4
+ .balign 4
mpciheader:
.ascii "PCIR" /* Signature */
.word pci_vendor_id /* Vendor identification */
diff --git a/src/arch/x86/prefix/rawprefix.S b/src/arch/x86/prefix/rawprefix.S
new file mode 100644
index 000000000..4cf5f391e
--- /dev/null
+++ b/src/arch/x86/prefix/rawprefix.S
@@ -0,0 +1,53 @@
+/*
+ * Raw binary prefix
+ *
+ * Assumes that entire image is already loaded as a contiguous block
+ * on a paragraph boundary and entered in real mode.
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
+
+ .text
+ .arch i386
+ .org 0
+ .code16
+
+#include <librm.h>
+
+ .section ".prefix", "ax", @progbits
+ .globl _raw_start
+_raw_start:
+
+ /* Adjust %cs so that %cs:0000 is the start of the image */
+ movw %cs, %ax
+ call 1f
+1: popw %bx
+ subw $1b, %bx
+ shrw $4, %bx
+ addw %bx, %ax
+ pushw %ax
+ pushw $2f
+ lret
+2:
+ /* Install iPXE */
+ call install
+
+ /* Set up real-mode stack */
+ movw %bx, %ss
+ movw $_estack16, %sp
+
+ /* Jump to .text16 segment */
+ pushw %ax
+ pushw $1f
+ lret
+ .section ".text16", "awx", @progbits
+1:
+ /* Run iPXE */
+ virtcall main
+
+ /* Uninstall iPXE */
+ call uninstall
+
+ /* Boot next device */
+ int $0x18
diff --git a/src/arch/x86/prefix/romprefix.S b/src/arch/x86/prefix/romprefix.S
index 3abef0eaf..a9934a725 100644
--- a/src/arch/x86/prefix/romprefix.S
+++ b/src/arch/x86/prefix/romprefix.S
@@ -88,7 +88,7 @@ checksum:
.previous
.ifeqs BUSTYPE, "PCIR"
- .align 4
+ .balign 4
pciheader:
.ascii "PCIR" /* Signature */
.word pci_vendor_id /* Vendor identification */
@@ -136,7 +136,7 @@ pci_devlist_end:
* BIOSes will scan on 16-byte boundaries rather than using
* the offset stored at 0x1a
*/
- .align 16
+ .balign 16
pnpheader:
.ascii "$PnP" /* Signature */
.byte 0x01 /* Structure revision */
@@ -184,7 +184,7 @@ prodstr_pci_id:
.globl undiheader
.weak undiloader
- .align 4
+ .balign 4
undiheader:
.ascii "UNDI" /* Signature */
.byte undiheader_len /* Length of structure */
@@ -199,7 +199,7 @@ undiheader:
.equ undiheader_len, . - undiheader
.size undiheader, . - undiheader
- .align 4
+ .balign 4
ipxeheader:
.ascii "iPXE" /* Signature */
.byte ipxeheader_len /* Length of structure */
diff --git a/src/arch/x86/prefix/unlzma.S b/src/arch/x86/prefix/unlzma.S
index ce18c756f..956eeb24c 100644
--- a/src/arch/x86/prefix/unlzma.S
+++ b/src/arch/x86/prefix/unlzma.S
@@ -231,7 +231,7 @@ rep_len_dec: .space sizeof__lzma_len_dec
literal: .rept ( ( 1 << LZMA_LC ) * 0x300 )
.word 0
.endr
- .align 4
+ .balign 4
.equ sizeof__lzma_dec, . - lzma_dec
.previous
diff --git a/src/arch/x86/scripts/pcbios.lds b/src/arch/x86/scripts/pcbios.lds
index c9a91c02b..de59adca9 100644
--- a/src/arch/x86/scripts/pcbios.lds
+++ b/src/arch/x86/scripts/pcbios.lds
@@ -58,11 +58,12 @@ SECTIONS {
*(SORT(.pci_devlist.*))
*(.prefix.*)
_mprefix = .;
- } .bss.prefix (NOLOAD) : AT ( _end_lma ) {
+ } .bss.prefix (NOLOAD) : AT ( _bss_prefix_lma ) {
_eprefix = .;
}
_prefix_filesz = ABSOLUTE ( _mprefix ) - ABSOLUTE ( _prefix );
_prefix_memsz = ABSOLUTE ( _eprefix ) - ABSOLUTE ( _prefix );
+ _prefix_padsz = ABSOLUTE ( _eprefix ) - ABSOLUTE ( _mprefix );
/*
* The 16-bit (real-mode) code section
@@ -82,7 +83,7 @@ SECTIONS {
*(.text16)
*(.text16.*)
_mtext16 = .;
- } .bss.text16 (NOLOAD) : AT ( _end_lma ) {
+ } .bss.text16 (NOLOAD) : AT ( _bss_text16_lma ) {
_etext16 = .;
}
_text16_early_filesz = ABSOLUTE ( _etext16_early ) - ABSOLUTE ( _text16 );
@@ -90,6 +91,7 @@ SECTIONS {
_text16_late_filesz = ABSOLUTE ( _mtext16 ) - ABSOLUTE ( _text16_late );
_text16_late_memsz = ABSOLUTE ( _etext16 ) - ABSOLUTE ( _text16_late );
_text16_memsz = ABSOLUTE ( _etext16 ) - ABSOLUTE ( _text16 );
+ _text16_padsz = ABSOLUTE ( _etext16 ) - ABSOLUTE ( _mtext16 );
/*
* The 16-bit (real-mode) data section
@@ -104,7 +106,7 @@ SECTIONS {
*(.data16)
*(.data16.*)
_mdata16 = .;
- } .bss.data16 (NOLOAD) : AT ( _end_lma ) {
+ } .bss.data16 (NOLOAD) : AT ( _bss_data16_lma ) {
*(.bss16)
*(.bss16.*)
*(.stack16)
@@ -114,6 +116,7 @@ SECTIONS {
}
_data16_filesz = ABSOLUTE ( _mdata16 ) - ABSOLUTE ( _data16 );
_data16_memsz = ABSOLUTE ( _edata16 ) - ABSOLUTE ( _data16 );
+ _data16_padsz = ABSOLUTE ( _edata16 ) - ABSOLUTE ( _mdata16 );
/*
* The 32-bit sections
@@ -135,7 +138,7 @@ SECTIONS {
KEEP(*(.provided))
KEEP(*(.provided.*))
_mtextdata = .;
- } .bss.textdata (NOLOAD) : AT ( _end_lma ) {
+ } .bss.textdata (NOLOAD) : AT ( _bss_textdata_lma ) {
*(.bss)
*(.bss.*)
*(COMMON)
@@ -157,6 +160,7 @@ SECTIONS {
}
_textdata_filesz = ABSOLUTE ( _mtextdata ) - ABSOLUTE ( _textdata );
_textdata_memsz = ABSOLUTE ( _etextdata ) - ABSOLUTE ( _textdata );
+ _textdata_padsz = ABSOLUTE ( _etextdata ) - ABSOLUTE ( _mtextdata );
/*
* Payload prefix
@@ -169,11 +173,12 @@ SECTIONS {
KEEP(*(.pprefix))
KEEP(*(.pprefix.*))
_mpprefix = .;
- } .bss.pprefix (NOLOAD) : AT ( _end_lma ) {
+ } .bss.pprefix (NOLOAD) : AT ( _bss_pprefix_lma ) {
_epprefix = .;
}
_pprefix_filesz = ABSOLUTE ( _mpprefix ) - ABSOLUTE ( _pprefix );
_pprefix_memsz = ABSOLUTE ( _epprefix ) - ABSOLUTE ( _pprefix );
+ _pprefix_padsz = ABSOLUTE ( _epprefix ) - ABSOLUTE ( _mpprefix );
/*
* Compressor information block
@@ -185,11 +190,12 @@ SECTIONS {
KEEP(*(.zinfo))
KEEP(*(.zinfo.*))
_mzinfo = .;
- } .bss.zinfo (NOLOAD) : AT ( _end_lma ) {
+ } .bss.zinfo (NOLOAD) : AT ( _bss_zinfo_lma ) {
_ezinfo = .;
}
_zinfo_filesz = ABSOLUTE ( _mzinfo ) - ABSOLUTE ( _zinfo );
_zinfo_memsz = ABSOLUTE ( _ezinfo ) - ABSOLUTE ( _zinfo );
+ _zinfo_padsz = ABSOLUTE ( _ezinfo ) - ABSOLUTE ( _mzinfo );
/*
* Weak symbols that need zero values if not otherwise defined
@@ -235,36 +241,65 @@ SECTIONS {
. = ALIGN ( _max_align );
_prefix_lma = .;
- . += _prefix_filesz;
+ . += ABSOLUTE ( _prefix_filesz );
. = ALIGN ( _max_align );
_text16_early_lma = .;
- . += _text16_early_filesz;
+ . += ABSOLUTE ( _text16_early_filesz );
. = ALIGN ( _max_align );
. = ALIGN ( _payload_align );
_pprefix_lma = .;
- . += _pprefix_filesz;
+ . += ABSOLUTE ( _pprefix_filesz );
. = ALIGN ( _max_align );
_payload_lma = .;
_pprefix_skip = ABSOLUTE ( _payload_lma ) - ABSOLUTE ( _pprefix_lma );
_text16_late_lma = .;
- . += _text16_late_filesz;
+ . += ABSOLUTE ( _text16_late_filesz );
. = ALIGN ( _max_align );
_data16_lma = .;
- . += _data16_filesz;
+ . += ABSOLUTE ( _data16_filesz );
. = ALIGN ( _max_align );
_textdata_lma = .;
- . += _textdata_filesz;
+ . += ABSOLUTE ( _textdata_filesz );
- _filesz = .; /* Do not include zinfo block in file size */
+ _filesz = .; /* Do not include .bss.* or .zinfo in file size */
+
+ /*
+ * Dummy load addresses for .bss.* and .zinfo sections
+ *
+ */
+
+ . = ALIGN ( _max_align );
+ _bss_prefix_lma = .;
+ . += ABSOLUTE ( _prefix_padsz );
+
+ . = ALIGN ( _max_align );
+ _bss_text16_lma = .;
+ . += ABSOLUTE ( _text16_padsz );
+
+ . = ALIGN ( _max_align );
+ _bss_data16_lma = .;
+ . += ABSOLUTE ( _data16_padsz );
+
+ . = ALIGN ( _max_align );
+ _bss_textdata_lma = .;
+ . += ABSOLUTE ( _textdata_padsz );
+
+ . = ALIGN ( _max_align );
+ _bss_pprefix_lma = .;
+ . += ABSOLUTE ( _pprefix_padsz );
+
+ . = ALIGN ( _max_align );
+ _bss_zinfo_lma = .;
+ . += ABSOLUTE ( _zinfo_padsz );
. = ALIGN ( _max_align );
_zinfo_lma = .;
- . += _zinfo_filesz;
+ . += ABSOLUTE ( _zinfo_filesz );
. = ALIGN ( _max_align );
_end_lma = .;
diff --git a/src/arch/x86/scripts/prefixonly.lds b/src/arch/x86/scripts/prefixonly.lds
new file mode 100644
index 000000000..dce0930b5
--- /dev/null
+++ b/src/arch/x86/scripts/prefixonly.lds
@@ -0,0 +1,29 @@
+/* -*- ld-script -*- */
+
+/*
+ * Linker script for prefix-only binaries (e.g. USB disk MBR)
+ *
+ */
+
+SECTIONS {
+
+ .prefix 0x0 : AT ( 0x0 ) {
+ *(.prefix)
+ }
+
+ /DISCARD/ : {
+ *(.comment)
+ *(.comment.*)
+ *(.note)
+ *(.note.*)
+ *(.eh_frame)
+ *(.eh_frame.*)
+ *(.rel)
+ *(.rel.*)
+ *(.einfo)
+ *(.einfo.*)
+ *(.discard)
+ *(.discard.*)
+ }
+
+}
diff --git a/src/arch/x86/transitions/liba20.S b/src/arch/x86/transitions/liba20.S
index 6c1e1f62f..57603353e 100644
--- a/src/arch/x86/transitions/liba20.S
+++ b/src/arch/x86/transitions/liba20.S
@@ -285,7 +285,7 @@ enable_a20:
ret
.section ".text16.early.data", "aw", @progbits
- .align 2
+ .balign 2
enable_a20_method:
.word 0
.size enable_a20_method, . - enable_a20_method
diff --git a/src/arch/x86/transitions/librm.S b/src/arch/x86/transitions/librm.S
index 9d3eff954..5dacb9b04 100644
--- a/src/arch/x86/transitions/librm.S
+++ b/src/arch/x86/transitions/librm.S
@@ -99,7 +99,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
****************************************************************************
*/
.section ".data16.gdt", "aw", @progbits
- .align 16
+ .balign 16
gdt:
gdtr: /* The first GDT entry is unused, the GDTR can fit here. */
gdt_limit: .word gdt_length - 1
@@ -210,9 +210,7 @@ VC_TMP_CR3: .space 4
VC_TMP_CR4: .space 4
VC_TMP_EMER: .space 8
.endif
-#ifdef TIVOLI_VMM_WORKAROUND
VC_TMP_FXSAVE: .space 512
-#endif
VC_TMP_END:
.previous
@@ -224,7 +222,7 @@ RC_TMP_END:
/* Shared temporary static buffer */
.section ".bss16.rm_tmpbuf", "aw", @nobits
- .align 16
+ .balign 16
rm_tmpbuf:
.space VC_TMP_END
.size rm_tmpbuf, . - rm_tmpbuf
@@ -350,6 +348,13 @@ init_librm_rmode:
/* Initialise IDT */
virtcall init_idt
+#ifdef TIVOLI_VMM_WORKAROUND
+ /* Check for FXSAVE/FXRSTOR */
+ clc
+ virtcall check_fxsr
+ setnc fxsr_supported
+#endif
+
/* Restore registers */
popl %edi
popl %ebx
@@ -366,6 +371,10 @@ set_seg_base:
roll $16, %eax
ret
+ .section ".data16.fxsr_supported", "awx", @progbits
+fxsr_supported: /* FXSAVE/FXRSTOR instructions supported */
+ .byte 0
+
/****************************************************************************
* real_to_prot (real-mode near call, 32-bit virtual return address)
*
@@ -1007,10 +1016,11 @@ virt_call:
cli
movw %cs:rm_ds, %ds
-#ifdef TIVOLI_VMM_WORKAROUND
/* Preserve FPU, MMX and SSE state in temporary static buffer */
+ testb $0xff, fxsr_supported
+ jz 1f
fxsave ( rm_tmpbuf + VC_TMP_FXSAVE )
-#endif
+1:
/* Preserve GDT and IDT in temporary static buffer */
sidt ( rm_tmpbuf + VC_TMP_IDT )
sgdt ( rm_tmpbuf + VC_TMP_GDT )
@@ -1077,10 +1087,11 @@ vc_rmode:
wrmsr
.endif
-#ifdef TIVOLI_VMM_WORKAROUND
/* Restore FPU, MMX and SSE state from temporary static buffer */
+ testb $0xff, fxsr_supported
+ jz 1f
fxrstor ( rm_tmpbuf + VC_TMP_FXSAVE )
-#endif
+1:
/* Restore registers and flags and return */
popl %eax /* skip %cs and %ss */
popw %ds
@@ -1470,7 +1481,7 @@ interrupt_wrapper:
****************************************************************************
*/
.section ".pages", "aw", @nobits
- .align SIZEOF_PT
+ .balign SIZEOF_PT
/* Page map level 4 entries (PML4Es)
*
diff --git a/src/arch/x86/transitions/librm_mgmt.c b/src/arch/x86/transitions/librm_mgmt.c
index f9e1d261a..da221e8b1 100644
--- a/src/arch/x86/transitions/librm_mgmt.c
+++ b/src/arch/x86/transitions/librm_mgmt.c
@@ -14,6 +14,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <realmode.h>
#include <pic8259.h>
#include <ipxe/shell.h>
+#include <ipxe/cpuid.h>
/*
* This file provides functions for managing librm.
@@ -118,7 +119,7 @@ void set_interrupt_vector ( unsigned int intr, void *vector ) {
* Initialise interrupt descriptor table
*
*/
-void init_idt ( void ) {
+__asmcall void init_idt ( void ) {
struct interrupt_vector *vec;
unsigned int intr;
@@ -386,6 +387,21 @@ static void iounmap_pages ( volatile const void *io_addr ) {
io_addr, first, i );
}
+/**
+ * Check for FXSAVE/FXRSTOR instruction support
+ *
+ */
+__asmcall void check_fxsr ( struct i386_all_regs *regs ) {
+ struct x86_features features;
+
+ /* Check for FXSR bit */
+ x86_features ( &features );
+ if ( ! ( features.intel.edx & CPUID_FEATURES_INTEL_EDX_FXSR ) )
+ regs->flags |= CF;
+ DBGC ( &features, "FXSAVE/FXRSTOR is%s supported\n",
+ ( ( regs->flags & CF ) ? " not" : "" ) );
+}
+
PROVIDE_UACCESS_INLINE ( librm, phys_to_user );
PROVIDE_UACCESS_INLINE ( librm, user_to_phys );
PROVIDE_UACCESS_INLINE ( librm, virt_to_user );
diff --git a/src/arch/x86/transitions/librm_test.c b/src/arch/x86/transitions/librm_test.c
index 77cf8022c..347d86a15 100644
--- a/src/arch/x86/transitions/librm_test.c
+++ b/src/arch/x86/transitions/librm_test.c
@@ -58,7 +58,8 @@ static struct profiler virt_call_profiler __profiler = { .name = "virt_call" };
/**
* Dummy function for profiling tests
*/
-static __asmcall void librm_test_call ( struct i386_all_regs *ix86 __unused ) {
+static __asmcall __used void
+librm_test_call ( struct i386_all_regs *ix86 __unused ) {
/* Do nothing */
}
diff --git a/src/arch/x86_64/Makefile.linux b/src/arch/x86_64/Makefile.linux
index 154f9d40d..c41ee49df 100644
--- a/src/arch/x86_64/Makefile.linux
+++ b/src/arch/x86_64/Makefile.linux
@@ -1,6 +1,10 @@
-LDSCRIPT = arch/x86_64/scripts/linux.lds
+# -*- makefile -*- : Force emacs to use Makefile mode
-SRCDIRS += arch/x86_64/core/linux
+# Linker script
+#
+LDSCRIPT = arch/x86_64/scripts/linux.lds
+# Include generic Linux Makefile
+#
MAKEDEPS += arch/x86/Makefile.linux
include arch/x86/Makefile.linux
diff --git a/src/arch/x86_64/core/linux/linux_syscall.S b/src/arch/x86_64/core/linux/linux_syscall.S
deleted file mode 100644
index d2805f94c..000000000
--- a/src/arch/x86_64/core/linux/linux_syscall.S
+++ /dev/null
@@ -1,33 +0,0 @@
-
- .section ".data"
- .globl linux_errno
-
-linux_errno: .int 0
-
- .section ".text"
- .code64
- .globl linux_syscall
- .type linux_syscall, @function
-
-linux_syscall:
- movq %rdi, %rax // C arg1 -> syscall number
- movq %rsi, %rdi // C arg2 -> syscall arg1
- movq %rdx, %rsi // C arg3 -> syscall arg2
- movq %rcx, %rdx // C arg4 -> syscall arg3
- movq %r8, %r10 // C arg5 -> syscall arg4
- movq %r9, %r8 // C arg6 -> syscall arg5
- movq 8(%rsp), %r9 // C arg7 -> syscall arg6
-
- syscall
-
- cmpq $-4095, %rax
- jae 1f
- ret
-
-1:
- negq %rax
- movl %eax, linux_errno
- movq $-1, %rax
- ret
-
- .size linux_syscall, . - linux_syscall
diff --git a/src/arch/x86_64/core/linux/linuxprefix.S b/src/arch/x86_64/core/linux/linuxprefix.S
deleted file mode 100644
index ec8a9decd..000000000
--- a/src/arch/x86_64/core/linux/linuxprefix.S
+++ /dev/null
@@ -1,25 +0,0 @@
-#include <linux/unistd.h>
-
- .section ".text"
- .code64
- .globl _linux_start
- .type _linux_start, @function
-
-_linux_start:
- xorq %rbp, %rbp
-
- popq %rdi // argc -> C arg1
- movq %rsp, %rsi // argv -> C arg2
-
- andq $~15, %rsp // 16-byte align the stack
-
- call save_args
-
- /* Our main doesn't use any arguments */
- call main
-
- movq %rax, %rdi // rc -> syscall arg1
- movq $__NR_exit, %rax
- syscall
-
- .size _linux_start, . - _linux_start
diff --git a/src/arch/x86_64/include/bits/compiler.h b/src/arch/x86_64/include/bits/compiler.h
index 46985da3e..5129f90d0 100644
--- a/src/arch/x86_64/include/bits/compiler.h
+++ b/src/arch/x86_64/include/bits/compiler.h
@@ -9,7 +9,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#ifndef ASSEMBLY
/** Declare a function with standard calling conventions */
-#define __asmcall __attribute__ (( used, regparm(0) ))
+#define __asmcall __attribute__ (( regparm(0) ))
/** Declare a function with libgcc implicit linkage */
#define __libgcc
diff --git a/src/arch/x86_64/include/bits/linux_api.h b/src/arch/x86_64/include/bits/linux_api.h
deleted file mode 100644
index 589fb5808..000000000
--- a/src/arch/x86_64/include/bits/linux_api.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _X86_64_LINUX_API_H
-#define _X86_64_LINUX_API_H
-
-#define __SYSCALL_mmap __NR_mmap
-
-#endif /* _X86_64_LINUX_API_H */