diff options
| author | Simon Rettberg | 2021-03-08 15:55:33 +0100 |
|---|---|---|
| committer | Simon Rettberg | 2021-03-08 15:55:33 +0100 |
| commit | 6707d9218c8e6e760e53068d5f41ceb31fac6ea0 (patch) | |
| tree | 88e8fc84ede2a0ed2c1cec3a6109beb9fb53abf5 /src/arch | |
| parent | Merge branch 'master' into openslx (diff) | |
| parent | [linux] Do not assume that stat() works on sysfs files (diff) | |
| download | ipxe-6707d9218c8e6e760e53068d5f41ceb31fac6ea0.tar.gz ipxe-6707d9218c8e6e760e53068d5f41ceb31fac6ea0.tar.xz ipxe-6707d9218c8e6e760e53068d5f41ceb31fac6ea0.zip | |
Merge branch 'master' into openslx
Diffstat (limited to 'src/arch')
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 */ |
