diff options
Diffstat (limited to 'qemu/roms/ipxe/src/arch/i386')
179 files changed, 0 insertions, 32455 deletions
diff --git a/qemu/roms/ipxe/src/arch/i386/Makefile b/qemu/roms/ipxe/src/arch/i386/Makefile deleted file mode 100644 index 99f875314..000000000 --- a/qemu/roms/ipxe/src/arch/i386/Makefile +++ /dev/null @@ -1,120 +0,0 @@ -# Force i386-only instructions -# -CFLAGS += -march=i386 - -# Code size reduction. -# -CFLAGS += -fomit-frame-pointer - -# Code size reduction. -# -ifeq ($(CCTYPE),gcc) -CFLAGS += -fstrength-reduce -endif - -# Code size reduction. gcc3 needs a different syntax to gcc2 if you -# want to avoid spurious warnings. -# -ifeq ($(CCTYPE),gcc) -GCC_VERSION := $(subst ., ,$(shell $(CC) -dumpversion)) -GCC_MAJOR := $(firstword $(GCC_VERSION)) -ifeq ($(GCC_MAJOR),2) -CFLAGS += -malign-jumps=1 -malign-loops=1 -malign-functions=1 -else -CFLAGS += -falign-jumps=1 -falign-loops=1 -falign-functions=1 -endif # gcc2 -endif # gcc - -# Code size reduction. This is almost always a win. The kernel uses -# it, too. -# -ifeq ($(CCTYPE),gcc) -CFLAGS += -mpreferred-stack-boundary=2 -endif - -# Code size reduction. Use regparm for all functions - C functions -# called from assembly (or vice versa) need __asmcall now -# -CFLAGS += -mregparm=3 - -# Code size reduction. Use -mrtd (same __asmcall requirements as above) -ifeq ($(CCTYPE),gcc) -CFLAGS += -mrtd -endif - -# Code size reduction. This is the logical complement to -mregparm=3. -# It doesn't currently buy us anything, but if anything ever tries to -# return small structures, let's be prepared -# -CFLAGS += -freg-struct-return - -# Force 32-bit code even on an x86-64 machine -# -CFLAGS += -m32 -ASFLAGS += --32 -ifeq ($(HOST_OS),FreeBSD) -LDFLAGS += -m elf_i386_fbsd -else ifeq ($(HOST_OS),OpenBSD) -LDFLAGS += -m elf_i386_obsd -else -LDFLAGS += -m elf_i386 -endif - -# EFI requires -fshort-wchar, and nothing else currently uses wchar_t -# -CFLAGS += -fshort-wchar - -# We need to undefine the default macro "i386" when compiling .S -# files, otherwise ".arch i386" translates to ".arch 1"... -# -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. -# -ifeq ($(CCTYPE),gcc) -PIE_TEST = [ -z "`$(CC) -fno-PIE -nopie -x c -c /dev/null -o /dev/null 2>&1`" ] -PIE_FLAGS := $(shell $(PIE_TEST) && $(ECHO) '-fno-PIE -nopie') -WORKAROUND_CFLAGS += $(PIE_FLAGS) -endif - -# Define version string for lkrnprefix.S -# -CFLAGS_lkrnprefix += -DVERSION="\"$(VERSION)\"" - -# Locations of utilities -# -ISOLINUX_BIN_LIST := \ - $(ISOLINUX_BIN) \ - /usr/lib/syslinux/isolinux.bin \ - /usr/lib/syslinux/bios/isolinux.bin \ - /usr/share/syslinux/isolinux.bin \ - /usr/share/syslinux/bios/isolinux.bin \ - /usr/local/share/syslinux/isolinux.bin \ - /usr/local/share/syslinux/bios/isolinux.bin \ - /usr/lib/ISOLINUX/isolinux.bin -ISOLINUX_BIN = $(firstword $(wildcard $(ISOLINUX_BIN_LIST))) - -# i386-specific directories containing source files -# -SRCDIRS += arch/i386/core arch/i386/transitions arch/i386/prefix -SRCDIRS += arch/i386/firmware/pcbios -SRCDIRS += arch/i386/image -SRCDIRS += arch/i386/interface/pcbios -SRCDIRS += arch/i386/interface/pxe -SRCDIRS += arch/i386/interface/pxeparent -SRCDIRS += arch/i386/interface/syslinux -SRCDIRS += arch/i386/interface/vmware -SRCDIRS += arch/i386/hci/commands - -# Include common x86 Makefile -# -MAKEDEPS += arch/x86/Makefile -include arch/x86/Makefile - -# Include platform-specific Makefile -# -MAKEDEPS += arch/i386/Makefile.$(PLATFORM) -include arch/i386/Makefile.$(PLATFORM) diff --git a/qemu/roms/ipxe/src/arch/i386/Makefile.efi b/qemu/roms/ipxe/src/arch/i386/Makefile.efi deleted file mode 100644 index aa809eb5d..000000000 --- a/qemu/roms/ipxe/src/arch/i386/Makefile.efi +++ /dev/null @@ -1,14 +0,0 @@ -# -*- makefile -*- : Force emacs to use Makefile mode - -# Specify EFI image builder -# -ELF2EFI = $(ELF2EFI32) - -# Use EFI ABI -# -CFLAGS += -malign-double - -# Include generic EFI Makefile -# -MAKEDEPS += arch/x86/Makefile.efi -include arch/x86/Makefile.efi diff --git a/qemu/roms/ipxe/src/arch/i386/Makefile.linux b/qemu/roms/ipxe/src/arch/i386/Makefile.linux deleted file mode 100644 index 46328c83b..000000000 --- a/qemu/roms/ipxe/src/arch/i386/Makefile.linux +++ /dev/null @@ -1,6 +0,0 @@ -LDSCRIPT = arch/i386/scripts/linux.lds - -SRCDIRS += arch/i386/core/linux - -MAKEDEPS += arch/x86/Makefile.linux -include arch/x86/Makefile.linux diff --git a/qemu/roms/ipxe/src/arch/i386/Makefile.pcbios b/qemu/roms/ipxe/src/arch/i386/Makefile.pcbios deleted file mode 100644 index ff823737d..000000000 --- a/qemu/roms/ipxe/src/arch/i386/Makefile.pcbios +++ /dev/null @@ -1,100 +0,0 @@ -# -*- makefile -*- : Force emacs to use Makefile mode - -# The i386 linker script -# -LDSCRIPT = arch/i386/scripts/i386.lds - -# Stop ld from complaining about our customised linker script -# -LDFLAGS += -N --no-check-sections - -# pcbios specific drivers -SRCDIRS += arch/i386/drivers -SRCDIRS += arch/i386/drivers/net - -# Media types. -# -MEDIA += rom -MEDIA += mrom -MEDIA += pcirom -MEDIA += isarom -MEDIA += pxe -MEDIA += kpxe -MEDIA += kkpxe -MEDIA += kkkpxe -MEDIA += lkrn -MEDIA += dsk -MEDIA += nbi -MEDIA += hd -MEDIA += raw -MEDIA += exe - -# Padding rules -# -PAD_rom = $(PERL) $(PADIMG) --blksize=512 --byte=0xff -PAD_mrom = $(PAD_rom) -PAD_pcirom = $(PAD_rom) -PAD_isarom = $(PAD_rom) -PAD_dsk = $(PERL) $(PADIMG) --blksize=512 -PAD_hd = $(PERL) $(PADIMG) --blksize=32768 -PAD_exe = $(PERL) $(PADIMG) --blksize=512 - -# Finalisation rules -# -FINALISE_rom = $(PERL) $(FIXROM) -FINALISE_mrom = $(FINALISE_rom) -FINALISE_pcirom = $(FINALISE_rom) -FINALISE_isarom = $(FINALISE_rom) - -# Use $(ROMS) rather than $(DRIVERS) for "allroms", "allmroms", etc. -# -LIST_NAME_rom := ROMS -LIST_NAME_mrom := ROMS -LIST_NAME_pcirom := ROMS -LIST_NAME_isarom := ROMS - -# rule to make a non-emulation ISO boot image -NON_AUTO_MEDIA += iso -%iso: %lkrn util/geniso - $(QM)$(ECHO) " [GENISO] $@" - $(Q)ISOLINUX_BIN=$(ISOLINUX_BIN) 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 $@ $< - -# rule to write disk images to /dev/fd0 -NON_AUTO_MEDIA += fd0 -%fd0 : %dsk - $(QM)$(ECHO) " [DD] $@" - $(Q)dd if=$< bs=512 conv=sync of=/dev/fd0 - $(Q)sync - -# Special target for building Master Boot Record binary -$(BIN)/mbr.bin : $(BIN)/mbr.o - $(QM)$(ECHO) " [OBJCOPY] $@" - $(Q)$(OBJCOPY) -O binary $< $@ - -# rule to make a USB disk image -$(BIN)/usbdisk.bin : $(BIN)/usbdisk.o - $(QM)$(ECHO) " [OBJCOPY] $@" - $(Q)$(OBJCOPY) -O binary $< $@ - -NON_AUTO_MEDIA += usb -%usb: $(BIN)/usbdisk.bin %hd - $(QM)$(ECHO) " [FINISH] $@" - $(Q)cat $^ > $@ - -# Padded floppy image (e.g. for iLO) -NON_AUTO_MEDIA += pdsk -%pdsk : %dsk - $(Q)cp $< $@ - $(Q)$(PADIMG) --blksize=1474560 $@ diff --git a/qemu/roms/ipxe/src/arch/i386/README.i386 b/qemu/roms/ipxe/src/arch/i386/README.i386 deleted file mode 100644 index b9b79cc4b..000000000 --- a/qemu/roms/ipxe/src/arch/i386/README.i386 +++ /dev/null @@ -1,197 +0,0 @@ -Etherboot/NILO i386 initialisation path and external call interface -=================================================================== - -1. Background - -GCC compiles 32-bit code. It is capable of producing -position-independent code, but the resulting binary is about 25% -bigger than the corresponding fixed-position code. Since one main use -of Etherboot is as firmware to be burned into an EPROM, code size must -be kept as small as possible. - -This means that we want to compile fixed-position code with GCC, and -link it to have a predetermined start address. The problem then is -that we must know the address that the code will be loaded to when it -runs. There are several ways to solve this: - -1. Pick an address, link the code with this start address, then make - sure that the code gets loaded at that location. This is - problematic, because we may pick an address that we later end up - wanting to use to load the operating system that we're booting. - -2. Pick an address, link the code with this start address, then set up - virtual addressing so that the virtual addresses match the - link-time addresses regardless of the real physical address that - the code is loaded to. This enables us to relocate Etherboot to - the top of high memory, where it will be out of the way of any - loading operating system. - -3. Link the code with a text start address of zero and a data start - address also of zero. Use 16-bit real mode and the - quasi-position-independence it gives you via segment addressing. - Doing this requires that we generate 16-bit code, rather than - 32-bit code, and restricts us to a maximum of 64kB in each segment. - -There are other possible approaches (e.g. including a relocation table -and code that performs standard dynamic relocation), but the three -options listed above are probably the best available. - -Etherboot can be invoked in a variety of ways (ROM, floppy, as a PXE -NBP, etc). Several of these ways involve control being passed to -Etherboot with the CPU in 16-bit real mode. Some will involve the CPU -being in 32-bit protected mode, and there's an outside chance that -some may involve the CPU being in 16-bit protected mode. We will -almost certainly have to effect a CPU mode change in order to reach -the mode we want to be in to execute the C code. - -Additionally, Etherboot may wish to call external routines, such as -BIOS interrupts, which must be called in 16-bit real mode. When -providing a PXE API, Etherboot must provide a mechanism for external -code to call it from 16-bit real mode. - -Not all i386 builds of Etherboot will want to make real-mode calls. -For example, when built for LinuxBIOS rather than the standard PCBIOS, -no real-mode calls are necessary. - -For the ultimate in PXE compatibility, we may want to build Etherboot -to run permanently in real mode. - -There is a wide variety of potential combinations of mode switches -that we may wish to implement. There are additional complications, -such as the inability to access a high-memory stack when running in -real mode. - -2. Transition libraries - -To handle all these various combinations of mode switches, we have -several "transition" libraries in Etherboot. We also have the concept -of an "internal" and an "external" environment. The internal -environment is the environment within which we can execute C code. -The external environment is the environment of whatever external code -we're trying to interface to, such as the system BIOS or a PXE NBP. - -As well as having a separate addressing scheme, the internal -environment also has a separate stack. - -The transition libraries are: - -a) librm - -librm handles transitions between an external 16-bit real-mode -environment and an internal 32-bit protected-mode environment with -virtual addresses. - -b) libkir - -libkir handles transitions between an external 16-bit real-mode (or -16:16 or 16:32 protected-mode) environment and an internal 16-bit -real-mode (or 16:16 protected-mode) environment. - -c) libpm - -libpm handles transitions between an external 32-bit protected-mode -environment with flat physical addresses and an internal 32-bit -protected-mode environment with virtual addresses. - -The transition libraries handle the transitions required when -Etherboot is started up for the first time, the transitions required -to execute any external code, and the transitions required when -Etherboot exits (if it exits). When Etherboot provides a PXE API, -they also handle the transitions required when a PXE client makes a -PXE API call to Etherboot. - -Etherboot may use multiple transition libraries. For example, an -Etherboot ELF image does not require librm for its initial transitions -from prefix to runtime, but may require librm for calling external -real-mode functions. - -3. Setup and initialisation - -Etherboot is conceptually divided into the prefix, the decompressor, -and the runtime image. (For non-compressed images, the decompressor -is a no-op.) The complete image comprises all three parts and is -distinct from the runtime image, which exclude the prefix and the -decompressor. - -The prefix does several tasks: - - Load the complete image into memory. (For example, the floppy - prefix issues BIOS calls to load the remainder of the complete image - from the floppy disk into RAM, and the ISA ROM prefix copies the ROM - contents into RAM for faster access.) - - Call the decompressor, if the runtime image is compressed. This - decompresses the runtime image. - - Call the runtime image's setup() routine. This is a routine - implemented in assembly code which sets up the internal environment - so that C code can execute. - - Call the runtime image's arch_initialise() routine. This is a - routine implemented in C which does some basic startup tasks, such - as initialising the console device, obtaining a memory map and - relocating the runtime image to high memory. - - Call the runtime image's arch_main() routine. This records the exit - mechanism requested by the prefix and calls main(). (The prefix - needs to register an exit mechanism because by the time main() - returns, the memory occupied by the prefix has most likely been - overwritten.) - -When acting as a PXE ROM, the ROM prefix contains an UNDI loader -routine in addition to its usual code. The UNDI loader performs a -similar sequence of steps: - - Load the complete image into memory. - - Call the decompressor. - - Call the runtime image's setup() routine. - - Call the runtime image's arch_initialise() routine. - - Call the runtime image's install_pxe_stack() routine. - - Return to caller. - -The runtime image's setup() routine will perform the following steps: - - Switch to the internal environment using an appropriate transition - library. This will record the parameters of the external - environment. - - Set up the internal environment: load a stack, and set up a GDT for - virtual addressing if virtual addressing is to be used. - - Switch back to the external environment using the transition - library. This will record the parameters of the internal - environment. - -Once the setup() routine has returned, the internal environment has been -set up ready for C code to run. The prefix can call C routines using -a function from the transition library. - -The runtime image's arch_initialise() routine will perform the -following steps: - - Zero the bss - - Initialise the console device(s) and print a welcome message. - - Obtain a memory map via the INT 15,E820 BIOS call or suitable - fallback mechanism. [not done if libkir is being used] - - Relocate the runtime image to the top of high memory. [not done if - libkir is being used] - - Install librm to base memory. [done only if librm is being used] - - Call initialise(). - - Return to the prefix, setting registers to indicate to the prefix - the new location of the transition library, if applicable. Which - registers these are is specific to the transition library being - used. - -Once the arch_initialise() routine has returned, the prefix will -probably call arch_main(). diff --git a/qemu/roms/ipxe/src/arch/i386/core/basemem_packet.c b/qemu/roms/ipxe/src/arch/i386/core/basemem_packet.c deleted file mode 100644 index 9f5fbf330..000000000 --- a/qemu/roms/ipxe/src/arch/i386/core/basemem_packet.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 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 ); - -/** - * @file - * - * Packet buffer in base memory. Used by various components which - * need to pass packets to and from external real-mode code. - * - */ - -#include <basemem_packet.h> - -#undef basemem_packet -char __bss16_array ( basemem_packet, [BASEMEM_PACKET_LEN] ); diff --git a/qemu/roms/ipxe/src/arch/i386/core/cachedhcp.c b/qemu/roms/ipxe/src/arch/i386/core/cachedhcp.c deleted file mode 100644 index a5c624035..000000000 --- a/qemu/roms/ipxe/src/arch/i386/core/cachedhcp.c +++ /dev/null @@ -1,175 +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 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. - */ - len = sizeof ( BOOTPLAYER_t ); - - /* Allocate and populate DHCP packet */ - dhcppkt = zalloc ( sizeof ( *dhcppkt ) + 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, - len ); - dhcppkt_init ( dhcppkt, dhcphdr, len ); - - /* Resize packet to required length. If reallocation fails, - * just continue to use the original packet. - */ - len = dhcppkt_len ( dhcppkt ); - 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 ) = { - .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/qemu/roms/ipxe/src/arch/i386/core/dumpregs.c b/qemu/roms/ipxe/src/arch/i386/core/dumpregs.c deleted file mode 100644 index 82dc21847..000000000 --- a/qemu/roms/ipxe/src/arch/i386/core/dumpregs.c +++ /dev/null @@ -1,23 +0,0 @@ -#include <stdio.h> -#include <realmode.h> - -void __asmcall _dump_regs ( struct i386_all_regs *ix86 ) { - - __asm__ __volatile__ ( - TEXT16_CODE ( ".globl dump_regs\n\t" - "\ndump_regs:\n\t" - "pushl $_dump_regs\n\t" - "pushw %%cs\n\t" - "call prot_call\n\t" - "addr32 leal 4(%%esp), %%esp\n\t" - "ret\n\t" ) : : ); - - printf ( "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n" - "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n" - "CS=%04x SS=%04x DS=%04x ES=%04x FS=%04x GS=%04x\n", - ix86->regs.eax, ix86->regs.ebx, ix86->regs.ecx, - ix86->regs.edx, ix86->regs.esi, ix86->regs.edi, - ix86->regs.ebp, ix86->regs.esp, - ix86->segs.cs, ix86->segs.ss, ix86->segs.ds, - ix86->segs.es, ix86->segs.fs, ix86->segs.gs ); -} diff --git a/qemu/roms/ipxe/src/arch/i386/core/gdbidt.S b/qemu/roms/ipxe/src/arch/i386/core/gdbidt.S deleted file mode 100644 index a1e309d7c..000000000 --- a/qemu/roms/ipxe/src/arch/i386/core/gdbidt.S +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Interrupt handlers for GDB stub - */ - -#define SIZEOF_I386_REGS 32 -#define SIZEOF_I386_FLAGS 4 - -/**************************************************************************** - * Interrupt handlers - **************************************************************************** - */ - .section ".text", "ax", @progbits - .code32 - -/* POSIX signal numbers for reporting traps to GDB */ -#define SIGILL 4 -#define SIGTRAP 5 -#define SIGBUS 7 -#define SIGFPE 8 -#define SIGSEGV 11 -#define SIGSTKFLT 16 - - .globl gdbmach_nocode_sigfpe -gdbmach_nocode_sigfpe: - pushl $SIGFPE - jmp gdbmach_interrupt - - .globl gdbmach_nocode_sigtrap -gdbmach_nocode_sigtrap: - pushl $SIGTRAP - jmp gdbmach_interrupt - - .globl gdbmach_nocode_sigstkflt -gdbmach_nocode_sigstkflt: - pushl $SIGSTKFLT - jmp gdbmach_interrupt - - .globl gdbmach_nocode_sigill -gdbmach_nocode_sigill: - pushl $SIGILL - jmp gdbmach_interrupt - - .globl gdbmach_withcode_sigbus -gdbmach_withcode_sigbus: - movl $SIGBUS, (%esp) - jmp gdbmach_interrupt - - .globl gdbmach_withcode_sigsegv -gdbmach_withcode_sigsegv: - movl $SIGSEGV, (%esp) - jmp gdbmach_interrupt - -/* When invoked, the stack contains: eflags, cs, eip, signo. */ -#define IH_OFFSET_GDB_REGS ( 0 ) -#define IH_OFFSET_GDB_EIP ( IH_OFFSET_GDB_REGS + SIZEOF_I386_REGS ) -#define IH_OFFSET_GDB_EFLAGS ( IH_OFFSET_GDB_EIP + 4 ) -#define IH_OFFSET_GDB_SEG_REGS ( IH_OFFSET_GDB_EFLAGS + SIZEOF_I386_FLAGS ) -#define IH_OFFSET_GDB_END ( IH_OFFSET_GDB_SEG_REGS + 6 * 4 ) -#define IH_OFFSET_SIGNO ( IH_OFFSET_GDB_END ) -#define IH_OFFSET_OLD_EIP ( IH_OFFSET_SIGNO + 4 ) -#define IH_OFFSET_OLD_CS ( IH_OFFSET_OLD_EIP + 4 ) -#define IH_OFFSET_OLD_EFLAGS ( IH_OFFSET_OLD_CS + 4 ) -#define IH_OFFSET_END ( IH_OFFSET_OLD_EFLAGS + 4 ) - -/* We also access the stack whilst still storing or restoring - * the register snapshot. Since ESP is in flux, we need - * special offsets. - */ -#define IH_OFFSET_FLUX_OLD_CS ( IH_OFFSET_OLD_CS - 44 ) -#define IH_OFFSET_FLUX_OLD_EFLAGS ( IH_OFFSET_OLD_EFLAGS - 40 ) -#define IH_OFFSET_FLUX_OLD_EIP ( IH_OFFSET_OLD_EIP - 36 ) -#define IH_OFFSET_FLUX_END ( IH_OFFSET_END - 20 ) -gdbmach_interrupt: - /* Store CPU state in GDB register snapshot */ - pushw $0 - pushw %gs - pushw $0 - pushw %fs - pushw $0 - pushw %es - pushw $0 - pushw %ds - pushw $0 - pushw %ss - pushw $0 - pushw IH_OFFSET_FLUX_OLD_CS + 2(%esp) - pushl IH_OFFSET_FLUX_OLD_EFLAGS(%esp) - pushl IH_OFFSET_FLUX_OLD_EIP(%esp) - pushl %edi - pushl %esi - pushl %ebp - leal IH_OFFSET_FLUX_END(%esp), %edi - pushl %edi /* old ESP */ - pushl %ebx - pushl %edx - pushl %ecx - pushl %eax - - /* Switch to virtual addressing */ - call _intr_to_virt - - /* Call GDB stub exception handler */ - pushl %esp - pushl (IH_OFFSET_SIGNO + 4)(%esp) - call gdbmach_handler - addl $8, %esp - - /* Copy register snapshot to new stack and switch to new stack */ - movl %esp, %esi - movl (IH_OFFSET_GDB_SEG_REGS + 4)(%esp), %eax - movl %eax, %es - movl (IH_OFFSET_GDB_REGS + 16)(%esp), %edi - subl $IH_OFFSET_END, %edi - movl $(IH_OFFSET_END / 4), %ecx - pushl %edi - ss rep movsl - popl %edi - movl %eax, %ss - movl %edi, %esp - - /* Restore CPU state from GDB register snapshot */ - popl %eax - popl %ecx - popl %edx - popl %ebx - popl %ebp /* Skip %esp: already loaded */ - popl %ebp - popl %esi - popl %edi - popl IH_OFFSET_FLUX_OLD_EIP(%esp) - popl IH_OFFSET_FLUX_OLD_EFLAGS(%esp) - popl IH_OFFSET_FLUX_OLD_CS(%esp) - popl %ds /* Skip %ss: already loaded */ - popl %ds - popl %es - popl %fs - popl %gs - - addl $4, %esp /* drop signo */ - iret diff --git a/qemu/roms/ipxe/src/arch/i386/core/gdbmach.c b/qemu/roms/ipxe/src/arch/i386/core/gdbmach.c deleted file mode 100644 index d92a4ac08..000000000 --- a/qemu/roms/ipxe/src/arch/i386/core/gdbmach.c +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (C) 2008 Stefan Hajnoczi <stefanha@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 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 <stddef.h> -#include <stdio.h> -#include <assert.h> -#include <ipxe/uaccess.h> -#include <ipxe/gdbstub.h> -#include <librm.h> -#include <gdbmach.h> - -/** @file - * - * GDB architecture-specific bits for i386 - * - */ - -enum { - DR7_CLEAR = 0x00000400, /* disable hardware breakpoints */ - DR6_CLEAR = 0xffff0ff0, /* clear breakpoint status */ -}; - -/** Hardware breakpoint, fields stored in x86 bit pattern form */ -struct hwbp { - int type; /* type (1=write watchpoint, 3=access watchpoint) */ - unsigned long addr; /* linear address */ - size_t len; /* length (0=1-byte, 1=2-byte, 3=4-byte) */ - int enabled; -}; - -static struct hwbp hwbps [ 4 ]; -static gdbreg_t dr7 = DR7_CLEAR; - -static struct hwbp *gdbmach_find_hwbp ( int type, unsigned long addr, size_t len ) { - struct hwbp *available = NULL; - unsigned int i; - for ( i = 0; i < sizeof hwbps / sizeof hwbps [ 0 ]; i++ ) { - if ( hwbps [ i ].type == type && hwbps [ i ].addr == addr && hwbps [ i ].len == len ) { - return &hwbps [ i ]; - } - if ( !hwbps [ i ].enabled ) { - available = &hwbps [ i ]; - } - } - return available; -} - -static void gdbmach_commit_hwbp ( struct hwbp *bp ) { - unsigned int regnum = bp - hwbps; - - /* Set breakpoint address */ - assert ( regnum < ( sizeof hwbps / sizeof hwbps [ 0 ] ) ); - switch ( regnum ) { - case 0: - __asm__ __volatile__ ( "movl %0, %%dr0\n" : : "r" ( bp->addr ) ); - break; - case 1: - __asm__ __volatile__ ( "movl %0, %%dr1\n" : : "r" ( bp->addr ) ); - break; - case 2: - __asm__ __volatile__ ( "movl %0, %%dr2\n" : : "r" ( bp->addr ) ); - break; - case 3: - __asm__ __volatile__ ( "movl %0, %%dr3\n" : : "r" ( bp->addr ) ); - break; - } - - /* Set type */ - dr7 &= ~( 0x3 << ( 16 + 4 * regnum ) ); - dr7 |= bp->type << ( 16 + 4 * regnum ); - - /* Set length */ - dr7 &= ~( 0x3 << ( 18 + 4 * regnum ) ); - dr7 |= bp->len << ( 18 + 4 * regnum ); - - /* Set/clear local enable bit */ - dr7 &= ~( 0x3 << 2 * regnum ); - dr7 |= bp->enabled << 2 * regnum; -} - -int gdbmach_set_breakpoint ( int type, unsigned long addr, size_t len, int enable ) { - struct hwbp *bp; - - /* Check and convert breakpoint type to x86 type */ - switch ( type ) { - case GDBMACH_WATCH: - type = 0x1; - break; - case GDBMACH_AWATCH: - type = 0x3; - break; - default: - return 0; /* unsupported breakpoint type */ - } - - /* Only lengths 1, 2, and 4 are supported */ - if ( len != 2 && len != 4 ) { - len = 1; - } - len--; /* convert to x86 breakpoint length bit pattern */ - - /* Calculate linear address by adding segment base */ - addr += virt_offset; - - /* Set up the breakpoint */ - bp = gdbmach_find_hwbp ( type, addr, len ); - if ( !bp ) { - return 0; /* ran out of hardware breakpoints */ - } - bp->type = type; - bp->addr = addr; - bp->len = len; - bp->enabled = enable; - gdbmach_commit_hwbp ( bp ); - return 1; -} - -static void gdbmach_disable_hwbps ( void ) { - /* Store and clear hardware breakpoints */ - __asm__ __volatile__ ( "movl %0, %%dr7\n" : : "r" ( DR7_CLEAR ) ); -} - -static void gdbmach_enable_hwbps ( void ) { - /* Clear breakpoint status register */ - __asm__ __volatile__ ( "movl %0, %%dr6\n" : : "r" ( DR6_CLEAR ) ); - - /* Restore hardware breakpoints */ - __asm__ __volatile__ ( "movl %0, %%dr7\n" : : "r" ( dr7 ) ); -} - -__asmcall void gdbmach_handler ( int signo, gdbreg_t *regs ) { - gdbmach_disable_hwbps(); - gdbstub_handler ( signo, regs ); - gdbmach_enable_hwbps(); -} - -static void * gdbmach_interrupt_vectors[] = { - gdbmach_nocode_sigfpe, /* Divide by zero */ - gdbmach_nocode_sigtrap, /* Debug trap */ - NULL, /* Non-maskable interrupt */ - gdbmach_nocode_sigtrap, /* Breakpoint */ - gdbmach_nocode_sigstkflt, /* Overflow */ - gdbmach_nocode_sigstkflt, /* Bound range exceeded */ - gdbmach_nocode_sigill, /* Invalid opcode */ - NULL, /* Device not available */ - gdbmach_withcode_sigbus, /* Double fault */ - NULL, /* Coprocessor segment overrun */ - gdbmach_withcode_sigsegv, /* Invalid TSS */ - gdbmach_withcode_sigsegv, /* Segment not present */ - gdbmach_withcode_sigsegv, /* Stack segment fault */ - gdbmach_withcode_sigsegv, /* General protection fault */ - gdbmach_withcode_sigsegv, /* Page fault */ -}; - -void gdbmach_init ( void ) { - unsigned int i; - - for ( i = 0 ; i < ( sizeof ( gdbmach_interrupt_vectors ) / - sizeof ( gdbmach_interrupt_vectors[0] ) ) ; i++ ) { - set_interrupt_vector ( i, gdbmach_interrupt_vectors[i] ); - } -} diff --git a/qemu/roms/ipxe/src/arch/i386/core/linux/linux_syscall.S b/qemu/roms/ipxe/src/arch/i386/core/linux/linux_syscall.S deleted file mode 100644 index 38a3e74bd..000000000 --- a/qemu/roms/ipxe/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/qemu/roms/ipxe/src/arch/i386/core/linux/linuxprefix.S b/qemu/roms/ipxe/src/arch/i386/core/linux/linuxprefix.S deleted file mode 100644 index 398d3cb21..000000000 --- a/qemu/roms/ipxe/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/qemu/roms/ipxe/src/arch/i386/core/nulltrap.c b/qemu/roms/ipxe/src/arch/i386/core/nulltrap.c deleted file mode 100644 index 3046fbecf..000000000 --- a/qemu/roms/ipxe/src/arch/i386/core/nulltrap.c +++ /dev/null @@ -1,51 +0,0 @@ -#include <stdint.h> -#include <stdio.h> - -__attribute__ (( noreturn, section ( ".text.null_trap" ) )) -void null_function_trap ( void ) { - void *stack; - - /* 128 bytes of NOPs; the idea of this is that if something - * dereferences a NULL pointer and overwrites us, we at least - * have some chance of still getting to execute the printf() - * statement. - */ - __asm__ __volatile__ ( "nop ; nop ; nop ; nop" ); - __asm__ __volatile__ ( "nop ; nop ; nop ; nop" ); - __asm__ __volatile__ ( "nop ; nop ; nop ; nop" ); - __asm__ __volatile__ ( "nop ; nop ; nop ; nop" ); - __asm__ __volatile__ ( "nop ; nop ; nop ; nop" ); - __asm__ __volatile__ ( "nop ; nop ; nop ; nop" ); - __asm__ __volatile__ ( "nop ; nop ; nop ; nop" ); - __asm__ __volatile__ ( "nop ; nop ; nop ; nop" ); - __asm__ __volatile__ ( "nop ; nop ; nop ; nop" ); - __asm__ __volatile__ ( "nop ; nop ; nop ; nop" ); - __asm__ __volatile__ ( "nop ; nop ; nop ; nop" ); - __asm__ __volatile__ ( "nop ; nop ; nop ; nop" ); - __asm__ __volatile__ ( "nop ; nop ; nop ; nop" ); - __asm__ __volatile__ ( "nop ; nop ; nop ; nop" ); - __asm__ __volatile__ ( "nop ; nop ; nop ; nop" ); - __asm__ __volatile__ ( "nop ; nop ; nop ; nop" ); - __asm__ __volatile__ ( "nop ; nop ; nop ; nop" ); - __asm__ __volatile__ ( "nop ; nop ; nop ; nop" ); - __asm__ __volatile__ ( "nop ; nop ; nop ; nop" ); - __asm__ __volatile__ ( "nop ; nop ; nop ; nop" ); - __asm__ __volatile__ ( "nop ; nop ; nop ; nop" ); - __asm__ __volatile__ ( "nop ; nop ; nop ; nop" ); - __asm__ __volatile__ ( "nop ; nop ; nop ; nop" ); - __asm__ __volatile__ ( "nop ; nop ; nop ; nop" ); - __asm__ __volatile__ ( "nop ; nop ; nop ; nop" ); - __asm__ __volatile__ ( "nop ; nop ; nop ; nop" ); - __asm__ __volatile__ ( "nop ; nop ; nop ; nop" ); - __asm__ __volatile__ ( "nop ; nop ; nop ; nop" ); - __asm__ __volatile__ ( "nop ; nop ; nop ; nop" ); - __asm__ __volatile__ ( "nop ; nop ; nop ; nop" ); - __asm__ __volatile__ ( "nop ; nop ; nop ; nop" ); - __asm__ __volatile__ ( "nop ; nop ; nop ; nop" ); - - __asm__ __volatile__ ( "movl %%esp, %0" : "=r" ( stack ) ); - printf ( "NULL method called from %p (stack %p)\n", - __builtin_return_address ( 0 ), stack ); - DBG_HD ( stack, 256 ); - while ( 1 ) {} -} diff --git a/qemu/roms/ipxe/src/arch/i386/core/patch_cf.S b/qemu/roms/ipxe/src/arch/i386/core/patch_cf.S deleted file mode 100644 index 4365563fe..000000000 --- a/qemu/roms/ipxe/src/arch/i386/core/patch_cf.S +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2009 H. Peter Anvin <hpa@zytor.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 (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 ) - - .text - .arch i386 - .code16 - -/**************************************************************************** - * Set/clear CF on the stack as appropriate, assumes stack is as it should - * be immediately before IRET - **************************************************************************** - */ - .section ".text16", "ax", @progbits - .globl patch_cf -patch_cf: - pushw %bp - movw %sp, %bp - setc 8(%bp) /* Set/reset CF; clears PF, AF, ZF, SF */ - popw %bp - ret - .size patch_cf, . - patch_cf diff --git a/qemu/roms/ipxe/src/arch/i386/core/pci_autoboot.c b/qemu/roms/ipxe/src/arch/i386/core/pci_autoboot.c deleted file mode 100644 index 337598091..000000000 --- a/qemu/roms/ipxe/src/arch/i386/core/pci_autoboot.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2014 Red Hat Inc. - * Alex Williamson <alex.williamson@redhat.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 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/device.h> -#include <ipxe/init.h> -#include <realmode.h> -#include <usr/autoboot.h> - -uint16_t __bss16 ( autoboot_busdevfn ); -#define autoboot_busdevfn __use_data16 ( autoboot_busdevfn ) - -/** - * Initialise PCI autoboot device - */ -static void pci_autoboot_init ( void ) { - - if ( autoboot_busdevfn ) - set_autoboot_busloc ( BUS_TYPE_PCI, autoboot_busdevfn ); -} - -/** PCI autoboot device initialisation function */ -struct init_fn pci_autoboot_init_fn __init_fn ( INIT_NORMAL ) = { - .initialise = pci_autoboot_init, -}; diff --git a/qemu/roms/ipxe/src/arch/i386/core/rdtsc_timer.c b/qemu/roms/ipxe/src/arch/i386/core/rdtsc_timer.c deleted file mode 100644 index e720a239c..000000000 --- a/qemu/roms/ipxe/src/arch/i386/core/rdtsc_timer.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 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 ); - -/** @file - * - * RDTSC timer - * - */ - -#include <assert.h> -#include <ipxe/timer.h> -#include <ipxe/pit8254.h> - -/** - * Number of TSC ticks per microsecond - * - * This is calibrated on the first use of the timer. - */ -static unsigned long rdtsc_ticks_per_usec; - -/** - * Delay for a fixed number of microseconds - * - * @v usecs Number of microseconds for which to delay - */ -static void rdtsc_udelay ( unsigned long usecs ) { - unsigned long start; - unsigned long elapsed; - - /* Sanity guard, since we may divide by this */ - if ( ! usecs ) - usecs = 1; - - start = currticks(); - if ( rdtsc_ticks_per_usec ) { - /* Already calibrated; busy-wait until done */ - do { - elapsed = ( currticks() - start ); - } while ( elapsed < ( usecs * rdtsc_ticks_per_usec ) ); - } else { - /* Not yet calibrated; use 8254 PIT and calibrate - * based on result. - */ - pit8254_udelay ( usecs ); - elapsed = ( currticks() - start ); - rdtsc_ticks_per_usec = ( elapsed / usecs ); - DBG ( "RDTSC timer calibrated: %ld ticks in %ld usecs " - "(%ld MHz)\n", elapsed, usecs, - ( rdtsc_ticks_per_usec << TSC_SHIFT ) ); - } -} - -/** - * Get number of ticks per second - * - * @ret ticks_per_sec Number of ticks per second - */ -static unsigned long rdtsc_ticks_per_sec ( void ) { - - /* Calibrate timer, if not already done */ - if ( ! rdtsc_ticks_per_usec ) - udelay ( 1 ); - - /* Sanity check */ - assert ( rdtsc_ticks_per_usec != 0 ); - - return ( rdtsc_ticks_per_usec * 1000 * 1000 ); -} - -PROVIDE_TIMER ( rdtsc, udelay, rdtsc_udelay ); -PROVIDE_TIMER_INLINE ( rdtsc, currticks ); -PROVIDE_TIMER ( rdtsc, ticks_per_sec, rdtsc_ticks_per_sec ); diff --git a/qemu/roms/ipxe/src/arch/i386/core/relocate.c b/qemu/roms/ipxe/src/arch/i386/core/relocate.c deleted file mode 100644 index 54ad387e4..000000000 --- a/qemu/roms/ipxe/src/arch/i386/core/relocate.c +++ /dev/null @@ -1,138 +0,0 @@ -#include <ipxe/io.h> -#include <registers.h> - -/* - * Originally by Eric Biederman - * - * Heavily modified by Michael Brown - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/* - * The linker passes in the symbol _max_align, which is the alignment - * that we must preserve, in bytes. - * - */ -extern char _max_align[]; -#define max_align ( ( unsigned int ) _max_align ) - -/* Linker symbols */ -extern char _textdata[]; -extern char _etextdata[]; - -/* within 1MB of 4GB is too close. - * MAX_ADDR is the maximum address we can easily do DMA to. - * - * Not sure where this constraint comes from, but kept it from Eric's - * old code - mcb30 - */ -#define MAX_ADDR (0xfff00000UL) - -/** - * Relocate iPXE - * - * @v ebp Maximum address to use for relocation - * @ret esi Current physical address - * @ret edi New physical address - * @ret ecx Length to copy - * - * This finds a suitable location for iPXE near the top of 32-bit - * address space, and returns the physical address of the new location - * to the prefix in %edi. - */ -__asmcall void relocate ( struct i386_all_regs *ix86 ) { - struct memory_map memmap; - unsigned long start, end, size, padded_size, max; - unsigned long new_start, new_end; - unsigned i; - - /* Get memory map and current location */ - get_memmap ( &memmap ); - start = virt_to_phys ( _textdata ); - end = virt_to_phys ( _etextdata ); - size = ( end - start ); - padded_size = ( size + max_align - 1 ); - - DBG ( "Relocate: currently at [%lx,%lx)\n" - "...need %lx bytes for %d-byte alignment\n", - start, end, padded_size, max_align ); - - /* Determine maximum usable address */ - max = MAX_ADDR; - if ( ix86->regs.ebp < max ) { - max = ix86->regs.ebp; - DBG ( "Limiting relocation to [0,%lx)\n", max ); - } - - /* Walk through the memory map and find the highest address - * below 4GB that iPXE will fit into. - */ - new_end = end; - for ( i = 0 ; i < memmap.count ; i++ ) { - struct memory_region *region = &memmap.regions[i]; - unsigned long r_start, r_end; - - DBG ( "Considering [%llx,%llx)\n", region->start, region->end); - - /* Truncate block to maximum address. This will be - * less than 4GB, which means that we can get away - * with using just 32-bit arithmetic after this stage. - */ - if ( region->start > max ) { - DBG ( "...starts after max=%lx\n", max ); - continue; - } - r_start = region->start; - if ( region->end > max ) { - DBG ( "...end truncated to max=%lx\n", max ); - r_end = max; - } else { - r_end = region->end; - } - DBG ( "...usable portion is [%lx,%lx)\n", r_start, r_end ); - - /* If we have rounded down r_end below r_ start, skip - * this block. - */ - if ( r_end < r_start ) { - DBG ( "...truncated to negative size\n" ); - continue; - } - - /* Check that there is enough space to fit in iPXE */ - if ( ( r_end - r_start ) < size ) { - DBG ( "...too small (need %lx bytes)\n", size ); - continue; - } - - /* If the start address of the iPXE we would - * place in this block is higher than the end address - * of the current highest block, use this block. - * - * Note that this avoids overlaps with the current - * iPXE, as well as choosing the highest of all viable - * blocks. - */ - if ( ( r_end - size ) > new_end ) { - new_end = r_end; - DBG ( "...new best block found.\n" ); - } - } - - /* Calculate new location of iPXE, and align it to the - * required alignemnt. - */ - new_start = new_end - padded_size; - new_start += ( start - new_start ) & ( max_align - 1 ); - new_end = new_start + size; - - DBG ( "Relocating from [%lx,%lx) to [%lx,%lx)\n", - start, end, new_start, new_end ); - - /* Let prefix know what to copy */ - ix86->regs.esi = start; - ix86->regs.edi = new_start; - ix86->regs.ecx = size; -} diff --git a/qemu/roms/ipxe/src/arch/i386/core/runtime.c b/qemu/roms/ipxe/src/arch/i386/core/runtime.c deleted file mode 100644 index d160fee04..000000000 --- a/qemu/roms/ipxe/src/arch/i386/core/runtime.c +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Copyright (C) 2011 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 ); - -/** @file - * - * Command line and initrd passed to iPXE at runtime - * - */ - -#include <stddef.h> -#include <stdint.h> -#include <stdlib.h> -#include <ctype.h> -#include <errno.h> -#include <assert.h> -#include <ipxe/init.h> -#include <ipxe/image.h> -#include <ipxe/script.h> -#include <ipxe/umalloc.h> -#include <realmode.h> - -/** Command line physical address - * - * This can be set by the prefix. - */ -uint32_t __bss16 ( cmdline_phys ); -#define cmdline_phys __use_data16 ( cmdline_phys ) - -/** initrd physical address - * - * This can be set by the prefix. - */ -uint32_t __bss16 ( initrd_phys ); -#define initrd_phys __use_data16 ( initrd_phys ) - -/** initrd length - * - * This can be set by the prefix. - */ -uint32_t __bss16 ( initrd_len ); -#define initrd_len __use_data16 ( initrd_len ) - -/** Internal copy of the command line */ -static char *cmdline_copy; - -/** Free command line image */ -static void cmdline_image_free ( struct refcnt *refcnt ) { - struct image *image = container_of ( refcnt, struct image, refcnt ); - - DBGC ( image, "RUNTIME freeing command line\n" ); - free ( cmdline_copy ); -} - -/** Embedded script representing the command line */ -static struct image cmdline_image = { - .refcnt = REF_INIT ( cmdline_image_free ), - .name = "<CMDLINE>", - .type = &script_image_type, -}; - -/** Colour for debug messages */ -#define colour &cmdline_image - -/** - * Strip unwanted cruft from command line - * - * @v cmdline Command line - * @v cruft Initial substring of cruft to strip - */ -static void cmdline_strip ( char *cmdline, const char *cruft ) { - char *strip; - char *strip_end; - - /* Find unwanted cruft, if present */ - if ( ! ( strip = strstr ( cmdline, cruft ) ) ) - return; - - /* Strip unwanted cruft */ - strip_end = strchr ( strip, ' ' ); - if ( strip_end ) { - *strip_end = '\0'; - DBGC ( colour, "RUNTIME stripping \"%s\"\n", strip ); - strcpy ( strip, ( strip_end + 1 ) ); - } else { - DBGC ( colour, "RUNTIME stripping \"%s\"\n", strip ); - *strip = '\0'; - } -} - -/** - * Initialise command line - * - * @ret rc Return status code - */ -static int cmdline_init ( void ) { - userptr_t cmdline_user; - char *cmdline; - size_t len; - int rc; - - /* Do nothing if no command line was specified */ - if ( ! cmdline_phys ) { - DBGC ( colour, "RUNTIME found no command line\n" ); - return 0; - } - cmdline_user = phys_to_user ( cmdline_phys ); - len = ( strlen_user ( cmdline_user, 0 ) + 1 /* NUL */ ); - - /* Allocate and copy command line */ - cmdline_copy = malloc ( len ); - if ( ! cmdline_copy ) { - DBGC ( colour, "RUNTIME could not allocate %zd bytes for " - "command line\n", len ); - rc = -ENOMEM; - goto err_alloc_cmdline_copy; - } - cmdline = cmdline_copy; - copy_from_user ( cmdline, cmdline_user, 0, len ); - DBGC ( colour, "RUNTIME found command line \"%s\" at %08x\n", - cmdline, cmdline_phys ); - - /* Mark command line as consumed */ - cmdline_phys = 0; - - /* Strip unwanted cruft from the command line */ - cmdline_strip ( cmdline, "BOOT_IMAGE=" ); - cmdline_strip ( cmdline, "initrd=" ); - while ( isspace ( *cmdline ) ) - cmdline++; - DBGC ( colour, "RUNTIME using command line \"%s\"\n", cmdline ); - - /* Prepare and register image */ - cmdline_image.data = virt_to_user ( cmdline ); - cmdline_image.len = strlen ( cmdline ); - if ( cmdline_image.len ) { - if ( ( rc = register_image ( &cmdline_image ) ) != 0 ) { - DBGC ( colour, "RUNTIME could not register command " - "line: %s\n", strerror ( rc ) ); - goto err_register_image; - } - } - - /* Drop our reference to the image */ - image_put ( &cmdline_image ); - - return 0; - - err_register_image: - image_put ( &cmdline_image ); - err_alloc_cmdline_copy: - return rc; -} - -/** - * Initialise initrd - * - * @ret rc Return status code - */ -static int initrd_init ( void ) { - struct image *image; - int rc; - - /* Do nothing if no initrd was specified */ - if ( ! initrd_phys ) { - DBGC ( colour, "RUNTIME found no initrd\n" ); - return 0; - } - if ( ! initrd_len ) { - DBGC ( colour, "RUNTIME found empty initrd\n" ); - return 0; - } - DBGC ( colour, "RUNTIME found initrd at [%x,%x)\n", - initrd_phys, ( initrd_phys + initrd_len ) ); - - /* Allocate image */ - image = alloc_image ( NULL ); - 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; - } - - /* 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; -} - -/** - * Initialise command line and initrd - * - */ -static void runtime_init ( void ) { - int rc; - - /* Initialise command line */ - if ( ( rc = cmdline_init() ) != 0 ) { - /* No way to report failure */ - return; - } - - /* Initialise initrd */ - if ( ( rc = initrd_init() ) != 0 ) { - /* No way to report failure */ - return; - } -} - -/** Command line and initrd initialisation function */ -struct startup_fn runtime_startup_fn __startup_fn ( STARTUP_NORMAL ) = { - .startup = runtime_init, -}; diff --git a/qemu/roms/ipxe/src/arch/i386/core/setjmp.S b/qemu/roms/ipxe/src/arch/i386/core/setjmp.S deleted file mode 100644 index 81d3b4911..000000000 --- a/qemu/roms/ipxe/src/arch/i386/core/setjmp.S +++ /dev/null @@ -1,64 +0,0 @@ -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) - - .text - .arch i386 - .code32 - - /* Must match jmp_buf structure layout */ - .struct 0 -env_retaddr: .long 0 -env_stack: .long 0 -env_ebx: .long 0 -env_esi: .long 0 -env_edi: .long 0 -env_ebp: .long 0 - .previous - -/* - * Save stack context for non-local goto - */ - .globl setjmp -setjmp: - /* Get jmp_buf pointer in %edx */ - movl 4(%esp),%edx - /* Save return address */ - movl 0(%esp),%eax - movl %eax, env_retaddr(%edx) - /* Save stack pointer */ - movl %esp, env_stack(%edx) - /* Save other registers */ - movl %ebx, env_ebx(%edx) - movl %esi, env_esi(%edx) - movl %edi, env_edi(%edx) - movl %ebp, env_ebp(%edx) - /* Return 0 when returning as setjmp() */ - xorl %eax, %eax - ret - .size setjmp, . - setjmp - -/* - * Non-local jump to a saved stack context - */ - .globl longjmp -longjmp: - /* Get jmp_buf pointer in %edx */ - movl 4(%esp),%edx - /* Get result in %eax */ - movl 8(%esp),%eax - /* Force result to non-zero */ - testl %eax, %eax - jnz 1f - incl %eax -1: /* Restore stack pointer */ - movl env_stack(%edx), %esp - /* Restore other registers */ - movl env_ebx(%edx), %ebx - movl env_esi(%edx), %esi - movl env_edi(%edx), %edi - movl env_ebp(%edx), %ebp - /* Replace return address on the new stack */ - popl %ecx /* discard */ - pushl env_retaddr(%edx) - /* Return to setjmp() caller */ - ret - .size longjmp, . - longjmp diff --git a/qemu/roms/ipxe/src/arch/i386/core/stack.S b/qemu/roms/ipxe/src/arch/i386/core/stack.S deleted file mode 100644 index 98f1cd9b9..000000000 --- a/qemu/roms/ipxe/src/arch/i386/core/stack.S +++ /dev/null @@ -1,15 +0,0 @@ -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) - - .arch i386 - -/**************************************************************************** - * Internal stack - **************************************************************************** - */ - .section ".stack", "aw", @nobits - .align 8 - .globl _stack -_stack: - .space 4096 - .globl _estack -_estack: diff --git a/qemu/roms/ipxe/src/arch/i386/core/stack16.S b/qemu/roms/ipxe/src/arch/i386/core/stack16.S deleted file mode 100644 index 4bc6f081a..000000000 --- a/qemu/roms/ipxe/src/arch/i386/core/stack16.S +++ /dev/null @@ -1,15 +0,0 @@ -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) - - .arch i386 - -/**************************************************************************** - * Internal stack - **************************************************************************** - */ - .section ".stack16", "aw", @nobits - .align 8 - .globl _stack16 -_stack16: - .space 4096 - .globl _estack16 -_estack16: diff --git a/qemu/roms/ipxe/src/arch/i386/core/video_subr.c b/qemu/roms/ipxe/src/arch/i386/core/video_subr.c deleted file mode 100644 index 3f701bd96..000000000 --- a/qemu/roms/ipxe/src/arch/i386/core/video_subr.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * - * modified from linuxbios code - * by Cai Qiang <rimy2000@hotmail.com> - * - */ - -#include "stddef.h" -#include "string.h" -#include <ipxe/io.h> -#include <ipxe/console.h> -#include <ipxe/init.h> -#include "vga.h" -#include <config/console.h> - -/* Set default console usage if applicable */ -#if ! ( defined ( CONSOLE_DIRECT_VGA ) && \ - CONSOLE_EXPLICIT ( CONSOLE_DIRECT_VGA ) ) -#undef CONSOLE_DIRECT_VGA -#define CONSOLE_DIRECT_VGA ( CONSOLE_USAGE_ALL & ~CONSOLE_USAGE_LOG ) -#endif - -struct console_driver vga_console __console_driver; - -static char *vidmem; /* The video buffer */ -static int video_line, video_col; - -#define VIDBUFFER 0xB8000 - -static void memsetw(void *s, int c, unsigned int n) -{ - unsigned int i; - u16 *ss = (u16 *) s; - - for (i = 0; i < n; i++) { - ss[i] = ( u16 ) c; - } -} - -static void video_init(void) -{ - static int inited=0; - - vidmem = (char *)phys_to_virt(VIDBUFFER); - - if (!inited) { - video_line = 0; - video_col = 0; - - memsetw(vidmem, VGA_ATTR_CLR_WHT, 2*1024); // - - inited=1; - } -} - -static void video_scroll(void) -{ - int i; - - memcpy(vidmem, vidmem + COLS * 2, (LINES - 1) * COLS * 2); - for (i = (LINES - 1) * COLS * 2; i < LINES * COLS * 2; i += 2) - vidmem[i] = ' '; -} - -static void vga_putc(int byte) -{ - if (byte == '\n') { - video_line++; - video_col = 0; - - } else if (byte == '\r') { - video_col = 0; - - } else if (byte == '\b') { - video_col--; - - } else if (byte == '\t') { - video_col += 4; - - } else if (byte == '\a') { - //beep - //beep(500); - - } else { - vidmem[((video_col + (video_line *COLS)) * 2)] = byte; - vidmem[((video_col + (video_line *COLS)) * 2) +1] = VGA_ATTR_CLR_WHT; - video_col++; - } - if (video_col < 0) { - video_col = 0; - } - if (video_col >= COLS) { - video_line++; - video_col = 0; - } - if (video_line >= LINES) { - video_scroll(); - video_line--; - } - // move the cursor - write_crtc((video_col + (video_line *COLS)) >> 8, CRTC_CURSOR_HI); - write_crtc((video_col + (video_line *COLS)) & 0x0ff, CRTC_CURSOR_LO); -} - -struct console_driver vga_console __console_driver = { - .putchar = vga_putc, - .disabled = CONSOLE_DISABLED, - .usage = CONSOLE_DIRECT_VGA, -}; - -struct init_fn video_init_fn __init_fn ( INIT_EARLY ) = { - .initialise = video_init, -}; diff --git a/qemu/roms/ipxe/src/arch/i386/core/virtaddr.S b/qemu/roms/ipxe/src/arch/i386/core/virtaddr.S deleted file mode 100644 index 425591570..000000000 --- a/qemu/roms/ipxe/src/arch/i386/core/virtaddr.S +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Functions to support the virtual addressing method of relocation - * that Etherboot uses. - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) - -#include "librm.h" - - .arch i386 - .text - .code32 - -/**************************************************************************** - * _virt_to_phys (virtual addressing) - * - * Switch from virtual to flat physical addresses. %esp is adjusted - * to a physical value. Segment registers are set to flat physical - * selectors. All other registers are preserved. Flags are - * preserved. - * - * Parameters: none - * Returns: none - **************************************************************************** - */ - .globl _virt_to_phys -_virt_to_phys: - /* Preserve registers and flags */ - pushfl - pushl %eax - pushl %ebp - - /* Change return address to a physical address */ - movl virt_offset, %ebp - addl %ebp, 12(%esp) - - /* Switch to physical code segment */ - cli - pushl $PHYSICAL_CS - leal 1f(%ebp), %eax - pushl %eax - lret -1: - /* Reload other segment registers and adjust %esp */ - movl $PHYSICAL_DS, %eax - movl %eax, %ds - movl %eax, %es - movl %eax, %fs - movl %eax, %gs - movl %eax, %ss - addl %ebp, %esp - - /* Restore registers and flags, and return */ - popl %ebp - popl %eax - popfl - ret - -/**************************************************************************** - * _phys_to_virt (flat physical addressing) - * - * Switch from flat physical to virtual addresses. %esp is adjusted - * to a virtual value. Segment registers are set to virtual - * selectors. All other registers are preserved. Flags are - * preserved. - * - * Parameters: none - * Returns: none - **************************************************************************** - */ - .globl _phys_to_virt -_phys_to_virt: - /* Preserve registers and flags */ - pushfl - pushl %eax - pushl %ebp - - /* Switch to virtual code segment */ - cli - ljmp $VIRTUAL_CS, $1f -1: - /* Reload data segment registers */ - movl $VIRTUAL_DS, %eax - movl %eax, %ds - movl %eax, %es - movl %eax, %fs - movl %eax, %gs - - /* Reload stack segment and adjust %esp */ - movl virt_offset, %ebp - movl %eax, %ss - subl %ebp, %esp - - /* Change the return address to a virtual address */ - subl %ebp, 12(%esp) - - /* Restore registers and flags, and return */ - popl %ebp - popl %eax - popfl - ret - -/**************************************************************************** - * _intr_to_virt (virtual code segment, virtual or physical stack segment) - * - * Switch from virtual code segment with either a virtual or physical - * stack segment to using virtual addressing. %esp is adjusted if - * necessary to a virtual value. Segment registers are set to virtual - * selectors. All other registers are preserved. Flags are - * preserved. - * - * Parameters: none - * Returns: none - **************************************************************************** - */ - .globl _intr_to_virt -_intr_to_virt: - /* Preserve registers and flags */ - pushfl - pushl %eax - pushl %ebp - - /* Check whether stack segment is physical or virtual */ - movl %ss, %eax - cmpw $VIRTUAL_DS, %ax - movl $VIRTUAL_DS, %eax - - /* Reload data segment registers */ - movl %eax, %ds - movl %eax, %es - movl %eax, %fs - movl %eax, %gs - - /* Reload stack segment and adjust %esp if necessary */ - je 1f - movl virt_offset, %ebp - movl %eax, %ss - subl %ebp, %esp -1: - /* Restore registers and flags, and return */ - popl %ebp - popl %eax - popfl - ret diff --git a/qemu/roms/ipxe/src/arch/i386/drivers/net/undi.c b/qemu/roms/ipxe/src/arch/i386/drivers/net/undi.c deleted file mode 100644 index 9820cf629..000000000 --- a/qemu/roms/ipxe/src/arch/i386/drivers/net/undi.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -FILE_LICENCE ( GPL2_OR_LATER ); - -#include <stdint.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <ipxe/pci.h> -#include <undi.h> -#include <undirom.h> -#include <undiload.h> -#include <undinet.h> -#include <undipreload.h> - -/** @file - * - * UNDI PCI driver - * - */ - -/** - * Find UNDI ROM for PCI device - * - * @v pci PCI device - * @ret undirom UNDI ROM, or NULL - * - * Try to find a driver for this device. Try an exact match on the - * ROM address first, then fall back to a vendor/device ID match only - */ -static struct undi_rom * undipci_find_rom ( struct pci_device *pci ) { - struct undi_rom *undirom; - unsigned long rombase; - - rombase = pci_bar_start ( pci, PCI_ROM_ADDRESS ); - undirom = undirom_find_pci ( pci->vendor, pci->device, rombase ); - if ( ! undirom ) - undirom = undirom_find_pci ( pci->vendor, pci->device, 0 ); - return undirom; -} - -/** - * Probe PCI device - * - * @v pci PCI device - * @v id PCI ID - * @ret rc Return status code - */ -static int undipci_probe ( struct pci_device *pci ) { - struct undi_device *undi; - struct undi_rom *undirom; - int rc; - - /* Allocate UNDI device structure */ - undi = zalloc ( sizeof ( *undi ) ); - if ( ! undi ) - return -ENOMEM; - pci_set_drvdata ( pci, undi ); - - /* Find/create our pixie */ - if ( preloaded_undi.pci_busdevfn == pci->busdevfn ) { - /* Claim preloaded UNDI device */ - DBGC ( undi, "UNDI %p using preloaded UNDI device\n", undi ); - memcpy ( undi, &preloaded_undi, sizeof ( *undi ) ); - memset ( &preloaded_undi, 0, sizeof ( preloaded_undi ) ); - } else { - /* Find UNDI ROM for PCI device */ - if ( ! ( undirom = undipci_find_rom ( pci ) ) ) { - rc = -ENODEV; - goto err_find_rom; - } - - /* Call UNDI ROM loader to create pixie */ - if ( ( rc = undi_load_pci ( undi, undirom, - pci->busdevfn ) ) != 0 ) { - goto err_load_pci; - } - } - - /* Add to device hierarchy */ - snprintf ( undi->dev.name, sizeof ( undi->dev.name ), - "UNDI-%s", pci->dev.name ); - memcpy ( &undi->dev.desc, &pci->dev.desc, sizeof ( undi->dev.desc ) ); - undi->dev.parent = &pci->dev; - INIT_LIST_HEAD ( &undi->dev.children ); - list_add ( &undi->dev.siblings, &pci->dev.children ); - - /* Create network device */ - if ( ( rc = undinet_probe ( undi ) ) != 0 ) - goto err_undinet_probe; - - return 0; - - err_undinet_probe: - undi_unload ( undi ); - list_del ( &undi->dev.siblings ); - err_find_rom: - err_load_pci: - free ( undi ); - pci_set_drvdata ( pci, NULL ); - return rc; -} - -/** - * Remove PCI device - * - * @v pci PCI device - */ -static void undipci_remove ( struct pci_device *pci ) { - struct undi_device *undi = pci_get_drvdata ( pci ); - - undinet_remove ( undi ); - undi_unload ( undi ); - list_del ( &undi->dev.siblings ); - free ( undi ); - pci_set_drvdata ( pci, NULL ); -} - -static struct pci_device_id undipci_nics[] = { - PCI_ROM ( 0xffff, 0xffff, "undipci", "UNDI (PCI)", 0 ), -}; - -struct pci_driver undipci_driver __pci_driver_fallback = { - .ids = undipci_nics, - .id_count = ( sizeof ( undipci_nics ) / sizeof ( undipci_nics[0] ) ), - .class = PCI_CLASS_ID ( PCI_CLASS_NETWORK, PCI_ANY_ID, PCI_ANY_ID ), - .probe = undipci_probe, - .remove = undipci_remove, -}; diff --git a/qemu/roms/ipxe/src/arch/i386/drivers/net/undiisr.S b/qemu/roms/ipxe/src/arch/i386/drivers/net/undiisr.S deleted file mode 100644 index b27effe1d..000000000 --- a/qemu/roms/ipxe/src/arch/i386/drivers/net/undiisr.S +++ /dev/null @@ -1,87 +0,0 @@ -FILE_LICENCE ( GPL2_OR_LATER ) - -#define PXENV_UNDI_ISR 0x0014 -#define PXENV_UNDI_ISR_IN_START 1 -#define PXENV_UNDI_ISR_OUT_OURS 0 -#define PXENV_UNDI_ISR_OUT_NOT_OURS 1 - -#define IRQ_PIC_CUTOFF 8 -#define ICR_EOI_NON_SPECIFIC 0x20 -#define PIC1_ICR 0x20 -#define PIC2_ICR 0xa0 - - .text - .arch i386 - .code16 - - .section ".text16", "ax", @progbits - .globl undiisr -undiisr: - - /* Preserve registers */ - pushw %ds - pushw %es - pushw %fs - pushw %gs - pushfl - pushal - - /* Set up our segment registers */ - movw %cs:rm_ds, %ax - movw %ax, %ds - - /* Check that we have an UNDI entry point */ - cmpw $0, pxeparent_entry_point - je chain - - /* Issue UNDI API call */ - movw %ax, %es - movw $undinet_params, %di - movw $PXENV_UNDI_ISR, %bx - movw $PXENV_UNDI_ISR_IN_START, funcflag - pushw %es - pushw %di - pushw %bx - lcall *pxeparent_entry_point - cli /* Just in case */ - addw $6, %sp - cmpw $PXENV_UNDI_ISR_OUT_OURS, funcflag - jne eoi - -trig: /* Record interrupt occurence */ - incb undiisr_trigger_count - -eoi: /* Send EOI */ - movb $ICR_EOI_NON_SPECIFIC, %al - cmpb $IRQ_PIC_CUTOFF, undiisr_irq - jb 1f - outb %al, $PIC2_ICR -1: outb %al, $PIC1_ICR - jmp exit - -chain: /* Chain to next handler */ - pushfw - lcall *undiisr_next_handler - -exit: /* Restore registers and return */ - cli - popal - movzwl %sp, %esp - addr32 movl -20(%esp), %esp /* %esp isn't restored by popal */ - popfl - popw %gs - popw %fs - popw %es - popw %ds - iret - - .section ".data16", "aw", @progbits -undinet_params: -status: .word 0 -funcflag: .word 0 -bufferlength: .word 0 -framelength: .word 0 -frameheaderlength: .word 0 -frame: .word 0, 0 -prottype: .byte 0 -pkttype: .byte 0 diff --git a/qemu/roms/ipxe/src/arch/i386/drivers/net/undiload.c b/qemu/roms/ipxe/src/arch/i386/drivers/net/undiload.c deleted file mode 100644 index 7160ee384..000000000 --- a/qemu/roms/ipxe/src/arch/i386/drivers/net/undiload.c +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 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 <string.h> -#include <pxe.h> -#include <realmode.h> -#include <bios.h> -#include <pnpbios.h> -#include <basemem.h> -#include <ipxe/pci.h> -#include <undi.h> -#include <undirom.h> -#include <undiload.h> - -/** @file - * - * UNDI load/unload - * - */ - -/* Disambiguate the various error causes */ -#define EINFO_EUNDILOAD \ - __einfo_uniqify ( EINFO_EPLATFORM, 0x01, \ - "UNDI loader error" ) -#define EUNDILOAD( status ) EPLATFORM ( EINFO_EUNDILOAD, status ) - -/** Parameter block for calling UNDI loader */ -static struct s_UNDI_LOADER __bss16 ( undi_loader ); -#define undi_loader __use_data16 ( undi_loader ) - -/** UNDI loader entry point */ -static SEGOFF16_t __bss16 ( undi_loader_entry ); -#define undi_loader_entry __use_data16 ( undi_loader_entry ) - -/** - * Call UNDI loader to create a pixie - * - * @v undi UNDI device - * @v undirom UNDI ROM - * @ret rc Return status code - */ -int undi_load ( struct undi_device *undi, struct undi_rom *undirom ) { - struct s_PXE ppxe; - unsigned int fbms_seg; - uint16_t exit; - int rc; - - /* Only one UNDI instance may be loaded at any given time */ - if ( undi_loader_entry.segment ) { - DBG ( "UNDI %p cannot load multiple instances\n", undi ); - return -EBUSY; - } - - /* Set up START_UNDI parameters */ - memset ( &undi_loader, 0, sizeof ( undi_loader ) ); - undi_loader.AX = undi->pci_busdevfn; - undi_loader.BX = undi->isapnp_csn; - undi_loader.DX = undi->isapnp_read_port; - undi_loader.ES = BIOS_SEG; - undi_loader.DI = find_pnp_bios(); - - /* Allocate base memory for PXE stack */ - undi->restore_fbms = get_fbms(); - fbms_seg = ( undi->restore_fbms << 6 ); - fbms_seg -= ( ( undirom->code_size + 0x0f ) >> 4 ); - undi_loader.UNDI_CS = fbms_seg; - fbms_seg -= ( ( undirom->data_size + 0x0f ) >> 4 ); - undi_loader.UNDI_DS = fbms_seg; - - /* Debug info */ - DBGC ( undi, "UNDI %p loading UNDI ROM %p to CS %04x DS %04x for ", - undi, undirom, undi_loader.UNDI_CS, undi_loader.UNDI_DS ); - if ( undi->pci_busdevfn != UNDI_NO_PCI_BUSDEVFN ) { - unsigned int bus = ( undi->pci_busdevfn >> 8 ); - unsigned int devfn = ( undi->pci_busdevfn & 0xff ); - DBGC ( undi, "PCI %02x:%02x.%x\n", - bus, PCI_SLOT ( devfn ), PCI_FUNC ( devfn ) ); - } - if ( undi->isapnp_csn != UNDI_NO_ISAPNP_CSN ) { - DBGC ( undi, "ISAPnP(%04x) CSN %04x\n", - undi->isapnp_read_port, undi->isapnp_csn ); - } - - /* Call loader */ - undi_loader_entry = undirom->loader_entry; - __asm__ __volatile__ ( REAL_CODE ( "pushl %%ebp\n\t" /* gcc bug */ - "pushw %%ds\n\t" - "pushw %%ax\n\t" - "lcall *undi_loader_entry\n\t" - "popl %%ebp\n\t" /* discard */ - "popl %%ebp\n\t" /* gcc bug */ ) - : "=a" ( exit ) - : "a" ( __from_data16 ( &undi_loader ) ) - : "ebx", "ecx", "edx", "esi", "edi" ); - - if ( exit != PXENV_EXIT_SUCCESS ) { - /* Clear entry point */ - memset ( &undi_loader_entry, 0, sizeof ( undi_loader_entry ) ); - - rc = -EUNDILOAD ( undi_loader.Status ); - DBGC ( undi, "UNDI %p loader failed: %s\n", - undi, strerror ( rc ) ); - return rc; - } - - /* Populate PXE device structure */ - undi->pxenv = undi_loader.PXENVptr; - undi->ppxe = undi_loader.PXEptr; - copy_from_real ( &ppxe, undi->ppxe.segment, undi->ppxe.offset, - sizeof ( ppxe ) ); - undi->entry = ppxe.EntryPointSP; - DBGC ( undi, "UNDI %p loaded PXENV+ %04x:%04x !PXE %04x:%04x " - "entry %04x:%04x\n", undi, undi->pxenv.segment, - undi->pxenv.offset, undi->ppxe.segment, undi->ppxe.offset, - undi->entry.segment, undi->entry.offset ); - - /* Update free base memory counter */ - undi->fbms = ( fbms_seg >> 6 ); - set_fbms ( undi->fbms ); - DBGC ( undi, "UNDI %p using [%d,%d) kB of base memory\n", - undi, undi->fbms, undi->restore_fbms ); - - return 0; -} - -/** - * Unload a pixie - * - * @v undi UNDI device - * @ret rc Return status code - * - * Erases the PXENV+ and !PXE signatures, and frees the used base - * memory (if possible). - */ -int undi_unload ( struct undi_device *undi ) { - static uint32_t dead = 0xdeaddead; - - DBGC ( undi, "UNDI %p unloading\n", undi ); - - /* Clear entry point */ - memset ( &undi_loader_entry, 0, sizeof ( undi_loader_entry ) ); - - /* Erase signatures */ - if ( undi->pxenv.segment ) - put_real ( dead, undi->pxenv.segment, undi->pxenv.offset ); - if ( undi->ppxe.segment ) - put_real ( dead, undi->ppxe.segment, undi->ppxe.offset ); - - /* Free base memory, if possible */ - if ( undi->fbms == get_fbms() ) { - DBGC ( undi, "UNDI %p freeing [%d,%d) kB of base memory\n", - undi, undi->fbms, undi->restore_fbms ); - set_fbms ( undi->restore_fbms ); - return 0; - } else { - DBGC ( undi, "UNDI %p leaking [%d,%d) kB of base memory\n", - undi, undi->fbms, undi->restore_fbms ); - return -EBUSY; - } -} diff --git a/qemu/roms/ipxe/src/arch/i386/drivers/net/undinet.c b/qemu/roms/ipxe/src/arch/i386/drivers/net/undinet.c deleted file mode 100644 index 6450665ff..000000000 --- a/qemu/roms/ipxe/src/arch/i386/drivers/net/undinet.c +++ /dev/null @@ -1,822 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -FILE_LICENCE ( GPL2_OR_LATER ); - -#include <string.h> -#include <unistd.h> -#include <byteswap.h> -#include <pxe.h> -#include <realmode.h> -#include <pic8259.h> -#include <biosint.h> -#include <pnpbios.h> -#include <basemem_packet.h> -#include <ipxe/io.h> -#include <ipxe/iobuf.h> -#include <ipxe/netdevice.h> -#include <ipxe/if_ether.h> -#include <ipxe/ethernet.h> -#include <ipxe/profile.h> -#include <undi.h> -#include <undinet.h> -#include <pxeparent.h> - -/** @file - * - * UNDI network device driver - * - */ - -/** An UNDI NIC */ -struct undi_nic { - /** Device supports IRQs */ - int irq_supported; - /** Assigned IRQ number */ - unsigned int irq; - /** Currently processing ISR */ - int isr_processing; - /** Bug workarounds */ - int hacks; -}; - -/** - * @defgroup undi_hacks UNDI workarounds - * @{ - */ - -/** Work around Etherboot 5.4 bugs */ -#define UNDI_HACK_EB54 0x0001 - -/** @} */ - -/** Maximum number of times to retry PXENV_UNDI_INITIALIZE */ -#define UNDI_INITIALIZE_RETRY_MAX 10 - -/** Delay between retries of PXENV_UNDI_INITIALIZE */ -#define UNDI_INITIALIZE_RETRY_DELAY_MS 200 - -/** Maximum number of received packets per poll */ -#define UNDI_RX_QUOTA 4 - -/** Alignment of received frame payload */ -#define UNDI_RX_ALIGN 16 - -static void undinet_close ( struct net_device *netdev ); - -/** Address of UNDI entry point */ -static SEGOFF16_t undinet_entry; - -/** Transmit profiler */ -static struct profiler undinet_tx_profiler __profiler = - { .name = "undinet.tx" }; - -/** Transmit call profiler */ -static struct profiler undinet_tx_call_profiler __profiler = - { .name = "undinet.tx_call" }; - -/** IRQ profiler */ -static struct profiler undinet_irq_profiler __profiler = - { .name = "undinet.irq" }; - -/** ISR call profiler */ -static struct profiler undinet_isr_call_profiler __profiler = - { .name = "undinet.isr_call" }; - -/** Receive profiler */ -static struct profiler undinet_rx_profiler __profiler = - { .name = "undinet.rx" }; - -/***************************************************************************** - * - * UNDI interrupt service routine - * - ***************************************************************************** - */ - -/** - * UNDI interrupt service routine - * - * The UNDI ISR increments a counter (@c trigger_count) and exits. - */ -extern void undiisr ( void ); - -/** IRQ number */ -uint8_t __data16 ( undiisr_irq ); -#define undiisr_irq __use_data16 ( undiisr_irq ) - -/** IRQ chain vector */ -struct segoff __data16 ( undiisr_next_handler ); -#define undiisr_next_handler __use_data16 ( undiisr_next_handler ) - -/** IRQ trigger count */ -volatile uint8_t __data16 ( undiisr_trigger_count ) = 0; -#define undiisr_trigger_count __use_data16 ( undiisr_trigger_count ) - -/** Last observed trigger count */ -static unsigned int last_trigger_count = 0; - -/** - * Hook UNDI interrupt service routine - * - * @v irq IRQ number - */ -static void undinet_hook_isr ( unsigned int irq ) { - - assert ( irq <= IRQ_MAX ); - assert ( undiisr_irq == 0 ); - - undiisr_irq = irq; - hook_bios_interrupt ( IRQ_INT ( irq ), - ( ( unsigned int ) undiisr ), - &undiisr_next_handler ); -} - -/** - * Unhook UNDI interrupt service routine - * - * @v irq IRQ number - */ -static void undinet_unhook_isr ( unsigned int irq ) { - - assert ( irq <= IRQ_MAX ); - - unhook_bios_interrupt ( IRQ_INT ( irq ), - ( ( unsigned int ) undiisr ), - &undiisr_next_handler ); - undiisr_irq = 0; -} - -/** - * Test to see if UNDI ISR has been triggered - * - * @ret triggered ISR has been triggered since last check - */ -static int undinet_isr_triggered ( void ) { - unsigned int this_trigger_count; - - /* Read trigger_count. Do this only once; it is volatile */ - this_trigger_count = undiisr_trigger_count; - - if ( this_trigger_count == last_trigger_count ) { - /* Not triggered */ - return 0; - } else { - /* Triggered */ - last_trigger_count = this_trigger_count; - return 1; - } -} - -/***************************************************************************** - * - * UNDI network device interface - * - ***************************************************************************** - */ - -/** UNDI transmit buffer descriptor */ -static struct s_PXENV_UNDI_TBD __data16 ( undinet_tbd ); -#define undinet_tbd __use_data16 ( undinet_tbd ) - -/** UNDI transmit destination address */ -static uint8_t __data16_array ( undinet_destaddr, [ETH_ALEN] ); -#define undinet_destaddr __use_data16 ( undinet_destaddr ) - -/** - * Transmit packet - * - * @v netdev Network device - * @v iobuf I/O buffer - * @ret rc Return status code - */ -static int undinet_transmit ( struct net_device *netdev, - struct io_buffer *iobuf ) { - struct undi_nic *undinic = netdev->priv; - struct s_PXENV_UNDI_TRANSMIT undi_transmit; - const void *ll_dest; - const void *ll_source; - uint16_t net_proto; - unsigned int flags; - uint8_t protocol; - size_t len; - int rc; - - /* Start profiling */ - profile_start ( &undinet_tx_profiler ); - - /* Technically, we ought to make sure that the previous - * transmission has completed before we re-use the buffer. - * However, many PXE stacks (including at least some Intel PXE - * stacks and Etherboot 5.4) fail to generate TX completions. - * In practice this won't be a problem, since our TX datapath - * has a very low packet volume and we can get away with - * assuming that a TX will be complete by the time we want to - * transmit the next packet. - */ - - /* Some PXE stacks are unable to cope with P_UNKNOWN, and will - * always try to prepend a link-layer header. Work around - * these stacks by stripping the existing link-layer header - * and allowing the PXE stack to (re)construct the link-layer - * header itself. - */ - if ( ( rc = eth_pull ( netdev, iobuf, &ll_dest, &ll_source, - &net_proto, &flags ) ) != 0 ) { - DBGC ( undinic, "UNDINIC %p could not strip Ethernet header: " - "%s\n", undinic, strerror ( rc ) ); - return rc; - } - memcpy ( undinet_destaddr, ll_dest, sizeof ( undinet_destaddr ) ); - switch ( net_proto ) { - case htons ( ETH_P_IP ) : - protocol = P_IP; - break; - case htons ( ETH_P_ARP ) : - protocol = P_ARP; - break; - case htons ( ETH_P_RARP ) : - protocol = P_RARP; - break; - default: - /* Unknown protocol; restore the original link-layer header */ - iob_push ( iobuf, sizeof ( struct ethhdr ) ); - protocol = P_UNKNOWN; - break; - } - - /* Copy packet to UNDI I/O buffer */ - len = iob_len ( iobuf ); - if ( len > sizeof ( basemem_packet ) ) - len = sizeof ( basemem_packet ); - memcpy ( &basemem_packet, iobuf->data, len ); - - /* Create PXENV_UNDI_TRANSMIT data structure */ - memset ( &undi_transmit, 0, sizeof ( undi_transmit ) ); - undi_transmit.Protocol = protocol; - undi_transmit.XmitFlag = ( ( flags & LL_BROADCAST ) ? - XMT_BROADCAST : XMT_DESTADDR ); - undi_transmit.DestAddr.segment = rm_ds; - undi_transmit.DestAddr.offset = __from_data16 ( &undinet_destaddr ); - undi_transmit.TBD.segment = rm_ds; - undi_transmit.TBD.offset = __from_data16 ( &undinet_tbd ); - - /* Create PXENV_UNDI_TBD data structure */ - undinet_tbd.ImmedLength = len; - undinet_tbd.Xmit.segment = rm_ds; - undinet_tbd.Xmit.offset = __from_data16 ( basemem_packet ); - - /* Issue PXE API call */ - profile_start ( &undinet_tx_call_profiler ); - if ( ( rc = pxeparent_call ( undinet_entry, PXENV_UNDI_TRANSMIT, - &undi_transmit, - sizeof ( undi_transmit ) ) ) != 0 ) - goto done; - profile_stop ( &undinet_tx_call_profiler ); - - /* Free I/O buffer */ - netdev_tx_complete ( netdev, iobuf ); - profile_stop ( &undinet_tx_profiler ); - done: - return rc; -} - -/** - * Poll for received packets - * - * @v netdev Network device - * - * Fun, fun, fun. UNDI drivers don't use polling; they use - * interrupts. We therefore cheat and pretend that an interrupt has - * occurred every time undinet_poll() is called. This isn't too much - * of a hack; PCI devices share IRQs and so the first thing that a - * proper ISR should do is call PXENV_UNDI_ISR to determine whether or - * not the UNDI NIC generated the interrupt; there is no harm done by - * spurious calls to PXENV_UNDI_ISR. Similarly, we wouldn't be - * handling them any more rapidly than the usual rate of - * undinet_poll() being called even if we did implement a full ISR. - * So it should work. Ha! - * - * Addendum (21/10/03). Some cards don't play nicely with this trick, - * so instead of doing it the easy way we have to go to all the hassle - * of installing a genuine interrupt service routine and dealing with - * the wonderful 8259 Programmable Interrupt Controller. Joy. - * - * Addendum (10/07/07). When doing things such as iSCSI boot, in - * which we have to co-operate with a running OS, we can't get away - * with the "ISR-just-increments-a-counter-and-returns" trick at all, - * because it involves tying up the PIC for far too long, and other - * interrupt-dependent components (e.g. local disks) start breaking. - * We therefore implement a "proper" ISR which calls PXENV_UNDI_ISR - * from within interrupt context in order to deassert the device - * interrupt, and sends EOI if applicable. - */ -static void undinet_poll ( struct net_device *netdev ) { - struct undi_nic *undinic = netdev->priv; - struct s_PXENV_UNDI_ISR undi_isr; - struct io_buffer *iobuf = NULL; - unsigned int quota = UNDI_RX_QUOTA; - size_t len; - size_t reserve_len; - size_t frag_len; - size_t max_frag_len; - int rc; - - if ( ! undinic->isr_processing ) { - /* Allow interrupt to occur. Do this even if - * interrupts are not known to be supported, since - * some cards erroneously report that they do not - * support interrupts. - */ - if ( ! undinet_isr_triggered() ) { - /* Allow interrupt to occur */ - profile_start ( &undinet_irq_profiler ); - __asm__ __volatile__ ( "sti\n\t" - "nop\n\t" - "nop\n\t" - "cli\n\t" ); - profile_stop ( &undinet_irq_profiler ); - - /* If interrupts are known to be supported, - * then do nothing on this poll; wait for the - * interrupt to be triggered. - */ - if ( undinic->irq_supported ) - return; - } - - /* Start ISR processing */ - undinic->isr_processing = 1; - undi_isr.FuncFlag = PXENV_UNDI_ISR_IN_PROCESS; - } else { - /* Continue ISR processing */ - undi_isr.FuncFlag = PXENV_UNDI_ISR_IN_GET_NEXT; - } - - /* Run through the ISR loop */ - while ( quota ) { - profile_start ( &undinet_isr_call_profiler ); - if ( ( rc = pxeparent_call ( undinet_entry, PXENV_UNDI_ISR, - &undi_isr, - sizeof ( undi_isr ) ) ) != 0 ) { - netdev_rx_err ( netdev, NULL, rc ); - break; - } - profile_stop ( &undinet_isr_call_profiler ); - switch ( undi_isr.FuncFlag ) { - case PXENV_UNDI_ISR_OUT_TRANSMIT: - /* We don't care about transmit completions */ - break; - case PXENV_UNDI_ISR_OUT_RECEIVE: - /* Packet fragment received */ - profile_start ( &undinet_rx_profiler ); - len = undi_isr.FrameLength; - frag_len = undi_isr.BufferLength; - reserve_len = ( -undi_isr.FrameHeaderLength & - ( UNDI_RX_ALIGN - 1 ) ); - if ( ( len == 0 ) || ( len < frag_len ) ) { - /* Don't laugh. VMWare does it. */ - DBGC ( undinic, "UNDINIC %p reported insane " - "fragment (%zd of %zd bytes)\n", - undinic, frag_len, len ); - netdev_rx_err ( netdev, NULL, -EINVAL ); - break; - } - if ( ! iobuf ) { - iobuf = alloc_iob ( reserve_len + len ); - if ( ! iobuf ) { - DBGC ( undinic, "UNDINIC %p could not " - "allocate %zd bytes for RX " - "buffer\n", undinic, len ); - /* Fragment will be dropped */ - netdev_rx_err ( netdev, NULL, -ENOMEM ); - goto done; - } - iob_reserve ( iobuf, reserve_len ); - } - max_frag_len = iob_tailroom ( iobuf ); - if ( frag_len > max_frag_len ) { - DBGC ( undinic, "UNDINIC %p fragment too big " - "(%zd+%zd does not fit into %zd)\n", - undinic, iob_len ( iobuf ), frag_len, - ( iob_len ( iobuf ) + max_frag_len ) ); - frag_len = max_frag_len; - } - copy_from_real ( iob_put ( iobuf, frag_len ), - undi_isr.Frame.segment, - undi_isr.Frame.offset, frag_len ); - if ( iob_len ( iobuf ) == len ) { - /* Whole packet received; deliver it */ - netdev_rx ( netdev, iob_disown ( iobuf ) ); - quota--; - /* Etherboot 5.4 fails to return all packets - * under mild load; pretend it retriggered. - */ - if ( undinic->hacks & UNDI_HACK_EB54 ) - --last_trigger_count; - } - profile_stop ( &undinet_rx_profiler ); - break; - case PXENV_UNDI_ISR_OUT_DONE: - /* Processing complete */ - undinic->isr_processing = 0; - goto done; - default: - /* Should never happen. VMWare does it routinely. */ - DBGC ( undinic, "UNDINIC %p ISR returned invalid " - "FuncFlag %04x\n", undinic, undi_isr.FuncFlag ); - undinic->isr_processing = 0; - goto done; - } - undi_isr.FuncFlag = PXENV_UNDI_ISR_IN_GET_NEXT; - } - - done: - if ( iobuf ) { - DBGC ( undinic, "UNDINIC %p returned incomplete packet " - "(%zd of %zd)\n", undinic, iob_len ( iobuf ), - ( iob_len ( iobuf ) + iob_tailroom ( iobuf ) ) ); - netdev_rx_err ( netdev, iobuf, -EINVAL ); - } -} - -/** - * Open NIC - * - * @v netdev Net device - * @ret rc Return status code - */ -static int undinet_open ( struct net_device *netdev ) { - struct undi_nic *undinic = netdev->priv; - struct s_PXENV_UNDI_SET_STATION_ADDRESS undi_set_address; - struct s_PXENV_UNDI_OPEN undi_open; - int rc; - - /* Hook interrupt service routine and enable interrupt if applicable */ - if ( undinic->irq ) { - undinet_hook_isr ( undinic->irq ); - enable_irq ( undinic->irq ); - send_eoi ( undinic->irq ); - } - - /* Set station address. Required for some PXE stacks; will - * spuriously fail on others. Ignore failures. We only ever - * use it to set the MAC address to the card's permanent value - * anyway. - */ - memcpy ( undi_set_address.StationAddress, netdev->ll_addr, - sizeof ( undi_set_address.StationAddress ) ); - pxeparent_call ( undinet_entry, PXENV_UNDI_SET_STATION_ADDRESS, - &undi_set_address, sizeof ( undi_set_address ) ); - - /* Open NIC. We ask for promiscuous operation, since it's the - * only way to ask for all multicast addresses. On any - * switched network, it shouldn't really make a difference to - * performance. - */ - memset ( &undi_open, 0, sizeof ( undi_open ) ); - undi_open.PktFilter = ( FLTR_DIRECTED | FLTR_BRDCST | FLTR_PRMSCS ); - if ( ( rc = pxeparent_call ( undinet_entry, PXENV_UNDI_OPEN, - &undi_open, sizeof ( undi_open ) ) ) != 0 ) - goto err; - - DBGC ( undinic, "UNDINIC %p opened\n", undinic ); - return 0; - - err: - undinet_close ( netdev ); - return rc; -} - -/** - * Close NIC - * - * @v netdev Net device - */ -static void undinet_close ( struct net_device *netdev ) { - struct undi_nic *undinic = netdev->priv; - struct s_PXENV_UNDI_ISR undi_isr; - struct s_PXENV_UNDI_CLOSE undi_close; - int rc; - - /* Ensure ISR has exited cleanly */ - while ( undinic->isr_processing ) { - undi_isr.FuncFlag = PXENV_UNDI_ISR_IN_GET_NEXT; - if ( ( rc = pxeparent_call ( undinet_entry, PXENV_UNDI_ISR, - &undi_isr, - sizeof ( undi_isr ) ) ) != 0 ) - break; - switch ( undi_isr.FuncFlag ) { - case PXENV_UNDI_ISR_OUT_TRANSMIT: - case PXENV_UNDI_ISR_OUT_RECEIVE: - /* Continue draining */ - break; - default: - /* Stop processing */ - undinic->isr_processing = 0; - break; - } - } - - /* Close NIC */ - pxeparent_call ( undinet_entry, PXENV_UNDI_CLOSE, - &undi_close, sizeof ( undi_close ) ); - - /* Disable interrupt and unhook ISR if applicable */ - if ( undinic->irq ) { - disable_irq ( undinic->irq ); - undinet_unhook_isr ( undinic->irq ); - } - - DBGC ( undinic, "UNDINIC %p closed\n", undinic ); -} - -/** - * Enable/disable interrupts - * - * @v netdev Net device - * @v enable Interrupts should be enabled - */ -static void undinet_irq ( struct net_device *netdev, int enable ) { - struct undi_nic *undinic = netdev->priv; - - /* Cannot support interrupts yet */ - DBGC ( undinic, "UNDINIC %p cannot %s interrupts\n", - undinic, ( enable ? "enable" : "disable" ) ); -} - -/** UNDI network device operations */ -static struct net_device_operations undinet_operations = { - .open = undinet_open, - .close = undinet_close, - .transmit = undinet_transmit, - .poll = undinet_poll, - .irq = undinet_irq, -}; - -/** A device with broken support for generating interrupts */ -struct undinet_irq_broken { - /** PCI vendor ID */ - uint16_t pci_vendor; - /** PCI device ID */ - uint16_t pci_device; -}; - -/** - * List of devices with broken support for generating interrupts - * - * Some PXE stacks are known to claim that IRQs are supported, but - * then never generate interrupts. No satisfactory solution has been - * found to this problem; the workaround is to add the PCI vendor and - * device IDs to this list. This is something of a hack, since it - * will generate false positives for identical devices with a working - * PXE stack (e.g. those that have been reflashed with iPXE), but it's - * an improvement on the current situation. - */ -static const struct undinet_irq_broken undinet_irq_broken_list[] = { - /* HP XX70x laptops */ - { .pci_vendor = 0x8086, .pci_device = 0x1502 }, - { .pci_vendor = 0x8086, .pci_device = 0x1503 }, -}; - -/** - * Check for devices with broken support for generating interrupts - * - * @v undi UNDI device - * @ret irq_is_broken Interrupt support is broken; no interrupts are generated - */ -static int undinet_irq_is_broken ( struct undi_device *undi ) { - const struct undinet_irq_broken *broken; - unsigned int i; - - for ( i = 0 ; i < ( sizeof ( undinet_irq_broken_list ) / - sizeof ( undinet_irq_broken_list[0] ) ) ; i++ ) { - broken = &undinet_irq_broken_list[i]; - if ( ( undi->dev.desc.bus_type == BUS_TYPE_PCI ) && - ( undi->dev.desc.vendor == broken->pci_vendor ) && - ( undi->dev.desc.device == broken->pci_device ) ) { - return 1; - } - } - return 0; -} - -/** - * Probe UNDI device - * - * @v undi UNDI device - * @ret rc Return status code - */ -int undinet_probe ( struct undi_device *undi ) { - struct net_device *netdev; - struct undi_nic *undinic; - struct s_PXENV_START_UNDI start_undi; - struct s_PXENV_UNDI_STARTUP undi_startup; - struct s_PXENV_UNDI_INITIALIZE undi_init; - struct s_PXENV_UNDI_GET_INFORMATION undi_info; - struct s_PXENV_UNDI_GET_IFACE_INFO undi_iface; - struct s_PXENV_UNDI_SHUTDOWN undi_shutdown; - struct s_PXENV_UNDI_CLEANUP undi_cleanup; - struct s_PXENV_STOP_UNDI stop_undi; - unsigned int retry; - int rc; - - /* Allocate net device */ - netdev = alloc_etherdev ( sizeof ( *undinic ) ); - if ( ! netdev ) - return -ENOMEM; - netdev_init ( netdev, &undinet_operations ); - undinic = netdev->priv; - undi_set_drvdata ( undi, netdev ); - netdev->dev = &undi->dev; - memset ( undinic, 0, sizeof ( *undinic ) ); - undinet_entry = undi->entry; - DBGC ( undinic, "UNDINIC %p using UNDI %p\n", undinic, undi ); - - /* Hook in UNDI stack */ - if ( ! ( undi->flags & UNDI_FL_STARTED ) ) { - memset ( &start_undi, 0, sizeof ( start_undi ) ); - start_undi.AX = undi->pci_busdevfn; - start_undi.BX = undi->isapnp_csn; - start_undi.DX = undi->isapnp_read_port; - start_undi.ES = BIOS_SEG; - start_undi.DI = find_pnp_bios(); - if ( ( rc = pxeparent_call ( undinet_entry, PXENV_START_UNDI, - &start_undi, - sizeof ( start_undi ) ) ) != 0 ) - goto err_start_undi; - } - undi->flags |= UNDI_FL_STARTED; - - /* Bring up UNDI stack */ - if ( ! ( undi->flags & UNDI_FL_INITIALIZED ) ) { - memset ( &undi_startup, 0, sizeof ( undi_startup ) ); - if ( ( rc = pxeparent_call ( undinet_entry, PXENV_UNDI_STARTUP, - &undi_startup, - sizeof ( undi_startup ) ) ) != 0 ) - goto err_undi_startup; - /* On some PXE stacks, PXENV_UNDI_INITIALIZE may fail - * due to a transient condition (e.g. media test - * failing because the link has only just come out of - * reset). We may therefore need to retry this call - * several times. - */ - for ( retry = 0 ; ; ) { - memset ( &undi_init, 0, sizeof ( undi_init ) ); - if ( ( rc = pxeparent_call ( undinet_entry, - PXENV_UNDI_INITIALIZE, - &undi_init, - sizeof ( undi_init ))) ==0) - break; - if ( ++retry > UNDI_INITIALIZE_RETRY_MAX ) - goto err_undi_initialize; - DBGC ( undinic, "UNDINIC %p retrying " - "PXENV_UNDI_INITIALIZE (retry %d)\n", - undinic, retry ); - /* Delay to allow link to settle if necessary */ - mdelay ( UNDI_INITIALIZE_RETRY_DELAY_MS ); - } - } - undi->flags |= UNDI_FL_INITIALIZED; - - /* Get device information */ - memset ( &undi_info, 0, sizeof ( undi_info ) ); - if ( ( rc = pxeparent_call ( undinet_entry, PXENV_UNDI_GET_INFORMATION, - &undi_info, sizeof ( undi_info ) ) ) != 0 ) - goto err_undi_get_information; - memcpy ( netdev->hw_addr, undi_info.PermNodeAddress, ETH_ALEN ); - memcpy ( netdev->ll_addr, undi_info.CurrentNodeAddress, ETH_ALEN ); - undinic->irq = undi_info.IntNumber; - if ( undinic->irq > IRQ_MAX ) { - DBGC ( undinic, "UNDINIC %p has invalid IRQ %d\n", - undinic, undinic->irq ); - rc = -EINVAL; - goto err_bad_irq; - } - DBGC ( undinic, "UNDINIC %p has MAC address %s and IRQ %d\n", - undinic, eth_ntoa ( netdev->hw_addr ), undinic->irq ); - - /* Get interface information */ - memset ( &undi_iface, 0, sizeof ( undi_iface ) ); - if ( ( rc = pxeparent_call ( undinet_entry, PXENV_UNDI_GET_IFACE_INFO, - &undi_iface, - sizeof ( undi_iface ) ) ) != 0 ) - goto err_undi_get_iface_info; - DBGC ( undinic, "UNDINIC %p has type %s, speed %d, flags %08x\n", - undinic, undi_iface.IfaceType, undi_iface.LinkSpeed, - undi_iface.ServiceFlags ); - if ( ( undi_iface.ServiceFlags & SUPPORTED_IRQ ) && - ( undinic->irq != 0 ) ) { - undinic->irq_supported = 1; - } - DBGC ( undinic, "UNDINIC %p using %s mode\n", undinic, - ( undinic->irq_supported ? "interrupt" : "polling" ) ); - if ( strncmp ( ( ( char * ) undi_iface.IfaceType ), "Etherboot", - sizeof ( undi_iface.IfaceType ) ) == 0 ) { - DBGC ( undinic, "UNDINIC %p Etherboot 5.4 workaround enabled\n", - undinic ); - undinic->hacks |= UNDI_HACK_EB54; - } - if ( undinet_irq_is_broken ( undi ) ) { - DBGC ( undinic, "UNDINIC %p forcing polling mode due to " - "broken interrupts\n", undinic ); - undinic->irq_supported = 0; - } - - /* Register network device */ - if ( ( rc = register_netdev ( netdev ) ) != 0 ) - goto err_register; - - /* Mark as link up; we don't handle link state */ - netdev_link_up ( netdev ); - - DBGC ( undinic, "UNDINIC %p added\n", undinic ); - return 0; - - err_register: - err_undi_get_iface_info: - err_bad_irq: - err_undi_get_information: - err_undi_initialize: - /* Shut down UNDI stack */ - memset ( &undi_shutdown, 0, sizeof ( undi_shutdown ) ); - pxeparent_call ( undinet_entry, PXENV_UNDI_SHUTDOWN, &undi_shutdown, - sizeof ( undi_shutdown ) ); - memset ( &undi_cleanup, 0, sizeof ( undi_cleanup ) ); - pxeparent_call ( undinet_entry, PXENV_UNDI_CLEANUP, &undi_cleanup, - sizeof ( undi_cleanup ) ); - undi->flags &= ~UNDI_FL_INITIALIZED; - err_undi_startup: - /* Unhook UNDI stack */ - memset ( &stop_undi, 0, sizeof ( stop_undi ) ); - pxeparent_call ( undinet_entry, PXENV_STOP_UNDI, &stop_undi, - sizeof ( stop_undi ) ); - undi->flags &= ~UNDI_FL_STARTED; - err_start_undi: - netdev_nullify ( netdev ); - netdev_put ( netdev ); - undi_set_drvdata ( undi, NULL ); - return rc; -} - -/** - * Remove UNDI device - * - * @v undi UNDI device - */ -void undinet_remove ( struct undi_device *undi ) { - struct net_device *netdev = undi_get_drvdata ( undi ); - struct undi_nic *undinic = netdev->priv; - struct s_PXENV_UNDI_SHUTDOWN undi_shutdown; - struct s_PXENV_UNDI_CLEANUP undi_cleanup; - struct s_PXENV_STOP_UNDI stop_undi; - - /* Unregister net device */ - unregister_netdev ( netdev ); - - /* If we are preparing for an OS boot, or if we cannot exit - * via the PXE stack, then shut down the PXE stack. - */ - if ( ! ( undi->flags & UNDI_FL_KEEP_ALL ) ) { - - /* Shut down UNDI stack */ - memset ( &undi_shutdown, 0, sizeof ( undi_shutdown ) ); - pxeparent_call ( undinet_entry, PXENV_UNDI_SHUTDOWN, - &undi_shutdown, sizeof ( undi_shutdown ) ); - memset ( &undi_cleanup, 0, sizeof ( undi_cleanup ) ); - pxeparent_call ( undinet_entry, PXENV_UNDI_CLEANUP, - &undi_cleanup, sizeof ( undi_cleanup ) ); - undi->flags &= ~UNDI_FL_INITIALIZED; - - /* Unhook UNDI stack */ - memset ( &stop_undi, 0, sizeof ( stop_undi ) ); - pxeparent_call ( undinet_entry, PXENV_STOP_UNDI, &stop_undi, - sizeof ( stop_undi ) ); - undi->flags &= ~UNDI_FL_STARTED; - } - - /* Clear entry point */ - memset ( &undinet_entry, 0, sizeof ( undinet_entry ) ); - - /* Free network device */ - netdev_nullify ( netdev ); - netdev_put ( netdev ); - - DBGC ( undinic, "UNDINIC %p removed\n", undinic ); -} diff --git a/qemu/roms/ipxe/src/arch/i386/drivers/net/undionly.c b/qemu/roms/ipxe/src/arch/i386/drivers/net/undionly.c deleted file mode 100644 index 70dbe4bfd..000000000 --- a/qemu/roms/ipxe/src/arch/i386/drivers/net/undionly.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 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 <stdio.h> -#include <string.h> -#include <ipxe/device.h> -#include <ipxe/init.h> -#include <ipxe/pci.h> -#include <undi.h> -#include <undinet.h> -#include <undipreload.h> - -/** @file - * - * "Pure" UNDI driver - * - * This is the UNDI driver without explicit support for PCI or any - * other bus type. It is capable only of using the preloaded UNDI - * device. It must not be combined in an image with any other - * drivers. - * - * If you want a PXE-loadable image that contains only the UNDI - * driver, build "bin/undionly.kpxe". - * - * If you want any other image format, or any other drivers in - * addition to the UNDI driver, build e.g. "bin/undi.dsk". - */ - -/** - * Probe UNDI root bus - * - * @v rootdev UNDI bus root device - * - * Scans the UNDI bus for devices and registers all devices it can - * find. - */ -static int undibus_probe ( struct root_device *rootdev ) { - struct undi_device *undi = &preloaded_undi; - int rc; - - /* Check for a valie preloaded UNDI device */ - if ( ! undi->entry.segment ) { - DBG ( "No preloaded UNDI device found!\n" ); - return -ENODEV; - } - - /* Add to device hierarchy */ - undi->dev.driver_name = "undionly"; - if ( undi->pci_busdevfn != UNDI_NO_PCI_BUSDEVFN ) { - undi->dev.desc.bus_type = BUS_TYPE_PCI; - undi->dev.desc.location = undi->pci_busdevfn; - undi->dev.desc.vendor = undi->pci_vendor; - undi->dev.desc.device = undi->pci_device; - snprintf ( undi->dev.name, sizeof ( undi->dev.name ), - "UNDI-PCI%02x:%02x.%x", - PCI_BUS ( undi->pci_busdevfn ), - PCI_SLOT ( undi->pci_busdevfn ), - PCI_FUNC ( undi->pci_busdevfn ) ); - } else if ( undi->isapnp_csn != UNDI_NO_ISAPNP_CSN ) { - undi->dev.desc.bus_type = BUS_TYPE_ISAPNP; - snprintf ( undi->dev.name, sizeof ( undi->dev.name ), - "UNDI-ISAPNP" ); - } - undi->dev.parent = &rootdev->dev; - list_add ( &undi->dev.siblings, &rootdev->dev.children); - INIT_LIST_HEAD ( &undi->dev.children ); - - /* Create network device */ - if ( ( rc = undinet_probe ( undi ) ) != 0 ) - goto err; - - return 0; - - err: - list_del ( &undi->dev.siblings ); - return rc; -} - -/** - * Remove UNDI root bus - * - * @v rootdev UNDI bus root device - */ -static void undibus_remove ( struct root_device *rootdev __unused ) { - struct undi_device *undi = &preloaded_undi; - - undinet_remove ( undi ); - list_del ( &undi->dev.siblings ); -} - -/** UNDI bus root device driver */ -static struct root_driver undi_root_driver = { - .probe = undibus_probe, - .remove = undibus_remove, -}; - -/** UNDI bus root device */ -struct root_device undi_root_device __root_device = { - .dev = { .name = "UNDI" }, - .driver = &undi_root_driver, -}; - -/** - * Prepare for exit - * - * @v booting System is shutting down for OS boot - */ -static void undionly_shutdown ( int booting ) { - /* If we are shutting down to boot an OS, clear the "keep PXE - * stack" flag. - */ - if ( booting ) - preloaded_undi.flags &= ~UNDI_FL_KEEP_ALL; -} - -struct startup_fn startup_undionly __startup_fn ( STARTUP_LATE ) = { - .shutdown = undionly_shutdown, -}; diff --git a/qemu/roms/ipxe/src/arch/i386/drivers/net/undipreload.c b/qemu/roms/ipxe/src/arch/i386/drivers/net/undipreload.c deleted file mode 100644 index fca771843..000000000 --- a/qemu/roms/ipxe/src/arch/i386/drivers/net/undipreload.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 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 <realmode.h> -#include <undipreload.h> - -/** @file - * - * Preloaded UNDI stack - * - */ - -/** - * Preloaded UNDI device - * - * This is the UNDI device that was present when Etherboot started - * execution (i.e. when loading a .kpxe image). The first driver to - * claim this device must zero out this data structure. - */ -struct undi_device __data16 ( preloaded_undi ); diff --git a/qemu/roms/ipxe/src/arch/i386/drivers/net/undirom.c b/qemu/roms/ipxe/src/arch/i386/drivers/net/undirom.c deleted file mode 100644 index b54c6170f..000000000 --- a/qemu/roms/ipxe/src/arch/i386/drivers/net/undirom.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -FILE_LICENCE ( GPL2_OR_LATER ); - -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <pxe.h> -#include <realmode.h> -#include <undirom.h> - -/** @file - * - * UNDI expansion ROMs - * - */ - -/** List of all UNDI ROMs */ -static LIST_HEAD ( undiroms ); - -/** - * Parse PXE ROM ID structure - * - * @v undirom UNDI ROM - * @v pxeromid Offset within ROM to PXE ROM ID structure - * @ret rc Return status code - */ -static int undirom_parse_pxeromid ( struct undi_rom *undirom, - unsigned int pxeromid ) { - struct undi_rom_id undi_rom_id; - unsigned int undiloader; - - DBGC ( undirom, "UNDIROM %p has PXE ROM ID at %04x:%04x\n", undirom, - undirom->rom_segment, pxeromid ); - - /* Read PXE ROM ID structure and verify */ - copy_from_real ( &undi_rom_id, undirom->rom_segment, pxeromid, - sizeof ( undi_rom_id ) ); - if ( undi_rom_id.Signature != UNDI_ROM_ID_SIGNATURE ) { - DBGC ( undirom, "UNDIROM %p has bad PXE ROM ID signature " - "%08x\n", undirom, undi_rom_id.Signature ); - return -EINVAL; - } - - /* Check for UNDI loader */ - undiloader = undi_rom_id.UNDILoader; - if ( ! undiloader ) { - DBGC ( undirom, "UNDIROM %p has no UNDI loader\n", undirom ); - return -EINVAL; - } - - /* Fill in UNDI ROM loader fields */ - undirom->loader_entry.segment = undirom->rom_segment; - undirom->loader_entry.offset = undiloader; - undirom->code_size = undi_rom_id.CodeSize; - undirom->data_size = undi_rom_id.DataSize; - - DBGC ( undirom, "UNDIROM %p has UNDI loader at %04x:%04x " - "(code %04zx data %04zx)\n", undirom, - undirom->loader_entry.segment, undirom->loader_entry.offset, - undirom->code_size, undirom->data_size ); - return 0; -} - -/** - * Parse PCI expansion header - * - * @v undirom UNDI ROM - * @v pcirheader Offset within ROM to PCI expansion header - */ -static int undirom_parse_pcirheader ( struct undi_rom *undirom, - unsigned int pcirheader ) { - struct pcir_header pcir_header; - - DBGC ( undirom, "UNDIROM %p has PCI expansion header at %04x:%04x\n", - undirom, undirom->rom_segment, pcirheader ); - - /* Read PCI expansion header and verify */ - copy_from_real ( &pcir_header, undirom->rom_segment, pcirheader, - sizeof ( pcir_header ) ); - if ( pcir_header.signature != PCIR_SIGNATURE ) { - DBGC ( undirom, "UNDIROM %p has bad PCI expansion header " - "signature %08x\n", undirom, pcir_header.signature ); - return -EINVAL; - } - - /* Fill in UNDI ROM PCI device fields */ - undirom->bus_type = PCI_NIC; - undirom->bus_id.pci.vendor_id = pcir_header.vendor_id; - undirom->bus_id.pci.device_id = pcir_header.device_id; - - DBGC ( undirom, "UNDIROM %p is for PCI devices %04x:%04x\n", undirom, - undirom->bus_id.pci.vendor_id, undirom->bus_id.pci.device_id ); - return 0; - -} - -/** - * Probe UNDI ROM - * - * @v rom_segment ROM segment address - * @ret rc Return status code - */ -static int undirom_probe ( unsigned int rom_segment ) { - struct undi_rom *undirom = NULL; - struct undi_rom_header romheader; - size_t rom_len; - unsigned int pxeromid; - unsigned int pcirheader; - int rc; - - /* Read expansion ROM header and verify */ - copy_from_real ( &romheader, rom_segment, 0, sizeof ( romheader ) ); - if ( romheader.Signature != ROM_SIGNATURE ) { - rc = -EINVAL; - goto err; - } - rom_len = ( romheader.ROMLength * 512 ); - - /* Allocate memory for UNDI ROM */ - undirom = zalloc ( sizeof ( *undirom ) ); - if ( ! undirom ) { - DBG ( "Could not allocate UNDI ROM structure\n" ); - rc = -ENOMEM; - goto err; - } - DBGC ( undirom, "UNDIROM %p trying expansion ROM at %04x:0000 " - "(%zdkB)\n", undirom, rom_segment, ( rom_len / 1024 ) ); - undirom->rom_segment = rom_segment; - - /* Check for and parse PXE ROM ID */ - pxeromid = romheader.PXEROMID; - if ( ! pxeromid ) { - DBGC ( undirom, "UNDIROM %p has no PXE ROM ID\n", undirom ); - rc = -EINVAL; - goto err; - } - if ( pxeromid > rom_len ) { - DBGC ( undirom, "UNDIROM %p PXE ROM ID outside ROM\n", - undirom ); - rc = -EINVAL; - goto err; - } - if ( ( rc = undirom_parse_pxeromid ( undirom, pxeromid ) ) != 0 ) - goto err; - - /* Parse PCIR header, if present */ - pcirheader = romheader.PCIRHeader; - if ( pcirheader ) - undirom_parse_pcirheader ( undirom, pcirheader ); - - /* Add to UNDI ROM list and return */ - DBGC ( undirom, "UNDIROM %p registered\n", undirom ); - list_add ( &undirom->list, &undiroms ); - return 0; - - err: - free ( undirom ); - return rc; -} - -/** - * Create UNDI ROMs for all possible expansion ROMs - * - * @ret - */ -static void undirom_probe_all_roms ( void ) { - static int probed = 0; - unsigned int rom_segment; - - /* Perform probe only once */ - if ( probed ) - return; - - DBG ( "Scanning for PXE expansion ROMs\n" ); - - /* Scan through expansion ROM region at 512 byte intervals */ - for ( rom_segment = 0xc000 ; rom_segment < 0x10000 ; - rom_segment += 0x20 ) { - undirom_probe ( rom_segment ); - } - - probed = 1; -} - -/** - * Find UNDI ROM for PCI device - * - * @v vendor_id PCI vendor ID - * @v device_id PCI device ID - * @v rombase ROM base address, or 0 for any - * @ret undirom UNDI ROM, or NULL - */ -struct undi_rom * undirom_find_pci ( unsigned int vendor_id, - unsigned int device_id, - unsigned int rombase ) { - struct undi_rom *undirom; - - undirom_probe_all_roms(); - - list_for_each_entry ( undirom, &undiroms, list ) { - if ( undirom->bus_type != PCI_NIC ) - continue; - if ( undirom->bus_id.pci.vendor_id != vendor_id ) - continue; - if ( undirom->bus_id.pci.device_id != device_id ) - continue; - if ( rombase && ( ( undirom->rom_segment << 4 ) != rombase ) ) - continue; - DBGC ( undirom, "UNDIROM %p matched PCI %04x:%04x (%08x)\n", - undirom, vendor_id, device_id, rombase ); - return undirom; - } - - DBG ( "No UNDI ROM matched PCI %04x:%04x (%08x)\n", - vendor_id, device_id, rombase ); - return NULL; -} diff --git a/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/basemem.c b/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/basemem.c deleted file mode 100644 index 6a46081aa..000000000 --- a/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/basemem.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 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 <realmode.h> -#include <bios.h> -#include <basemem.h> -#include <ipxe/hidemem.h> - -/** @file - * - * Base memory allocation - * - */ - -/** - * Set the BIOS free base memory counter - * - * @v new_fbms New free base memory counter (in kB) - */ -void set_fbms ( unsigned int new_fbms ) { - uint16_t fbms = new_fbms; - - /* Update the BIOS memory counter */ - put_real ( fbms, BDA_SEG, BDA_FBMS ); - - /* Update our hidden memory region map */ - hide_basemem(); -} diff --git a/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/bios_console.c b/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/bios_console.c deleted file mode 100644 index 63413cdc1..000000000 --- a/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/bios_console.c +++ /dev/null @@ -1,395 +0,0 @@ -/* - * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 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 <assert.h> -#include <realmode.h> -#include <bios.h> -#include <ipxe/console.h> -#include <ipxe/ansiesc.h> -#include <ipxe/keymap.h> -#include <config/console.h> - -#define ATTR_BOLD 0x08 - -#define ATTR_FCOL_MASK 0x07 -#define ATTR_FCOL_BLACK 0x00 -#define ATTR_FCOL_BLUE 0x01 -#define ATTR_FCOL_GREEN 0x02 -#define ATTR_FCOL_CYAN 0x03 -#define ATTR_FCOL_RED 0x04 -#define ATTR_FCOL_MAGENTA 0x05 -#define ATTR_FCOL_YELLOW 0x06 -#define ATTR_FCOL_WHITE 0x07 - -#define ATTR_BLINK 0x80 - -#define ATTR_BCOL_MASK 0x70 -#define ATTR_BCOL_BLACK 0x00 -#define ATTR_BCOL_BLUE 0x10 -#define ATTR_BCOL_GREEN 0x20 -#define ATTR_BCOL_CYAN 0x30 -#define ATTR_BCOL_RED 0x40 -#define ATTR_BCOL_MAGENTA 0x50 -#define ATTR_BCOL_YELLOW 0x60 -#define ATTR_BCOL_WHITE 0x70 - -#define ATTR_DEFAULT ATTR_FCOL_WHITE - -/* Set default console usage if applicable */ -#if ! ( defined ( CONSOLE_PCBIOS ) && CONSOLE_EXPLICIT ( CONSOLE_PCBIOS ) ) -#undef CONSOLE_PCBIOS -#define CONSOLE_PCBIOS ( CONSOLE_USAGE_ALL & ~CONSOLE_USAGE_LOG ) -#endif - -/** Current character attribute */ -static unsigned int bios_attr = ATTR_DEFAULT; - -/** - * Handle ANSI CUP (cursor position) - * - * @v ctx ANSI escape sequence context - * @v count Parameter count - * @v params[0] Row (1 is top) - * @v params[1] Column (1 is left) - */ -static void bios_handle_cup ( struct ansiesc_context *ctx __unused, - unsigned int count __unused, int params[] ) { - int cx = ( params[1] - 1 ); - int cy = ( params[0] - 1 ); - - if ( cx < 0 ) - cx = 0; - if ( cy < 0 ) - cy = 0; - - __asm__ __volatile__ ( REAL_CODE ( "sti\n\t" - "int $0x10\n\t" - "cli\n\t" ) - : : "a" ( 0x0200 ), "b" ( 1 ), - "d" ( ( cy << 8 ) | cx ) ); -} - -/** - * Handle ANSI ED (erase in page) - * - * @v ctx ANSI escape sequence context - * @v count Parameter count - * @v params[0] Region to erase - */ -static void bios_handle_ed ( struct ansiesc_context *ctx __unused, - unsigned int count __unused, - int params[] __unused ) { - /* We assume that we always clear the whole screen */ - assert ( params[0] == ANSIESC_ED_ALL ); - - __asm__ __volatile__ ( REAL_CODE ( "sti\n\t" - "int $0x10\n\t" - "cli\n\t" ) - : : "a" ( 0x0600 ), "b" ( bios_attr << 8 ), - "c" ( 0 ), - "d" ( ( ( console_height - 1 ) << 8 ) | - ( console_width - 1 ) ) ); -} - -/** - * Handle ANSI SGR (set graphics rendition) - * - * @v ctx ANSI escape sequence context - * @v count Parameter count - * @v params List of graphic rendition aspects - */ -static void bios_handle_sgr ( struct ansiesc_context *ctx __unused, - unsigned int count, int params[] ) { - static const uint8_t bios_attr_fcols[10] = { - ATTR_FCOL_BLACK, ATTR_FCOL_RED, ATTR_FCOL_GREEN, - ATTR_FCOL_YELLOW, ATTR_FCOL_BLUE, ATTR_FCOL_MAGENTA, - ATTR_FCOL_CYAN, ATTR_FCOL_WHITE, - ATTR_FCOL_WHITE, ATTR_FCOL_WHITE /* defaults */ - }; - static const uint8_t bios_attr_bcols[10] = { - ATTR_BCOL_BLACK, ATTR_BCOL_RED, ATTR_BCOL_GREEN, - ATTR_BCOL_YELLOW, ATTR_BCOL_BLUE, ATTR_BCOL_MAGENTA, - ATTR_BCOL_CYAN, ATTR_BCOL_WHITE, - ATTR_BCOL_BLACK, ATTR_BCOL_BLACK /* defaults */ - }; - unsigned int i; - int aspect; - - for ( i = 0 ; i < count ; i++ ) { - aspect = params[i]; - if ( aspect == 0 ) { - bios_attr = ATTR_DEFAULT; - } else if ( aspect == 1 ) { - bios_attr |= ATTR_BOLD; - } else if ( aspect == 5 ) { - bios_attr |= ATTR_BLINK; - } else if ( aspect == 22 ) { - bios_attr &= ~ATTR_BOLD; - } else if ( aspect == 25 ) { - bios_attr &= ~ATTR_BLINK; - } else if ( ( aspect >= 30 ) && ( aspect <= 39 ) ) { - bios_attr &= ~ATTR_FCOL_MASK; - bios_attr |= bios_attr_fcols[ aspect - 30 ]; - } else if ( ( aspect >= 40 ) && ( aspect <= 49 ) ) { - bios_attr &= ~ATTR_BCOL_MASK; - bios_attr |= bios_attr_bcols[ aspect - 40 ]; - } - } -} - -/** - * Handle ANSI DECTCEM set (show cursor) - * - * @v ctx ANSI escape sequence context - * @v count Parameter count - * @v params List of graphic rendition aspects - */ -static void bios_handle_dectcem_set ( struct ansiesc_context *ctx __unused, - unsigned int count __unused, - int params[] __unused ) { - uint8_t height; - - /* Get character height */ - get_real ( height, BDA_SEG, BDA_CHAR_HEIGHT ); - - __asm__ __volatile__ ( REAL_CODE ( "sti\n\t" - "int $0x10\n\t" - "cli\n\t" ) - : : "a" ( 0x0100 ), - "c" ( ( ( height - 2 ) << 8 ) | - ( height - 1 ) ) ); -} - -/** - * Handle ANSI DECTCEM reset (hide cursor) - * - * @v ctx ANSI escape sequence context - * @v count Parameter count - * @v params List of graphic rendition aspects - */ -static void bios_handle_dectcem_reset ( struct ansiesc_context *ctx __unused, - unsigned int count __unused, - int params[] __unused ) { - - __asm__ __volatile__ ( REAL_CODE ( "sti\n\t" - "int $0x10\n\t" - "cli\n\t" ) - : : "a" ( 0x0100 ), "c" ( 0x2000 ) ); -} - -/** BIOS console ANSI escape sequence handlers */ -static struct ansiesc_handler bios_ansiesc_handlers[] = { - { ANSIESC_CUP, bios_handle_cup }, - { ANSIESC_ED, bios_handle_ed }, - { ANSIESC_SGR, bios_handle_sgr }, - { ANSIESC_DECTCEM_SET, bios_handle_dectcem_set }, - { ANSIESC_DECTCEM_RESET, bios_handle_dectcem_reset }, - { 0, NULL } -}; - -/** BIOS console ANSI escape sequence context */ -static struct ansiesc_context bios_ansiesc_ctx = { - .handlers = bios_ansiesc_handlers, -}; - -/** - * Print a character to BIOS console - * - * @v character Character to be printed - */ -static void bios_putchar ( int character ) { - int discard_a, discard_b, discard_c; - - /* Intercept ANSI escape sequences */ - character = ansiesc_process ( &bios_ansiesc_ctx, character ); - if ( character < 0 ) - return; - - /* Print character with attribute */ - __asm__ __volatile__ ( REAL_CODE ( "pushl %%ebp\n\t" /* gcc bug */ - "sti\n\t" - /* Skip non-printable characters */ - "cmpb $0x20, %%al\n\t" - "jb 1f\n\t" - /* Read attribute */ - "movb %%al, %%cl\n\t" - "movb $0x08, %%ah\n\t" - "int $0x10\n\t" - "xchgb %%al, %%cl\n\t" - /* Skip if attribute matches */ - "cmpb %%ah, %%bl\n\t" - "je 1f\n\t" - /* Set attribute */ - "movw $0x0001, %%cx\n\t" - "movb $0x09, %%ah\n\t" - "int $0x10\n\t" - "\n1:\n\t" - /* Print character */ - "xorw %%bx, %%bx\n\t" - "movb $0x0e, %%ah\n\t" - "int $0x10\n\t" - "cli\n\t" - "popl %%ebp\n\t" /* gcc bug */ ) - : "=a" ( discard_a ), "=b" ( discard_b ), - "=c" ( discard_c ) - : "a" ( character ), "b" ( bios_attr ) ); -} - -/** - * Pointer to current ANSI output sequence - * - * While we are in the middle of returning an ANSI sequence for a - * special key, this will point to the next character to return. When - * not in the middle of such a sequence, this will point to a NUL - * (note: not "will be NULL"). - */ -static const char *ansi_input = ""; - -/** A mapping from a BIOS scan code to an ANSI escape sequence */ -#define BIOS_KEY( key, ansi ) key ansi "\0" - -/** Mapping from BIOS scan codes to ANSI escape sequences */ -static const char ansi_sequences[] = { - BIOS_KEY ( "\x53", "[3~" ) /* Delete */ - BIOS_KEY ( "\x48", "[A" ) /* Up arrow */ - BIOS_KEY ( "\x50", "[B" ) /* Down arrow */ - BIOS_KEY ( "\x4b", "[D" ) /* Left arrow */ - BIOS_KEY ( "\x4d", "[C" ) /* Right arrow */ - BIOS_KEY ( "\x47", "[H" ) /* Home */ - BIOS_KEY ( "\x4f", "[F" ) /* End */ - BIOS_KEY ( "\x49", "[5~" ) /* Page up */ - BIOS_KEY ( "\x51", "[6~" ) /* Page down */ - BIOS_KEY ( "\x3f", "[15~" ) /* F5 */ - BIOS_KEY ( "\x40", "[17~" ) /* F6 */ - BIOS_KEY ( "\x41", "[18~" ) /* F7 */ - BIOS_KEY ( "\x42", "[19~" ) /* F8 (required for PXE) */ - BIOS_KEY ( "\x43", "[20~" ) /* F9 */ - BIOS_KEY ( "\x44", "[21~" ) /* F10 */ - BIOS_KEY ( "\x85", "[23~" ) /* F11 */ - BIOS_KEY ( "\x86", "[24~" ) /* F12 */ -}; - -/** - * Get ANSI escape sequence corresponding to BIOS scancode - * - * @v scancode BIOS scancode - * @ret ansi_seq ANSI escape sequence, if any, otherwise NULL - */ -static const char * scancode_to_ansi_seq ( unsigned int scancode ) { - const char *seq = ansi_sequences; - - while ( *seq ) { - if ( *(seq++) == ( ( char ) scancode ) ) - return seq; - seq += ( strlen ( seq ) + 1 ); - } - DBG ( "Unrecognised BIOS scancode %02x\n", scancode ); - return NULL; -} - -/** - * Map a key - * - * @v character Character read from console - * @ret character Mapped character - */ -static int bios_keymap ( unsigned int character ) { - struct key_mapping *mapping; - - for_each_table_entry ( mapping, KEYMAP ) { - if ( mapping->from == character ) - return mapping->to; - } - return character; -} - -/** - * Get character from BIOS console - * - * @ret character Character read from console - */ -static int bios_getchar ( void ) { - uint16_t keypress; - unsigned int character; - const char *ansi_seq; - - /* If we are mid-sequence, pass out the next byte */ - if ( ( character = *ansi_input ) ) { - ansi_input++; - return character; - } - - /* Read character from real BIOS console */ - __asm__ __volatile__ ( REAL_CODE ( "sti\n\t" - "int $0x16\n\t" - "cli\n\t" ) - : "=a" ( keypress ) : "a" ( 0x1000 ) ); - character = ( keypress & 0xff ); - - /* If it's a normal character, just map and return it */ - if ( character && ( character < 0x80 ) ) - return bios_keymap ( character ); - - /* Otherwise, check for a special key that we know about */ - if ( ( ansi_seq = scancode_to_ansi_seq ( keypress >> 8 ) ) ) { - /* Start of escape sequence: return ESC (0x1b) */ - ansi_input = ansi_seq; - return 0x1b; - } - - return 0; -} - -/** - * Check for character ready to read from BIOS console - * - * @ret True Character available to read - * @ret False No character available to read - */ -static int bios_iskey ( void ) { - unsigned int discard_a; - unsigned int flags; - - /* If we are mid-sequence, we are always ready */ - if ( *ansi_input ) - return 1; - - /* Otherwise check the real BIOS console */ - __asm__ __volatile__ ( REAL_CODE ( "sti\n\t" - "int $0x16\n\t" - "pushfw\n\t" - "popw %w0\n\t" - "cli\n\t" ) - : "=r" ( flags ), "=a" ( discard_a ) - : "a" ( 0x1100 ) ); - return ( ! ( flags & ZF ) ); -} - -struct console_driver bios_console __console_driver = { - .putchar = bios_putchar, - .getchar = bios_getchar, - .iskey = bios_iskey, - .usage = CONSOLE_PCBIOS, -}; diff --git a/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/e820mangler.S b/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/e820mangler.S deleted file mode 100644 index d5d97b482..000000000 --- a/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/e820mangler.S +++ /dev/null @@ -1,589 +0,0 @@ -/* - * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 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 ) - - .text - .arch i386 - .code16 - -#define SMAP 0x534d4150 - -/* Most documentation refers to the E820 buffer as being 20 bytes, and - * the API makes it perfectly legitimate to pass only a 20-byte buffer - * and expect to get valid data. However, some morons at ACPI decided - * to extend the data structure by adding an extra "extended - * attributes" field and by including critical information within this - * field, such as whether or not the region is enabled. A caller who - * passes in only a 20-byte buffer therefore risks getting very, very - * misleading information. - * - * I have personally witnessed an HP BIOS that returns a value of - * 0x0009 in the extended attributes field. If we don't pass this - * value through to the caller, 32-bit WinPE will die, usually with a - * PAGE_FAULT_IN_NONPAGED_AREA blue screen of death. - * - * Allow a ridiculously large maximum value (64 bytes) for the E820 - * buffer as a guard against insufficiently creative idiots in the - * future. - */ -#define E820MAXSIZE 64 - -/**************************************************************************** - * - * Allowed memory windows - * - * There are two ways to view this list. The first is as a list of - * (non-overlapping) allowed memory regions, sorted by increasing - * address. The second is as a list of (non-overlapping) hidden - * memory regions, again sorted by increasing address. The second - * view is offset by half an entry from the first: think about this - * for a moment and it should make sense. - * - * xxx_memory_window is used to indicate an "allowed region" - * structure, hidden_xxx_memory is used to indicate a "hidden region" - * structure. Each structure is 16 bytes in length. - * - **************************************************************************** - */ - .section ".data16", "aw", @progbits - .align 16 - .globl hidemem_base - .globl hidemem_umalloc - .globl hidemem_textdata -memory_windows: -base_memory_window: .long 0x00000000, 0x00000000 /* Start of memory */ - -hidemem_base: .long 0x000a0000, 0x00000000 /* Changes at runtime */ -ext_memory_window: .long 0x000a0000, 0x00000000 /* 640kB mark */ - -hidemem_umalloc: .long 0xffffffff, 0xffffffff /* Changes at runtime */ - .long 0xffffffff, 0xffffffff /* Changes at runtime */ - -hidemem_textdata: .long 0xffffffff, 0xffffffff /* Changes at runtime */ - .long 0xffffffff, 0xffffffff /* Changes at runtime */ - - .long 0xffffffff, 0xffffffff /* End of memory */ -memory_windows_end: - -/**************************************************************************** - * Truncate region to memory window - * - * Parameters: - * %edx:%eax Start of region - * %ecx:%ebx Length of region - * %si Memory window - * Returns: - * %edx:%eax Start of windowed region - * %ecx:%ebx Length of windowed region - **************************************************************************** - */ - .section ".text16", "ax", @progbits -window_region: - /* Convert (start,len) to (start, end) */ - addl %eax, %ebx - adcl %edx, %ecx - /* Truncate to window start */ - cmpl 4(%si), %edx - jne 1f - cmpl 0(%si), %eax -1: jae 2f - movl 4(%si), %edx - movl 0(%si), %eax -2: /* Truncate to window end */ - cmpl 12(%si), %ecx - jne 1f - cmpl 8(%si), %ebx -1: jbe 2f - movl 12(%si), %ecx - movl 8(%si), %ebx -2: /* Convert (start, end) back to (start, len) */ - subl %eax, %ebx - sbbl %edx, %ecx - /* If length is <0, set length to 0 */ - jae 1f - xorl %ebx, %ebx - xorl %ecx, %ecx - ret - .size window_region, . - window_region - -/**************************************************************************** - * Patch "memory above 1MB" figure - * - * Parameters: - * %ax Memory above 1MB, in 1kB blocks - * Returns: - * %ax Modified memory above 1M in 1kB blocks - **************************************************************************** - */ - .section ".text16", "ax", @progbits -patch_1m: - pushal - /* Convert to (start,len) format and call truncate */ - xorl %ecx, %ecx - movzwl %ax, %ebx - shll $10, %ebx - xorl %edx, %edx - movl $0x100000, %eax - movw $ext_memory_window, %si - call window_region - /* Convert back to "memory above 1MB" format and return via %ax */ - pushfw - shrl $10, %ebx - popfw - movw %sp, %bp - movw %bx, 28(%bp) - popal - ret - .size patch_1m, . - patch_1m - -/**************************************************************************** - * Patch "memory above 16MB" figure - * - * Parameters: - * %bx Memory above 16MB, in 64kB blocks - * Returns: - * %bx Modified memory above 16M in 64kB blocks - **************************************************************************** - */ - .section ".text16", "ax", @progbits -patch_16m: - pushal - /* Convert to (start,len) format and call truncate */ - xorl %ecx, %ecx - shll $16, %ebx - xorl %edx, %edx - movl $0x1000000, %eax - movw $ext_memory_window, %si - call window_region - /* Convert back to "memory above 16MB" format and return via %bx */ - pushfw - shrl $16, %ebx - popfw - movw %sp, %bp - movw %bx, 16(%bp) - popal - ret - .size patch_16m, . - patch_16m - -/**************************************************************************** - * Patch "memory between 1MB and 16MB" and "memory above 16MB" figures - * - * Parameters: - * %ax Memory between 1MB and 16MB, in 1kB blocks - * %bx Memory above 16MB, in 64kB blocks - * Returns: - * %ax Modified memory between 1MB and 16MB, in 1kB blocks - * %bx Modified memory above 16MB, in 64kB blocks - **************************************************************************** - */ - .section ".text16", "ax", @progbits -patch_1m_16m: - call patch_1m - call patch_16m - /* If 1M region is no longer full-length, kill off the 16M region */ - cmpw $( 15 * 1024 ), %ax - je 1f - xorw %bx, %bx -1: ret - .size patch_1m_16m, . - patch_1m_16m - -/**************************************************************************** - * Get underlying e820 memory region to underlying_e820 buffer - * - * Parameters: - * As for INT 15,e820 - * Returns: - * As for INT 15,e820 - * - * Wraps the underlying INT 15,e820 call so that the continuation - * value (%ebx) is a 16-bit simple sequence counter (with the high 16 - * bits ignored), and termination is always via CF=1 rather than - * %ebx=0. - * - **************************************************************************** - */ - .section ".text16", "ax", @progbits -get_underlying_e820: - - /* If the requested region is in the cache, return it */ - cmpw %bx, underlying_e820_index - jne 2f - pushw %di - pushw %si - movw $underlying_e820_cache, %si - cmpl underlying_e820_cache_size, %ecx - jbe 1f - movl underlying_e820_cache_size, %ecx -1: pushl %ecx - rep movsb - popl %ecx - popw %si - popw %di - incw %bx - movl %edx, %eax - clc - ret -2: - /* If the requested region is earlier than the cached region, - * invalidate the cache. - */ - cmpw %bx, underlying_e820_index - jbe 1f - movw $0xffff, underlying_e820_index -1: - /* If the cache is invalid, reset the underlying %ebx */ - cmpw $0xffff, underlying_e820_index - jne 1f - andl $0, underlying_e820_ebx -1: - /* If the cache is valid but the continuation value is zero, - * this means that the previous underlying call returned with - * %ebx=0. Return with CF=1 in this case. - */ - cmpw $0xffff, underlying_e820_index - je 1f - cmpl $0, underlying_e820_ebx - jne 1f - stc - ret -1: - /* Get the next region into the cache */ - pushl %eax - pushl %ebx - pushl %ecx - pushl %edx - pushl %esi /* Some implementations corrupt %esi, so we */ - pushl %edi /* preserve %esi, %edi and %ebp to be paranoid */ - pushl %ebp - pushw %es - pushw %ds - popw %es - movw $underlying_e820_cache, %di - cmpl $E820MAXSIZE, %ecx - jbe 1f - movl $E820MAXSIZE, %ecx -1: movl underlying_e820_ebx, %ebx - stc - pushfw - lcall *%cs:int15_vector - popw %es - popl %ebp - popl %edi - popl %esi - /* Check for error return from underlying e820 call */ - jc 2f /* CF set: error */ - cmpl $SMAP, %eax - je 3f /* 'SMAP' missing: error */ -2: /* An error occurred: return values returned by underlying e820 call */ - stc /* Force CF set if SMAP was missing */ - addr32 leal 16(%esp), %esp /* avoid changing other flags */ - ret -3: /* No error occurred */ - movl %ebx, underlying_e820_ebx - movl %ecx, underlying_e820_cache_size - popl %edx - popl %ecx - popl %ebx - popl %eax - /* Mark cache as containing this result */ - incw underlying_e820_index - - /* Loop until found */ - jmp get_underlying_e820 - .size get_underlying_e820, . - get_underlying_e820 - - .section ".data16", "aw", @progbits -underlying_e820_index: - .word 0xffff /* Initialise to an invalid value */ - .size underlying_e820_index, . - underlying_e820_index - - .section ".bss16", "aw", @nobits -underlying_e820_ebx: - .long 0 - .size underlying_e820_ebx, . - underlying_e820_ebx - - .section ".bss16", "aw", @nobits -underlying_e820_cache: - .space E820MAXSIZE - .size underlying_e820_cache, . - underlying_e820_cache - - .section ".bss16", "aw", @nobits -underlying_e820_cache_size: - .long 0 - .size underlying_e820_cache_size, . - underlying_e820_cache_size - -/**************************************************************************** - * Get windowed e820 region, without empty region stripping - * - * Parameters: - * As for INT 15,e820 - * Returns: - * As for INT 15,e820 - * - * Wraps the underlying INT 15,e820 call so that each underlying - * region is returned N times, windowed to fit within N visible-memory - * windows. Termination is always via CF=1. - * - **************************************************************************** - */ - .section ".text16", "ax", @progbits -get_windowed_e820: - - /* Preserve registers */ - pushl %esi - pushw %bp - - /* Split %ebx into %si:%bx, store original %bx in %bp */ - pushl %ebx - popw %bp - popw %si - - /* %si == 0 => start of memory_windows list */ - testw %si, %si - jne 1f - movw $memory_windows, %si -1: - /* Get (cached) underlying e820 region to buffer */ - call get_underlying_e820 - jc 99f /* Abort on error */ - - /* Preserve registers */ - pushal - /* start => %edx:%eax, len => %ecx:%ebx */ - movl %es:0(%di), %eax - movl %es:4(%di), %edx - movl %es:8(%di), %ebx - movl %es:12(%di), %ecx - /* Truncate region to current window */ - call window_region -1: /* Store modified values in e820 map entry */ - movl %eax, %es:0(%di) - movl %edx, %es:4(%di) - movl %ebx, %es:8(%di) - movl %ecx, %es:12(%di) - /* Restore registers */ - popal - - /* Derive continuation value for next call */ - addw $16, %si - cmpw $memory_windows_end, %si - jne 1f - /* End of memory windows: reset %si and allow %bx to continue */ - xorw %si, %si - jmp 2f -1: /* More memory windows to go: restore original %bx */ - movw %bp, %bx -2: /* Construct %ebx from %si:%bx */ - pushw %si - pushw %bx - popl %ebx - -98: /* Clear CF */ - clc -99: /* Restore registers and return */ - popw %bp - popl %esi - ret - .size get_windowed_e820, . - get_windowed_e820 - -/**************************************************************************** - * Get windowed e820 region, with empty region stripping - * - * Parameters: - * As for INT 15,e820 - * Returns: - * As for INT 15,e820 - * - * Wraps the underlying INT 15,e820 call so that each underlying - * region is returned up to N times, windowed to fit within N - * visible-memory windows. Empty windows are never returned. - * Termination is always via CF=1. - * - **************************************************************************** - */ - .section ".text16", "ax", @progbits -get_nonempty_e820: - - /* Record entry parameters */ - pushl %eax - pushl %ecx - pushl %edx - - /* Get next windowed region */ - call get_windowed_e820 - jc 99f /* abort on error */ - - /* If region is non-empty, finish here */ - cmpl $0, %es:8(%di) - jne 98f - cmpl $0, %es:12(%di) - jne 98f - - /* Region was empty: restore entry parameters and go to next region */ - popl %edx - popl %ecx - popl %eax - jmp get_nonempty_e820 - -98: /* Clear CF */ - clc -99: /* Return values from underlying call */ - addr32 leal 12(%esp), %esp /* avoid changing flags */ - ret - .size get_nonempty_e820, . - get_nonempty_e820 - -/**************************************************************************** - * Get mangled e820 region, with empty region stripping - * - * Parameters: - * As for INT 15,e820 - * Returns: - * As for INT 15,e820 - * - * Wraps the underlying INT 15,e820 call so that underlying regions - * are windowed to the allowed memory regions. Empty regions are - * stripped from the map. Termination is always via %ebx=0. - * - **************************************************************************** - */ - .section ".text16", "ax", @progbits -get_mangled_e820: - - /* Get a nonempty region */ - call get_nonempty_e820 - jc 99f /* Abort on error */ - - /* Peek ahead to see if there are any further nonempty regions */ - pushal - pushw %es - movw %sp, %bp - subw %cx, %sp - movl $0xe820, %eax - movl $SMAP, %edx - pushw %ss - popw %es - movw %sp, %di - call get_nonempty_e820 - movw %bp, %sp - popw %es - popal - jnc 99f /* There are further nonempty regions */ - - /* No futher nonempty regions: zero %ebx and clear CF */ - xorl %ebx, %ebx - -99: /* Return */ - ret - .size get_mangled_e820, . - get_mangled_e820 - -/**************************************************************************** - * INT 15,e820 handler - **************************************************************************** - */ - .section ".text16", "ax", @progbits -int15_e820: - pushw %ds - pushw %cs:rm_ds - popw %ds - call get_mangled_e820 - popw %ds - call patch_cf - iret - .size int15_e820, . - int15_e820 - -/**************************************************************************** - * INT 15,e801 handler - **************************************************************************** - */ - .section ".text16", "ax", @progbits -int15_e801: - /* Call previous handler */ - pushfw - lcall *%cs:int15_vector - call patch_cf - /* Edit result */ - pushw %ds - pushw %cs:rm_ds - popw %ds - call patch_1m_16m - xchgw %ax, %cx - xchgw %bx, %dx - call patch_1m_16m - xchgw %ax, %cx - xchgw %bx, %dx - popw %ds - iret - .size int15_e801, . - int15_e801 - -/**************************************************************************** - * INT 15,88 handler - **************************************************************************** - */ - .section ".text16", "ax", @progbits -int15_88: - /* Call previous handler */ - pushfw - lcall *%cs:int15_vector - call patch_cf - /* Edit result */ - pushw %ds - pushw %cs:rm_ds - popw %ds - call patch_1m - popw %ds - iret - .size int15_88, . - int15_88 - -/**************************************************************************** - * INT 15 handler - **************************************************************************** - */ - .section ".text16", "ax", @progbits - .globl int15 -int15: - /* See if we want to intercept this call */ - pushfw - cmpw $0xe820, %ax - jne 1f - cmpl $SMAP, %edx - jne 1f - popfw - jmp int15_e820 -1: cmpw $0xe801, %ax - jne 2f - popfw - jmp int15_e801 -2: cmpb $0x88, %ah - jne 3f - popfw - jmp int15_88 -3: popfw - ljmp *%cs:int15_vector - .size int15, . - int15 - - .section ".text16.data", "aw", @progbits - .globl int15_vector -int15_vector: - .long 0 - .size int15_vector, . - int15_vector diff --git a/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/fakee820.c b/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/fakee820.c deleted file mode 100644 index 15f4d772f..000000000 --- a/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/fakee820.c +++ /dev/null @@ -1,98 +0,0 @@ -/* Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 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 <realmode.h> -#include <biosint.h> - -/** Assembly routine in inline asm */ -extern void int15_fakee820(); - -/** Original INT 15 handler */ -static struct segoff __text16 ( real_int15_vector ); -#define real_int15_vector __use_text16 ( real_int15_vector ) - -/** An INT 15,e820 memory map entry */ -struct e820_entry { - /** Start of region */ - uint64_t start; - /** Length of region */ - uint64_t len; - /** Type of region */ - uint32_t type; -} __attribute__ (( packed )); - -#define E820_TYPE_RAM 1 /**< Normal memory */ -#define E820_TYPE_RSVD 2 /**< Reserved and unavailable */ -#define E820_TYPE_ACPI 3 /**< ACPI reclaim memory */ -#define E820_TYPE_NVS 4 /**< ACPI NVS memory */ - -/** Fake e820 map */ -static struct e820_entry __text16_array ( e820map, [] ) __used = { - { 0x00000000ULL, ( 0x000a0000ULL - 0x00000000ULL ), E820_TYPE_RAM }, - { 0x00100000ULL, ( 0xcfb50000ULL - 0x00100000ULL ), E820_TYPE_RAM }, - { 0xcfb50000ULL, ( 0xcfb64000ULL - 0xcfb50000ULL ), E820_TYPE_RSVD }, - { 0xcfb64000ULL, ( 0xcfb66000ULL - 0xcfb64000ULL ), E820_TYPE_RSVD }, - { 0xcfb66000ULL, ( 0xcfb85c00ULL - 0xcfb66000ULL ), E820_TYPE_ACPI }, - { 0xcfb85c00ULL, ( 0xd0000000ULL - 0xcfb85c00ULL ), E820_TYPE_RSVD }, - { 0xe0000000ULL, ( 0xf0000000ULL - 0xe0000000ULL ), E820_TYPE_RSVD }, - { 0xfe000000ULL, (0x100000000ULL - 0xfe000000ULL ), E820_TYPE_RSVD }, - {0x100000000ULL, (0x230000000ULL -0x100000000ULL ), E820_TYPE_RAM }, -}; -#define e820map __use_text16 ( e820map ) - -void fake_e820 ( void ) { - __asm__ __volatile__ ( - TEXT16_CODE ( "\nint15_fakee820:\n\t" - "pushfw\n\t" - "cmpl $0xe820, %%eax\n\t" - "jne 99f\n\t" - "cmpl $0x534d4150, %%edx\n\t" - "jne 99f\n\t" - "pushaw\n\t" - "movw %%sp, %%bp\n\t" - "andb $~0x01, 22(%%bp)\n\t" /* Clear return CF */ - "leaw e820map(%%bx), %%si\n\t" - "cs rep movsb\n\t" - "popaw\n\t" - "movl %%edx, %%eax\n\t" - "addl $20, %%ebx\n\t" - "cmpl %0, %%ebx\n\t" - "jne 1f\n\t" - "xorl %%ebx,%%ebx\n\t" - "\n1:\n\t" - "popfw\n\t" - "iret\n\t" - "\n99:\n\t" - "popfw\n\t" - "ljmp *%%cs:real_int15_vector\n\t" ) - : : "i" ( sizeof ( e820map ) ) ); - - hook_bios_interrupt ( 0x15, ( unsigned int ) int15_fakee820, - &real_int15_vector ); -} - -void unfake_e820 ( void ) { - unhook_bios_interrupt ( 0x15, ( unsigned int ) int15_fakee820, - &real_int15_vector ); -} diff --git a/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/hidemem.c b/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/hidemem.c deleted file mode 100644 index 253c601ff..000000000 --- a/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/hidemem.c +++ /dev/null @@ -1,235 +0,0 @@ -/* Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 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 <assert.h> -#include <realmode.h> -#include <biosint.h> -#include <basemem.h> -#include <fakee820.h> -#include <ipxe/init.h> -#include <ipxe/io.h> -#include <ipxe/hidemem.h> - -/** Set to true if you want to test a fake E820 map */ -#define FAKE_E820 0 - -/** Alignment for hidden memory regions */ -#define ALIGN_HIDDEN 4096 /* 4kB page alignment should be enough */ - -/** - * A hidden region of iPXE - * - * This represents a region that will be edited out of the system's - * memory map. - * - * This structure is accessed by assembly code, so must not be - * changed. - */ -struct hidden_region { - /** Physical start address */ - uint64_t start; - /** Physical end address */ - uint64_t end; -}; - -/** Hidden base memory */ -extern struct hidden_region __data16 ( hidemem_base ); -#define hidemem_base __use_data16 ( hidemem_base ) - -/** Hidden umalloc memory */ -extern struct hidden_region __data16 ( hidemem_umalloc ); -#define hidemem_umalloc __use_data16 ( hidemem_umalloc ) - -/** Hidden text memory */ -extern struct hidden_region __data16 ( hidemem_textdata ); -#define hidemem_textdata __use_data16 ( hidemem_textdata ) - -/** Assembly routine in e820mangler.S */ -extern void int15(); - -/** Vector for storing original INT 15 handler */ -extern struct segoff __text16 ( int15_vector ); -#define int15_vector __use_text16 ( int15_vector ) - -/* The linker defines these symbols for us */ -extern char _textdata[]; -extern char _etextdata[]; -extern char _text16_memsz[]; -#define _text16_memsz ( ( unsigned int ) _text16_memsz ) -extern char _data16_memsz[]; -#define _data16_memsz ( ( unsigned int ) _data16_memsz ) - -/** - * Hide region of memory from system memory map - * - * @v region Hidden memory region - * @v start Start of region - * @v end End of region - */ -static void hide_region ( struct hidden_region *region, - physaddr_t start, physaddr_t end ) { - - /* Some operating systems get a nasty shock if a region of the - * E820 map seems to start on a non-page boundary. Make life - * safer by rounding out our edited region. - */ - region->start = ( start & ~( ALIGN_HIDDEN - 1 ) ); - region->end = ( ( end + ALIGN_HIDDEN - 1 ) & ~( ALIGN_HIDDEN - 1 ) ); - - DBG ( "Hiding region [%llx,%llx)\n", region->start, region->end ); -} - -/** - * Hide used base memory - * - */ -void hide_basemem ( void ) { - /* Hide from the top of free base memory to 640kB. Don't use - * hide_region(), because we don't want this rounded to the - * nearest page boundary. - */ - hidemem_base.start = ( get_fbms() * 1024 ); -} - -/** - * Hide umalloc() region - * - */ -void hide_umalloc ( physaddr_t start, physaddr_t end ) { - assert ( end <= virt_to_phys ( _textdata ) ); - hide_region ( &hidemem_umalloc, start, end ); -} - -/** - * Hide .text and .data - * - */ -void hide_textdata ( void ) { - hide_region ( &hidemem_textdata, virt_to_phys ( _textdata ), - virt_to_phys ( _etextdata ) ); -} - -/** - * Hide Etherboot - * - * Installs an INT 15 handler to edit Etherboot out of the memory map - * returned by the BIOS. - */ -static void hide_etherboot ( void ) { - struct memory_map memmap; - unsigned int rm_ds_top; - unsigned int rm_cs_top; - unsigned int fbms; - - /* Dump memory map before mangling */ - DBG ( "Hiding iPXE from system memory map\n" ); - get_memmap ( &memmap ); - - /* Hook in fake E820 map, if we're testing one */ - if ( FAKE_E820 ) { - DBG ( "Hooking in fake E820 map\n" ); - fake_e820(); - get_memmap ( &memmap ); - } - - /* Initialise the hidden regions */ - hide_basemem(); - hide_umalloc ( virt_to_phys ( _textdata ), virt_to_phys ( _textdata ) ); - hide_textdata(); - - /* Some really moronic BIOSes bring up the PXE stack via the - * UNDI loader entry point and then don't bother to unload it - * before overwriting the code and data segments. If this - * happens, we really don't want to leave INT 15 hooked, - * because that will cause any loaded OS to die horribly as - * soon as it attempts to fetch the system memory map. - * - * We use a heuristic to guess whether or not we are being - * loaded sensibly. - */ - rm_cs_top = ( ( ( rm_cs << 4 ) + _text16_memsz + 1024 - 1 ) >> 10 ); - rm_ds_top = ( ( ( rm_ds << 4 ) + _data16_memsz + 1024 - 1 ) >> 10 ); - fbms = get_fbms(); - if ( ( rm_cs_top < fbms ) && ( rm_ds_top < fbms ) ) { - DBG ( "Detected potentially unsafe UNDI load at CS=%04x " - "DS=%04x FBMS=%dkB\n", rm_cs, rm_ds, fbms ); - DBG ( "Disabling INT 15 memory hiding\n" ); - return; - } - - /* Hook INT 15 */ - hook_bios_interrupt ( 0x15, ( unsigned int ) int15, - &int15_vector ); - - /* Dump memory map after mangling */ - DBG ( "Hidden iPXE from system memory map\n" ); - get_memmap ( &memmap ); -} - -/** - * Unhide Etherboot - * - * Uninstalls the INT 15 handler installed by hide_etherboot(), if - * possible. - */ -static void unhide_etherboot ( int flags __unused ) { - struct memory_map memmap; - int rc; - - /* If we have more than one hooked interrupt at this point, it - * means that some other vector is still hooked, in which case - * we can't safely unhook INT 15 because we need to keep our - * memory protected. (We expect there to be at least one - * hooked interrupt, because INT 15 itself is still hooked). - */ - if ( hooked_bios_interrupts > 1 ) { - DBG ( "Cannot unhide: %d interrupt vectors still hooked\n", - hooked_bios_interrupts ); - return; - } - - /* Try to unhook INT 15 */ - if ( ( rc = unhook_bios_interrupt ( 0x15, ( unsigned int ) int15, - &int15_vector ) ) != 0 ) { - DBG ( "Cannot unhook INT15: %s\n", strerror ( rc ) ); - /* Leave it hooked; there's nothing else we can do, - * and it should be intrinsically safe (though - * wasteful of RAM). - */ - } - - /* Unhook fake E820 map, if used */ - if ( FAKE_E820 ) - unfake_e820(); - - /* Dump memory map after unhiding */ - DBG ( "Unhidden iPXE from system memory map\n" ); - get_memmap ( &memmap ); -} - -/** Hide Etherboot startup function */ -struct startup_fn hide_etherboot_startup_fn __startup_fn ( STARTUP_EARLY ) = { - .startup = hide_etherboot, - .shutdown = unhide_etherboot, -}; diff --git a/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/memmap.c b/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/memmap.c deleted file mode 100644 index bcacecd6a..000000000 --- a/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/memmap.c +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 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 <errno.h> -#include <realmode.h> -#include <bios.h> -#include <memsizes.h> -#include <ipxe/io.h> - -/** - * @file - * - * Memory mapping - * - */ - -/** Magic value for INT 15,e820 calls */ -#define SMAP ( 0x534d4150 ) - -/** An INT 15,e820 memory map entry */ -struct e820_entry { - /** Start of region */ - uint64_t start; - /** Length of region */ - uint64_t len; - /** Type of region */ - uint32_t type; - /** Extended attributes (optional) */ - uint32_t attrs; -} __attribute__ (( packed )); - -#define E820_TYPE_RAM 1 /**< Normal memory */ -#define E820_TYPE_RESERVED 2 /**< Reserved and unavailable */ -#define E820_TYPE_ACPI 3 /**< ACPI reclaim memory */ -#define E820_TYPE_NVS 4 /**< ACPI NVS memory */ - -#define E820_ATTR_ENABLED 0x00000001UL -#define E820_ATTR_NONVOLATILE 0x00000002UL -#define E820_ATTR_UNKNOWN 0xfffffffcUL - -#define E820_MIN_SIZE 20 - -/** Buffer for INT 15,e820 calls */ -static struct e820_entry __bss16 ( e820buf ); -#define e820buf __use_data16 ( e820buf ) - -/** We are running during POST; inhibit INT 15,e820 and INT 15,e801 */ -uint8_t __bss16 ( memmap_post ); -#define memmap_post __use_data16 ( memmap_post ) - -/** - * Get size of extended memory via INT 15,e801 - * - * @ret extmem Extended memory size, in kB, or 0 - */ -static unsigned int extmemsize_e801 ( void ) { - uint16_t extmem_1m_to_16m_k, extmem_16m_plus_64k; - uint16_t confmem_1m_to_16m_k, confmem_16m_plus_64k; - unsigned int flags; - unsigned int extmem; - - /* Inhibit INT 15,e801 during POST */ - if ( memmap_post ) { - DBG ( "INT 15,e801 not available during POST\n" ); - return 0; - } - - __asm__ __volatile__ ( REAL_CODE ( "stc\n\t" - "int $0x15\n\t" - "pushfw\n\t" - "popw %w0\n\t" ) - : "=r" ( flags ), - "=a" ( extmem_1m_to_16m_k ), - "=b" ( extmem_16m_plus_64k ), - "=c" ( confmem_1m_to_16m_k ), - "=d" ( confmem_16m_plus_64k ) - : "a" ( 0xe801 ) ); - - if ( flags & CF ) { - DBG ( "INT 15,e801 failed with CF set\n" ); - return 0; - } - - if ( ! ( extmem_1m_to_16m_k | extmem_16m_plus_64k ) ) { - DBG ( "INT 15,e801 extmem=0, using confmem\n" ); - extmem_1m_to_16m_k = confmem_1m_to_16m_k; - extmem_16m_plus_64k = confmem_16m_plus_64k; - } - - extmem = ( extmem_1m_to_16m_k + ( extmem_16m_plus_64k * 64 ) ); - DBG ( "INT 15,e801 extended memory size %d+64*%d=%d kB " - "[100000,%llx)\n", extmem_1m_to_16m_k, extmem_16m_plus_64k, - extmem, ( 0x100000 + ( ( ( uint64_t ) extmem ) * 1024 ) ) ); - - /* Sanity check. Some BIOSes report the entire 4GB address - * space as available, which cannot be correct (since that - * would leave no address space available for 32-bit PCI - * BARs). - */ - if ( extmem == ( 0x400000 - 0x400 ) ) { - DBG ( "INT 15,e801 reported whole 4GB; assuming insane\n" ); - return 0; - } - - return extmem; -} - -/** - * Get size of extended memory via INT 15,88 - * - * @ret extmem Extended memory size, in kB - */ -static unsigned int extmemsize_88 ( void ) { - uint16_t extmem; - - /* Ignore CF; it is not reliable for this call */ - __asm__ __volatile__ ( REAL_CODE ( "int $0x15" ) - : "=a" ( extmem ) : "a" ( 0x8800 ) ); - - DBG ( "INT 15,88 extended memory size %d kB [100000, %x)\n", - extmem, ( 0x100000 + ( extmem * 1024 ) ) ); - return extmem; -} - -/** - * Get size of extended memory - * - * @ret extmem Extended memory size, in kB - * - * Note that this is only an approximation; for an accurate picture, - * use the E820 memory map obtained via get_memmap(); - */ -unsigned int extmemsize ( void ) { - unsigned int extmem_e801; - unsigned int extmem_88; - - /* Try INT 15,e801 first, then fall back to INT 15,88 */ - extmem_88 = extmemsize_88(); - extmem_e801 = extmemsize_e801(); - return ( extmem_e801 ? extmem_e801 : extmem_88 ); -} - -/** - * Get e820 memory map - * - * @v memmap Memory map to fill in - * @ret rc Return status code - */ -static int meme820 ( struct memory_map *memmap ) { - struct memory_region *region = memmap->regions; - struct memory_region *prev_region = NULL; - uint32_t next = 0; - uint32_t smap; - size_t size; - unsigned int flags; - unsigned int discard_D; - - /* Inhibit INT 15,e820 during POST */ - if ( memmap_post ) { - DBG ( "INT 15,e820 not available during POST\n" ); - return -ENOTTY; - } - - /* Clear the E820 buffer. Do this once before starting, - * rather than on each call; some BIOSes rely on the contents - * being preserved between calls. - */ - memset ( &e820buf, 0, sizeof ( e820buf ) ); - - do { - /* Some BIOSes corrupt %esi for fun. Guard against - * this by telling gcc that all non-output registers - * may be corrupted. - */ - __asm__ __volatile__ ( REAL_CODE ( "pushl %%ebp\n\t" - "stc\n\t" - "int $0x15\n\t" - "pushfw\n\t" - "popw %%dx\n\t" - "popl %%ebp\n\t" ) - : "=a" ( smap ), "=b" ( next ), - "=c" ( size ), "=d" ( flags ), - "=D" ( discard_D ) - : "a" ( 0xe820 ), "b" ( next ), - "D" ( __from_data16 ( &e820buf ) ), - "c" ( sizeof ( e820buf ) ), - "d" ( SMAP ) - : "esi", "memory" ); - - if ( smap != SMAP ) { - DBG ( "INT 15,e820 failed SMAP signature check\n" ); - return -ENOTSUP; - } - - if ( size < E820_MIN_SIZE ) { - DBG ( "INT 15,e820 returned only %zd bytes\n", size ); - return -EINVAL; - } - - if ( flags & CF ) { - DBG ( "INT 15,e820 terminated on CF set\n" ); - break; - } - - /* If first region is not RAM, assume map is invalid */ - if ( ( memmap->count == 0 ) && - ( e820buf.type != E820_TYPE_RAM ) ) { - DBG ( "INT 15,e820 failed, first entry not RAM\n" ); - return -EINVAL; - } - - DBG ( "INT 15,e820 region [%llx,%llx) type %d", - e820buf.start, ( e820buf.start + e820buf.len ), - ( int ) e820buf.type ); - if ( size > offsetof ( typeof ( e820buf ), attrs ) ) { - DBG ( " (%s", ( ( e820buf.attrs & E820_ATTR_ENABLED ) - ? "enabled" : "disabled" ) ); - if ( e820buf.attrs & E820_ATTR_NONVOLATILE ) - DBG ( ", non-volatile" ); - if ( e820buf.attrs & E820_ATTR_UNKNOWN ) - DBG ( ", other [%08x]", e820buf.attrs ); - DBG ( ")" ); - } - DBG ( "\n" ); - - /* Discard non-RAM regions */ - if ( e820buf.type != E820_TYPE_RAM ) - continue; - - /* Check extended attributes, if present */ - if ( size > offsetof ( typeof ( e820buf ), attrs ) ) { - if ( ! ( e820buf.attrs & E820_ATTR_ENABLED ) ) - continue; - if ( e820buf.attrs & E820_ATTR_NONVOLATILE ) - continue; - } - - region->start = e820buf.start; - region->end = e820buf.start + e820buf.len; - - /* Check for adjacent regions and merge them */ - if ( prev_region && ( region->start == prev_region->end ) ) { - prev_region->end = region->end; - } else { - prev_region = region; - region++; - memmap->count++; - } - - if ( memmap->count >= ( sizeof ( memmap->regions ) / - sizeof ( memmap->regions[0] ) ) ) { - DBG ( "INT 15,e820 too many regions returned\n" ); - /* Not a fatal error; what we've got so far at - * least represents valid regions of memory, - * even if we couldn't get them all. - */ - break; - } - } while ( next != 0 ); - - /* Sanity checks. Some BIOSes report complete garbage via INT - * 15,e820 (especially at POST time), despite passing the - * signature checks. We currently check for a base memory - * region (starting at 0) and at least one high memory region - * (starting at 0x100000). - */ - if ( memmap->count < 2 ) { - DBG ( "INT 15,e820 returned only %d regions; assuming " - "insane\n", memmap->count ); - return -EINVAL; - } - if ( memmap->regions[0].start != 0 ) { - DBG ( "INT 15,e820 region 0 starts at %llx (expected 0); " - "assuming insane\n", memmap->regions[0].start ); - return -EINVAL; - } - if ( memmap->regions[1].start != 0x100000 ) { - DBG ( "INT 15,e820 region 1 starts at %llx (expected 100000); " - "assuming insane\n", memmap->regions[0].start ); - return -EINVAL; - } - - return 0; -} - -/** - * Get memory map - * - * @v memmap Memory map to fill in - */ -void x86_get_memmap ( struct memory_map *memmap ) { - unsigned int basemem, extmem; - int rc; - - DBG ( "Fetching system memory map\n" ); - - /* Clear memory map */ - memset ( memmap, 0, sizeof ( *memmap ) ); - - /* Get base and extended memory sizes */ - basemem = basememsize(); - DBG ( "FBMS base memory size %d kB [0,%x)\n", - basemem, ( basemem * 1024 ) ); - extmem = extmemsize(); - - /* Try INT 15,e820 first */ - if ( ( rc = meme820 ( memmap ) ) == 0 ) { - DBG ( "Obtained system memory map via INT 15,e820\n" ); - return; - } - - /* Fall back to constructing a map from basemem and extmem sizes */ - DBG ( "INT 15,e820 failed; constructing map\n" ); - memmap->regions[0].end = ( basemem * 1024 ); - memmap->regions[1].start = 0x100000; - memmap->regions[1].end = 0x100000 + ( extmem * 1024 ); - memmap->count = 2; -} - -PROVIDE_IOAPI ( x86, get_memmap, x86_get_memmap ); diff --git a/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/pnpbios.c b/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/pnpbios.c deleted file mode 100644 index 20ec35d75..000000000 --- a/qemu/roms/ipxe/src/arch/i386/firmware/pcbios/pnpbios.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 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 <string.h> -#include <errno.h> -#include <realmode.h> -#include <pnpbios.h> - -/** @file - * - * PnP BIOS - * - */ - -/** PnP BIOS structure */ -struct pnp_bios { - /** Signature - * - * Must be equal to @c PNP_BIOS_SIGNATURE - */ - uint32_t signature; - /** Version as BCD (e.g. 1.0 is 0x10) */ - uint8_t version; - /** Length of this structure */ - uint8_t length; - /** System capabilities */ - uint16_t control; - /** Checksum */ - uint8_t checksum; -} __attribute__ (( packed )); - -/** Signature for a PnP BIOS structure */ -#define PNP_BIOS_SIGNATURE \ - ( ( '$' << 0 ) + ( 'P' << 8 ) + ( 'n' << 16 ) + ( 'P' << 24 ) ) - -/** - * Test address for PnP BIOS structure - * - * @v offset Offset within BIOS segment to test - * @ret rc Return status code - */ -static int is_pnp_bios ( unsigned int offset ) { - union { - struct pnp_bios pnp_bios; - uint8_t bytes[256]; /* 256 is maximum length possible */ - } u; - size_t len; - unsigned int i; - uint8_t sum = 0; - - /* Read start of header and verify signature */ - copy_from_real ( &u.pnp_bios, BIOS_SEG, offset, sizeof ( u.pnp_bios )); - if ( u.pnp_bios.signature != PNP_BIOS_SIGNATURE ) - return -EINVAL; - - /* Read whole header and verify checksum */ - len = u.pnp_bios.length; - copy_from_real ( &u.bytes, BIOS_SEG, offset, len ); - for ( i = 0 ; i < len ; i++ ) { - sum += u.bytes[i]; - } - if ( sum != 0 ) - return -EINVAL; - - DBG ( "Found PnP BIOS at %04x:%04x\n", BIOS_SEG, offset ); - - return 0; -} - -/** - * Locate Plug-and-Play BIOS - * - * @ret pnp_offset Offset of PnP BIOS structure within BIOS segment - * - * The PnP BIOS structure will be at BIOS_SEG:pnp_offset. If no PnP - * BIOS is found, -1 is returned. - */ -int find_pnp_bios ( void ) { - static int pnp_offset = 0; - - if ( pnp_offset ) - return pnp_offset; - - for ( pnp_offset = 0 ; pnp_offset < 0x10000 ; pnp_offset += 0x10 ) { - if ( is_pnp_bios ( pnp_offset ) == 0 ) - return pnp_offset; - } - - pnp_offset = -1; - return pnp_offset; -} diff --git a/qemu/roms/ipxe/src/arch/i386/hci/commands/pxe_cmd.c b/qemu/roms/ipxe/src/arch/i386/hci/commands/pxe_cmd.c deleted file mode 100644 index 473b97f97..000000000 --- a/qemu/roms/ipxe/src/arch/i386/hci/commands/pxe_cmd.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (C) 2010 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. - */ - -#include <ipxe/netdevice.h> -#include <ipxe/command.h> -#include <ipxe/parseopt.h> -#include <hci/ifmgmt_cmd.h> -#include <pxe_call.h> - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/** @file - * - * PXE commands - * - */ - -/** "startpxe" options */ -struct startpxe_options {}; - -/** "startpxe" option list */ -static struct option_descriptor startpxe_opts[] = {}; - -/** - * "startpxe" payload - * - * @v netdev Network device - * @v opts Command options - * @ret rc Return status code - */ -static int startpxe_payload ( struct net_device *netdev, - struct startpxe_options *opts __unused ) { - - if ( netdev_is_open ( netdev ) ) - pxe_activate ( netdev ); - - return 0; -} - -/** "startpxe" command descriptor */ -static struct ifcommon_command_descriptor startpxe_cmd = - IFCOMMON_COMMAND_DESC ( struct startpxe_options, startpxe_opts, - 0, MAX_ARGUMENTS, "[<interface>]", - startpxe_payload, 0 ); - -/** - * The "startpxe" command - * - * @v argc Argument count - * @v argv Argument list - * @ret rc Return status code - */ -static int startpxe_exec ( int argc, char **argv ) { - return ifcommon_exec ( argc, argv, &startpxe_cmd ); -} - -/** "stoppxe" options */ -struct stoppxe_options {}; - -/** "stoppxe" option list */ -static struct option_descriptor stoppxe_opts[] = {}; - -/** "stoppxe" command descriptor */ -static struct command_descriptor stoppxe_cmd = - COMMAND_DESC ( struct stoppxe_options, stoppxe_opts, 0, 0, NULL ); - -/** - * The "stoppxe" command - * - * @v argc Argument count - * @v argv Argument list - * @ret rc Return status code - */ -static int stoppxe_exec ( int argc __unused, char **argv __unused ) { - struct stoppxe_options opts; - int rc; - - /* Parse options */ - if ( ( rc = parse_options ( argc, argv, &stoppxe_cmd, &opts ) ) != 0 ) - return rc; - - pxe_deactivate(); - - return 0; -} - -/** PXE commands */ -struct command pxe_commands[] __command = { - { - .name = "startpxe", - .exec = startpxe_exec, - }, - { - .name = "stoppxe", - .exec = stoppxe_exec, - }, -}; diff --git a/qemu/roms/ipxe/src/arch/i386/image/bootsector.c b/qemu/roms/ipxe/src/arch/i386/image/bootsector.c deleted file mode 100644 index dba87613c..000000000 --- a/qemu/roms/ipxe/src/arch/i386/image/bootsector.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 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 ); - -/** - * @file - * - * x86 bootsector image format - * - */ - -#include <errno.h> -#include <realmode.h> -#include <biosint.h> -#include <bootsector.h> -#include <ipxe/console.h> - -/** Vector for storing original INT 18 handler - * - * We do not chain to this vector, so there is no need to place it in - * .text16. - */ -static struct segoff int18_vector; - -/** Vector for storing original INT 19 handler - * - * We do not chain to this vector, so there is no need to place it in - * .text16. - */ -static struct segoff int19_vector; - -/** Restart point for INT 18 or 19 */ -extern void bootsector_exec_fail ( void ); - -/** - * Jump to preloaded bootsector - * - * @v segment Real-mode segment - * @v offset Real-mode offset - * @v drive Drive number to pass to boot sector - * @ret rc Return status code - */ -int call_bootsector ( unsigned int segment, unsigned int offset, - unsigned int drive ) { - int discard_b, discard_D, discard_d; - - /* Reset console, since boot sector will probably use it */ - console_reset(); - - DBG ( "Booting from boot sector at %04x:%04x\n", segment, offset ); - - /* Hook INTs 18 and 19 to capture failure paths */ - hook_bios_interrupt ( 0x18, ( unsigned int ) bootsector_exec_fail, - &int18_vector ); - hook_bios_interrupt ( 0x19, ( unsigned int ) bootsector_exec_fail, - &int19_vector ); - - /* Boot the loaded sector - * - * We assume that the boot sector may completely destroy our - * real-mode stack, so we preserve everything we need in - * static storage. - */ - __asm__ __volatile__ ( REAL_CODE ( /* Save return address off-stack */ - "popw %%cs:saved_retaddr\n\t" - /* Save stack pointer */ - "movw %%ss, %%ax\n\t" - "movw %%ax, %%cs:saved_ss\n\t" - "movw %%sp, %%cs:saved_sp\n\t" - /* Save frame pointer (gcc bug) */ - "movl %%ebp, %%cs:saved_ebp\n\t" - /* Prepare jump to boot sector */ - "pushw %%bx\n\t" - "pushw %%di\n\t" - /* Clear all registers */ - "xorl %%eax, %%eax\n\t" - "xorl %%ebx, %%ebx\n\t" - "xorl %%ecx, %%ecx\n\t" - /* %edx contains drive number */ - "xorl %%esi, %%esi\n\t" - "xorl %%edi, %%edi\n\t" - "xorl %%ebp, %%ebp\n\t" - "movw %%ax, %%ds\n\t" - "movw %%ax, %%es\n\t" - "movw %%ax, %%fs\n\t" - "movw %%ax, %%gs\n\t" - /* Jump to boot sector */ - "sti\n\t" - "lret\n\t" - /* Preserved variables */ - "\nsaved_ebp: .long 0\n\t" - "\nsaved_ss: .word 0\n\t" - "\nsaved_sp: .word 0\n\t" - "\nsaved_retaddr: .word 0\n\t" - /* Boot failure return point */ - "\nbootsector_exec_fail:\n\t" - /* Restore frame pointer (gcc bug) */ - "movl %%cs:saved_ebp, %%ebp\n\t" - /* Restore stack pointer */ - "movw %%cs:saved_ss, %%ax\n\t" - "movw %%ax, %%ss\n\t" - "movw %%cs:saved_sp, %%sp\n\t" - /* Return via saved address */ - "jmp *%%cs:saved_retaddr\n\t" ) - : "=b" ( discard_b ), "=D" ( discard_D ), - "=d" ( discard_d ) - : "b" ( segment ), "D" ( offset ), - "d" ( drive ) - : "eax", "ecx", "esi" ); - - DBG ( "Booted disk returned via INT 18 or 19\n" ); - - /* Unhook INTs 18 and 19 */ - unhook_bios_interrupt ( 0x18, ( unsigned int ) bootsector_exec_fail, - &int18_vector ); - unhook_bios_interrupt ( 0x19, ( unsigned int ) bootsector_exec_fail, - &int19_vector ); - - return -ECANCELED; -} diff --git a/qemu/roms/ipxe/src/arch/i386/image/bzimage.c b/qemu/roms/ipxe/src/arch/i386/image/bzimage.c deleted file mode 100644 index a64206cd3..000000000 --- a/qemu/roms/ipxe/src/arch/i386/image/bzimage.c +++ /dev/null @@ -1,669 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 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 ); - -/** - * @file - * - * Linux bzImage image format - * - */ - -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> -#include <realmode.h> -#include <bzimage.h> -#include <initrd.h> -#include <ipxe/uaccess.h> -#include <ipxe/image.h> -#include <ipxe/segment.h> -#include <ipxe/init.h> -#include <ipxe/cpio.h> -#include <ipxe/features.h> - -FEATURE ( FEATURE_IMAGE, "bzImage", DHCP_EB_FEATURE_BZIMAGE, 1 ); - -/** - * bzImage context - */ -struct bzimage_context { - /** Boot protocol version */ - unsigned int version; - /** Real-mode kernel portion load segment address */ - unsigned int rm_kernel_seg; - /** Real-mode kernel portion load address */ - userptr_t rm_kernel; - /** Real-mode kernel portion file size */ - size_t rm_filesz; - /** Real-mode heap top (offset from rm_kernel) */ - size_t rm_heap; - /** Command line (offset from rm_kernel) */ - size_t rm_cmdline; - /** Command line maximum length */ - size_t cmdline_size; - /** Real-mode kernel portion total memory size */ - size_t rm_memsz; - /** Non-real-mode kernel portion load address */ - userptr_t pm_kernel; - /** Non-real-mode kernel portion file and memory size */ - size_t pm_sz; - /** Video mode */ - unsigned int vid_mode; - /** Memory limit */ - uint64_t mem_limit; - /** Initrd address */ - physaddr_t ramdisk_image; - /** Initrd size */ - physaddr_t ramdisk_size; - - /** Command line magic block */ - struct bzimage_cmdline cmdline_magic; - /** bzImage header */ - struct bzimage_header bzhdr; -}; - -/** - * Parse bzImage header - * - * @v image bzImage file - * @v bzimg bzImage context - * @v src bzImage to parse - * @ret rc Return status code - */ -static int bzimage_parse_header ( struct image *image, - struct bzimage_context *bzimg, - userptr_t src ) { - unsigned int syssize; - int is_bzimage; - - /* Sanity check */ - if ( image->len < ( BZI_HDR_OFFSET + sizeof ( bzimg->bzhdr ) ) ) { - DBGC ( image, "bzImage %p too short for kernel header\n", - image ); - return -ENOEXEC; - } - - /* Read in header structures */ - memset ( bzimg, 0, sizeof ( *bzimg ) ); - copy_from_user ( &bzimg->cmdline_magic, src, BZI_CMDLINE_OFFSET, - sizeof ( bzimg->cmdline_magic ) ); - copy_from_user ( &bzimg->bzhdr, src, BZI_HDR_OFFSET, - sizeof ( bzimg->bzhdr ) ); - - /* Calculate size of real-mode portion */ - bzimg->rm_filesz = ( ( ( bzimg->bzhdr.setup_sects ? - bzimg->bzhdr.setup_sects : 4 ) + 1 ) << 9 ); - if ( bzimg->rm_filesz > image->len ) { - DBGC ( image, "bzImage %p too short for %zd byte of setup\n", - image, bzimg->rm_filesz ); - return -ENOEXEC; - } - bzimg->rm_memsz = BZI_ASSUMED_RM_SIZE; - - /* Calculate size of protected-mode portion */ - bzimg->pm_sz = ( image->len - bzimg->rm_filesz ); - syssize = ( ( bzimg->pm_sz + 15 ) / 16 ); - - /* Check for signatures and determine version */ - if ( bzimg->bzhdr.boot_flag != BZI_BOOT_FLAG ) { - DBGC ( image, "bzImage %p missing 55AA signature\n", image ); - return -ENOEXEC; - } - if ( bzimg->bzhdr.header == BZI_SIGNATURE ) { - /* 2.00+ */ - bzimg->version = bzimg->bzhdr.version; - } else { - /* Pre-2.00. Check that the syssize field is correct, - * as a guard against accepting arbitrary binary data, - * since the 55AA check is pretty lax. Note that the - * syssize field is unreliable for protocols between - * 2.00 and 2.03 inclusive, so we should not always - * check this field. - */ - bzimg->version = 0x0100; - if ( bzimg->bzhdr.syssize != syssize ) { - DBGC ( image, "bzImage %p bad syssize %x (expected " - "%x)\n", image, bzimg->bzhdr.syssize, syssize ); - return -ENOEXEC; - } - } - - /* Determine image type */ - is_bzimage = ( ( bzimg->version >= 0x0200 ) ? - ( bzimg->bzhdr.loadflags & BZI_LOAD_HIGH ) : 0 ); - - /* Calculate load address of real-mode portion */ - bzimg->rm_kernel_seg = ( is_bzimage ? 0x1000 : 0x9000 ); - bzimg->rm_kernel = real_to_user ( bzimg->rm_kernel_seg, 0 ); - - /* Allow space for the stack and heap */ - bzimg->rm_memsz += BZI_STACK_SIZE; - bzimg->rm_heap = bzimg->rm_memsz; - - /* Allow space for the command line */ - bzimg->rm_cmdline = bzimg->rm_memsz; - bzimg->rm_memsz += BZI_CMDLINE_SIZE; - - /* Calculate load address of protected-mode portion */ - bzimg->pm_kernel = phys_to_user ( is_bzimage ? BZI_LOAD_HIGH_ADDR - : BZI_LOAD_LOW_ADDR ); - - /* Extract video mode */ - bzimg->vid_mode = bzimg->bzhdr.vid_mode; - - /* Extract memory limit */ - bzimg->mem_limit = ( ( bzimg->version >= 0x0203 ) ? - bzimg->bzhdr.initrd_addr_max : BZI_INITRD_MAX ); - - /* Extract command line size */ - bzimg->cmdline_size = ( ( bzimg->version >= 0x0206 ) ? - bzimg->bzhdr.cmdline_size : BZI_CMDLINE_SIZE ); - - DBGC ( image, "bzImage %p version %04x RM %#lx+%#zx PM %#lx+%#zx " - "cmdlen %zd\n", image, bzimg->version, - user_to_phys ( bzimg->rm_kernel, 0 ), bzimg->rm_filesz, - user_to_phys ( bzimg->pm_kernel, 0 ), bzimg->pm_sz, - bzimg->cmdline_size ); - - return 0; -} - -/** - * Update bzImage header in loaded kernel - * - * @v image bzImage file - * @v bzimg bzImage context - * @v dst bzImage to update - */ -static void bzimage_update_header ( struct image *image, - struct bzimage_context *bzimg, - userptr_t dst ) { - - /* Set loader type */ - if ( bzimg->version >= 0x0200 ) - bzimg->bzhdr.type_of_loader = BZI_LOADER_TYPE_IPXE; - - /* Set heap end pointer */ - if ( bzimg->version >= 0x0201 ) { - bzimg->bzhdr.heap_end_ptr = ( bzimg->rm_heap - 0x200 ); - bzimg->bzhdr.loadflags |= BZI_CAN_USE_HEAP; - } - - /* Set command line */ - if ( bzimg->version >= 0x0202 ) { - bzimg->bzhdr.cmd_line_ptr = user_to_phys ( bzimg->rm_kernel, - bzimg->rm_cmdline ); - } else { - bzimg->cmdline_magic.magic = BZI_CMDLINE_MAGIC; - bzimg->cmdline_magic.offset = bzimg->rm_cmdline; - if ( bzimg->version >= 0x0200 ) - bzimg->bzhdr.setup_move_size = bzimg->rm_memsz; - } - - /* Set video mode */ - bzimg->bzhdr.vid_mode = bzimg->vid_mode; - - /* Set initrd address */ - if ( bzimg->version >= 0x0200 ) { - bzimg->bzhdr.ramdisk_image = bzimg->ramdisk_image; - bzimg->bzhdr.ramdisk_size = bzimg->ramdisk_size; - } - - /* Write out header structures */ - copy_to_user ( dst, BZI_CMDLINE_OFFSET, &bzimg->cmdline_magic, - sizeof ( bzimg->cmdline_magic ) ); - copy_to_user ( dst, BZI_HDR_OFFSET, &bzimg->bzhdr, - sizeof ( bzimg->bzhdr ) ); - - DBGC ( image, "bzImage %p vidmode %d\n", image, bzimg->vid_mode ); -} - -/** - * Parse kernel command line for bootloader parameters - * - * @v image bzImage file - * @v bzimg bzImage context - * @v cmdline Kernel command line - * @ret rc Return status code - */ -static int bzimage_parse_cmdline ( struct image *image, - struct bzimage_context *bzimg, - const char *cmdline ) { - char *vga; - char *mem; - - /* Look for "vga=" */ - if ( ( vga = strstr ( cmdline, "vga=" ) ) ) { - vga += 4; - if ( strcmp ( vga, "normal" ) == 0 ) { - bzimg->vid_mode = BZI_VID_MODE_NORMAL; - } else if ( strcmp ( vga, "ext" ) == 0 ) { - bzimg->vid_mode = BZI_VID_MODE_EXT; - } else if ( strcmp ( vga, "ask" ) == 0 ) { - bzimg->vid_mode = BZI_VID_MODE_ASK; - } else { - bzimg->vid_mode = strtoul ( vga, &vga, 0 ); - if ( *vga && ( *vga != ' ' ) ) { - DBGC ( image, "bzImage %p strange \"vga=\"" - "terminator '%c'\n", image, *vga ); - } - } - } - - /* Look for "mem=" */ - if ( ( mem = strstr ( cmdline, "mem=" ) ) ) { - mem += 4; - bzimg->mem_limit = strtoul ( mem, &mem, 0 ); - switch ( *mem ) { - case 'G': - case 'g': - bzimg->mem_limit <<= 10; - case 'M': - case 'm': - bzimg->mem_limit <<= 10; - case 'K': - case 'k': - bzimg->mem_limit <<= 10; - break; - case '\0': - case ' ': - break; - default: - DBGC ( image, "bzImage %p strange \"mem=\" " - "terminator '%c'\n", image, *mem ); - break; - } - bzimg->mem_limit -= 1; - } - - return 0; -} - -/** - * Set command line - * - * @v image bzImage image - * @v bzimg bzImage context - * @v cmdline Kernel command line - */ -static void bzimage_set_cmdline ( struct image *image, - struct bzimage_context *bzimg, - const char *cmdline ) { - size_t cmdline_len; - - /* Copy command line down to real-mode portion */ - cmdline_len = ( strlen ( cmdline ) + 1 ); - if ( cmdline_len > bzimg->cmdline_size ) - cmdline_len = bzimg->cmdline_size; - copy_to_user ( bzimg->rm_kernel, bzimg->rm_cmdline, - cmdline, cmdline_len ); - DBGC ( image, "bzImage %p command line \"%s\"\n", image, cmdline ); -} - -/** - * Parse standalone image command line for cpio parameters - * - * @v image bzImage file - * @v cpio CPIO header - * @v cmdline Command line - */ -static void bzimage_parse_cpio_cmdline ( struct image *image, - struct cpio_header *cpio, - const char *cmdline ) { - char *arg; - char *end; - unsigned int mode; - - /* Look for "mode=" */ - if ( ( arg = strstr ( cmdline, "mode=" ) ) ) { - arg += 5; - mode = strtoul ( arg, &end, 8 /* Octal for file mode */ ); - if ( *end && ( *end != ' ' ) ) { - DBGC ( image, "bzImage %p strange \"mode=\"" - "terminator '%c'\n", image, *end ); - } - cpio_set_field ( cpio->c_mode, ( 0100000 | mode ) ); - } -} - -/** - * Align initrd length - * - * @v len Length - * @ret len Length rounded up to INITRD_ALIGN - */ -static inline size_t bzimage_align ( size_t len ) { - - return ( ( len + INITRD_ALIGN - 1 ) & ~( INITRD_ALIGN - 1 ) ); -} - -/** - * Load initrd - * - * @v image bzImage image - * @v initrd initrd image - * @v address Address at which to load, or UNULL - * @ret len Length of loaded image, excluding zero-padding - */ -static size_t bzimage_load_initrd ( struct image *image, - struct image *initrd, - userptr_t address ) { - char *filename = initrd->cmdline; - char *cmdline; - struct cpio_header cpio; - size_t offset; - size_t name_len; - size_t pad_len; - - /* Do not include kernel image itself as an initrd */ - if ( initrd == image ) - return 0; - - /* Create cpio header for non-prebuilt images */ - if ( filename && filename[0] ) { - cmdline = strchr ( filename, ' ' ); - name_len = ( ( cmdline ? ( ( size_t ) ( cmdline - filename ) ) - : strlen ( filename ) ) + 1 /* NUL */ ); - memset ( &cpio, '0', sizeof ( cpio ) ); - memcpy ( cpio.c_magic, CPIO_MAGIC, sizeof ( cpio.c_magic ) ); - cpio_set_field ( cpio.c_mode, 0100644 ); - cpio_set_field ( cpio.c_nlink, 1 ); - cpio_set_field ( cpio.c_filesize, initrd->len ); - cpio_set_field ( cpio.c_namesize, name_len ); - if ( cmdline ) { - bzimage_parse_cpio_cmdline ( image, &cpio, - ( cmdline + 1 /* ' ' */ )); - } - offset = ( ( sizeof ( cpio ) + name_len + 0x03 ) & ~0x03 ); - } else { - offset = 0; - name_len = 0; - } - - /* Copy in initrd image body (and cpio header if applicable) */ - if ( address ) { - memmove_user ( address, offset, initrd->data, 0, initrd->len ); - if ( offset ) { - memset_user ( address, 0, 0, offset ); - copy_to_user ( address, 0, &cpio, sizeof ( cpio ) ); - copy_to_user ( address, sizeof ( cpio ), filename, - ( name_len - 1 /* NUL (or space) */ ) ); - } - DBGC ( image, "bzImage %p initrd %p [%#08lx,%#08lx,%#08lx)" - "%s%s\n", image, initrd, user_to_phys ( address, 0 ), - user_to_phys ( address, offset ), - user_to_phys ( address, ( offset + initrd->len ) ), - ( filename ? " " : "" ), ( filename ? filename : "" ) ); - DBGC2_MD5A ( image, user_to_phys ( address, offset ), - user_to_virt ( address, offset ), initrd->len ); - } - offset += initrd->len; - - /* Zero-pad to next INITRD_ALIGN boundary */ - pad_len = ( ( -offset ) & ( INITRD_ALIGN - 1 ) ); - if ( address ) - memset_user ( address, offset, 0, pad_len ); - - return offset; -} - -/** - * Check that initrds can be loaded - * - * @v image bzImage image - * @v bzimg bzImage context - * @ret rc Return status code - */ -static int bzimage_check_initrds ( struct image *image, - struct bzimage_context *bzimg ) { - struct image *initrd; - userptr_t bottom; - size_t len = 0; - int rc; - - /* Calculate total loaded length of initrds */ - for_each_image ( initrd ) { - - /* Skip kernel */ - if ( initrd == image ) - continue; - - /* Calculate length */ - len += bzimage_load_initrd ( image, initrd, UNULL ); - len = bzimage_align ( len ); - - DBGC ( image, "bzImage %p initrd %p from [%#08lx,%#08lx)%s%s\n", - image, initrd, user_to_phys ( initrd->data, 0 ), - user_to_phys ( initrd->data, initrd->len ), - ( initrd->cmdline ? " " : "" ), - ( initrd->cmdline ? initrd->cmdline : "" ) ); - DBGC2_MD5A ( image, user_to_phys ( initrd->data, 0 ), - user_to_virt ( initrd->data, 0 ), initrd->len ); - } - - /* Calculate lowest usable address */ - bottom = userptr_add ( bzimg->pm_kernel, bzimg->pm_sz ); - - /* Check that total length fits within space available for - * reshuffling. This is a conservative check, since CPIO - * headers are not present during reshuffling, but this - * doesn't hurt and keeps the code simple. - */ - if ( ( rc = initrd_reshuffle_check ( len, bottom ) ) != 0 ) { - DBGC ( image, "bzImage %p failed reshuffle check: %s\n", - image, strerror ( rc ) ); - return rc; - } - - /* Check that total length fits within kernel's memory limit */ - if ( user_to_phys ( bottom, len ) > bzimg->mem_limit ) { - DBGC ( image, "bzImage %p not enough space for initrds\n", - image ); - return -ENOBUFS; - } - - return 0; -} - -/** - * Load initrds, if any - * - * @v image bzImage image - * @v bzimg bzImage context - */ -static void bzimage_load_initrds ( struct image *image, - struct bzimage_context *bzimg ) { - struct image *initrd; - struct image *highest = NULL; - struct image *other; - userptr_t top; - userptr_t dest; - size_t offset; - size_t len; - - /* Reshuffle initrds into desired order */ - initrd_reshuffle ( userptr_add ( bzimg->pm_kernel, bzimg->pm_sz ) ); - - /* Find highest initrd */ - for_each_image ( initrd ) { - if ( ( highest == NULL ) || - ( userptr_sub ( initrd->data, highest->data ) > 0 ) ) { - highest = initrd; - } - } - - /* Do nothing if there are no initrds */ - if ( ! highest ) - return; - - /* Find highest usable address */ - top = userptr_add ( highest->data, bzimage_align ( highest->len ) ); - if ( user_to_phys ( top, 0 ) > bzimg->mem_limit ) - top = phys_to_user ( bzimg->mem_limit ); - DBGC ( image, "bzImage %p loading initrds from %#08lx downwards\n", - image, user_to_phys ( top, 0 ) ); - - /* Load initrds in order */ - for_each_image ( initrd ) { - - /* Calculate cumulative length of following - * initrds (including padding). - */ - offset = 0; - for_each_image ( other ) { - if ( other == initrd ) - offset = 0; - offset += bzimage_load_initrd ( image, other, UNULL ); - offset = bzimage_align ( offset ); - } - - /* Load initrd at this address */ - dest = userptr_add ( top, -offset ); - len = bzimage_load_initrd ( image, initrd, dest ); - - /* Record initrd location */ - if ( ! bzimg->ramdisk_image ) - bzimg->ramdisk_image = user_to_phys ( dest, 0 ); - bzimg->ramdisk_size = ( user_to_phys ( dest, len ) - - bzimg->ramdisk_image ); - } - DBGC ( image, "bzImage %p initrds at [%#08lx,%#08lx)\n", - image, bzimg->ramdisk_image, - ( bzimg->ramdisk_image + bzimg->ramdisk_size ) ); -} - -/** - * Execute bzImage image - * - * @v image bzImage image - * @ret rc Return status code - */ -static int bzimage_exec ( struct image *image ) { - struct bzimage_context bzimg; - const char *cmdline = ( image->cmdline ? image->cmdline : "" ); - int rc; - - /* Read and parse header from image */ - if ( ( rc = bzimage_parse_header ( image, &bzimg, - image->data ) ) != 0 ) - return rc; - - /* Prepare segments */ - if ( ( rc = prep_segment ( bzimg.rm_kernel, bzimg.rm_filesz, - bzimg.rm_memsz ) ) != 0 ) { - DBGC ( image, "bzImage %p could not prepare RM segment: %s\n", - image, strerror ( rc ) ); - return rc; - } - if ( ( rc = prep_segment ( bzimg.pm_kernel, bzimg.pm_sz, - bzimg.pm_sz ) ) != 0 ) { - DBGC ( image, "bzImage %p could not prepare PM segment: %s\n", - image, strerror ( rc ) ); - return rc; - } - - /* Parse command line for bootloader parameters */ - if ( ( rc = bzimage_parse_cmdline ( image, &bzimg, cmdline ) ) != 0) - return rc; - - /* Check that initrds can be loaded */ - if ( ( rc = bzimage_check_initrds ( image, &bzimg ) ) != 0 ) - return rc; - - /* Remove kernel from image list (without invalidating image pointer) */ - unregister_image ( image_get ( image ) ); - - /* Load segments */ - memcpy_user ( bzimg.rm_kernel, 0, image->data, - 0, bzimg.rm_filesz ); - memcpy_user ( bzimg.pm_kernel, 0, image->data, - bzimg.rm_filesz, bzimg.pm_sz ); - - /* Store command line */ - bzimage_set_cmdline ( image, &bzimg, cmdline ); - - /* Prepare for exiting. Must do this before loading initrds, - * since loading the initrds will corrupt the external heap. - */ - shutdown_boot(); - - /* Load any initrds */ - bzimage_load_initrds ( image, &bzimg ); - - /* Update kernel header */ - bzimage_update_header ( image, &bzimg, bzimg.rm_kernel ); - - DBGC ( image, "bzImage %p jumping to RM kernel at %04x:0000 " - "(stack %04x:%04zx)\n", image, ( bzimg.rm_kernel_seg + 0x20 ), - bzimg.rm_kernel_seg, bzimg.rm_heap ); - - /* Jump to the kernel */ - __asm__ __volatile__ ( REAL_CODE ( "movw %w0, %%ds\n\t" - "movw %w0, %%es\n\t" - "movw %w0, %%fs\n\t" - "movw %w0, %%gs\n\t" - "movw %w0, %%ss\n\t" - "movw %w1, %%sp\n\t" - "pushw %w2\n\t" - "pushw $0\n\t" - "lret\n\t" ) - : : "r" ( bzimg.rm_kernel_seg ), - "r" ( bzimg.rm_heap ), - "r" ( bzimg.rm_kernel_seg + 0x20 ) ); - - /* There is no way for the image to return, since we provide - * no return address. - */ - assert ( 0 ); - - return -ECANCELED; /* -EIMPOSSIBLE */ -} - -/** - * Probe bzImage image - * - * @v image bzImage file - * @ret rc Return status code - */ -int bzimage_probe ( struct image *image ) { - struct bzimage_context bzimg; - int rc; - - /* Read and parse header from image */ - if ( ( rc = bzimage_parse_header ( image, &bzimg, - image->data ) ) != 0 ) - return rc; - - return 0; -} - -/** Linux bzImage image type */ -struct image_type bzimage_image_type __image_type ( PROBE_NORMAL ) = { - .name = "bzImage", - .probe = bzimage_probe, - .exec = bzimage_exec, -}; diff --git a/qemu/roms/ipxe/src/arch/i386/image/com32.c b/qemu/roms/ipxe/src/arch/i386/image/com32.c deleted file mode 100644 index c12ffb684..000000000 --- a/qemu/roms/ipxe/src/arch/i386/image/com32.c +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright (C) 2008 Daniel Verkamp <daniel@drv.nu>. - * - * 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. - */ - -/** - * @file - * - * SYSLINUX COM32 image format - * - */ - -FILE_LICENCE ( GPL2_OR_LATER ); - -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <strings.h> -#include <errno.h> -#include <assert.h> -#include <realmode.h> -#include <basemem.h> -#include <comboot.h> -#include <ipxe/uaccess.h> -#include <ipxe/image.h> -#include <ipxe/segment.h> -#include <ipxe/init.h> -#include <ipxe/io.h> - -/** - * Execute COMBOOT image - * - * @v image COM32 image - * @ret rc Return status code - */ -static int com32_exec_loop ( struct image *image ) { - struct memory_map memmap; - unsigned int i; - int state; - uint32_t avail_mem_top; - - state = rmsetjmp ( comboot_return ); - - switch ( state ) { - case 0: /* First time through; invoke COM32 program */ - - /* Get memory map */ - get_memmap ( &memmap ); - - /* Find end of block covering COM32 image loading area */ - for ( i = 0, avail_mem_top = 0 ; i < memmap.count ; i++ ) { - if ( (memmap.regions[i].start <= COM32_START_PHYS) && - (memmap.regions[i].end > COM32_START_PHYS + image->len) ) { - avail_mem_top = memmap.regions[i].end; - break; - } - } - - DBGC ( image, "COM32 %p: available memory top = 0x%x\n", - image, avail_mem_top ); - - assert ( avail_mem_top != 0 ); - - com32_external_esp = phys_to_virt ( avail_mem_top ); - - /* Hook COMBOOT API interrupts */ - hook_comboot_interrupts(); - - /* Unregister image, so that a "boot" command doesn't - * throw us into an execution loop. We never - * reregister ourselves; COMBOOT images expect to be - * removed on exit. - */ - unregister_image ( image ); - - __asm__ __volatile__ ( - "movl %%esp, (com32_internal_esp)\n\t" /* Save internal virtual address space ESP */ - "movl (com32_external_esp), %%esp\n\t" /* Switch to COM32 ESP (top of available memory) */ - "call _virt_to_phys\n\t" /* Switch to flat physical address space */ - "sti\n\t" /* Enable interrupts */ - "pushl %0\n\t" /* Pointer to CDECL helper function */ - "pushl %1\n\t" /* Pointer to FAR call helper function */ - "pushl %2\n\t" /* Size of low memory bounce buffer */ - "pushl %3\n\t" /* Pointer to low memory bounce buffer */ - "pushl %4\n\t" /* Pointer to INT call helper function */ - "pushl %5\n\t" /* Pointer to the command line arguments */ - "pushl $6\n\t" /* Number of additional arguments */ - "call *%6\n\t" /* Execute image */ - "cli\n\t" /* Disable interrupts */ - "call _phys_to_virt\n\t" /* Switch back to internal virtual address space */ - "movl (com32_internal_esp), %%esp\n\t" /* Switch back to internal stack */ - : - : - /* %0 */ "r" ( virt_to_phys ( com32_cfarcall_wrapper ) ), - /* %1 */ "r" ( virt_to_phys ( com32_farcall_wrapper ) ), - /* %2 */ "r" ( get_fbms() * 1024 - (COM32_BOUNCE_SEG << 4) ), - /* %3 */ "i" ( COM32_BOUNCE_SEG << 4 ), - /* %4 */ "r" ( virt_to_phys ( com32_intcall_wrapper ) ), - /* %5 */ "r" ( virt_to_phys ( image->cmdline ? - image->cmdline : "" ) ), - /* %6 */ "r" ( COM32_START_PHYS ) - : - "memory" ); - DBGC ( image, "COM32 %p: returned\n", image ); - break; - - case COMBOOT_EXIT: - DBGC ( image, "COM32 %p: exited\n", image ); - break; - - case COMBOOT_EXIT_RUN_KERNEL: - assert ( image->replacement ); - DBGC ( image, "COM32 %p: exited to run kernel %s\n", - image, image->replacement->name ); - break; - - case COMBOOT_EXIT_COMMAND: - DBGC ( image, "COM32 %p: exited after executing command\n", - image ); - break; - - default: - assert ( 0 ); - break; - } - - unhook_comboot_interrupts(); - comboot_force_text_mode(); - - return 0; -} - -/** - * Check image name extension - * - * @v image COM32 image - * @ret rc Return status code - */ -static int com32_identify ( struct image *image ) { - const char *ext; - static const uint8_t magic[] = { 0xB8, 0xFF, 0x4C, 0xCD, 0x21 }; - uint8_t buf[5]; - - if ( image->len >= 5 ) { - /* Check for magic number - * mov eax,21cd4cffh - * B8 FF 4C CD 21 - */ - copy_from_user ( buf, image->data, 0, sizeof(buf) ); - if ( ! memcmp ( buf, magic, sizeof(buf) ) ) { - DBGC ( image, "COM32 %p: found magic number\n", - image ); - return 0; - } - } - - /* Magic number not found; check filename extension */ - - ext = strrchr( image->name, '.' ); - - if ( ! ext ) { - DBGC ( image, "COM32 %p: no extension\n", - image ); - return -ENOEXEC; - } - - ++ext; - - if ( strcasecmp( ext, "c32" ) ) { - DBGC ( image, "COM32 %p: unrecognized extension %s\n", - image, ext ); - return -ENOEXEC; - } - - return 0; -} - - -/** - * Load COM32 image into memory - * @v image COM32 image - * @ret rc Return status code - */ -static int com32_load_image ( struct image *image ) { - size_t filesz, memsz; - userptr_t buffer; - int rc; - - filesz = image->len; - memsz = filesz; - buffer = phys_to_user ( COM32_START_PHYS ); - if ( ( rc = prep_segment ( buffer, filesz, memsz ) ) != 0 ) { - DBGC ( image, "COM32 %p: could not prepare segment: %s\n", - image, strerror ( rc ) ); - return rc; - } - - /* Copy image to segment */ - memcpy_user ( buffer, 0, image->data, 0, filesz ); - - return 0; -} - -/** - * Prepare COM32 low memory bounce buffer - * @v image COM32 image - * @ret rc Return status code - */ -static int com32_prepare_bounce_buffer ( struct image * image ) { - unsigned int seg; - userptr_t seg_userptr; - size_t filesz, memsz; - int rc; - - seg = COM32_BOUNCE_SEG; - seg_userptr = real_to_user ( seg, 0 ); - - /* Ensure the entire 64k segment is free */ - memsz = 0xFFFF; - filesz = 0; - - /* Prepare, verify, and load the real-mode segment */ - if ( ( rc = prep_segment ( seg_userptr, filesz, memsz ) ) != 0 ) { - DBGC ( image, "COM32 %p: could not prepare bounce buffer segment: %s\n", - image, strerror ( rc ) ); - return rc; - } - - return 0; -} - -/** - * Probe COM32 image - * - * @v image COM32 image - * @ret rc Return status code - */ -static int com32_probe ( struct image *image ) { - int rc; - - DBGC ( image, "COM32 %p: name '%s'\n", image, image->name ); - - /* Check if this is a COMBOOT image */ - if ( ( rc = com32_identify ( image ) ) != 0 ) { - return rc; - } - - return 0; -} - -/** - * Execute COMBOOT image - * - * @v image COM32 image - * @ret rc Return status code - */ -static int com32_exec ( struct image *image ) { - int rc; - - /* Load image */ - if ( ( rc = com32_load_image ( image ) ) != 0 ) { - return rc; - } - - /* Prepare bounce buffer segment */ - if ( ( rc = com32_prepare_bounce_buffer ( image ) ) != 0 ) { - return rc; - } - - return com32_exec_loop ( image ); -} - -/** SYSLINUX COM32 image type */ -struct image_type com32_image_type __image_type ( PROBE_NORMAL ) = { - .name = "COM32", - .probe = com32_probe, - .exec = com32_exec, -}; diff --git a/qemu/roms/ipxe/src/arch/i386/image/comboot.c b/qemu/roms/ipxe/src/arch/i386/image/comboot.c deleted file mode 100644 index 1ec02331d..000000000 --- a/qemu/roms/ipxe/src/arch/i386/image/comboot.c +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright (C) 2008 Daniel Verkamp <daniel@drv.nu>. - * - * 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. - */ - -/** - * @file - * - * SYSLINUX COMBOOT (16-bit) image format - * - */ - -FILE_LICENCE ( GPL2_OR_LATER ); - -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <strings.h> -#include <errno.h> -#include <assert.h> -#include <realmode.h> -#include <basemem.h> -#include <comboot.h> -#include <ipxe/uaccess.h> -#include <ipxe/image.h> -#include <ipxe/segment.h> -#include <ipxe/init.h> -#include <ipxe/features.h> - -FEATURE ( FEATURE_IMAGE, "COMBOOT", DHCP_EB_FEATURE_COMBOOT, 1 ); - -/** - * COMBOOT PSP, copied to offset 0 of code segment - */ -struct comboot_psp { - /** INT 20 instruction, executed if COMBOOT image returns with RET */ - uint16_t int20; - /** Segment of first non-free paragraph of memory */ - uint16_t first_non_free_para; -}; - -/** Offset in PSP of command line */ -#define COMBOOT_PSP_CMDLINE_OFFSET 0x81 - -/** Maximum length of command line in PSP - * (127 bytes minus space and CR) */ -#define COMBOOT_MAX_CMDLINE_LEN 125 - - -/** - * Copy command line to PSP - * - * @v image COMBOOT image - */ -static void comboot_copy_cmdline ( struct image * image, userptr_t seg_userptr ) { - const char *cmdline = ( image->cmdline ? image->cmdline : "" ); - int cmdline_len = strlen ( cmdline ); - if( cmdline_len > COMBOOT_MAX_CMDLINE_LEN ) - cmdline_len = COMBOOT_MAX_CMDLINE_LEN; - uint8_t len_byte = cmdline_len; - char spc = ' ', cr = '\r'; - - /* Copy length to byte before command line */ - copy_to_user ( seg_userptr, COMBOOT_PSP_CMDLINE_OFFSET - 1, - &len_byte, 1 ); - - /* Command line starts with space */ - copy_to_user ( seg_userptr, - COMBOOT_PSP_CMDLINE_OFFSET, - &spc, 1 ); - - /* Copy command line */ - copy_to_user ( seg_userptr, - COMBOOT_PSP_CMDLINE_OFFSET + 1, - cmdline, cmdline_len ); - - /* Command line ends with CR */ - copy_to_user ( seg_userptr, - COMBOOT_PSP_CMDLINE_OFFSET + cmdline_len + 1, - &cr, 1 ); -} - -/** - * Initialize PSP - * - * @v image COMBOOT image - * @v seg_userptr segment to initialize - */ -static void comboot_init_psp ( struct image * image, userptr_t seg_userptr ) { - struct comboot_psp psp; - - /* Fill PSP */ - - /* INT 20h instruction, byte order reversed */ - psp.int20 = 0x20CD; - - /* get_fbms() returns BIOS free base memory counter, which is in - * kilobytes; x * 1024 / 16 == x * 64 == x << 6 */ - psp.first_non_free_para = get_fbms() << 6; - - DBGC ( image, "COMBOOT %p: first non-free paragraph = 0x%x\n", - image, psp.first_non_free_para ); - - /* Copy the PSP to offset 0 of segment. - * The rest of the PSP was already zeroed by - * comboot_prepare_segment. */ - copy_to_user ( seg_userptr, 0, &psp, sizeof( psp ) ); - - /* Copy the command line to the PSP */ - comboot_copy_cmdline ( image, seg_userptr ); -} - -/** - * Execute COMBOOT image - * - * @v image COMBOOT image - * @ret rc Return status code - */ -static int comboot_exec_loop ( struct image *image ) { - userptr_t seg_userptr = real_to_user ( COMBOOT_PSP_SEG, 0 ); - int state; - - state = rmsetjmp ( comboot_return ); - - switch ( state ) { - case 0: /* First time through; invoke COMBOOT program */ - - /* Initialize PSP */ - comboot_init_psp ( image, seg_userptr ); - - /* Hook COMBOOT API interrupts */ - hook_comboot_interrupts(); - - DBGC ( image, "executing 16-bit COMBOOT image at %4x:0100\n", - COMBOOT_PSP_SEG ); - - /* Unregister image, so that a "boot" command doesn't - * throw us into an execution loop. We never - * reregister ourselves; COMBOOT images expect to be - * removed on exit. - */ - unregister_image ( image ); - - /* Store stack segment at 0x38 and stack pointer at 0x3A - * in the PSP and jump to the image */ - __asm__ __volatile__ ( - REAL_CODE ( /* Save return address with segment on old stack */ - "popw %%ax\n\t" - "pushw %%cs\n\t" - "pushw %%ax\n\t" - /* Set DS=ES=segment with image */ - "movw %w0, %%ds\n\t" - "movw %w0, %%es\n\t" - /* Set SS:SP to new stack (end of image segment) */ - "movw %w0, %%ss\n\t" - "xor %%sp, %%sp\n\t" - "pushw $0\n\t" - "pushw %w0\n\t" - "pushw $0x100\n\t" - /* Zero registers (some COM files assume GP regs are 0) */ - "xorw %%ax, %%ax\n\t" - "xorw %%bx, %%bx\n\t" - "xorw %%cx, %%cx\n\t" - "xorw %%dx, %%dx\n\t" - "xorw %%si, %%si\n\t" - "xorw %%di, %%di\n\t" - "xorw %%bp, %%bp\n\t" - "lret\n\t" ) - : : "r" ( COMBOOT_PSP_SEG ) : "eax" ); - DBGC ( image, "COMBOOT %p: returned\n", image ); - break; - - case COMBOOT_EXIT: - DBGC ( image, "COMBOOT %p: exited\n", image ); - break; - - case COMBOOT_EXIT_RUN_KERNEL: - assert ( image->replacement ); - DBGC ( image, "COMBOOT %p: exited to run kernel %s\n", - image, image->replacement->name ); - break; - - case COMBOOT_EXIT_COMMAND: - DBGC ( image, "COMBOOT %p: exited after executing command\n", - image ); - break; - - default: - assert ( 0 ); - break; - } - - unhook_comboot_interrupts(); - comboot_force_text_mode(); - - return 0; -} - -/** - * Check image name extension - * - * @v image COMBOOT image - * @ret rc Return status code - */ -static int comboot_identify ( struct image *image ) { - const char *ext; - - ext = strrchr( image->name, '.' ); - - if ( ! ext ) { - DBGC ( image, "COMBOOT %p: no extension\n", - image ); - return -ENOEXEC; - } - - ++ext; - - if ( strcasecmp( ext, "cbt" ) ) { - DBGC ( image, "COMBOOT %p: unrecognized extension %s\n", - image, ext ); - return -ENOEXEC; - } - - return 0; -} - -/** - * Load COMBOOT image into memory, preparing a segment and returning it - * @v image COMBOOT image - * @ret rc Return status code - */ -static int comboot_prepare_segment ( struct image *image ) -{ - userptr_t seg_userptr; - size_t filesz, memsz; - int rc; - - /* Load image in segment */ - seg_userptr = real_to_user ( COMBOOT_PSP_SEG, 0 ); - - /* Allow etra 0x100 bytes before image for PSP */ - filesz = image->len + 0x100; - - /* Ensure the entire 64k segment is free */ - memsz = 0xFFFF; - - /* Prepare, verify, and load the real-mode segment */ - if ( ( rc = prep_segment ( seg_userptr, filesz, memsz ) ) != 0 ) { - DBGC ( image, "COMBOOT %p: could not prepare segment: %s\n", - image, strerror ( rc ) ); - return rc; - } - - /* Zero PSP */ - memset_user ( seg_userptr, 0, 0, 0x100 ); - - /* Copy image to segment:0100 */ - memcpy_user ( seg_userptr, 0x100, image->data, 0, image->len ); - - return 0; -} - -/** - * Probe COMBOOT image - * - * @v image COMBOOT image - * @ret rc Return status code - */ -static int comboot_probe ( struct image *image ) { - int rc; - - DBGC ( image, "COMBOOT %p: name '%s'\n", - image, image->name ); - - /* Check if this is a COMBOOT image */ - if ( ( rc = comboot_identify ( image ) ) != 0 ) { - - return rc; - } - - return 0; -} - -/** - * Execute COMBOOT image - * - * @v image COMBOOT image - * @ret rc Return status code - */ -static int comboot_exec ( struct image *image ) { - int rc; - - /* Sanity check for filesize */ - if( image->len >= 0xFF00 ) { - DBGC( image, "COMBOOT %p: image too large\n", - image ); - return -ENOEXEC; - } - - /* Prepare segment and load image */ - if ( ( rc = comboot_prepare_segment ( image ) ) != 0 ) { - return rc; - } - - return comboot_exec_loop ( image ); -} - -/** SYSLINUX COMBOOT (16-bit) image type */ -struct image_type comboot_image_type __image_type ( PROBE_NORMAL ) = { - .name = "COMBOOT", - .probe = comboot_probe, - .exec = comboot_exec, -}; diff --git a/qemu/roms/ipxe/src/arch/i386/image/elfboot.c b/qemu/roms/ipxe/src/arch/i386/image/elfboot.c deleted file mode 100644 index dc3568929..000000000 --- a/qemu/roms/ipxe/src/arch/i386/image/elfboot.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 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 <errno.h> -#include <elf.h> -#include <ipxe/image.h> -#include <ipxe/elf.h> -#include <ipxe/features.h> -#include <ipxe/init.h> - -/** - * @file - * - * ELF bootable image - * - */ - -FEATURE ( FEATURE_IMAGE, "ELF", DHCP_EB_FEATURE_ELF, 1 ); - -/** - * Execute ELF image - * - * @v image ELF image - * @ret rc Return status code - */ -static int elfboot_exec ( struct image *image ) { - physaddr_t entry; - physaddr_t max; - int rc; - - /* Load the image using core ELF support */ - if ( ( rc = elf_load ( image, &entry, &max ) ) != 0 ) { - DBGC ( image, "ELF %p could not load: %s\n", - image, strerror ( rc ) ); - return rc; - } - - /* An ELF image has no callback interface, so we need to shut - * down before invoking it. - */ - shutdown_boot(); - - /* Jump to OS with flat physical addressing */ - DBGC ( image, "ELF %p starting execution at %lx\n", image, entry ); - __asm__ __volatile__ ( PHYS_CODE ( "pushl %%ebp\n\t" /* gcc bug */ - "call *%%edi\n\t" - "popl %%ebp\n\t" /* gcc bug */ ) - : : "D" ( entry ) - : "eax", "ebx", "ecx", "edx", "esi", "memory" ); - - DBGC ( image, "ELF %p returned\n", image ); - - /* It isn't safe to continue after calling shutdown() */ - while ( 1 ) {} - - return -ECANCELED; /* -EIMPOSSIBLE, anyone? */ -} - -/** - * Check that ELF segment uses flat physical addressing - * - * @v image ELF file - * @v phdr ELF program header - * @v dest Destination address - * @ret rc Return status code - */ -static int elfboot_check_segment ( struct image *image, Elf_Phdr *phdr, - physaddr_t dest ) { - - /* Check that ELF segment uses flat physical addressing */ - if ( phdr->p_vaddr != dest ) { - DBGC ( image, "ELF %p uses virtual addressing (phys %x, " - "virt %x)\n", image, phdr->p_paddr, phdr->p_vaddr ); - return -ENOEXEC; - } - - return 0; -} - -/** - * Probe ELF image - * - * @v image ELF file - * @ret rc Return status code - */ -static int elfboot_probe ( struct image *image ) { - Elf32_Ehdr ehdr; - static const uint8_t e_ident[] = { - [EI_MAG0] = ELFMAG0, - [EI_MAG1] = ELFMAG1, - [EI_MAG2] = ELFMAG2, - [EI_MAG3] = ELFMAG3, - [EI_CLASS] = ELFCLASS32, - [EI_DATA] = ELFDATA2LSB, - [EI_VERSION] = EV_CURRENT, - }; - physaddr_t entry; - physaddr_t max; - int rc; - - /* Read ELF header */ - copy_from_user ( &ehdr, image->data, 0, sizeof ( ehdr ) ); - if ( memcmp ( ehdr.e_ident, e_ident, sizeof ( e_ident ) ) != 0 ) { - DBGC ( image, "Invalid ELF identifier\n" ); - return -ENOEXEC; - } - - /* Check that this image uses flat physical addressing */ - if ( ( rc = elf_segments ( image, &ehdr, elfboot_check_segment, - &entry, &max ) ) != 0 ) { - DBGC ( image, "Unloadable ELF image\n" ); - return rc; - } - - return 0; -} - -/** ELF image type */ -struct image_type elfboot_image_type __image_type ( PROBE_NORMAL ) = { - .name = "ELF", - .probe = elfboot_probe, - .exec = elfboot_exec, -}; diff --git a/qemu/roms/ipxe/src/arch/i386/image/initrd.c b/qemu/roms/ipxe/src/arch/i386/image/initrd.c deleted file mode 100644 index 80c197417..000000000 --- a/qemu/roms/ipxe/src/arch/i386/image/initrd.c +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Copyright (C) 2012 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 (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 <errno.h> -#include <initrd.h> -#include <ipxe/image.h> -#include <ipxe/uaccess.h> -#include <ipxe/init.h> -#include <ipxe/memblock.h> - -/** @file - * - * Initial ramdisk (initrd) reshuffling - * - */ - -/** Maximum address available for initrd */ -userptr_t initrd_top; - -/** Minimum address available for initrd */ -userptr_t initrd_bottom; - -/** - * Squash initrds as high as possible in memory - * - * @v top Highest possible address - * @ret used Lowest address used by initrds - */ -static userptr_t initrd_squash_high ( userptr_t top ) { - userptr_t current = top; - struct image *initrd; - struct image *highest; - size_t len; - - /* Squash up any initrds already within or below the region */ - while ( 1 ) { - - /* Find the highest image not yet in its final position */ - highest = NULL; - for_each_image ( initrd ) { - if ( ( userptr_sub ( initrd->data, current ) < 0 ) && - ( ( highest == NULL ) || - ( userptr_sub ( initrd->data, - highest->data ) > 0 ) ) ) { - highest = initrd; - } - } - if ( ! highest ) - break; - - /* Move this image to its final position */ - len = ( ( highest->len + INITRD_ALIGN - 1 ) & - ~( INITRD_ALIGN - 1 ) ); - current = userptr_sub ( current, len ); - DBGC ( &images, "INITRD squashing %s [%#08lx,%#08lx)->" - "[%#08lx,%#08lx)\n", highest->name, - user_to_phys ( highest->data, 0 ), - user_to_phys ( highest->data, highest->len ), - user_to_phys ( current, 0 ), - user_to_phys ( current, highest->len ) ); - memmove_user ( current, 0, highest->data, 0, highest->len ); - highest->data = current; - } - - /* Copy any remaining initrds (e.g. embedded images) to the region */ - for_each_image ( initrd ) { - if ( userptr_sub ( initrd->data, top ) >= 0 ) { - len = ( ( initrd->len + INITRD_ALIGN - 1 ) & - ~( INITRD_ALIGN - 1 ) ); - current = userptr_sub ( current, len ); - DBGC ( &images, "INITRD copying %s [%#08lx,%#08lx)->" - "[%#08lx,%#08lx)\n", initrd->name, - user_to_phys ( initrd->data, 0 ), - user_to_phys ( initrd->data, initrd->len ), - user_to_phys ( current, 0 ), - user_to_phys ( current, initrd->len ) ); - memcpy_user ( current, 0, initrd->data, 0, - initrd->len ); - initrd->data = current; - } - } - - return current; -} - -/** - * Swap position of two adjacent initrds - * - * @v low Lower initrd - * @v high Higher initrd - * @v free Free space - * @v free_len Length of free space - */ -static void initrd_swap ( struct image *low, struct image *high, - userptr_t free, size_t free_len ) { - size_t len = 0; - size_t frag_len; - size_t new_len; - - DBGC ( &images, "INITRD swapping %s [%#08lx,%#08lx)<->[%#08lx,%#08lx) " - "%s\n", low->name, user_to_phys ( low->data, 0 ), - user_to_phys ( low->data, low->len ), - user_to_phys ( high->data, 0 ), - user_to_phys ( high->data, high->len ), high->name ); - - /* Round down length of free space */ - free_len &= ~( INITRD_ALIGN - 1 ); - assert ( free_len > 0 ); - - /* Swap image data */ - while ( len < high->len ) { - - /* Calculate maximum fragment length */ - frag_len = ( high->len - len ); - if ( frag_len > free_len ) - frag_len = free_len; - new_len = ( ( len + frag_len + INITRD_ALIGN - 1 ) & - ~( INITRD_ALIGN - 1 ) ); - - /* Swap fragments */ - memcpy_user ( free, 0, high->data, len, frag_len ); - memmove_user ( low->data, new_len, low->data, len, low->len ); - memcpy_user ( low->data, len, free, 0, frag_len ); - len = new_len; - } - - /* Adjust data pointers */ - high->data = low->data; - low->data = userptr_add ( low->data, len ); -} - -/** - * Swap position of any two adjacent initrds not currently in the correct order - * - * @v free Free space - * @v free_len Length of free space - * @ret swapped A pair of initrds was swapped - */ -static int initrd_swap_any ( userptr_t free, size_t free_len ) { - struct image *low; - struct image *high; - size_t padded_len; - userptr_t adjacent; - - /* Find any pair of initrds that can be swapped */ - for_each_image ( low ) { - - /* Calculate location of adjacent image (if any) */ - padded_len = ( ( low->len + INITRD_ALIGN - 1 ) & - ~( INITRD_ALIGN - 1 ) ); - adjacent = userptr_add ( low->data, padded_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; - } - } - - /* Nothing swapped */ - return 0; -} - -/** - * Dump initrd locations (for debug) - * - */ -static void initrd_dump ( void ) { - struct image *initrd; - - /* Do nothing unless debugging is enabled */ - if ( ! DBG_LOG ) - return; - - /* Dump initrd locations */ - for_each_image ( initrd ) { - DBGC ( &images, "INITRD %s at [%#08lx,%#08lx)\n", - initrd->name, user_to_phys ( initrd->data, 0 ), - user_to_phys ( initrd->data, initrd->len ) ); - DBGC2_MD5A ( &images, user_to_phys ( initrd->data, 0 ), - user_to_virt ( initrd->data, 0 ), initrd->len ); - } -} - -/** - * Reshuffle initrds into desired order at top of memory - * - * @v bottom Lowest address available for initrds - * - * After this function returns, the initrds have been rearranged in - * memory and the external heap structures will have been corrupted. - * Reshuffling must therefore take place immediately prior to jumping - * to the loaded OS kernel; no further execution within iPXE is - * permitted. - */ -void initrd_reshuffle ( userptr_t bottom ) { - userptr_t top; - userptr_t used; - userptr_t free; - size_t free_len; - - /* Calculate limits of available space for initrds */ - top = initrd_top; - if ( userptr_sub ( initrd_bottom, bottom ) > 0 ) - bottom = initrd_bottom; - - /* Debug */ - DBGC ( &images, "INITRD region [%#08lx,%#08lx)\n", - user_to_phys ( bottom, 0 ), user_to_phys ( top, 0 ) ); - initrd_dump(); - - /* Squash initrds as high as possible in memory */ - used = initrd_squash_high ( top ); - - /* Calculate available free space */ - free = bottom; - free_len = userptr_sub ( used, free ); - - /* Bubble-sort initrds into desired order */ - while ( initrd_swap_any ( free, free_len ) ) {} - - /* Debug */ - initrd_dump(); -} - -/** - * Check that there is enough space to reshuffle initrds - * - * @v len Total length of initrds (including padding) - * @v bottom Lowest address available for initrds - * @ret rc Return status code - */ -int initrd_reshuffle_check ( size_t len, userptr_t bottom ) { - userptr_t top; - size_t available; - - /* Calculate limits of available space for initrds */ - top = initrd_top; - if ( userptr_sub ( initrd_bottom, bottom ) > 0 ) - bottom = initrd_bottom; - available = userptr_sub ( top, bottom ); - - /* Allow for a sensible minimum amount of free space */ - len += INITRD_MIN_FREE_LEN; - - /* Check for available space */ - return ( ( len < available ) ? 0 : -ENOBUFS ); -} - -/** - * initrd startup function - * - */ -static void initrd_startup ( void ) { - size_t len; - - /* Record largest memory block available. Do this after any - * allocations made during driver startup (e.g. large host - * memory blocks for Infiniband devices, which may still be in - * use at the time of rearranging if a SAN device is hooked) - * but before any allocations for downloaded images (which we - * can safely reuse when rearranging). - */ - len = largest_memblock ( &initrd_bottom ); - initrd_top = userptr_add ( initrd_bottom, len ); -} - -/** initrd startup function */ -struct startup_fn startup_initrd __startup_fn ( STARTUP_LATE ) = { - .startup = initrd_startup, -}; diff --git a/qemu/roms/ipxe/src/arch/i386/image/multiboot.c b/qemu/roms/ipxe/src/arch/i386/image/multiboot.c deleted file mode 100644 index 0c85df708..000000000 --- a/qemu/roms/ipxe/src/arch/i386/image/multiboot.c +++ /dev/null @@ -1,492 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 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 ); - -/** - * @file - * - * Multiboot image format - * - */ - -#include <stdio.h> -#include <errno.h> -#include <assert.h> -#include <realmode.h> -#include <multiboot.h> -#include <ipxe/uaccess.h> -#include <ipxe/image.h> -#include <ipxe/segment.h> -#include <ipxe/io.h> -#include <ipxe/elf.h> -#include <ipxe/init.h> -#include <ipxe/features.h> -#include <ipxe/uri.h> -#include <ipxe/version.h> - -FEATURE ( FEATURE_IMAGE, "MBOOT", DHCP_EB_FEATURE_MULTIBOOT, 1 ); - -/** - * Maximum number of modules we will allow for - * - * If this has bitten you: sorry. I did have a perfect scheme with a - * dynamically allocated list of modules on the protected-mode stack, - * but it was incompatible with some broken OSes that can only access - * low memory at boot time (even though we kindly set up 4GB flat - * physical addressing as per the multiboot specification. - * - */ -#define MAX_MODULES 8 - -/** - * Maximum combined length of command lines - * - * Again; sorry. Some broken OSes zero out any non-base memory that - * isn't part of the loaded module set, so we can't just use - * virt_to_phys(cmdline) to point to the command lines, even though - * this would comply with the Multiboot spec. - */ -#define MB_MAX_CMDLINE 512 - -/** Multiboot flags that we support */ -#define MB_SUPPORTED_FLAGS ( MB_FLAG_PGALIGN | MB_FLAG_MEMMAP | \ - MB_FLAG_VIDMODE | MB_FLAG_RAW ) - -/** Compulsory feature multiboot flags */ -#define MB_COMPULSORY_FLAGS 0x0000ffff - -/** Optional feature multiboot flags */ -#define MB_OPTIONAL_FLAGS 0xffff0000 - -/** - * Multiboot flags that we don't support - * - * We only care about the compulsory feature flags (bits 0-15); we are - * allowed to ignore the optional feature flags. - */ -#define MB_UNSUPPORTED_FLAGS ( MB_COMPULSORY_FLAGS & ~MB_SUPPORTED_FLAGS ) - -/** A multiboot header descriptor */ -struct multiboot_header_info { - /** The actual multiboot header */ - struct multiboot_header mb; - /** Offset of header within the multiboot image */ - size_t offset; -}; - -/** Multiboot module command lines */ -static char __bss16_array ( mb_cmdlines, [MB_MAX_CMDLINE] ); -#define mb_cmdlines __use_data16 ( mb_cmdlines ) - -/** Offset within module command lines */ -static unsigned int mb_cmdline_offset; - -/** - * Build multiboot memory map - * - * @v image Multiboot image - * @v mbinfo Multiboot information structure - * @v mbmemmap Multiboot memory map - * @v limit Maxmimum number of memory map entries - */ -static void multiboot_build_memmap ( struct image *image, - struct multiboot_info *mbinfo, - struct multiboot_memory_map *mbmemmap, - unsigned int limit ) { - struct memory_map memmap; - unsigned int i; - - /* Get memory map */ - get_memmap ( &memmap ); - - /* Translate into multiboot format */ - memset ( mbmemmap, 0, sizeof ( *mbmemmap ) ); - for ( i = 0 ; i < memmap.count ; i++ ) { - if ( i >= limit ) { - DBGC ( image, "MULTIBOOT %p limit of %d memmap " - "entries reached\n", image, limit ); - break; - } - mbmemmap[i].size = ( sizeof ( mbmemmap[i] ) - - sizeof ( mbmemmap[i].size ) ); - mbmemmap[i].base_addr = memmap.regions[i].start; - mbmemmap[i].length = ( memmap.regions[i].end - - memmap.regions[i].start ); - mbmemmap[i].type = MBMEM_RAM; - mbinfo->mmap_length += sizeof ( mbmemmap[i] ); - if ( memmap.regions[i].start == 0 ) - mbinfo->mem_lower = ( memmap.regions[i].end / 1024 ); - if ( memmap.regions[i].start == 0x100000 ) - mbinfo->mem_upper = ( ( memmap.regions[i].end - - 0x100000 ) / 1024 ); - } -} - -/** - * Add command line in base memory - * - * @v image Image - * @ret physaddr Physical address of command line - */ -static physaddr_t multiboot_add_cmdline ( struct image *image ) { - char *mb_cmdline = ( mb_cmdlines + mb_cmdline_offset ); - size_t remaining = ( sizeof ( mb_cmdlines ) - mb_cmdline_offset ); - char *buf = mb_cmdline; - size_t len; - - /* Copy image URI to base memory buffer as start of command line */ - len = ( format_uri ( image->uri, buf, remaining ) + 1 /* NUL */ ); - if ( len > remaining ) - len = remaining; - mb_cmdline_offset += len; - buf += len; - remaining -= len; - - /* Copy command line to base memory buffer, if present */ - if ( image->cmdline ) { - mb_cmdline_offset--; /* Strip NUL */ - buf--; - remaining++; - len = ( snprintf ( buf, remaining, " %s", - image->cmdline ) + 1 /* NUL */ ); - if ( len > remaining ) - len = remaining; - mb_cmdline_offset += len; - } - - return virt_to_phys ( mb_cmdline ); -} - -/** - * Add multiboot modules - * - * @v image Multiboot image - * @v start Start address for modules - * @v mbinfo Multiboot information structure - * @v modules Multiboot module list - * @ret rc Return status code - */ -static int multiboot_add_modules ( struct image *image, physaddr_t start, - struct multiboot_info *mbinfo, - struct multiboot_module *modules, - unsigned int limit ) { - struct image *module_image; - struct multiboot_module *module; - int rc; - - /* Add each image as a multiboot module */ - for_each_image ( module_image ) { - - if ( mbinfo->mods_count >= limit ) { - DBGC ( image, "MULTIBOOT %p limit of %d modules " - "reached\n", image, limit ); - break; - } - - /* Do not include kernel image itself as a module */ - if ( module_image == image ) - continue; - - /* Page-align the module */ - start = ( ( start + 0xfff ) & ~0xfff ); - - /* Prepare segment */ - if ( ( rc = prep_segment ( phys_to_user ( start ), - module_image->len, - module_image->len ) ) != 0 ) { - DBGC ( image, "MULTIBOOT %p could not prepare module " - "%s: %s\n", image, module_image->name, - strerror ( rc ) ); - return rc; - } - - /* Copy module */ - memcpy_user ( phys_to_user ( start ), 0, - module_image->data, 0, module_image->len ); - - /* Add module to list */ - module = &modules[mbinfo->mods_count++]; - module->mod_start = start; - module->mod_end = ( start + module_image->len ); - module->string = multiboot_add_cmdline ( module_image ); - module->reserved = 0; - DBGC ( image, "MULTIBOOT %p module %s is [%x,%x)\n", - image, module_image->name, module->mod_start, - module->mod_end ); - start += module_image->len; - } - - return 0; -} - -/** - * The multiboot information structure - * - * Kept in base memory because some OSes won't find it elsewhere, - * along with the other structures belonging to the Multiboot - * information table. - */ -static struct multiboot_info __bss16 ( mbinfo ); -#define mbinfo __use_data16 ( mbinfo ) - -/** The multiboot bootloader name */ -static char __bss16_array ( mb_bootloader_name, [32] ); -#define mb_bootloader_name __use_data16 ( mb_bootloader_name ) - -/** The multiboot memory map */ -static struct multiboot_memory_map - __bss16_array ( mbmemmap, [MAX_MEMORY_REGIONS] ); -#define mbmemmap __use_data16 ( mbmemmap ) - -/** The multiboot module list */ -static struct multiboot_module __bss16_array ( mbmodules, [MAX_MODULES] ); -#define mbmodules __use_data16 ( mbmodules ) - -/** - * Find multiboot header - * - * @v image Multiboot file - * @v hdr Multiboot header descriptor to fill in - * @ret rc Return status code - */ -static int multiboot_find_header ( struct image *image, - struct multiboot_header_info *hdr ) { - uint32_t buf[64]; - size_t offset; - unsigned int buf_idx; - uint32_t checksum; - - /* Scan through first 8kB of image file 256 bytes at a time. - * (Use the buffering to avoid the overhead of a - * copy_from_user() for every dword.) - */ - for ( offset = 0 ; offset < 8192 ; offset += sizeof ( buf[0] ) ) { - /* Check for end of image */ - if ( offset > image->len ) - break; - /* Refill buffer if applicable */ - buf_idx = ( ( offset % sizeof ( buf ) ) / sizeof ( buf[0] ) ); - if ( buf_idx == 0 ) { - copy_from_user ( buf, image->data, offset, - sizeof ( buf ) ); - } - /* Check signature */ - if ( buf[buf_idx] != MULTIBOOT_HEADER_MAGIC ) - continue; - /* Copy header and verify checksum */ - copy_from_user ( &hdr->mb, image->data, offset, - sizeof ( hdr->mb ) ); - checksum = ( hdr->mb.magic + hdr->mb.flags + - hdr->mb.checksum ); - if ( checksum != 0 ) - continue; - /* Record offset of multiboot header and return */ - hdr->offset = offset; - return 0; - } - - /* No multiboot header found */ - return -ENOEXEC; -} - -/** - * Load raw multiboot image into memory - * - * @v image Multiboot file - * @v hdr Multiboot header descriptor - * @ret entry Entry point - * @ret max Maximum used address - * @ret rc Return status code - */ -static int multiboot_load_raw ( struct image *image, - struct multiboot_header_info *hdr, - physaddr_t *entry, physaddr_t *max ) { - size_t offset; - size_t filesz; - size_t memsz; - userptr_t buffer; - int rc; - - /* Sanity check */ - if ( ! ( hdr->mb.flags & MB_FLAG_RAW ) ) { - DBGC ( image, "MULTIBOOT %p is not flagged as a raw image\n", - image ); - return -EINVAL; - } - - /* Verify and prepare segment */ - offset = ( hdr->offset - hdr->mb.header_addr + hdr->mb.load_addr ); - filesz = ( hdr->mb.load_end_addr ? - ( hdr->mb.load_end_addr - hdr->mb.load_addr ) : - ( image->len - offset ) ); - memsz = ( hdr->mb.bss_end_addr ? - ( hdr->mb.bss_end_addr - hdr->mb.load_addr ) : filesz ); - buffer = phys_to_user ( hdr->mb.load_addr ); - if ( ( rc = prep_segment ( buffer, filesz, memsz ) ) != 0 ) { - DBGC ( image, "MULTIBOOT %p could not prepare segment: %s\n", - image, strerror ( rc ) ); - return rc; - } - - /* Copy image to segment */ - memcpy_user ( buffer, 0, image->data, offset, filesz ); - - /* Record execution entry point and maximum used address */ - *entry = hdr->mb.entry_addr; - *max = ( hdr->mb.load_addr + memsz ); - - return 0; -} - -/** - * Load ELF multiboot image into memory - * - * @v image Multiboot file - * @ret entry Entry point - * @ret max Maximum used address - * @ret rc Return status code - */ -static int multiboot_load_elf ( struct image *image, physaddr_t *entry, - physaddr_t *max ) { - int rc; - - /* Load ELF image*/ - if ( ( rc = elf_load ( image, entry, max ) ) != 0 ) { - DBGC ( image, "MULTIBOOT %p ELF image failed to load: %s\n", - image, strerror ( rc ) ); - return rc; - } - - return 0; -} - -/** - * Execute multiboot image - * - * @v image Multiboot image - * @ret rc Return status code - */ -static int multiboot_exec ( struct image *image ) { - struct multiboot_header_info hdr; - physaddr_t entry; - physaddr_t max; - int rc; - - /* Locate multiboot header, if present */ - if ( ( rc = multiboot_find_header ( image, &hdr ) ) != 0 ) { - DBGC ( image, "MULTIBOOT %p has no multiboot header\n", - image ); - return rc; - } - - /* Abort if we detect flags that we cannot support */ - if ( hdr.mb.flags & MB_UNSUPPORTED_FLAGS ) { - DBGC ( image, "MULTIBOOT %p flags %08x not supported\n", - image, ( hdr.mb.flags & MB_UNSUPPORTED_FLAGS ) ); - return -ENOTSUP; - } - - /* There is technically a bit MB_FLAG_RAW to indicate whether - * this is an ELF or a raw image. In practice, grub will use - * the ELF header if present, and Solaris relies on this - * behaviour. - */ - if ( ( ( rc = multiboot_load_elf ( image, &entry, &max ) ) != 0 ) && - ( ( rc = multiboot_load_raw ( image, &hdr, &entry, &max ) ) != 0 )) - return rc; - - /* Populate multiboot information structure */ - memset ( &mbinfo, 0, sizeof ( mbinfo ) ); - mbinfo.flags = ( MBI_FLAG_LOADER | MBI_FLAG_MEM | MBI_FLAG_MMAP | - MBI_FLAG_CMDLINE | MBI_FLAG_MODS ); - mb_cmdline_offset = 0; - mbinfo.cmdline = multiboot_add_cmdline ( image ); - mbinfo.mods_addr = virt_to_phys ( mbmodules ); - mbinfo.mmap_addr = virt_to_phys ( mbmemmap ); - snprintf ( mb_bootloader_name, sizeof ( mb_bootloader_name ), - "iPXE %s", product_version ); - mbinfo.boot_loader_name = virt_to_phys ( mb_bootloader_name ); - if ( ( rc = multiboot_add_modules ( image, max, &mbinfo, mbmodules, - ( sizeof ( mbmodules ) / - sizeof ( mbmodules[0] ) ) ) ) !=0) - return rc; - - /* Multiboot images may not return and have no callback - * interface, so shut everything down prior to booting the OS. - */ - shutdown_boot(); - - /* Build memory map after unhiding bootloader memory regions as part of - * shutting everything down. - */ - multiboot_build_memmap ( image, &mbinfo, mbmemmap, - ( sizeof(mbmemmap) / sizeof(mbmemmap[0]) ) ); - - /* Jump to OS with flat physical addressing */ - DBGC ( image, "MULTIBOOT %p starting execution at %lx\n", - image, entry ); - __asm__ __volatile__ ( PHYS_CODE ( "pushl %%ebp\n\t" - "call *%%edi\n\t" - "popl %%ebp\n\t" ) - : : "a" ( MULTIBOOT_BOOTLOADER_MAGIC ), - "b" ( virt_to_phys ( &mbinfo ) ), - "D" ( entry ) - : "ecx", "edx", "esi", "memory" ); - - DBGC ( image, "MULTIBOOT %p returned\n", image ); - - /* It isn't safe to continue after calling shutdown() */ - while ( 1 ) {} - - return -ECANCELED; /* -EIMPOSSIBLE, anyone? */ -} - -/** - * Probe multiboot image - * - * @v image Multiboot file - * @ret rc Return status code - */ -static int multiboot_probe ( struct image *image ) { - struct multiboot_header_info hdr; - int rc; - - /* Locate multiboot header, if present */ - if ( ( rc = multiboot_find_header ( image, &hdr ) ) != 0 ) { - DBGC ( image, "MULTIBOOT %p has no multiboot header\n", - image ); - return rc; - } - DBGC ( image, "MULTIBOOT %p found header with flags %08x\n", - image, hdr.mb.flags ); - - return 0; -} - -/** Multiboot image type */ -struct image_type multiboot_image_type __image_type ( PROBE_MULTIBOOT ) = { - .name = "Multiboot", - .probe = multiboot_probe, - .exec = multiboot_exec, -}; diff --git a/qemu/roms/ipxe/src/arch/i386/image/nbi.c b/qemu/roms/ipxe/src/arch/i386/image/nbi.c deleted file mode 100644 index 99046144d..000000000 --- a/qemu/roms/ipxe/src/arch/i386/image/nbi.c +++ /dev/null @@ -1,427 +0,0 @@ -#include <errno.h> -#include <assert.h> -#include <realmode.h> -#include <memsizes.h> -#include <basemem_packet.h> -#include <ipxe/uaccess.h> -#include <ipxe/segment.h> -#include <ipxe/init.h> -#include <ipxe/netdevice.h> -#include <ipxe/fakedhcp.h> -#include <ipxe/image.h> -#include <ipxe/features.h> -#include <ipxe/version.h> - -/** @file - * - * NBI image format. - * - * The Net Boot Image format is defined by the "Draft Net Boot Image - * Proposal 0.3" by Jamie Honan, Gero Kuhlmann and Ken Yap. It is now - * considered to be a legacy format, but it still included because a - * large amount of software (e.g. nymph, LTSP) makes use of NBI files. - * - * Etherboot does not implement the INT 78 callback interface - * described by the NBI specification. For a callback interface on - * x86 architecture, use PXE. - * - */ - -FEATURE ( FEATURE_IMAGE, "NBI", DHCP_EB_FEATURE_NBI, 1 ); - -/** - * An NBI image header - * - * Note that the length field uses a peculiar encoding; use the - * NBI_LENGTH() macro to decode the actual header length. - * - */ -struct imgheader { - unsigned long magic; /**< Magic number (NBI_MAGIC) */ - union { - unsigned char length; /**< Nibble-coded header length */ - unsigned long flags; /**< Image flags */ - }; - segoff_t location; /**< 16-bit seg:off header location */ - union { - segoff_t segoff; /**< 16-bit seg:off entry point */ - unsigned long linear; /**< 32-bit entry point */ - } execaddr; -} __attribute__ (( packed )); - -/** NBI magic number */ -#define NBI_MAGIC 0x1B031336UL - -/* Interpretation of the "length" fields */ -#define NBI_NONVENDOR_LENGTH(len) ( ( (len) & 0x0f ) << 2 ) -#define NBI_VENDOR_LENGTH(len) ( ( (len) & 0xf0 ) >> 2 ) -#define NBI_LENGTH(len) ( NBI_NONVENDOR_LENGTH(len) + NBI_VENDOR_LENGTH(len) ) - -/* Interpretation of the "flags" fields */ -#define NBI_PROGRAM_RETURNS(flags) ( (flags) & ( 1 << 8 ) ) -#define NBI_LINEAR_EXEC_ADDR(flags) ( (flags) & ( 1 << 31 ) ) - -/** NBI header length */ -#define NBI_HEADER_LENGTH 512 - -/** - * An NBI segment header - * - * Note that the length field uses a peculiar encoding; use the - * NBI_LENGTH() macro to decode the actual header length. - * - */ -struct segheader { - unsigned char length; /**< Nibble-coded header length */ - unsigned char vendortag; /**< Vendor-defined private tag */ - unsigned char reserved; - unsigned char flags; /**< Segment flags */ - unsigned long loadaddr; /**< Load address */ - unsigned long imglength; /**< Segment length in NBI file */ - unsigned long memlength; /**< Segment length in memory */ -}; - -/* Interpretation of the "flags" fields */ -#define NBI_LOADADDR_FLAGS(flags) ( (flags) & 0x03 ) -#define NBI_LOADADDR_ABS 0x00 -#define NBI_LOADADDR_AFTER 0x01 -#define NBI_LOADADDR_END 0x02 -#define NBI_LOADADDR_BEFORE 0x03 -#define NBI_LAST_SEGHEADER(flags) ( (flags) & ( 1 << 2 ) ) - -/* Define a type for passing info to a loaded program */ -struct ebinfo { - uint8_t major, minor; /* Version */ - uint16_t flags; /* Bit flags */ -}; - -/** - * Prepare a segment for an NBI image - * - * @v image NBI image - * @v offset Offset within NBI image - * @v filesz Length of initialised-data portion of the segment - * @v memsz Total length of the segment - * @v src Source for initialised data - * @ret rc Return status code - */ -static int nbi_prepare_segment ( struct image *image, size_t offset __unused, - userptr_t dest, size_t filesz, size_t memsz ){ - int rc; - - if ( ( rc = prep_segment ( dest, filesz, memsz ) ) != 0 ) { - DBGC ( image, "NBI %p could not prepare segment: %s\n", - image, strerror ( rc ) ); - return rc; - } - - return 0; -} - -/** - * Load a segment for an NBI image - * - * @v image NBI image - * @v offset Offset within NBI image - * @v filesz Length of initialised-data portion of the segment - * @v memsz Total length of the segment - * @v src Source for initialised data - * @ret rc Return status code - */ -static int nbi_load_segment ( struct image *image, size_t offset, - userptr_t dest, size_t filesz, - size_t memsz __unused ) { - memcpy_user ( dest, 0, image->data, offset, filesz ); - return 0; -} - -/** - * Process segments of an NBI image - * - * @v image NBI image - * @v imgheader Image header information - * @v process Function to call for each segment - * @ret rc Return status code - */ -static int nbi_process_segments ( struct image *image, - struct imgheader *imgheader, - int ( * process ) ( struct image *image, - size_t offset, - userptr_t dest, - size_t filesz, - size_t memsz ) ) { - struct segheader sh; - size_t offset = 0; - size_t sh_off; - userptr_t dest; - size_t filesz; - size_t memsz; - int rc; - - /* Copy image header to target location */ - dest = real_to_user ( imgheader->location.segment, - imgheader->location.offset ); - filesz = memsz = NBI_HEADER_LENGTH; - if ( ( rc = process ( image, offset, dest, filesz, memsz ) ) != 0 ) - return rc; - offset += filesz; - - /* Process segments in turn */ - sh_off = NBI_LENGTH ( imgheader->length ); - do { - /* Read segment header */ - copy_from_user ( &sh, image->data, sh_off, sizeof ( sh ) ); - if ( sh.length == 0 ) { - /* Avoid infinite loop? */ - DBGC ( image, "NBI %p invalid segheader length 0\n", - image ); - return -ENOEXEC; - } - - /* Calculate segment load address */ - switch ( NBI_LOADADDR_FLAGS ( sh.flags ) ) { - case NBI_LOADADDR_ABS: - dest = phys_to_user ( sh.loadaddr ); - break; - case NBI_LOADADDR_AFTER: - dest = userptr_add ( dest, memsz + sh.loadaddr ); - break; - case NBI_LOADADDR_BEFORE: - dest = userptr_add ( dest, -sh.loadaddr ); - break; - case NBI_LOADADDR_END: - /* Not correct according to the spec, but - * maintains backwards compatibility with - * previous versions of Etherboot. - */ - dest = phys_to_user ( ( extmemsize() + 1024 ) * 1024 - - sh.loadaddr ); - break; - default: - /* Cannot be reached */ - assert ( 0 ); - } - - /* Process this segment */ - filesz = sh.imglength; - memsz = sh.memlength; - if ( ( offset + filesz ) > image->len ) { - DBGC ( image, "NBI %p segment outside file\n", image ); - return -ENOEXEC; - } - if ( ( rc = process ( image, offset, dest, - filesz, memsz ) ) != 0 ) { - return rc; - } - offset += filesz; - - /* Next segheader */ - sh_off += NBI_LENGTH ( sh.length ); - if ( sh_off >= NBI_HEADER_LENGTH ) { - DBGC ( image, "NBI %p header overflow\n", image ); - return -ENOEXEC; - } - - } while ( ! NBI_LAST_SEGHEADER ( sh.flags ) ); - - if ( offset != image->len ) { - DBGC ( image, "NBI %p length wrong (file %zd, metadata %zd)\n", - image, image->len, offset ); - return -ENOEXEC; - } - - return 0; -} - -/** - * Boot a 16-bit NBI image - * - * @v imgheader Image header information - * @ret rc Return status code, if image returns - */ -static int nbi_boot16 ( struct image *image, struct imgheader *imgheader ) { - int discard_D, discard_S, discard_b; - int rc; - - DBGC ( image, "NBI %p executing 16-bit image at %04x:%04x\n", image, - imgheader->execaddr.segoff.segment, - imgheader->execaddr.segoff.offset ); - - __asm__ __volatile__ ( - REAL_CODE ( "pushl %%ebp\n\t" /* gcc bug */ - "pushw %%ds\n\t" /* far pointer to bootp data */ - "pushw %%bx\n\t" - "pushl %%esi\n\t" /* location */ - "pushw %%cs\n\t" /* lcall execaddr */ - "call 1f\n\t" - "jmp 2f\n\t" - "\n1:\n\t" - "pushl %%edi\n\t" - "lret\n\t" - "\n2:\n\t" - "addw $8,%%sp\n\t" /* clean up stack */ - "popl %%ebp\n\t" /* gcc bug */ ) - : "=a" ( rc ), "=D" ( discard_D ), "=S" ( discard_S ), - "=b" ( discard_b ) - : "D" ( imgheader->execaddr.segoff ), - "S" ( imgheader->location ), - "b" ( __from_data16 ( basemem_packet ) ) - : "ecx", "edx" ); - - return rc; -} - -/** - * Boot a 32-bit NBI image - * - * @v imgheader Image header information - * @ret rc Return status code, if image returns - */ -static int nbi_boot32 ( struct image *image, struct imgheader *imgheader ) { - struct ebinfo loaderinfo = { - product_major_version, product_minor_version, - 0 - }; - int discard_D, discard_S, discard_b; - int rc; - - DBGC ( image, "NBI %p executing 32-bit image at %lx\n", - image, imgheader->execaddr.linear ); - - /* Jump to OS with flat physical addressing */ - __asm__ __volatile__ ( - PHYS_CODE ( "pushl %%ebp\n\t" /* gcc bug */ - "pushl %%ebx\n\t" /* bootp data */ - "pushl %%esi\n\t" /* imgheader */ - "pushl %%eax\n\t" /* loaderinfo */ - "call *%%edi\n\t" - "addl $12, %%esp\n\t" /* clean up stack */ - "popl %%ebp\n\t" /* gcc bug */ ) - : "=a" ( rc ), "=D" ( discard_D ), "=S" ( discard_S ), - "=b" ( discard_b ) - : "D" ( imgheader->execaddr.linear ), - "S" ( ( imgheader->location.segment << 4 ) + - imgheader->location.offset ), - "b" ( virt_to_phys ( basemem_packet ) ), - "a" ( virt_to_phys ( &loaderinfo ) ) - : "ecx", "edx", "memory" ); - - return rc; -} - -/** - * Prepare DHCP parameter block for NBI image - * - * @v image NBI image - * @ret rc Return status code - */ -static int nbi_prepare_dhcp ( struct image *image ) { - struct net_device *boot_netdev; - int rc; - - boot_netdev = last_opened_netdev(); - if ( ! boot_netdev ) { - DBGC ( image, "NBI %p could not identify a network device\n", - image ); - return -ENODEV; - } - - if ( ( rc = create_fakedhcpack ( boot_netdev, basemem_packet, - sizeof ( basemem_packet ) ) ) != 0 ) { - DBGC ( image, "NBI %p failed to build DHCP packet\n", image ); - return rc; - } - - return 0; -} - -/** - * Execute a loaded NBI image - * - * @v image NBI image - * @ret rc Return status code - */ -static int nbi_exec ( struct image *image ) { - struct imgheader imgheader; - int may_return; - int rc; - - /* Retrieve image header */ - copy_from_user ( &imgheader, image->data, 0, sizeof ( imgheader ) ); - - DBGC ( image, "NBI %p placing header at %hx:%hx\n", image, - imgheader.location.segment, imgheader.location.offset ); - - /* NBI files can have overlaps between segments; the bss of - * one segment may overlap the initialised data of another. I - * assume this is a design flaw, but there are images out - * there that we need to work with. We therefore do two - * passes: first to initialise the segments, then to copy the - * data. This avoids zeroing out already-copied data. - */ - if ( ( rc = nbi_process_segments ( image, &imgheader, - nbi_prepare_segment ) ) != 0 ) - return rc; - if ( ( rc = nbi_process_segments ( image, &imgheader, - nbi_load_segment ) ) != 0 ) - return rc; - - /* Prepare DHCP option block */ - if ( ( rc = nbi_prepare_dhcp ( image ) ) != 0 ) - return rc; - - /* Shut down now if NBI image will not return */ - may_return = NBI_PROGRAM_RETURNS ( imgheader.flags ); - if ( ! may_return ) - shutdown_boot(); - - /* Execute NBI image */ - if ( NBI_LINEAR_EXEC_ADDR ( imgheader.flags ) ) { - rc = nbi_boot32 ( image, &imgheader ); - } else { - rc = nbi_boot16 ( image, &imgheader ); - } - - if ( ! may_return ) { - /* Cannot continue after shutdown() called */ - DBGC ( image, "NBI %p returned %d from non-returnable image\n", - image, rc ); - while ( 1 ) {} - } - - DBGC ( image, "NBI %p returned %d\n", image, rc ); - - return rc; -} - -/** - * Probe NBI image - * - * @v image NBI image - * @ret rc Return status code - */ -static int nbi_probe ( struct image *image ) { - struct imgheader imgheader; - - /* If we don't have enough data give up */ - if ( image->len < NBI_HEADER_LENGTH ) { - DBGC ( image, "NBI %p too short for an NBI image\n", image ); - return -ENOEXEC; - } - - /* Check image header */ - copy_from_user ( &imgheader, image->data, 0, sizeof ( imgheader ) ); - if ( imgheader.magic != NBI_MAGIC ) { - DBGC ( image, "NBI %p has no NBI signature\n", image ); - return -ENOEXEC; - } - - return 0; -} - -/** NBI image type */ -struct image_type nbi_image_type __image_type ( PROBE_NORMAL ) = { - .name = "NBI", - .probe = nbi_probe, - .exec = nbi_exec, -}; diff --git a/qemu/roms/ipxe/src/arch/i386/image/pxe_image.c b/qemu/roms/ipxe/src/arch/i386/image/pxe_image.c deleted file mode 100644 index 5b0f6eb89..000000000 --- a/qemu/roms/ipxe/src/arch/i386/image/pxe_image.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 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 ); - -/** - * @file - * - * PXE image format - * - */ - -#include <pxe.h> -#include <pxe_call.h> -#include <ipxe/uaccess.h> -#include <ipxe/image.h> -#include <ipxe/segment.h> -#include <ipxe/netdevice.h> -#include <ipxe/features.h> -#include <ipxe/console.h> -#include <ipxe/efi/efi.h> -#include <ipxe/efi/IndustryStandard/PeImage.h> - -FEATURE ( FEATURE_IMAGE, "PXE", DHCP_EB_FEATURE_PXE, 1 ); - -/** PXE command line */ -const char *pxe_cmdline; - -/** - * Execute PXE image - * - * @v image PXE image - * @ret rc Return status code - */ -static int pxe_exec ( struct image *image ) { - userptr_t buffer = real_to_user ( 0, 0x7c00 ); - struct net_device *netdev; - int rc; - - /* Verify and prepare segment */ - if ( ( rc = prep_segment ( buffer, image->len, image->len ) ) != 0 ) { - DBGC ( image, "IMAGE %p could not prepare segment: %s\n", - image, strerror ( rc ) ); - return rc; - } - - /* Copy image to segment */ - memcpy_user ( buffer, 0, image->data, 0, image->len ); - - /* Arbitrarily pick the most recently opened network device */ - if ( ( netdev = last_opened_netdev() ) == NULL ) { - DBGC ( image, "IMAGE %p could not locate PXE net device\n", - image ); - return -ENODEV; - } - netdev_get ( netdev ); - - /* Activate PXE */ - pxe_activate ( netdev ); - - /* Set PXE command line */ - pxe_cmdline = image->cmdline; - - /* Reset console since PXE NBP will probably use it */ - console_reset(); - - /* Start PXE NBP */ - rc = pxe_start_nbp(); - - /* Clear PXE command line */ - pxe_cmdline = NULL; - - /* Deactivate PXE */ - pxe_deactivate(); - - /* Try to reopen network device. Ignore errors, since the NBP - * may have called PXENV_STOP_UNDI. - */ - netdev_open ( netdev ); - netdev_put ( netdev ); - - return rc; -} - -/** - * Probe PXE image - * - * @v image PXE file - * @ret rc Return status code - */ -int pxe_probe ( struct image *image ) { - - /* Images too large to fit in base memory cannot be PXE - * images. We include this check to help prevent unrecognised - * images from being marked as PXE images, since PXE images - * have no signature we can check against. - */ - if ( image->len > ( 0xa0000 - 0x7c00 ) ) - return -ENOEXEC; - - /* Rejecting zero-length images is also useful, since these - * end up looking to the user like bugs in iPXE. - */ - if ( ! image->len ) - return -ENOEXEC; - - return 0; -} - -/** - * Probe PXE image (with rejection of potential EFI images) - * - * @v image PXE file - * @ret rc Return status code - */ -int pxe_probe_no_mz ( struct image *image ) { - uint16_t magic; - int rc; - - /* Probe PXE image */ - if ( ( rc = pxe_probe ( image ) ) != 0 ) - return rc; - - /* Reject image with an "MZ" signature which may indicate an - * EFI image incorrectly handed out to a BIOS system. - */ - if ( image->len >= sizeof ( magic ) ) { - copy_from_user ( &magic, image->data, 0, sizeof ( magic ) ); - if ( magic == cpu_to_le16 ( EFI_IMAGE_DOS_SIGNATURE ) ) { - DBGC ( image, "IMAGE %p may be an EFI image\n", - image ); - return -ENOTTY; - } - } - - return 0; -} - -/** PXE image type */ -struct image_type pxe_image_type[] __image_type ( PROBE_PXE ) = { - { - .name = "PXE-NBP", - .probe = pxe_probe_no_mz, - .exec = pxe_exec, - }, - { - .name = "PXE-NBP (may be EFI?)", - .probe = pxe_probe, - .exec = pxe_exec, - }, -}; diff --git a/qemu/roms/ipxe/src/arch/i386/image/sdi.c b/qemu/roms/ipxe/src/arch/i386/image/sdi.c deleted file mode 100644 index fa2d0b73f..000000000 --- a/qemu/roms/ipxe/src/arch/i386/image/sdi.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2012 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 (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 <string.h> -#include <errno.h> -#include <realmode.h> -#include <sdi.h> -#include <ipxe/image.h> -#include <ipxe/features.h> - -/** @file - * - * System Deployment Image (SDI) - * - * Based on the MSDN article "RAM boot using SDI in Windows XP - * Embedded with Service Pack 1", available at the time of writing - * from: - * - * http://msdn.microsoft.com/en-us/library/ms838543.aspx - */ - -FEATURE ( FEATURE_IMAGE, "SDI", DHCP_EB_FEATURE_SDI, 1 ); - -/** - * Parse SDI image header - * - * @v image SDI file - * @v sdi SDI header to fill in - * @ret rc Return status code - */ -static int sdi_parse_header ( struct image *image, struct sdi_header *sdi ) { - - /* Sanity check */ - if ( image->len < sizeof ( *sdi ) ) { - DBGC ( image, "SDI %p too short for SDI header\n", image ); - return -ENOEXEC; - } - - /* Read in header */ - copy_from_user ( sdi, image->data, 0, sizeof ( *sdi ) ); - - /* Check signature */ - if ( sdi->magic != SDI_MAGIC ) { - DBGC ( image, "SDI %p is not an SDI image\n", image ); - return -ENOEXEC; - } - - return 0; -} - -/** - * Execute SDI image - * - * @v image SDI file - * @ret rc Return status code - */ -static int sdi_exec ( struct image *image ) { - struct sdi_header sdi; - uint32_t sdiptr; - int rc; - - /* Parse image header */ - if ( ( rc = sdi_parse_header ( image, &sdi ) ) != 0 ) - return rc; - - /* Check that image is bootable */ - if ( sdi.boot_size == 0 ) { - DBGC ( image, "SDI %p is not bootable\n", image ); - return -ENOTTY; - } - DBGC ( image, "SDI %p image at %08lx+%08zx\n", - image, user_to_phys ( image->data, 0 ), image->len ); - DBGC ( image, "SDI %p boot code at %08lx+%llx\n", image, - user_to_phys ( image->data, sdi.boot_offset ), sdi.boot_size ); - - /* Copy boot code */ - memcpy_user ( real_to_user ( SDI_BOOT_SEG, SDI_BOOT_OFF ), 0, - image->data, sdi.boot_offset, sdi.boot_size ); - - /* Jump to boot code */ - sdiptr = ( user_to_phys ( image->data, 0 ) | SDI_WTF ); - __asm__ __volatile__ ( REAL_CODE ( "ljmp %0, %1\n\t" ) - : : "i" ( SDI_BOOT_SEG ), - "i" ( SDI_BOOT_OFF ), - "d" ( sdiptr ) ); - - /* There is no way for the image to return, since we provide - * no return address. - */ - assert ( 0 ); - - return -ECANCELED; /* -EIMPOSSIBLE */ -} - -/** - * Probe SDI image - * - * @v image SDI file - * @ret rc Return status code - */ -static int sdi_probe ( struct image *image ) { - struct sdi_header sdi; - int rc; - - /* Parse image */ - if ( ( rc = sdi_parse_header ( image, &sdi ) ) != 0 ) - return rc; - - return 0; -} - -/** SDI image type */ -struct image_type sdi_image_type __image_type ( PROBE_NORMAL ) = { - .name = "SDI", - .probe = sdi_probe, - .exec = sdi_exec, -}; diff --git a/qemu/roms/ipxe/src/arch/i386/include/basemem.h b/qemu/roms/ipxe/src/arch/i386/include/basemem.h deleted file mode 100644 index 01c2ea917..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/basemem.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef _BASEMEM_H -#define _BASEMEM_H - -/** @file - * - * Base memory allocation - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdint.h> -#include <realmode.h> -#include <bios.h> - -/** - * Read the BIOS free base memory counter - * - * @ret fbms Free base memory counter (in kB) - */ -static inline unsigned int get_fbms ( void ) { - uint16_t fbms; - - get_real ( fbms, BDA_SEG, BDA_FBMS ); - return fbms; -} - -extern void set_fbms ( unsigned int new_fbms ); - -/* Actually in hidemem.c, but putting it here avoids polluting the - * architecture-independent include/hidemem.h. - */ -extern void hide_basemem ( void ); - -#endif /* _BASEMEM_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/basemem_packet.h b/qemu/roms/ipxe/src/arch/i386/include/basemem_packet.h deleted file mode 100644 index def6dee31..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/basemem_packet.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef BASEMEM_PACKET_H -#define BASEMEM_PACKET_H - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <realmode.h> - -/** Maximum length of base memory packet buffer */ -#define BASEMEM_PACKET_LEN 1514 - -/** Base memory packet buffer */ -extern char __bss16_array ( basemem_packet, [BASEMEM_PACKET_LEN] ); -#define basemem_packet __use_data16 ( basemem_packet ) - -#endif /* BASEMEM_PACKET_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/bios.h b/qemu/roms/ipxe/src/arch/i386/include/bios.h deleted file mode 100644 index 988bbc62b..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/bios.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef BIOS_H -#define BIOS_H - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#define BDA_SEG 0x0040 -#define BDA_EQUIPMENT_WORD 0x0010 -#define BDA_FBMS 0x0013 -#define BDA_REBOOT 0x0072 -#define BDA_REBOOT_WARM 0x1234 -#define BDA_NUM_DRIVES 0x0075 -#define BDA_CHAR_HEIGHT 0x0085 - -#endif /* BIOS_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/bios_disks.h b/qemu/roms/ipxe/src/arch/i386/include/bios_disks.h deleted file mode 100644 index 0dd7c4ebb..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/bios_disks.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef BIOS_DISKS_H -#define BIOS_DISKS_H - -#include "dev.h" - -/* - * Constants - * - */ - -#define BIOS_DISK_MAX_NAME_LEN 6 - -struct bios_disk_sector { - char data[512]; -}; - -/* - * The location of a BIOS disk - * - */ -struct bios_disk_loc { - uint8_t drive; -}; - -/* - * A physical BIOS disk device - * - */ -struct bios_disk_device { - char name[BIOS_DISK_MAX_NAME_LEN]; - uint8_t drive; - uint8_t type; -}; - -/* - * A BIOS disk driver, with a valid device ID range and naming - * function. - * - */ -struct bios_disk_driver { - void ( *fill_drive_name ) ( char *buf, uint8_t drive ); - uint8_t min_drive; - uint8_t max_drive; -}; - -/* - * Define a BIOS disk driver - * - */ -#define BIOS_DISK_DRIVER( _name, _fill_drive_name, _min_drive, _max_drive ) \ - static struct bios_disk_driver _name = { \ - .fill_drive_name = _fill_drive_name, \ - .min_drive = _min_drive, \ - .max_drive = _max_drive, \ - } - -/* - * Functions in bios_disks.c - * - */ - - -/* - * bios_disk bus global definition - * - */ -extern struct bus_driver bios_disk_driver; - -#endif /* BIOS_DISKS_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/biosint.h b/qemu/roms/ipxe/src/arch/i386/include/biosint.h deleted file mode 100644 index 67d6a3811..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/biosint.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef BIOSINT_H -#define BIOSINT_H - -/** - * @file BIOS interrupts - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <realmode.h> - -struct segoff; - -/** - * Hooked interrupt count - * - * At exit, after unhooking all possible interrupts, this counter - * should be examined. If it is non-zero, it means that we failed to - * unhook at least one interrupt vector, and so must not free up the - * memory we are using. (Note that this also implies that we should - * re-hook INT 15 in order to hide ourselves from the memory map). - */ -extern uint16_t __text16 ( hooked_bios_interrupts ); -#define hooked_bios_interrupts __use_text16 ( hooked_bios_interrupts ) - -extern void hook_bios_interrupt ( unsigned int interrupt, unsigned int handler, - struct segoff *chain_vector ); -extern int unhook_bios_interrupt ( unsigned int interrupt, - unsigned int handler, - struct segoff *chain_vector ); - -#endif /* BIOSINT_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/bits/byteswap.h b/qemu/roms/ipxe/src/arch/i386/include/bits/byteswap.h deleted file mode 100644 index 53b6a454d..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/bits/byteswap.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef _BITS_BYTESWAP_H -#define _BITS_BYTESWAP_H - -/** @file - * - * Byte-order swapping functions - * - */ - -#include <stdint.h> - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -static inline __attribute__ (( always_inline, const )) uint16_t -__bswap_variable_16 ( uint16_t x ) { - __asm__ ( "xchgb %b0,%h0" : "=q" ( x ) : "0" ( x ) ); - return x; -} - -static inline __attribute__ (( always_inline )) void -__bswap_16s ( uint16_t *x ) { - __asm__ ( "rorw $8, %0" : "+m" ( *x ) ); -} - -static inline __attribute__ (( always_inline, const )) uint32_t -__bswap_variable_32 ( uint32_t x ) { - __asm__ ( "bswapl %0" : "=r" ( x ) : "0" ( x ) ); - return x; -} - -static inline __attribute__ (( always_inline )) void -__bswap_32s ( uint32_t *x ) { - __asm__ ( "bswapl %0" : "=r" ( *x ) : "0" ( *x ) ); -} - -static inline __attribute__ (( always_inline, const )) uint64_t -__bswap_variable_64 ( uint64_t x ) { - uint32_t in_high = ( x >> 32 ); - uint32_t in_low = ( x & 0xffffffffUL ); - uint32_t out_high; - uint32_t out_low; - - __asm__ ( "bswapl %0\n\t" - "bswapl %1\n\t" - "xchgl %0,%1\n\t" - : "=r" ( out_high ), "=r" ( out_low ) - : "0" ( in_high ), "1" ( in_low ) ); - - return ( ( ( ( uint64_t ) out_high ) << 32 ) | - ( ( uint64_t ) out_low ) ); -} - -static inline __attribute__ (( always_inline )) void -__bswap_64s ( uint64_t *x ) { - struct { - uint32_t __attribute__ (( may_alias )) low; - uint32_t __attribute__ (( may_alias )) high; - } __attribute__ (( may_alias )) *dwords = ( ( void * ) x ); - uint32_t discard; - - __asm__ ( "movl %0,%2\n\t" - "bswapl %2\n\t" - "xchgl %2,%1\n\t" - "bswapl %2\n\t" - "movl %2,%0\n\t" - : "+m" ( dwords->low ), "+m" ( dwords->high ), - "=r" ( discard ) ); -} - -#endif /* _BITS_BYTESWAP_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/bits/compiler.h b/qemu/roms/ipxe/src/arch/i386/include/bits/compiler.h deleted file mode 100644 index 87201135f..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/bits/compiler.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef _BITS_COMPILER_H -#define _BITS_COMPILER_H - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/** Dummy relocation type */ -#define RELOC_TYPE_NONE R_386_NONE - -#ifndef ASSEMBLY - -/** Declare a function with standard calling conventions */ -#define __asmcall __attribute__ (( cdecl, regparm(0) )) - -/** - * Declare a function with libgcc implicit linkage - * - * It seems as though gcc expects its implicit arithmetic functions to - * be cdecl, even if -mrtd is specified. This is somewhat - * inconsistent; for example, if -mregparm=3 is used then the implicit - * functions do become regparm(3). - * - * The implicit calls to memcpy() and memset() which gcc can generate - * do not seem to have this inconsistency; -mregparm and -mrtd affect - * them in the same way as any other function. - * - * Update (25/4/14): it appears that more recent gcc versions do allow - * -mrtd to affect calls to the implicit arithmetic functions. There - * is nothing obvious in the gcc changelogs to indicate precisely when - * this happened. From experimentation with available gcc versions, - * the change occurred sometime between v4.6.3 and v4.7.2. We assume - * that only versions up to v4.6.x require the special treatment. - */ -#if ( __GNUC__ < 4 ) || ( ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ <= 6 ) ) -#define __libgcc __attribute__ (( cdecl )) -#else -#define __libgcc -#endif - -#endif /* ASSEMBLY */ - -#endif /* _BITS_COMPILER_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/bits/entropy.h b/qemu/roms/ipxe/src/arch/i386/include/bits/entropy.h deleted file mode 100644 index bfeb5e3b5..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/bits/entropy.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _BITS_ENTROPY_H -#define _BITS_ENTROPY_H - -/** @file - * - * i386-specific entropy API implementations - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <ipxe/rtc_entropy.h> - -#endif /* _BITS_ENTROPY_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/bits/hyperv.h b/qemu/roms/ipxe/src/arch/i386/include/bits/hyperv.h deleted file mode 100644 index 3565c8a83..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/bits/hyperv.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef _BITS_HYPERV_H -#define _BITS_HYPERV_H - -/** @file - * - * Hyper-V interface - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stddef.h> -#include <stdint.h> -#include <ipxe/io.h> - -/** - * Issue hypercall - * - * @v hv Hyper-V hypervisor - * @v code Call code - * @v in Input parameters - * @v out Output parameters - * @ret status Status code - */ -static inline __attribute__ (( always_inline )) int -hv_call ( struct hv_hypervisor *hv, unsigned int code, const void *in, - void *out ) { - void *hypercall = hv->hypercall; - uint32_t in_phys; - uint32_t out_phys; - uint32_t discard_ecx; - uint32_t discard_edx; - uint16_t result; - - in_phys = ( ( __builtin_constant_p ( in ) && ( in == NULL ) ) - ? 0 : virt_to_phys ( in ) ); - out_phys = ( ( __builtin_constant_p ( out ) && ( out == NULL ) ) - ? 0 : virt_to_phys ( out ) ); - __asm__ __volatile__ ( "call *%9" - : "=a" ( result ), "=c" ( discard_ecx ), - "=d" ( discard_edx ) - : "d" ( 0 ), "a" ( code ), - "b" ( 0 ), "c" ( in_phys ), - "D" ( 0 ), "S" ( out_phys ), - "m" ( hypercall ) ); - return result; -} - -/** - * Set bit atomically - * - * @v bits Bit field - * @v bit Bit to set - */ -static inline __attribute__ (( always_inline )) void -hv_set_bit ( void *bits, unsigned int bit ) { - struct { - uint32_t dword[ ( bit / 32 ) + 1 ]; - } *dwords = bits; - - /* Set bit using "lock bts". Inform compiler that any memory - * from the start of the bit field up to and including the - * dword containing this bit may be modified. (This is - * overkill but shouldn't matter in practice since we're - * unlikely to subsequently read other bits from the same bit - * field.) - */ - __asm__ __volatile__ ( "lock bts %1, %0" - : "+m" ( *dwords ) : "Ir" ( bit ) ); -} - -#endif /* _BITS_HYPERV_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/bits/linux_api.h b/qemu/roms/ipxe/src/arch/i386/include/bits/linux_api.h deleted file mode 100644 index dc6e7416e..000000000 --- a/qemu/roms/ipxe/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/qemu/roms/ipxe/src/arch/i386/include/bits/nap.h b/qemu/roms/ipxe/src/arch/i386/include/bits/nap.h deleted file mode 100644 index e8bcfd13b..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/bits/nap.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef _BITS_NAP_H -#define _BITS_NAP_H - -/** @file - * - * i386-specific CPU sleeping API implementations - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <ipxe/bios_nap.h> -#include <ipxe/efi/efix86_nap.h> - -#endif /* _BITS_MAP_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/bits/profile.h b/qemu/roms/ipxe/src/arch/i386/include/bits/profile.h deleted file mode 100644 index e184d7b51..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/bits/profile.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _BITS_PROFILE_H -#define _BITS_PROFILE_H - -/** @file - * - * Profiling - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdint.h> - -/** - * Get profiling timestamp - * - * @ret timestamp Timestamp - */ -static inline __attribute__ (( always_inline )) uint64_t -profile_timestamp ( void ) { - uint64_t tsc; - - /* Read timestamp counter */ - __asm__ __volatile__ ( "rdtsc" : "=A" ( tsc ) ); - return tsc; -} - -#endif /* _BITS_PROFILE_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/bits/reboot.h b/qemu/roms/ipxe/src/arch/i386/include/bits/reboot.h deleted file mode 100644 index 803dacfe4..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/bits/reboot.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _BITS_REBOOT_H -#define _BITS_REBOOT_H - -/** @file - * - * i386-specific reboot API implementations - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <ipxe/bios_reboot.h> - -#endif /* _BITS_REBOOT_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/bits/sanboot.h b/qemu/roms/ipxe/src/arch/i386/include/bits/sanboot.h deleted file mode 100644 index f02d2e649..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/bits/sanboot.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _BITS_SANBOOT_H -#define _BITS_SANBOOT_H - -/** @file - * - * i386-specific sanboot API implementations - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <ipxe/bios_sanboot.h> - -#endif /* _BITS_SANBOOT_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/bits/smbios.h b/qemu/roms/ipxe/src/arch/i386/include/bits/smbios.h deleted file mode 100644 index 2ab31e74b..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/bits/smbios.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _BITS_SMBIOS_H -#define _BITS_SMBIOS_H - -/** @file - * - * i386-specific SMBIOS API implementations - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <ipxe/bios_smbios.h> - -#endif /* _BITS_SMBIOS_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/bits/stdint.h b/qemu/roms/ipxe/src/arch/i386/include/bits/stdint.h deleted file mode 100644 index fe1f9946a..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/bits/stdint.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef _BITS_STDINT_H -#define _BITS_STDINT_H - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -typedef __SIZE_TYPE__ size_t; -typedef signed long ssize_t; -typedef signed long off_t; - -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned int uint32_t; -typedef unsigned long long uint64_t; - -typedef signed char int8_t; -typedef signed short int16_t; -typedef signed int int32_t; -typedef signed long long int64_t; - -typedef unsigned long physaddr_t; -typedef unsigned long intptr_t; - -#endif /* _BITS_STDINT_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/bits/strings.h b/qemu/roms/ipxe/src/arch/i386/include/bits/strings.h deleted file mode 100644 index 453545f00..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/bits/strings.h +++ /dev/null @@ -1,94 +0,0 @@ -#ifndef _BITS_STRINGS_H -#define _BITS_STRINGS_H - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/** - * Find first (i.e. least significant) set bit - * - * @v value Value - * @ret lsb Least significant bit set in value (LSB=1), or zero - */ -static inline __attribute__ (( always_inline )) int __ffsl ( long value ) { - long lsb_minus_one; - - /* If the input value is zero, the BSF instruction returns - * ZF=0 and leaves an undefined value in the output register. - * Perform this check in C rather than asm so that it can be - * omitted in cases where the compiler is able to prove that - * the input is non-zero. - */ - if ( value ) { - __asm__ ( "bsfl %1, %0" - : "=r" ( lsb_minus_one ) - : "rm" ( value ) ); - return ( lsb_minus_one + 1 ); - } else { - return 0; - } -} - -/** - * Find first (i.e. least significant) set bit - * - * @v value Value - * @ret lsb Least significant bit set in value (LSB=1), or zero - */ -static inline __attribute__ (( always_inline )) int __ffsll ( long long value ){ - unsigned long high = ( value >> 32 ); - unsigned long low = ( value >> 0 ); - - if ( low ) { - return ( __ffsl ( low ) ); - } else if ( high ) { - return ( 32 + __ffsl ( high ) ); - } else { - return 0; - } -} - -/** - * Find last (i.e. most significant) set bit - * - * @v value Value - * @ret msb Most significant bit set in value (LSB=1), or zero - */ -static inline __attribute__ (( always_inline )) int __flsl ( long value ) { - long msb_minus_one; - - /* If the input value is zero, the BSR instruction returns - * ZF=0 and leaves an undefined value in the output register. - * Perform this check in C rather than asm so that it can be - * omitted in cases where the compiler is able to prove that - * the input is non-zero. - */ - if ( value ) { - __asm__ ( "bsrl %1, %0" - : "=r" ( msb_minus_one ) - : "rm" ( value ) ); - return ( msb_minus_one + 1 ); - } else { - return 0; - } -} - -/** - * Find last (i.e. most significant) set bit - * - * @v value Value - * @ret msb Most significant bit set in value (LSB=1), or zero - */ -static inline __attribute__ (( always_inline )) int __flsll ( long long value ){ - unsigned long high = ( value >> 32 ); - unsigned long low = ( value >> 0 ); - - if ( high ) { - return ( 32 + __flsl ( high ) ); - } else if ( low ) { - return ( __flsl ( low ) ); - } else { - return 0; - } -} - -#endif /* _BITS_STRINGS_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/bits/time.h b/qemu/roms/ipxe/src/arch/i386/include/bits/time.h deleted file mode 100644 index 6a5d63d32..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/bits/time.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _BITS_TIME_H -#define _BITS_TIME_H - -/** @file - * - * i386-specific time API implementations - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <ipxe/rtc_time.h> - -#endif /* _BITS_TIME_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/bits/timer.h b/qemu/roms/ipxe/src/arch/i386/include/bits/timer.h deleted file mode 100644 index f7d86d78c..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/bits/timer.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef _BITS_TIMER_H -#define _BITS_TIMER_H - -/** @file - * - * i386-specific timer API implementations - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <ipxe/bios_timer.h> -#include <ipxe/rdtsc_timer.h> - -#endif /* _BITS_TIMER_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/bits/uaccess.h b/qemu/roms/ipxe/src/arch/i386/include/bits/uaccess.h deleted file mode 100644 index aac09ba95..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/bits/uaccess.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _BITS_UACCESS_H -#define _BITS_UACCESS_H - -/** @file - * - * i386-specific user access API implementations - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <librm.h> - -#endif /* _BITS_UACCESS_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/bits/umalloc.h b/qemu/roms/ipxe/src/arch/i386/include/bits/umalloc.h deleted file mode 100644 index 113f16fd1..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/bits/umalloc.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _BITS_UMALLOC_H -#define _BITS_UMALLOC_H - -/** @file - * - * i386-specific user memory allocation API implementations - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <ipxe/memtop_umalloc.h> - -#endif /* _BITS_UMALLOC_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/bochs.h b/qemu/roms/ipxe/src/arch/i386/include/bochs.h deleted file mode 100644 index 9d090fc12..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/bochs.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef BOCHS_H -#define BOCHS_H - -/** @file - * - * bochs breakpoints - * - * This file defines @c bochsbp, the magic breakpoint instruction that - * is incredibly useful when debugging under bochs. This file should - * never be included in production code. - * - * Use the pseudo-instruction @c bochsbp in assembly code, or the - * bochsbp() function in C code. - * - */ - -#ifdef ASSEMBLY - -/* Breakpoint for when debugging under bochs */ -#define bochsbp xchgw %bx, %bx -#define BOCHSBP bochsbp - -#else /* ASSEMBLY */ - -/** Breakpoint for when debugging under bochs */ -static inline void bochsbp ( void ) { - __asm__ __volatile__ ( "xchgw %bx, %bx" ); -} - -#endif /* ASSEMBLY */ - -#warning "bochs.h should not be included into production code" - -#endif /* BOCHS_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/bootsector.h b/qemu/roms/ipxe/src/arch/i386/include/bootsector.h deleted file mode 100644 index c5d35aae3..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/bootsector.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _BOOTSECTOR_H -#define _BOOTSECTOR_H - -/** @file - * - * x86 bootsector image format - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -extern int call_bootsector ( unsigned int segment, unsigned int offset, - unsigned int drive ); - -#endif /* _BOOTSECTOR_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/bzimage.h b/qemu/roms/ipxe/src/arch/i386/include/bzimage.h deleted file mode 100644 index 4933ce5b1..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/bzimage.h +++ /dev/null @@ -1,142 +0,0 @@ -#ifndef _BZIMAGE_H -#define _BZIMAGE_H - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdint.h> - -/** - * A bzImage header - * - * As documented in Documentation/i386/boot.txt - */ -struct bzimage_header { - /** The size of the setup in sectors - * - * If this field contains 0, assume it contains 4. - */ - uint8_t setup_sects; - /** If set, the root is mounted readonly */ - uint16_t root_flags; - /** DO NOT USE - for bootsect.S use only */ - uint16_t syssize; - /** DO NOT USE - obsolete */ - uint16_t swap_dev; - /** DO NOT USE - for bootsect.S use only */ - uint16_t ram_size; - /** Video mode control */ - uint16_t vid_mode; - /** Default root device number */ - uint16_t root_dev; - /** 0xAA55 magic number */ - uint16_t boot_flag; - /** Jump instruction */ - uint16_t jump; - /** Magic signature "HdrS" */ - uint32_t header; - /** Boot protocol version supported */ - uint16_t version; - /** Boot loader hook (see below) */ - uint32_t realmode_swtch; - /** The load-low segment (0x1000) (obsolete) */ - uint16_t start_sys; - /** Pointer to kernel version string */ - uint16_t kernel_version; - /** Boot loader identifier */ - uint8_t type_of_loader; - /** Boot protocol option flags */ - uint8_t loadflags; - /** Move to high memory size (used with hooks) */ - uint16_t setup_move_size; - /** Boot loader hook (see below) */ - uint32_t code32_start; - /** initrd load address (set by boot loader) */ - uint32_t ramdisk_image; - /** initrd size (set by boot loader) */ - uint32_t ramdisk_size; - /** DO NOT USE - for bootsect.S use only */ - uint32_t bootsect_kludge; - /** Free memory after setup end */ - uint16_t heap_end_ptr; - /** Unused */ - uint16_t pad1; - /** 32-bit pointer to the kernel command line */ - uint32_t cmd_line_ptr; - /** Highest legal initrd address */ - uint32_t initrd_addr_max; - /** Physical addr alignment required for kernel */ - uint32_t kernel_alignment; - /** Whether kernel is relocatable or not */ - uint8_t relocatable_kernel; - /** Unused */ - uint8_t pad2[3]; - /** Maximum size of the kernel command line */ - uint32_t cmdline_size; -} __attribute__ (( packed )); - -/** Offset of bzImage header within kernel image */ -#define BZI_HDR_OFFSET 0x1f1 - -/** bzImage boot flag value */ -#define BZI_BOOT_FLAG 0xaa55 - -/** bzImage magic signature value */ -#define BZI_SIGNATURE 0x53726448 - -/** bzImage boot loader identifier for Etherboot */ -#define BZI_LOADER_TYPE_ETHERBOOT 0x40 - -/** bzImage boot loader identifier for iPXE - * - * We advertise ourselves as Etherboot version 6. - */ -#define BZI_LOADER_TYPE_IPXE ( BZI_LOADER_TYPE_ETHERBOOT | 0x06 ) - -/** bzImage "load high" flag */ -#define BZI_LOAD_HIGH 0x01 - -/** Load address for high-loaded kernels */ -#define BZI_LOAD_HIGH_ADDR 0x100000 - -/** Load address for low-loaded kernels */ -#define BZI_LOAD_LOW_ADDR 0x10000 - -/** bzImage "kernel can use heap" flag */ -#define BZI_CAN_USE_HEAP 0x80 - -/** bzImage special video mode "normal" */ -#define BZI_VID_MODE_NORMAL 0xffff - -/** bzImage special video mode "ext" */ -#define BZI_VID_MODE_EXT 0xfffe - -/** bzImage special video mode "ask" */ -#define BZI_VID_MODE_ASK 0xfffd - -/** bzImage maximum initrd address for versions < 2.03 */ -#define BZI_INITRD_MAX 0x37ffffff - -/** bzImage command-line structure used by older kernels */ -struct bzimage_cmdline { - /** Magic signature */ - uint16_t magic; - /** Offset to command line */ - uint16_t offset; -} __attribute__ (( packed )); - -/** Offset of bzImage command-line structure within kernel image */ -#define BZI_CMDLINE_OFFSET 0x20 - -/** bzImage command line present magic marker value */ -#define BZI_CMDLINE_MAGIC 0xa33f - -/** Assumed size of real-mode portion (including .bss) */ -#define BZI_ASSUMED_RM_SIZE 0x8000 - -/** Amount of stack space to provide */ -#define BZI_STACK_SIZE 0x1000 - -/** Maximum size of command line */ -#define BZI_CMDLINE_SIZE 0x7ff - -#endif /* _BZIMAGE_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/comboot.h b/qemu/roms/ipxe/src/arch/i386/include/comboot.h deleted file mode 100644 index 2d2f04fe1..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/comboot.h +++ /dev/null @@ -1,132 +0,0 @@ -#ifndef COMBOOT_H -#define COMBOOT_H - -/** - * @file - * - * SYSLINUX COMBOOT - */ - -FILE_LICENCE ( GPL2_OR_LATER ); - -#include <stdint.h> -#include <setjmp.h> -#include <ipxe/in.h> - -/** Segment used for COMBOOT PSP and image */ -#define COMBOOT_PSP_SEG 0x07C0 - -/** Entry point address of COM32 images */ -#define COM32_START_PHYS 0x101000 - -/** COM32 bounce buffer segment */ -#define COM32_BOUNCE_SEG 0x07C0 - -/** Size of SYSLINUX file block in bytes */ -#define COMBOOT_FILE_BLOCKSZ 512 - -/** COMBOOT feature flags (INT 22h AX=15h) */ -#define COMBOOT_FEATURE_LOCAL_BOOT (1 << 0) -#define COMBOOT_FEATURE_IDLE_LOOP (1 << 1) - -/** Maximum number of shuffle descriptors for - * shuffle and boot functions - * (INT 22h AX=0012h, 001Ah, 001Bh) - */ -#define COMBOOT_MAX_SHUFFLE_DESCRIPTORS 682 - -typedef union { - uint32_t l; - uint16_t w[2]; - uint8_t b[4]; -} com32_reg32_t; - -typedef struct { - uint16_t gs; /* Offset 0 */ - uint16_t fs; /* Offset 2 */ - uint16_t es; /* Offset 4 */ - uint16_t ds; /* Offset 6 */ - - com32_reg32_t edi; /* Offset 8 */ - com32_reg32_t esi; /* Offset 12 */ - com32_reg32_t ebp; /* Offset 16 */ - com32_reg32_t _unused_esp; /* Offset 20 */ - com32_reg32_t ebx; /* Offset 24 */ - com32_reg32_t edx; /* Offset 28 */ - com32_reg32_t ecx; /* Offset 32 */ - com32_reg32_t eax; /* Offset 36 */ - - com32_reg32_t eflags; /* Offset 40 */ -} com32sys_t; - -typedef struct { - uint32_t eax; /* Offset 0 */ - uint32_t ecx; /* Offset 4 */ - uint32_t edx; /* Offset 8 */ - uint32_t ebx; /* Offset 12 */ - uint32_t esp; /* Offset 16 */ - uint32_t ebp; /* Offset 20 */ - uint32_t esi; /* Offset 24 */ - uint32_t edi; /* Offset 28 */ - - uint32_t eip; /* Offset 32 */ -} syslinux_pm_regs; - -typedef struct { - uint16_t es; /* Offset 0 */ - uint16_t _unused_cs; /* Offset 2 */ - uint16_t ds; /* Offset 4 */ - uint16_t ss; /* Offset 6 */ - uint16_t fs; /* Offset 8 */ - uint16_t gs; /* Offset 10 */ - - uint32_t eax; /* Offset 12 */ - uint32_t ecx; /* Offset 16 */ - uint32_t edx; /* Offset 20 */ - uint32_t ebx; /* Offset 24 */ - uint32_t esp; /* Offset 28 */ - uint32_t ebp; /* Offset 32 */ - uint32_t esi; /* Offset 36 */ - uint32_t edi; /* Offset 40 */ - - uint16_t ip; /* Offset 44 */ - uint16_t cs; /* Offset 46 */ -} syslinux_rm_regs; - -typedef struct { - uint32_t dest; - uint32_t src; - uint32_t len; -} comboot_shuffle_descriptor; - -extern void hook_comboot_interrupts ( ); -extern void unhook_comboot_interrupts ( ); - -/* These are not the correct prototypes, but it doens't matter, - * as we only ever get the address of these functions; - * they are only called from COM32 code running in PHYS_CODE - */ -extern void com32_intcall_wrapper ( ); -extern void com32_farcall_wrapper ( ); -extern void com32_cfarcall_wrapper ( ); - -/* Resolve a hostname to an (IPv4) address */ -extern int comboot_resolv ( const char *name, struct in_addr *address ); - -/* setjmp/longjmp context buffer used to return after loading an image */ -extern rmjmp_buf comboot_return; - -extern void *com32_external_esp; - -#define COMBOOT_EXIT 1 -#define COMBOOT_EXIT_RUN_KERNEL 2 -#define COMBOOT_EXIT_COMMAND 3 - -extern void comboot_force_text_mode ( void ); - -#define COMBOOT_VIDEO_GRAPHICS 0x01 -#define COMBOOT_VIDEO_NONSTANDARD 0x02 -#define COMBOOT_VIDEO_VESA 0x04 -#define COMBOOT_VIDEO_NOTEXT 0x08 - -#endif diff --git a/qemu/roms/ipxe/src/arch/i386/include/efi/ipxe/dhcp_arch.h b/qemu/roms/ipxe/src/arch/i386/include/efi/ipxe/dhcp_arch.h deleted file mode 100644 index c17c1ea5e..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/efi/ipxe/dhcp_arch.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2010 VMware, Inc. All Rights Reserved. - * - * 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 (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * 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. - */ - -#ifndef _DHCP_ARCH_H -#define _DHCP_ARCH_H - -/** @file - * - * Architecture-specific DHCP options - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <ipxe/dhcp.h> - -#define DHCP_ARCH_VENDOR_CLASS_ID \ - DHCP_STRING ( 'P', 'X', 'E', 'C', 'l', 'i', 'e', 'n', 't', ':', \ - 'A', 'r', 'c', 'h', ':', '0', '0', '0', '0', '6', ':', \ - 'U', 'N', 'D', 'I', ':', '0', '0', '3', '0', '1', '0' ) - -#define DHCP_ARCH_CLIENT_ARCHITECTURE \ - DHCP_WORD ( DHCP_CLIENT_ARCHITECTURE_IA32 ) - -#define DHCP_ARCH_CLIENT_NDI DHCP_OPTION ( 1 /* UNDI */ , 3, 10 /* v3.10 */ ) - -#endif diff --git a/qemu/roms/ipxe/src/arch/i386/include/fakee820.h b/qemu/roms/ipxe/src/arch/i386/include/fakee820.h deleted file mode 100644 index 552b1e48d..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/fakee820.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _FAKEE820_H -#define _FAKEE820_H - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -extern void fake_e820 ( void ); -extern void unfake_e820 ( void ); - -#endif /* _FAKEE820_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/gdbmach.h b/qemu/roms/ipxe/src/arch/i386/include/gdbmach.h deleted file mode 100644 index 416ae341a..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/gdbmach.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef GDBMACH_H -#define GDBMACH_H - -/** @file - * - * GDB architecture specifics - * - * This file declares functions for manipulating the machine state and - * debugging context. - * - */ - -#include <stdint.h> - -typedef unsigned long gdbreg_t; - -/* The register snapshot, this must be in sync with interrupt handler and the - * GDB protocol. */ -enum { - GDBMACH_EAX, - GDBMACH_ECX, - GDBMACH_EDX, - GDBMACH_EBX, - GDBMACH_ESP, - GDBMACH_EBP, - GDBMACH_ESI, - GDBMACH_EDI, - GDBMACH_EIP, - GDBMACH_EFLAGS, - GDBMACH_CS, - GDBMACH_SS, - GDBMACH_DS, - GDBMACH_ES, - GDBMACH_FS, - GDBMACH_GS, - GDBMACH_NREGS, - GDBMACH_SIZEOF_REGS = GDBMACH_NREGS * sizeof ( gdbreg_t ) -}; - -/* Breakpoint types */ -enum { - GDBMACH_BPMEM, - GDBMACH_BPHW, - GDBMACH_WATCH, - GDBMACH_RWATCH, - GDBMACH_AWATCH, -}; - -/* Interrupt vectors */ -extern void gdbmach_nocode_sigfpe ( void ); -extern void gdbmach_nocode_sigtrap ( void ); -extern void gdbmach_nocode_sigstkflt ( void ); -extern void gdbmach_nocode_sigill ( void ); -extern void gdbmach_withcode_sigbus ( void ); -extern void gdbmach_withcode_sigsegv ( void ); - -static inline void gdbmach_set_pc ( gdbreg_t *regs, gdbreg_t pc ) { - regs [ GDBMACH_EIP ] = pc; -} - -static inline void gdbmach_set_single_step ( gdbreg_t *regs, int step ) { - regs [ GDBMACH_EFLAGS ] &= ~( 1 << 8 ); /* Trace Flag (TF) */ - regs [ GDBMACH_EFLAGS ] |= ( step << 8 ); -} - -static inline void gdbmach_breakpoint ( void ) { - __asm__ __volatile__ ( "int $3\n" ); -} - -extern int gdbmach_set_breakpoint ( int type, unsigned long addr, size_t len, int enable ); - -extern void gdbmach_init ( void ); - -#endif /* GDBMACH_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/initrd.h b/qemu/roms/ipxe/src/arch/i386/include/initrd.h deleted file mode 100644 index ddb3e5a45..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/initrd.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef _INITRD_H -#define _INITRD_H - -/** @file - * - * Initial ramdisk (initrd) reshuffling - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <ipxe/uaccess.h> - -/** Minimum alignment for initrds - * - * Some versions of Linux complain about initrds that are not - * page-aligned. - */ -#define INITRD_ALIGN 4096 - -/** Minimum free space required to reshuffle initrds - * - * Chosen to avoid absurdly long reshuffling times - */ -#define INITRD_MIN_FREE_LEN ( 512 * 1024 ) - -extern void initrd_reshuffle ( userptr_t bottom ); -extern int initrd_reshuffle_check ( size_t len, userptr_t bottom ); - -#endif /* _INITRD_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/int13.h b/qemu/roms/ipxe/src/arch/i386/include/int13.h deleted file mode 100644 index f82a583c6..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/int13.h +++ /dev/null @@ -1,333 +0,0 @@ -#ifndef INT13_H -#define INT13_H - -/** @file - * - * INT 13 emulation - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdint.h> -#include <ipxe/list.h> -#include <ipxe/edd.h> -#include <realmode.h> - -/** - * @defgroup int13ops INT 13 operation codes - * @{ - */ - -/** Reset disk system */ -#define INT13_RESET 0x00 -/** Get status of last operation */ -#define INT13_GET_LAST_STATUS 0x01 -/** Read sectors */ -#define INT13_READ_SECTORS 0x02 -/** Write sectors */ -#define INT13_WRITE_SECTORS 0x03 -/** Get drive parameters */ -#define INT13_GET_PARAMETERS 0x08 -/** Get disk type */ -#define INT13_GET_DISK_TYPE 0x15 -/** Extensions installation check */ -#define INT13_EXTENSION_CHECK 0x41 -/** Extended read */ -#define INT13_EXTENDED_READ 0x42 -/** Extended write */ -#define INT13_EXTENDED_WRITE 0x43 -/** Verify sectors */ -#define INT13_EXTENDED_VERIFY 0x44 -/** Extended seek */ -#define INT13_EXTENDED_SEEK 0x47 -/** Get extended drive parameters */ -#define INT13_GET_EXTENDED_PARAMETERS 0x48 -/** Get CD-ROM status / terminate emulation */ -#define INT13_CDROM_STATUS_TERMINATE 0x4b -/** Read CD-ROM boot catalog */ -#define INT13_CDROM_READ_BOOT_CATALOG 0x4d - -/** @} */ - -/** - * @defgroup int13status INT 13 status codes - * @{ - */ - -/** Operation completed successfully */ -#define INT13_STATUS_SUCCESS 0x00 -/** Invalid function or parameter */ -#define INT13_STATUS_INVALID 0x01 -/** Read error */ -#define INT13_STATUS_READ_ERROR 0x04 -/** Reset failed */ -#define INT13_STATUS_RESET_FAILED 0x05 -/** Write error */ -#define INT13_STATUS_WRITE_ERROR 0xcc - -/** @} */ - -/** Block size for non-extended INT 13 calls */ -#define INT13_BLKSIZE 512 - -/** @defgroup int13fddtype INT 13 floppy disk drive types - * @{ - */ - -/** 360K */ -#define INT13_FDD_TYPE_360K 0x01 -/** 1.2M */ -#define INT13_FDD_TYPE_1M2 0x02 -/** 720K */ -#define INT13_FDD_TYPE_720K 0x03 -/** 1.44M */ -#define INT13_FDD_TYPE_1M44 0x04 - -/** An INT 13 disk address packet */ -struct int13_disk_address { - /** Size of the packet, in bytes */ - uint8_t bufsize; - /** Reserved */ - uint8_t reserved_a; - /** Block count */ - uint8_t count; - /** Reserved */ - uint8_t reserved_b; - /** Data buffer */ - struct segoff buffer; - /** Starting block number */ - uint64_t lba; - /** Data buffer (EDD 3.0+ only) */ - uint64_t buffer_phys; - /** Block count (EDD 4.0+ only) */ - uint32_t long_count; - /** Reserved */ - uint32_t reserved_c; -} __attribute__ (( packed )); - -/** INT 13 disk parameters */ -struct int13_disk_parameters { - /** Size of this structure */ - uint16_t bufsize; - /** Flags */ - uint16_t flags; - /** Number of cylinders */ - uint32_t cylinders; - /** Number of heads */ - uint32_t heads; - /** Number of sectors per track */ - uint32_t sectors_per_track; - /** Total number of sectors on drive */ - uint64_t sectors; - /** Bytes per sector */ - uint16_t sector_size; - /** Device parameter table extension */ - struct segoff dpte; - /** Device path information */ - struct edd_device_path_information dpi; -} __attribute__ (( packed )); - -/** - * @defgroup int13types INT 13 disk types - * @{ - */ - -/** No such drive */ -#define INT13_DISK_TYPE_NONE 0x00 -/** Floppy without change-line support */ -#define INT13_DISK_TYPE_FDD 0x01 -/** Floppy with change-line support */ -#define INT13_DISK_TYPE_FDD_CL 0x02 -/** Hard disk */ -#define INT13_DISK_TYPE_HDD 0x03 - -/** @} */ - -/** - * @defgroup int13flags INT 13 disk parameter flags - * @{ - */ - -/** DMA boundary errors handled transparently */ -#define INT13_FL_DMA_TRANSPARENT 0x01 -/** CHS information is valid */ -#define INT13_FL_CHS_VALID 0x02 -/** Removable drive */ -#define INT13_FL_REMOVABLE 0x04 -/** Write with verify supported */ -#define INT13_FL_VERIFIABLE 0x08 -/** Has change-line supported (valid only for removable drives) */ -#define INT13_FL_CHANGE_LINE 0x10 -/** Drive can be locked (valid only for removable drives) */ -#define INT13_FL_LOCKABLE 0x20 -/** CHS is max possible, not current media (valid only for removable drives) */ -#define INT13_FL_CHS_MAX 0x40 - -/** @} */ - -/** - * @defgroup int13exts INT 13 extension flags - * @{ - */ - -/** Extended disk access functions supported */ -#define INT13_EXTENSION_LINEAR 0x01 -/** Removable drive functions supported */ -#define INT13_EXTENSION_REMOVABLE 0x02 -/** EDD functions supported */ -#define INT13_EXTENSION_EDD 0x04 -/** 64-bit extensions are present */ -#define INT13_EXTENSION_64BIT 0x08 - -/** @} */ - -/** - * @defgroup int13vers INT 13 extension versions - * @{ - */ - -/** INT13 extensions version 1.x */ -#define INT13_EXTENSION_VER_1_X 0x01 -/** INT13 extensions version 2.0 (EDD-1.0) */ -#define INT13_EXTENSION_VER_2_0 0x20 -/** INT13 extensions version 2.1 (EDD-1.1) */ -#define INT13_EXTENSION_VER_2_1 0x21 -/** INT13 extensions version 3.0 (EDD-3.0) */ -#define INT13_EXTENSION_VER_3_0 0x30 - -/** @} */ - -/** Maximum number of sectors for which CHS geometry is allowed to be valid - * - * This number is taken from the EDD specification. - */ -#define INT13_MAX_CHS_SECTORS 15482880 - -/** Bootable CD-ROM specification packet */ -struct int13_cdrom_specification { - /** Size of packet in bytes */ - uint8_t size; - /** Boot media type */ - uint8_t media_type; - /** Drive number */ - uint8_t drive; - /** CD-ROM controller number */ - uint8_t controller; - /** LBA of disk image to emulate */ - uint32_t lba; - /** Device specification */ - uint16_t device; - /** Segment of 3K buffer for caching CD-ROM reads */ - uint16_t cache_segment; - /** Load segment for initial boot image */ - uint16_t load_segment; - /** Number of 512-byte sectors to load */ - uint16_t load_sectors; - /** Low 8 bits of cylinder number */ - uint8_t cyl; - /** Sector number, plus high 2 bits of cylinder number */ - uint8_t cyl_sector; - /** Head number */ - uint8_t head; -} __attribute__ (( packed )); - -/** Bootable CD-ROM boot catalog command packet */ -struct int13_cdrom_boot_catalog_command { - /** Size of packet in bytes */ - uint8_t size; - /** Number of sectors of boot catalog to read */ - uint8_t count; - /** Buffer for boot catalog */ - uint32_t buffer; - /** First sector in boot catalog to transfer */ - uint16_t start; -} __attribute__ (( packed )); - -/** A C/H/S address within a partition table entry */ -struct partition_chs { - /** Head number */ - uint8_t head; - /** Sector number, plus high 2 bits of cylinder number */ - uint8_t cyl_sector; - /** Low 8 bits of cylinder number */ - uint8_t cyl; -} __attribute__ (( packed )); - -#define PART_HEAD(chs) ( (chs).head ) -#define PART_SECTOR(chs) ( (chs).cyl_sector & 0x3f ) -#define PART_CYLINDER(chs) ( (chs).cyl | ( ( (chs).cyl_sector & 0xc0 ) << 2 ) ) - -/** A partition table entry within the MBR */ -struct partition_table_entry { - /** Bootable flag */ - uint8_t bootable; - /** C/H/S start address */ - struct partition_chs chs_start; - /** System indicator (partition type) */ - uint8_t type; - /** C/H/S end address */ - struct partition_chs chs_end; - /** Linear start address */ - uint32_t start; - /** Linear length */ - uint32_t length; -} __attribute__ (( packed )); - -/** A Master Boot Record */ -struct master_boot_record { - /** Code area */ - uint8_t code[440]; - /** Disk signature */ - uint32_t signature; - /** Padding */ - uint8_t pad[2]; - /** Partition table */ - struct partition_table_entry partitions[4]; - /** 0x55aa MBR signature */ - uint16_t magic; -} __attribute__ (( packed )); - -/** MBR magic signature */ -#define INT13_MBR_MAGIC 0xaa55 - -/** A floppy disk geometry */ -struct int13_fdd_geometry { - /** Number of tracks */ - uint8_t tracks; - /** Number of heads and sectors per track */ - uint8_t heads_spt; -}; - -/** Define a floppy disk geometry */ -#define INT13_FDD_GEOMETRY( cylinders, heads, sectors ) \ - { \ - .tracks = (cylinders), \ - .heads_spt = ( ( (heads) << 6 ) | (sectors) ), \ - } - -/** Get floppy disk number of cylinders */ -#define INT13_FDD_CYLINDERS( geometry ) ( (geometry)->tracks ) - -/** Get floppy disk number of heads */ -#define INT13_FDD_HEADS( geometry ) ( (geometry)->heads_spt >> 6 ) - -/** Get floppy disk number of sectors per track */ -#define INT13_FDD_SECTORS( geometry ) ( (geometry)->heads_spt & 0x3f ) - -/** A floppy drive parameter table */ -struct int13_fdd_parameters { - uint8_t step_rate__head_unload; - uint8_t head_load__ndma; - uint8_t motor_off_delay; - uint8_t bytes_per_sector; - uint8_t sectors_per_track; - uint8_t gap_length; - uint8_t data_length; - uint8_t format_gap_length; - uint8_t format_filler; - uint8_t head_settle_time; - uint8_t motor_start_time; -} __attribute__ (( packed )); - -#endif /* INT13_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/ipxe/bios_nap.h b/qemu/roms/ipxe/src/arch/i386/include/ipxe/bios_nap.h deleted file mode 100644 index c9b82c1e5..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/ipxe/bios_nap.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _IPXE_BIOS_NAP_H -#define _IPXE_BIOS_NAP_H - -/** @file - * - * BIOS CPU sleeping - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#ifdef NAP_PCBIOS -#define NAP_PREFIX_pcbios -#else -#define NAP_PREFIX_pcbios __pcbios_ -#endif - -#endif /* _IPXE_BIOS_NAP_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/ipxe/bios_reboot.h b/qemu/roms/ipxe/src/arch/i386/include/ipxe/bios_reboot.h deleted file mode 100644 index 3f6df9073..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/ipxe/bios_reboot.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _IPXE_BIOS_REBOOT_H -#define _IPXE_BIOS_REBOOT_H - -/** @file - * - * Standard PC-BIOS reboot mechanism - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#ifdef REBOOT_PCBIOS -#define REBOOT_PREFIX_pcbios -#else -#define REBOOT_PREFIX_pcbios __pcbios_ -#endif - -#endif /* _IPXE_BIOS_REBOOT_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/ipxe/bios_sanboot.h b/qemu/roms/ipxe/src/arch/i386/include/ipxe/bios_sanboot.h deleted file mode 100644 index 1a86b7d57..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/ipxe/bios_sanboot.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef _IPXE_BIOS_SANBOOT_H -#define _IPXE_BIOS_SANBOOT_H - -/** @file - * - * Standard PC-BIOS sanboot interface - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#ifdef SANBOOT_PCBIOS -#define SANBOOT_PREFIX_pcbios -#else -#define SANBOOT_PREFIX_pcbios __pcbios_ -#endif - -/** - * Get default SAN drive number - * - * @ret drive Default drive number - */ -static inline __always_inline unsigned int -SANBOOT_INLINE ( pcbios, san_default_drive ) ( void ) { - /* Default to booting from first hard disk */ - return 0x80; -} - -#endif /* _IPXE_BIOS_SANBOOT_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/ipxe/bios_smbios.h b/qemu/roms/ipxe/src/arch/i386/include/ipxe/bios_smbios.h deleted file mode 100644 index 9f7f9c8ff..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/ipxe/bios_smbios.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _IPXE_BIOS_SMBIOS_H -#define _IPXE_BIOS_SMBIOS_H - -/** @file - * - * Standard PC-BIOS SMBIOS interface - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#ifdef SMBIOS_PCBIOS -#define SMBIOS_PREFIX_pcbios -#else -#define SMBIOS_PREFIX_pcbios __pcbios_ -#endif - -#endif /* _IPXE_BIOS_SMBIOS_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/ipxe/bios_timer.h b/qemu/roms/ipxe/src/arch/i386/include/ipxe/bios_timer.h deleted file mode 100644 index 6b88a623c..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/ipxe/bios_timer.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef _IPXE_BIOS_TIMER_H -#define _IPXE_BIOS_TIMER_H - -/** @file - * - * BIOS timer - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#ifdef TIMER_PCBIOS -#define TIMER_PREFIX_pcbios -#else -#define TIMER_PREFIX_pcbios __pcbios_ -#endif - -#include <ipxe/pit8254.h> - -/** - * Delay for a fixed number of microseconds - * - * @v usecs Number of microseconds for which to delay - */ -static inline __always_inline void -TIMER_INLINE ( pcbios, udelay ) ( unsigned long usecs ) { - /* BIOS timer is not high-resolution enough for udelay(), so - * we use the 8254 Programmable Interval Timer. - */ - pit8254_udelay ( usecs ); -} - -/** - * Get number of ticks per second - * - * @ret ticks_per_sec Number of ticks per second - */ -static inline __always_inline unsigned long -TIMER_INLINE ( pcbios, ticks_per_sec ) ( void ) { - /* BIOS timer ticks over at 18.2 ticks per second */ - return 18; -} - -#endif /* _IPXE_BIOS_TIMER_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/ipxe/errno/pcbios.h b/qemu/roms/ipxe/src/arch/i386/include/ipxe/errno/pcbios.h deleted file mode 100644 index 6312adaa4..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/ipxe/errno/pcbios.h +++ /dev/null @@ -1,115 +0,0 @@ -#ifndef _IPXE_ERRNO_PCBIOS_H -#define _IPXE_ERRNO_PCBIOS_H - -/** - * @file - * - * PC-BIOS platform error codes - * - * We use the PXE-specified error codes as the platform error codes - * for the PC-BIOS platform. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <pxe_error.h> - -/** - * Convert platform error code to platform component of iPXE error code - * - * @v platform Platform error code - * @ret errno Platform component of iPXE error code - */ -#define PLATFORM_TO_ERRNO( platform ) ( (platform) & 0xff ) - -/** - * Convert iPXE error code to platform error code - * - * @v errno iPXE error code - * @ret platform Platform error code - */ -#define ERRNO_TO_PLATFORM( errno ) ( (errno) & 0xff ) - -/* Platform-specific error codes */ -#define PLATFORM_ENOERR PXENV_STATUS_SUCCESS -#define PLATFORM_E2BIG PXENV_STATUS_BAD_FUNC -#define PLATFORM_EACCES PXENV_STATUS_TFTP_ACCESS_VIOLATION -#define PLATFORM_EADDRINUSE PXENV_STATUS_UDP_OPEN -#define PLATFORM_EADDRNOTAVAIL PXENV_STATUS_UDP_OPEN -#define PLATFORM_EAFNOSUPPORT PXENV_STATUS_UNSUPPORTED -#define PLATFORM_EAGAIN PXENV_STATUS_FAILURE -#define PLATFORM_EALREADY PXENV_STATUS_UDP_OPEN -#define PLATFORM_EBADF PXENV_STATUS_TFTP_CLOSED -#define PLATFORM_EBADMSG PXENV_STATUS_FAILURE -#define PLATFORM_EBUSY PXENV_STATUS_OUT_OF_RESOURCES -#define PLATFORM_ECANCELED PXENV_STATUS_BINL_CANCELED_BY_KEYSTROKE -#define PLATFORM_ECHILD PXENV_STATUS_TFTP_FILE_NOT_FOUND -#define PLATFORM_ECONNABORTED PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION -#define PLATFORM_ECONNREFUSED PXENV_STATUS_TFTP_CANNOT_OPEN_CONNECTION -#define PLATFORM_ECONNRESET PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION -#define PLATFORM_EDEADLK PXENV_STATUS_FAILURE -#define PLATFORM_EDESTADDRREQ PXENV_STATUS_BAD_FUNC -#define PLATFORM_EDOM PXENV_STATUS_FAILURE -#define PLATFORM_EDQUOT PXENV_STATUS_FAILURE -#define PLATFORM_EEXIST PXENV_STATUS_FAILURE -#define PLATFORM_EFAULT PXENV_STATUS_MCOPY_PROBLEM -#define PLATFORM_EFBIG PXENV_STATUS_MCOPY_PROBLEM -#define PLATFORM_EHOSTUNREACH PXENV_STATUS_ARP_TIMEOUT -#define PLATFORM_EIDRM PXENV_STATUS_FAILURE -#define PLATFORM_EILSEQ PXENV_STATUS_FAILURE -#define PLATFORM_EINPROGRESS PXENV_STATUS_FAILURE -#define PLATFORM_EINTR PXENV_STATUS_FAILURE -#define PLATFORM_EINVAL PXENV_STATUS_BAD_FUNC -#define PLATFORM_EIO PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION -#define PLATFORM_EISCONN PXENV_STATUS_UDP_OPEN -#define PLATFORM_EISDIR PXENV_STATUS_FAILURE -#define PLATFORM_ELOOP PXENV_STATUS_FAILURE -#define PLATFORM_EMFILE PXENV_STATUS_OUT_OF_RESOURCES -#define PLATFORM_EMLINK PXENV_STATUS_FAILURE -#define PLATFORM_EMSGSIZE PXENV_STATUS_BAD_FUNC -#define PLATFORM_EMULTIHOP PXENV_STATUS_FAILURE -#define PLATFORM_ENAMETOOLONG PXENV_STATUS_FAILURE -#define PLATFORM_ENETDOWN PXENV_STATUS_ARP_TIMEOUT -#define PLATFORM_ENETRESET PXENV_STATUS_FAILURE -#define PLATFORM_ENETUNREACH PXENV_STATUS_ARP_TIMEOUT -#define PLATFORM_ENFILE PXENV_STATUS_OUT_OF_RESOURCES -#define PLATFORM_ENOBUFS PXENV_STATUS_OUT_OF_RESOURCES -#define PLATFORM_ENODATA PXENV_STATUS_FAILURE -#define PLATFORM_ENODEV PXENV_STATUS_TFTP_FILE_NOT_FOUND -#define PLATFORM_ENOENT PXENV_STATUS_TFTP_FILE_NOT_FOUND -#define PLATFORM_ENOEXEC PXENV_STATUS_FAILURE -#define PLATFORM_ENOLCK PXENV_STATUS_FAILURE -#define PLATFORM_ENOLINK PXENV_STATUS_FAILURE -#define PLATFORM_ENOMEM PXENV_STATUS_OUT_OF_RESOURCES -#define PLATFORM_ENOMSG PXENV_STATUS_FAILURE -#define PLATFORM_ENOPROTOOPT PXENV_STATUS_UNSUPPORTED -#define PLATFORM_ENOSPC PXENV_STATUS_OUT_OF_RESOURCES -#define PLATFORM_ENOSR PXENV_STATUS_OUT_OF_RESOURCES -#define PLATFORM_ENOSTR PXENV_STATUS_FAILURE -#define PLATFORM_ENOSYS PXENV_STATUS_UNSUPPORTED -#define PLATFORM_ENOTCONN PXENV_STATUS_FAILURE -#define PLATFORM_ENOTDIR PXENV_STATUS_FAILURE -#define PLATFORM_ENOTEMPTY PXENV_STATUS_FAILURE -#define PLATFORM_ENOTSOCK PXENV_STATUS_FAILURE -#define PLATFORM_ENOTSUP PXENV_STATUS_UNSUPPORTED -#define PLATFORM_ENOTTY PXENV_STATUS_FAILURE -#define PLATFORM_ENXIO PXENV_STATUS_TFTP_FILE_NOT_FOUND -#define PLATFORM_EOPNOTSUPP PXENV_STATUS_UNSUPPORTED -#define PLATFORM_EOVERFLOW PXENV_STATUS_FAILURE -#define PLATFORM_EPERM PXENV_STATUS_TFTP_ACCESS_VIOLATION -#define PLATFORM_EPIPE PXENV_STATUS_FAILURE -#define PLATFORM_EPROTO PXENV_STATUS_FAILURE -#define PLATFORM_EPROTONOSUPPORT PXENV_STATUS_UNSUPPORTED -#define PLATFORM_EPROTOTYPE PXENV_STATUS_FAILURE -#define PLATFORM_ERANGE PXENV_STATUS_FAILURE -#define PLATFORM_EROFS PXENV_STATUS_FAILURE -#define PLATFORM_ESPIPE PXENV_STATUS_FAILURE -#define PLATFORM_ESRCH PXENV_STATUS_TFTP_FILE_NOT_FOUND -#define PLATFORM_ESTALE PXENV_STATUS_FAILURE -#define PLATFORM_ETIME PXENV_STATUS_FAILURE -#define PLATFORM_ETIMEDOUT PXENV_STATUS_TFTP_READ_TIMEOUT -#define PLATFORM_ETXTBSY PXENV_STATUS_FAILURE -#define PLATFORM_EWOULDBLOCK PXENV_STATUS_TFTP_OPEN -#define PLATFORM_EXDEV PXENV_STATUS_FAILURE - -#endif /* _IPXE_ERRNO_PCBIOS_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/ipxe/guestrpc.h b/qemu/roms/ipxe/src/arch/i386/include/ipxe/guestrpc.h deleted file mode 100644 index bc3d85506..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/ipxe/guestrpc.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef _IPXE_GUESTRPC_H -#define _IPXE_GUESTRPC_H - -/** @file - * - * VMware GuestRPC mechanism - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdint.h> -#include <ipxe/vmware.h> - -/** GuestRPC magic number */ -#define GUESTRPC_MAGIC 0x49435052 /* "RPCI" */ - -/** Open RPC channel */ -#define GUESTRPC_OPEN 0x00 - -/** Open RPC channel success status */ -#define GUESTRPC_OPEN_SUCCESS 0x00010000 - -/** Send RPC command length */ -#define GUESTRPC_COMMAND_LEN 0x01 - -/** Send RPC command length success status */ -#define GUESTRPC_COMMAND_LEN_SUCCESS 0x00810000 - -/** Send RPC command data */ -#define GUESTRPC_COMMAND_DATA 0x02 - -/** Send RPC command data success status */ -#define GUESTRPC_COMMAND_DATA_SUCCESS 0x00010000 - -/** Receive RPC reply length */ -#define GUESTRPC_REPLY_LEN 0x03 - -/** Receive RPC reply length success status */ -#define GUESTRPC_REPLY_LEN_SUCCESS 0x00830000 - -/** Receive RPC reply data */ -#define GUESTRPC_REPLY_DATA 0x04 - -/** Receive RPC reply data success status */ -#define GUESTRPC_REPLY_DATA_SUCCESS 0x00010000 - -/** Finish receiving RPC reply */ -#define GUESTRPC_REPLY_FINISH 0x05 - -/** Finish receiving RPC reply success status */ -#define GUESTRPC_REPLY_FINISH_SUCCESS 0x00010000 - -/** Close RPC channel */ -#define GUESTRPC_CLOSE 0x06 - -/** Close RPC channel success status */ -#define GUESTRPC_CLOSE_SUCCESS 0x00010000 - -/** RPC command success status */ -#define GUESTRPC_SUCCESS 0x2031 /* "1 " */ - -extern int guestrpc_open ( void ); -extern void guestrpc_close ( int channel ); -extern int guestrpc_command ( int channel, const char *command, char *reply, - size_t reply_len ); - -#endif /* _IPXE_GUESTRPC_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/ipxe/memtop_umalloc.h b/qemu/roms/ipxe/src/arch/i386/include/ipxe/memtop_umalloc.h deleted file mode 100644 index dee055d16..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/ipxe/memtop_umalloc.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _IPXE_MEMTOP_UMALLOC_H -#define _IPXE_MEMTOP_UMALLOC_H - -/** @file - * - * External memory allocation - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#ifdef UMALLOC_MEMTOP -#define UMALLOC_PREFIX_memtop -#else -#define UMALLOC_PREFIX_memtop __memtop_ -#endif - -#endif /* _IPXE_MEMTOP_UMALLOC_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/ipxe/msr.h b/qemu/roms/ipxe/src/arch/i386/include/ipxe/msr.h deleted file mode 100644 index 5705318fd..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/ipxe/msr.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef _IPXE_MSR_H -#define _IPXE_MSR_H - -/** @file - * - * Model-specific registers - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/** - * Read model-specific register - * - * @v msr Model-specific register - * @ret value Value - */ -static inline __attribute__ (( always_inline )) uint64_t -rdmsr ( unsigned int msr ) { - uint64_t value; - - __asm__ __volatile__ ( "rdmsr" : "=A" ( value ) : "c" ( msr ) ); - return value; -} - -/** - * Write model-specific register - * - * @v msr Model-specific register - * @v value Value - */ -static inline __attribute__ (( always_inline )) void -wrmsr ( unsigned int msr, uint64_t value ) { - - __asm__ __volatile__ ( "wrmsr" : : "c" ( msr ), "A" ( value ) ); -} - -#endif /* _IPXE_MSR_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/ipxe/rdtsc_timer.h b/qemu/roms/ipxe/src/arch/i386/include/ipxe/rdtsc_timer.h deleted file mode 100644 index 598f4bb08..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/ipxe/rdtsc_timer.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef _IPXE_RDTSC_TIMER_H -#define _IPXE_RDTSC_TIMER_H - -/** @file - * - * RDTSC timer - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#ifdef TIMER_RDTSC -#define TIMER_PREFIX_rdtsc -#else -#define TIMER_PREFIX_rdtsc __rdtsc_ -#endif - -/** - * RDTSC values can easily overflow an unsigned long. We discard the - * low-order bits in order to obtain sensibly-scaled values. - */ -#define TSC_SHIFT 8 - -/** - * Get current system time in ticks - * - * @ret ticks Current time, in ticks - */ -static inline __always_inline unsigned long -TIMER_INLINE ( rdtsc, currticks ) ( void ) { - unsigned long ticks; - - __asm__ __volatile__ ( "rdtsc\n\t" - "shrdl %1, %%edx, %%eax\n\t" - : "=a" ( ticks ) : "i" ( TSC_SHIFT ) : "edx" ); - return ticks; -} - -#endif /* _IPXE_RDTSC_TIMER_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/ipxe/rtc_entropy.h b/qemu/roms/ipxe/src/arch/i386/include/ipxe/rtc_entropy.h deleted file mode 100644 index e214745d0..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/ipxe/rtc_entropy.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef _IPXE_RTC_ENTROPY_H -#define _IPXE_RTC_ENTROPY_H - -/** @file - * - * RTC-based entropy source - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdint.h> - -#ifdef ENTROPY_RTC -#define ENTROPY_PREFIX_rtc -#else -#define ENTROPY_PREFIX_rtc __rtc_ -#endif - -/** - * min-entropy per sample - * - * @ret min_entropy min-entropy of each sample - */ -static inline __always_inline double -ENTROPY_INLINE ( rtc, min_entropy_per_sample ) ( void ) { - - /* The min-entropy has been measured on several platforms - * using the entropy_sample test code. Modelling the samples - * as independent, and using a confidence level of 99.99%, the - * measurements were as follows: - * - * qemu-kvm : 7.38 bits - * VMware : 7.46 bits - * Physical hardware : 2.67 bits - * - * We choose the lowest of these (2.67 bits) and apply a 50% - * safety margin to allow for some potential non-independence - * of samples. - */ - return 1.3; -} - -extern uint8_t rtc_sample ( void ); - -/** - * Get noise sample - * - * @ret noise Noise sample - * @ret rc Return status code - */ -static inline __always_inline int -ENTROPY_INLINE ( rtc, get_noise ) ( noise_sample_t *noise ) { - - /* Get sample */ - *noise = rtc_sample(); - - /* Always successful */ - return 0; -} - -#endif /* _IPXE_RTC_ENTROPY_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/ipxe/rtc_time.h b/qemu/roms/ipxe/src/arch/i386/include/ipxe/rtc_time.h deleted file mode 100644 index cb8c7f49e..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/ipxe/rtc_time.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _IPXE_RTC_TIME_H -#define _IPXE_RTC_TIME_H - -/** @file - * - * RTC-based time source - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#ifdef TIME_RTC -#define TIME_PREFIX_rtc -#else -#define TIME_PREFIX_rtc __rtc_ -#endif - -#endif /* _IPXE_RTC_TIME_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/ipxe/vesafb.h b/qemu/roms/ipxe/src/arch/i386/include/ipxe/vesafb.h deleted file mode 100644 index efc8f2cb8..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/ipxe/vesafb.h +++ /dev/null @@ -1,210 +0,0 @@ -#ifndef _IPXE_VESAFB_H -#define _IPXE_VESAFB_H - -/** @file - * - * VESA frame buffer console - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdint.h> -#include <realmode.h> - -/** INT 10,4f00: return controller information */ -#define VBE_CONTROLLER_INFO 0x4f00 - -/** VBE controller information */ -struct vbe_controller_info { - /** VBE signature */ - uint32_t vbe_signature; - /** VBE minor version */ - uint8_t vbe_minor_version; - /** VBE major version */ - uint8_t vbe_major_version; - /** Pointer to OEM string */ - struct segoff oem_string_ptr; - /** Capabilities of graphics controller */ - uint32_t capabilities; - /** Pointer to video mode list */ - struct segoff video_mode_ptr; - /** Number of 64kB memory blocks */ - uint16_t total_memory; - /** VBE implementation software revision */ - uint16_t oem_software_rev; - /** Pointer to vendor name string */ - struct segoff oem_vendor_name_ptr; - /** Pointer to product name string */ - struct segoff oem_product_name_ptr; - /** Pointer to product revision string */ - struct segoff oem_product_rev_ptr; - /** Reserved for VBE implementation scratch area */ - uint8_t reserved[222]; - /* VBE2.0 defines an additional 256-byte data area for - * including the OEM strings inline within the VBE information - * block; we omit this to reduce the amount of base memory - * required for VBE calls. - */ -} __attribute__ (( packed )); - -/** VBE controller information signature */ -#define VBE_CONTROLLER_SIGNATURE \ - ( ( 'V' << 0 ) | ( 'E' << 8 ) | ( 'S' << 16 ) | ( 'A' << 24 ) ) - -/** VBE mode list end marker */ -#define VBE_MODE_END 0xffff - -/** INT 10,4f01: return VBE mode information */ -#define VBE_MODE_INFO 0x4f01 - -/** VBE mode information */ -struct vbe_mode_info { - /** Mode attributes */ - uint16_t mode_attributes; - /** Window A attributes */ - uint8_t win_a_attributes; - /** Window B attributes */ - uint8_t win_b_attributes; - /** Window granularity */ - uint16_t win_granularity; - /** Window size */ - uint16_t win_size; - /** Window A start segment */ - uint16_t win_a_segment; - /** Window B start segment */ - uint16_t win_b_segment; - /** Pointer to window function */ - struct segoff win_func_ptr; - /** Bytes per scan line */ - uint16_t bytes_per_scan_line; - /** Horizontal resolution in pixels or characters */ - uint16_t x_resolution; - /** Vertical resolution in pixels or characters */ - uint16_t y_resolution; - /** Character cell width in pixels */ - uint8_t x_char_size; - /** Character cell height in pixels */ - uint8_t y_char_size; - /** Number of memory planes */ - uint8_t number_of_planes; - /** Bits per pixel */ - uint8_t bits_per_pixel; - /** Number of banks */ - uint8_t number_of_banks; - /** Memory model type */ - uint8_t memory_model; - /** Bank size in kB */ - uint8_t bank_size; - /** Number of images */ - uint8_t number_of_image_pages; - /** Reserved for page function */ - uint8_t reserved_1; - /** Size of direct colour red mask in bits */ - uint8_t red_mask_size; - /** Bit position of LSB of red mask */ - uint8_t red_field_position; - /** Size of direct colour green mask in bits */ - uint8_t green_mask_size; - /** Bit position of LSB of green mask */ - uint8_t green_field_position; - /** Size of direct colour blue mask in bits */ - uint8_t blue_mask_size; - /** Bit position of LSB of blue mask */ - uint8_t blue_field_position; - /** Size of direct colour reserved mask in bits */ - uint8_t rsvd_mask_size; - /** Bit position of LSB of reserved mask */ - uint8_t rsvd_field_position; - /** Direct colour mode attributes */ - uint8_t direct_colour_mode_info; - /** Physical address for flat memory frame buffer */ - uint32_t phys_base_ptr; - /** Pointer to start of off-screen memory */ - uint32_t off_screen_mem_offset; - /** Amount of off-screen memory in 1kB units */ - uint16_t off_screen_mem_size; - /** Reserved */ - uint8_t reserved_2[206]; -} __attribute__ (( packed )); - -/** VBE mode attributes */ -enum vbe_mode_attributes { - /** Mode supported in hardware */ - VBE_MODE_ATTR_SUPPORTED = 0x0001, - /** TTY output functions supported by BIOS */ - VBE_MODE_ATTR_TTY = 0x0004, - /** Colour mode */ - VBE_MODE_ATTR_COLOUR = 0x0008, - /** Graphics mode */ - VBE_MODE_ATTR_GRAPHICS = 0x0010, - /** Not a VGA compatible mode */ - VBE_MODE_ATTR_NOT_VGA = 0x0020, - /** VGA compatible windowed memory mode is not available */ - VBE_MODE_ATTR_NOT_WINDOWED = 0x0040, - /** Linear frame buffer mode is available */ - VBE_MODE_ATTR_LINEAR = 0x0080, - /** Double scan mode is available */ - VBE_MODE_ATTR_DOUBLE = 0x0100, - /** Interlaced mode is available */ - VBE_MODE_ATTR_INTERLACED = 0x0200, - /** Hardware triple buffering support */ - VBE_MODE_ATTR_TRIPLE_BUF = 0x0400, - /** Hardware stereoscopic display support */ - VBE_MODE_ATTR_STEREO = 0x0800, - /** Dual display start address support */ - VBE_MODE_ATTR_DUAL = 0x1000, -}; - -/** VBE mode memory models */ -enum vbe_mode_memory_model { - /** Text mode */ - VBE_MODE_MODEL_TEXT = 0x00, - /** CGA graphics mode */ - VBE_MODE_MODEL_CGA = 0x01, - /** Hercules graphics mode */ - VBE_MODE_MODEL_HERCULES = 0x02, - /** Planar mode */ - VBE_MODE_MODEL_PLANAR = 0x03, - /** Packed pixel mode */ - VBE_MODE_MODEL_PACKED_PIXEL = 0x04, - /** Non-chain 4, 256 colour mode */ - VBE_MODE_MODEL_NON_CHAIN_4 = 0x05, - /** Direct colour mode */ - VBE_MODE_MODEL_DIRECT_COLOUR = 0x06, - /** YUV mode */ - VBE_MODE_MODEL_YUV = 0x07, -}; - -/** INT 10,4f02: set VBE mode */ -#define VBE_SET_MODE 0x4f02 - -/** VBE linear frame buffer mode bit */ -#define VBE_MODE_LINEAR 0x4000 - -/** INT 10,1130: get font information */ -#define VBE_GET_FONT 0x1130 - -/** Font sets */ -enum vbe_font_set { - /** 8x14 character font */ - VBE_FONT_8x14 = 0x0200, - /** 8x8 double dot font */ - VBE_FONT_8x8_DOUBLE = 0x0300, - /** 8x8 double dot font (high 128 characters) */ - VBE_FONT_8x8_DOUBLE_HIGH = 0x0400, - /** 9x14 alpha alternate font */ - VBE_FONT_9x14_ALPHA_ALT = 0x0500, - /** 8x16 font */ - VBE_FONT_8x16 = 0x0600, - /** 9x16 alternate font */ - VBE_FONT_9x16_ALT = 0x0700, -}; - -/** INT 10,00: set VGA mode */ -#define VBE_SET_VGA_MODE 0x0000 - -/** INT 10,0f: get VGA mode */ -#define VBE_GET_VGA_MODE 0x0f00 - -#endif /* _IPXE_VESAFB_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/ipxe/vmware.h b/qemu/roms/ipxe/src/arch/i386/include/ipxe/vmware.h deleted file mode 100644 index 24f60a03a..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/ipxe/vmware.h +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef _IPXE_VMWARE_H -#define _IPXE_VMWARE_H - -/** @file - * - * VMware backdoor mechanism - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdint.h> - -/** VMware backdoor I/O port */ -#define VMW_PORT 0x5658 - -/** VMware backdoor magic value */ -#define VMW_MAGIC 0x564d5868 /* "VMXh" */ - -/** VMware backdoor magic instruction */ -#define VMW_BACKDOOR "inl %%dx, %%eax" - -/** Get VMware version */ -#define VMW_CMD_GET_VERSION 0x0a - -/** Issue GuestRPC command */ -#define VMW_CMD_GUESTRPC 0x1e - -/** - * Get VMware version - * - * @ret version VMware version(?) - * @ret magic VMware magic number, if present - * @ret product_type VMware product type - */ -static inline __attribute__ (( always_inline )) void -vmware_cmd_get_version ( uint32_t *version, uint32_t *magic, - uint32_t *product_type ) { - uint32_t discard_d; - - /* Perform backdoor call */ - __asm__ __volatile__ ( VMW_BACKDOOR - : "=a" ( *version ), "=b" ( *magic ), - "=c" ( *product_type ), "=d" ( discard_d ) - : "0" ( VMW_MAGIC ), "1" ( 0 ), - "2" ( VMW_CMD_GET_VERSION ), - "3" ( VMW_PORT ) ); -} - -/** - * Issue GuestRPC command - * - * @v channel Channel number - * @v subcommand GuestRPC subcommand - * @v parameter Subcommand-specific parameter - * @ret edxhi Subcommand-specific result - * @ret ebx Subcommand-specific result - * @ret status Command status - */ -static inline __attribute__ (( always_inline )) uint32_t -vmware_cmd_guestrpc ( int channel, uint16_t subcommand, uint32_t parameter, - uint16_t *edxhi, uint32_t *ebx ) { - uint32_t discard_a; - uint32_t status; - uint32_t edx; - - /* Perform backdoor call */ - __asm__ __volatile__ ( VMW_BACKDOOR - : "=a" ( discard_a ), "=b" ( *ebx ), - "=c" ( status ), "=d" ( edx ) - : "0" ( VMW_MAGIC ), "1" ( parameter ), - "2" ( VMW_CMD_GUESTRPC | ( subcommand << 16 )), - "3" ( VMW_PORT | ( channel << 16 ) ) ); - *edxhi = ( edx >> 16 ); - - return status; -} - -extern int vmware_present ( void ); - -#endif /* _IPXE_VMWARE_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/kir.h b/qemu/roms/ipxe/src/arch/i386/include/kir.h deleted file mode 100644 index 84633d26f..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/kir.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef KIR_H -#define KIR_H - -#ifndef KEEP_IT_REAL -#error "kir.h can be used only with -DKEEP_IT_REAL" -#endif - -#ifdef ASSEMBLY - -#define code32 code16gcc - -#else /* ASSEMBLY */ - -__asm__ ( ".code16gcc" ); - -#endif /* ASSEMBLY */ - -#endif /* KIR_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/libkir.h b/qemu/roms/ipxe/src/arch/i386/include/libkir.h deleted file mode 100644 index 1f5b13504..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/libkir.h +++ /dev/null @@ -1,233 +0,0 @@ -#ifndef LIBKIR_H -#define LIBKIR_H - -#include "realmode.h" - -#ifndef ASSEMBLY - -/* - * Full API documentation for these functions is in realmode.h. - * - */ - -/* Access to variables in .data16 and .text16 in a way compatible with librm */ -#define __data16( variable ) variable -#define __data16_array( variable, array ) variable array -#define __bss16( variable ) variable -#define __bss16_array( variable, array ) variable array -#define __text16( variable ) variable -#define __text16_array( variable,array ) variable array -#define __use_data16( variable ) variable -#define __use_text16( variable ) variable -#define __from_data16( pointer ) pointer -#define __from_text16( pointer ) pointer - -/* Real-mode data and code segments */ -static inline __attribute__ (( always_inline )) unsigned int _rm_cs ( void ) { - uint16_t cs; - __asm__ __volatile__ ( "movw %%cs, %w0" : "=r" ( cs ) ); - return cs; -} - -static inline __attribute__ (( always_inline )) unsigned int _rm_ds ( void ) { - uint16_t ds; - __asm__ __volatile__ ( "movw %%ds, %w0" : "=r" ( ds ) ); - return ds; -} - -#define rm_cs ( _rm_cs() ) -#define rm_ds ( _rm_ds() ) - -/* Copy to/from base memory */ - -static inline void copy_to_real_libkir ( unsigned int dest_seg, - unsigned int dest_off, - const void *src, size_t n ) { - unsigned int discard_D, discard_S, discard_c; - - __asm__ __volatile__ ( "pushw %%es\n\t" - "movw %3, %%es\n\t" - "rep movsb\n\t" - "popw %%es\n\t" - : "=D" ( discard_D ), "=S" ( discard_S ), - "=c" ( discard_c ) - : "r" ( dest_seg ), "D" ( dest_off ), - "S" ( src ), - "c" ( n ) - : "memory" ); -} - -static inline void copy_from_real_libkir ( void *dest, - unsigned int src_seg, - unsigned int src_off, - size_t n ) { - unsigned int discard_D, discard_S, discard_c; - - __asm__ __volatile__ ( "pushw %%ds\n\t" - "movw %4, %%ds\n\t" - "rep movsb\n\t" - "popw %%ds\n\t" - : "=D" ( discard_D ), "=S" ( discard_S ), - "=c" ( discard_c ) - : "D" ( dest ), - "r" ( src_seg ), "S" ( src_off ), - "c" ( n ) - : "memory" ); -} - -#define copy_to_real copy_to_real_libkir -#define copy_from_real copy_from_real_libkir - -/* - * Transfer individual values to/from base memory. There may well be - * a neater way to do this. We have two versions: one for constant - * offsets (where the mov instruction must be of the form "mov - * %es:123, %xx") and one for non-constant offsets (where the mov - * instruction must be of the form "mov %es:(%xx), %yx". If it's - * possible to incorporate both forms into one __asm__ instruction, I - * don't know how to do it. - * - * Ideally, the mov instruction should be "mov%z0"; the "%z0" is meant - * to expand to either "b", "w" or "l" depending on the size of - * operand 0. This would remove the (minor) ambiguity in the mov - * instruction. However, gcc on at least my system barfs with an - * "internal compiler error" when confronted with %z0. - * - */ - -#define put_real_kir_const_off( var, seg, off ) \ - __asm__ ( "movw %w1, %%es\n\t" \ - "mov %0, %%es:%c2\n\t" \ - "pushw %%ds\n\t" /* restore %es */ \ - "popw %%es\n\t" \ - : \ - : "r,r" ( var ), "rm,rm" ( seg ), "i,!r" ( off ) \ - ) - -#define put_real_kir_nonconst_off( var, seg, off ) \ - __asm__ ( "movw %w1, %%es\n\t" \ - "mov %0, %%es:(%2)\n\t" \ - "pushw %%ds\n\t" /* restore %es */ \ - "popw %%es\n\t" \ - : \ - : "r" ( var ), "rm" ( seg ), "r" ( off ) \ - ) - -#define put_real_kir( var, seg, off ) \ - do { \ - if ( __builtin_constant_p ( off ) ) \ - put_real_kir_const_off ( var, seg, off ); \ - else \ - put_real_kir_nonconst_off ( var, seg, off ); \ - } while ( 0 ) - -#define get_real_kir_const_off( var, seg, off ) \ - __asm__ ( "movw %w1, %%es\n\t" \ - "mov %%es:%c2, %0\n\t" \ - "pushw %%ds\n\t" /* restore %es */ \ - "popw %%es\n\t" \ - : "=r,r" ( var ) \ - : "rm,rm" ( seg ), "i,!r" ( off ) \ - ) - -#define get_real_kir_nonconst_off( var, seg, off ) \ - __asm__ ( "movw %w1, %%es\n\t" \ - "mov %%es:(%2), %0\n\t" \ - "pushw %%ds\n\t" /* restore %es */ \ - "popw %%es\n\t" \ - : "=r" ( var ) \ - : "rm" ( seg ), "r" ( off ) \ - ) - -#define get_real_kir( var, seg, off ) \ - do { \ - if ( __builtin_constant_p ( off ) ) \ - get_real_kir_const_off ( var, seg, off ); \ - else \ - get_real_kir_nonconst_off ( var, seg, off ); \ - } while ( 0 ) - -#define put_real put_real_kir -#define get_real get_real_kir - -/** - * A pointer to a user buffer - * - * This is actually a struct segoff, but encoded as a uint32_t to - * ensure that gcc passes it around efficiently. - */ -typedef uint32_t userptr_t; - -/** - * Copy data to user buffer - * - * @v buffer User buffer - * @v offset Offset within user buffer - * @v src Source - * @v len Length - */ -static inline __attribute__ (( always_inline )) void -copy_to_user ( userptr_t buffer, off_t offset, const void *src, size_t len ) { - copy_to_real ( ( buffer >> 16 ), ( ( buffer & 0xffff ) + offset ), - src, len ); -} - -/** - * Copy data from user buffer - * - * @v dest Destination - * @v buffer User buffer - * @v offset Offset within user buffer - * @v len Length - */ -static inline __attribute__ (( always_inline )) void -copy_from_user ( void *dest, userptr_t buffer, off_t offset, size_t len ) { - copy_from_real ( dest, ( buffer >> 16 ), - ( ( buffer & 0xffff ) + offset ), len ); -} - -/** - * Convert segment:offset address to user buffer - * - * @v segment Real-mode segment - * @v offset Real-mode offset - * @ret buffer User buffer - */ -static inline __attribute__ (( always_inline )) userptr_t -real_to_user ( unsigned int segment, unsigned int offset ) { - return ( ( segment << 16 ) | offset ); -} - -/** - * Convert virtual address to user buffer - * - * @v virtual Virtual address - * @ret buffer User buffer - * - * This constructs a user buffer from an ordinary pointer. Use it - * when you need to pass a pointer to an internal buffer to a function - * that expects a @c userptr_t. - */ -static inline __attribute__ (( always_inline )) userptr_t -virt_to_user ( void * virtual ) { - return real_to_user ( rm_ds, ( intptr_t ) virtual ); -} - -/* TEXT16_CODE: declare a fragment of code that resides in .text16 */ -#define TEXT16_CODE( asm_code_str ) \ - ".section \".text16\", \"ax\", @progbits\n\t" \ - ".code16\n\t" \ - ".arch i386\n\t" \ - asm_code_str "\n\t" \ - ".code16gcc\n\t" \ - ".previous\n\t" - -/* REAL_CODE: declare a fragment of code that executes in real mode */ -#define REAL_CODE( asm_code_str ) \ - ".code16\n\t" \ - asm_code_str "\n\t" \ - ".code16gcc\n\t" - -#endif /* ASSEMBLY */ - -#endif /* LIBKIR_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/librm.h b/qemu/roms/ipxe/src/arch/i386/include/librm.h deleted file mode 100644 index a8a578a39..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/librm.h +++ /dev/null @@ -1,267 +0,0 @@ -#ifndef LIBRM_H -#define LIBRM_H - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/* Segment selectors as used in our protected-mode GDTs. - * - * Don't change these unless you really know what you're doing. - */ - -#define VIRTUAL_CS 0x08 -#define VIRTUAL_DS 0x10 -#define PHYSICAL_CS 0x18 -#define PHYSICAL_DS 0x20 -#define REAL_CS 0x28 -#define REAL_DS 0x30 -#if 0 -#define LONG_CS 0x38 -#define LONG_DS 0x40 -#endif - -#ifndef ASSEMBLY - -#ifdef UACCESS_LIBRM -#define UACCESS_PREFIX_librm -#else -#define UACCESS_PREFIX_librm __librm_ -#endif - -/* Variables in librm.S */ -extern unsigned long virt_offset; - -/** - * Convert physical address to user pointer - * - * @v phys_addr Physical address - * @ret userptr User pointer - */ -static inline __always_inline userptr_t -UACCESS_INLINE ( librm, phys_to_user ) ( unsigned long phys_addr ) { - return ( phys_addr - virt_offset ); -} - -/** - * Convert user buffer to physical address - * - * @v userptr User pointer - * @v offset Offset from user pointer - * @ret phys_addr Physical address - */ -static inline __always_inline unsigned long -UACCESS_INLINE ( librm, user_to_phys ) ( userptr_t userptr, off_t offset ) { - return ( userptr + offset + virt_offset ); -} - -static inline __always_inline userptr_t -UACCESS_INLINE ( librm, virt_to_user ) ( volatile const void *addr ) { - return trivial_virt_to_user ( addr ); -} - -static inline __always_inline void * -UACCESS_INLINE ( librm, user_to_virt ) ( userptr_t userptr, off_t offset ) { - return trivial_user_to_virt ( userptr, offset ); -} - -static inline __always_inline userptr_t -UACCESS_INLINE ( librm, userptr_add ) ( userptr_t userptr, off_t offset ) { - return trivial_userptr_add ( userptr, offset ); -} - -static inline __always_inline off_t -UACCESS_INLINE ( librm, userptr_sub ) ( userptr_t userptr, - userptr_t subtrahend ) { - return trivial_userptr_sub ( userptr, subtrahend ); -} - -static inline __always_inline void -UACCESS_INLINE ( librm, memcpy_user ) ( userptr_t dest, off_t dest_off, - userptr_t src, off_t src_off, - size_t len ) { - trivial_memcpy_user ( dest, dest_off, src, src_off, len ); -} - -static inline __always_inline void -UACCESS_INLINE ( librm, memmove_user ) ( userptr_t dest, off_t dest_off, - userptr_t src, off_t src_off, - size_t len ) { - trivial_memmove_user ( dest, dest_off, src, src_off, len ); -} - -static inline __always_inline int -UACCESS_INLINE ( librm, memcmp_user ) ( userptr_t first, off_t first_off, - userptr_t second, off_t second_off, - size_t len ) { - return trivial_memcmp_user ( first, first_off, second, second_off, len); -} - -static inline __always_inline void -UACCESS_INLINE ( librm, memset_user ) ( userptr_t buffer, off_t offset, - int c, size_t len ) { - trivial_memset_user ( buffer, offset, c, len ); -} - -static inline __always_inline size_t -UACCESS_INLINE ( librm, strlen_user ) ( userptr_t buffer, off_t offset ) { - return trivial_strlen_user ( buffer, offset ); -} - -static inline __always_inline off_t -UACCESS_INLINE ( librm, memchr_user ) ( userptr_t buffer, off_t offset, - int c, size_t len ) { - return trivial_memchr_user ( buffer, offset, c, len ); -} - - -/****************************************************************************** - * - * Access to variables in .data16 and .text16 - * - */ - -extern char *data16; -extern char *text16; - -#define __data16( variable ) \ - __attribute__ (( section ( ".data16" ) )) \ - _data16_ ## variable __asm__ ( #variable ) - -#define __data16_array( variable, array ) \ - __attribute__ (( section ( ".data16" ) )) \ - _data16_ ## variable array __asm__ ( #variable ) - -#define __bss16( variable ) \ - __attribute__ (( section ( ".bss16" ) )) \ - _data16_ ## variable __asm__ ( #variable ) - -#define __bss16_array( variable, array ) \ - __attribute__ (( section ( ".bss16" ) )) \ - _data16_ ## variable array __asm__ ( #variable ) - -#define __text16( variable ) \ - __attribute__ (( section ( ".text16.data" ) )) \ - _text16_ ## variable __asm__ ( #variable ) - -#define __text16_array( variable, array ) \ - __attribute__ (( section ( ".text16.data" ) )) \ - _text16_ ## variable array __asm__ ( #variable ) - -#define __use_data16( variable ) \ - ( * ( ( typeof ( _data16_ ## variable ) * ) \ - & ( data16 [ ( size_t ) & ( _data16_ ## variable ) ] ) ) ) - -#define __use_text16( variable ) \ - ( * ( ( typeof ( _text16_ ## variable ) * ) \ - & ( text16 [ ( size_t ) & ( _text16_ ## variable ) ] ) ) ) - -#define __from_data16( pointer ) \ - ( ( unsigned int ) \ - ( ( ( void * ) (pointer) ) - ( ( void * ) data16 ) ) ) - -#define __from_text16( pointer ) \ - ( ( unsigned int ) \ - ( ( ( void * ) (pointer) ) - ( ( void * ) text16 ) ) ) - -/* Variables in librm.S, present in the normal data segment */ -extern uint16_t rm_sp; -extern uint16_t rm_ss; -extern uint16_t __text16 ( rm_cs ); -#define rm_cs __use_text16 ( rm_cs ) -extern uint16_t __text16 ( rm_ds ); -#define rm_ds __use_text16 ( rm_ds ) - -extern uint16_t copy_user_to_rm_stack ( userptr_t data, size_t size ); -extern void remove_user_from_rm_stack ( userptr_t data, size_t size ); - -/* TEXT16_CODE: declare a fragment of code that resides in .text16 */ -#define TEXT16_CODE( asm_code_str ) \ - ".section \".text16\", \"ax\", @progbits\n\t" \ - ".code16\n\t" \ - asm_code_str "\n\t" \ - ".code32\n\t" \ - ".previous\n\t" - -/* REAL_CODE: declare a fragment of code that executes in real mode */ -#define REAL_CODE( asm_code_str ) \ - "pushl $1f\n\t" \ - "call real_call\n\t" \ - "addl $4, %%esp\n\t" \ - TEXT16_CODE ( "\n1:\n\t" \ - asm_code_str \ - "\n\t" \ - "ret\n\t" ) - -/* PHYS_CODE: declare a fragment of code that executes in flat physical mode */ -#define PHYS_CODE( asm_code_str ) \ - "call _virt_to_phys\n\t" \ - asm_code_str \ - "call _phys_to_virt\n\t" - -/** Number of interrupts */ -#define NUM_INT 256 - -/** An interrupt descriptor table register */ -struct idtr { - /** Limit */ - uint16_t limit; - /** Base */ - uint32_t base; -} __attribute__ (( packed )); - -/** An interrupt descriptor table entry */ -struct interrupt_descriptor { - /** Low 16 bits of address */ - uint16_t low; - /** Code segment */ - uint16_t segment; - /** Unused */ - uint8_t unused; - /** Type and attributes */ - uint8_t attr; - /** High 16 bits of address */ - uint16_t high; -} __attribute__ (( packed )); - -/** Interrupt descriptor is present */ -#define IDTE_PRESENT 0x80 - -/** Interrupt descriptor 32-bit interrupt gate type */ -#define IDTE_TYPE_IRQ32 0x0e - -/** An interrupt vector - * - * Each interrupt vector comprises an eight-byte fragment of code: - * - * 60 pushal - * b0 xx movb $INT, %al - * e9 xx xx xx xx jmp interrupt_wrapper - */ -struct interrupt_vector { - /** "pushal" instruction */ - uint8_t pushal; - /** "movb" instruction */ - uint8_t movb; - /** Interrupt number */ - uint8_t intr; - /** "jmp" instruction */ - uint8_t jmp; - /** Interrupt wrapper address offset */ - uint32_t offset; - /** Next instruction after jump */ - uint8_t next[0]; -} __attribute__ (( packed )); - -/** "pushal" instruction */ -#define PUSHAL_INSN 0x60 - -/** "movb" instruction */ -#define MOVB_INSN 0xb0 - -/** "jmp" instruction */ -#define JMP_INSN 0xe9 - -extern void set_interrupt_vector ( unsigned int intr, void *vector ); - -#endif /* ASSEMBLY */ - -#endif /* LIBRM_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/limits.h b/qemu/roms/ipxe/src/arch/i386/include/limits.h deleted file mode 100644 index bb48b75ab..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/limits.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef LIMITS_H -#define LIMITS_H 1 - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/* Number of bits in a `char' */ -#define CHAR_BIT 8 - -/* Minimum and maximum values a `signed char' can hold */ -#define SCHAR_MIN (-128) -#define SCHAR_MAX 127 - -/* Maximum value an `unsigned char' can hold. (Minimum is 0.) */ -#define UCHAR_MAX 255 - -/* Minimum and maximum values a `char' can hold */ -#define CHAR_MIN SCHAR_MIN -#define CHAR_MAX SCHAR_MAX - -/* Minimum and maximum values a `signed short int' can hold */ -#define SHRT_MIN (-32768) -#define SHRT_MAX 32767 - -/* Maximum value an `unsigned short' can hold. (Minimum is 0.) */ -#define USHRT_MAX 65535 - - -/* Minimum and maximum values a `signed int' can hold */ -#define INT_MIN (-INT_MAX - 1) -#define INT_MAX 2147483647 - -/* Maximum value an `unsigned int' can hold. (Minimum is 0.) */ -#define UINT_MAX 4294967295U - - -/* Minimum and maximum values a `signed int' can hold */ -#define INT_MAX 2147483647 -#define INT_MIN (-INT_MAX - 1) - - -/* Maximum value an `unsigned int' can hold. (Minimum is 0.) */ -#define UINT_MAX 4294967295U - - -/* Minimum and maximum values a `signed long' can hold */ -#define LONG_MAX 2147483647 -#define LONG_MIN (-LONG_MAX - 1L) - -/* Maximum value an `unsigned long' can hold. (Minimum is 0.) */ -#define ULONG_MAX 4294967295UL - -/* Minimum and maximum values a `signed long long' can hold */ -#define LLONG_MAX 9223372036854775807LL -#define LLONG_MIN (-LONG_MAX - 1LL) - - -/* Maximum value an `unsigned long long' can hold. (Minimum is 0.) */ -#define ULLONG_MAX 18446744073709551615ULL - - -#endif /* LIMITS_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/memsizes.h b/qemu/roms/ipxe/src/arch/i386/include/memsizes.h deleted file mode 100644 index f115f7574..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/memsizes.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef _MEMSIZES_H -#define _MEMSIZES_H - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <basemem.h> - -/** - * Get size of base memory from BIOS free base memory counter - * - * @ret basemem Base memory size, in kB - */ -static inline unsigned int basememsize ( void ) { - return get_fbms(); -} - -extern unsigned int extmemsize ( void ); - -#endif /* _MEMSIZES_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/multiboot.h b/qemu/roms/ipxe/src/arch/i386/include/multiboot.h deleted file mode 100644 index ae09df6c7..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/multiboot.h +++ /dev/null @@ -1,149 +0,0 @@ -#ifndef _MULTIBOOT_H -#define _MULTIBOOT_H - -/** - * @file - * - * Multiboot operating systems - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdint.h> - -/** The magic number for the Multiboot header */ -#define MULTIBOOT_HEADER_MAGIC 0x1BADB002 - -/** Boot modules must be page aligned */ -#define MB_FLAG_PGALIGN 0x00000001 - -/** Memory map must be provided */ -#define MB_FLAG_MEMMAP 0x00000002 - -/** Video mode information must be provided */ -#define MB_FLAG_VIDMODE 0x00000004 - -/** Image is a raw multiboot image (not ELF) */ -#define MB_FLAG_RAW 0x00010000 - -/** - * The magic number passed by a Multiboot-compliant boot loader - * - * Must be passed in register %eax when jumping to the Multiboot OS - * image. - */ -#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002 - -/** Multiboot information structure mem_* fields are valid */ -#define MBI_FLAG_MEM 0x00000001 - -/** Multiboot information structure boot_device field is valid */ -#define MBI_FLAG_BOOTDEV 0x00000002 - -/** Multiboot information structure cmdline field is valid */ -#define MBI_FLAG_CMDLINE 0x00000004 - -/** Multiboot information structure module fields are valid */ -#define MBI_FLAG_MODS 0x00000008 - -/** Multiboot information structure a.out symbol table is valid */ -#define MBI_FLAG_AOUT 0x00000010 - -/** Multiboot information struture ELF section header table is valid */ -#define MBI_FLAG_ELF 0x00000020 - -/** Multiboot information structure memory map is valid */ -#define MBI_FLAG_MMAP 0x00000040 - -/** Multiboot information structure drive list is valid */ -#define MBI_FLAG_DRIVES 0x00000080 - -/** Multiboot information structure ROM configuration field is valid */ -#define MBI_FLAG_CFGTBL 0x00000100 - -/** Multiboot information structure boot loader name field is valid */ -#define MBI_FLAG_LOADER 0x00000200 - -/** Multiboot information structure APM table is valid */ -#define MBI_FLAG_APM 0x00000400 - -/** Multiboot information structure video information is valid */ -#define MBI_FLAG_VBE 0x00000800 - -/** A multiboot header */ -struct multiboot_header { - uint32_t magic; - uint32_t flags; - uint32_t checksum; - uint32_t header_addr; - uint32_t load_addr; - uint32_t load_end_addr; - uint32_t bss_end_addr; - uint32_t entry_addr; -} __attribute__ (( packed, may_alias )); - -/** A multiboot a.out symbol table */ -struct multiboot_aout_symbol_table { - uint32_t tabsize; - uint32_t strsize; - uint32_t addr; - uint32_t reserved; -} __attribute__ (( packed, may_alias )); - -/** A multiboot ELF section header table */ -struct multiboot_elf_section_header_table { - uint32_t num; - uint32_t size; - uint32_t addr; - uint32_t shndx; -} __attribute__ (( packed, may_alias )); - -/** A multiboot information structure */ -struct multiboot_info { - uint32_t flags; - uint32_t mem_lower; - uint32_t mem_upper; - uint32_t boot_device; - uint32_t cmdline; - uint32_t mods_count; - uint32_t mods_addr; - union { - struct multiboot_aout_symbol_table aout_syms; - struct multiboot_elf_section_header_table elf_sections; - } syms; - uint32_t mmap_length; - uint32_t mmap_addr; - uint32_t drives_length; - uint32_t drives_addr; - uint32_t config_table; - uint32_t boot_loader_name; - uint32_t apm_table; - uint32_t vbe_control_info; - uint32_t vbe_mode_info; - uint16_t vbe_mode; - uint16_t vbe_interface_seg; - uint16_t vbe_interface_off; - uint16_t vbe_interface_len; -} __attribute__ (( packed, may_alias )); - -/** A multiboot module structure */ -struct multiboot_module { - uint32_t mod_start; - uint32_t mod_end; - uint32_t string; - uint32_t reserved; -} __attribute__ (( packed, may_alias )); - -/** A multiboot memory map entry */ -struct multiboot_memory_map { - uint32_t size; - uint64_t base_addr; - uint64_t length; - uint32_t type; -} __attribute__ (( packed, may_alias )); - -/** Usable RAM */ -#define MBMEM_RAM 1 - -#endif /* _MULTIBOOT_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/pcbios/ipxe/dhcp_arch.h b/qemu/roms/ipxe/src/arch/i386/include/pcbios/ipxe/dhcp_arch.h deleted file mode 100644 index e07e4c192..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/pcbios/ipxe/dhcp_arch.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2010 VMware, Inc. All Rights Reserved. - * - * 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 (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * 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. - */ - -#ifndef _DHCP_ARCH_H -#define _DHCP_ARCH_H - -/** @file - * - * Architecture-specific DHCP options - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <ipxe/dhcp.h> - -#define DHCP_ARCH_VENDOR_CLASS_ID \ - DHCP_STRING ( 'P', 'X', 'E', 'C', 'l', 'i', 'e', 'n', 't', ':', \ - 'A', 'r', 'c', 'h', ':', '0', '0', '0', '0', '0', ':', \ - 'U', 'N', 'D', 'I', ':', '0', '0', '2', '0', '0', '1' ) - -#define DHCP_ARCH_CLIENT_ARCHITECTURE \ - DHCP_WORD ( DHCP_CLIENT_ARCHITECTURE_X86 ) - -#define DHCP_ARCH_CLIENT_NDI DHCP_OPTION ( 1 /* UNDI */ , 2, 1 /* v2.1 */ ) - -#endif diff --git a/qemu/roms/ipxe/src/arch/i386/include/pnpbios.h b/qemu/roms/ipxe/src/arch/i386/include/pnpbios.h deleted file mode 100644 index d14873700..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/pnpbios.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef _PNPBIOS_H -#define _PNPBIOS_H - -/** @file - * - * PnP BIOS - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/* BIOS segment address */ -#define BIOS_SEG 0xf000 - -extern int find_pnp_bios ( void ); - -#endif /* _PNPBIOS_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/pxe.h b/qemu/roms/ipxe/src/arch/i386/include/pxe.h deleted file mode 100644 index 66d752683..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/pxe.h +++ /dev/null @@ -1,199 +0,0 @@ -#ifndef PXE_H -#define PXE_H - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include "pxe_types.h" -#include "pxe_error.h" -#include "pxe_api.h" -#include <ipxe/device.h> -#include <ipxe/tables.h> - -/** PXE API invalid function code */ -#define PXENV_UNKNOWN 0xffff - -/** Parameter block for pxenv_unknown() */ -struct s_PXENV_UNKNOWN { - PXENV_STATUS_t Status; /**< PXE status code */ -} __attribute__ (( packed )); - -typedef struct s_PXENV_UNKNOWN PXENV_UNKNOWN_t; - -/* Union used for PXE API calls; we don't know the type of the - * structure until we interpret the opcode. Also, Status is available - * in the same location for any opcode, and it's convenient to have - * non-specific access to it. - */ -union u_PXENV_ANY { - /* Make it easy to read status for any operation */ - PXENV_STATUS_t Status; - struct s_PXENV_UNKNOWN unknown; - struct s_PXENV_UNLOAD_STACK unload_stack; - struct s_PXENV_GET_CACHED_INFO get_cached_info; - struct s_PXENV_TFTP_READ_FILE restart_tftp; - struct s_PXENV_START_UNDI start_undi; - struct s_PXENV_STOP_UNDI stop_undi; - struct s_PXENV_START_BASE start_base; - struct s_PXENV_STOP_BASE stop_base; - struct s_PXENV_TFTP_OPEN tftp_open; - struct s_PXENV_TFTP_CLOSE tftp_close; - struct s_PXENV_TFTP_READ tftp_read; - struct s_PXENV_TFTP_READ_FILE tftp_read_file; - struct s_PXENV_TFTP_GET_FSIZE tftp_get_fsize; - struct s_PXENV_UDP_OPEN udp_open; - struct s_PXENV_UDP_CLOSE udp_close; - struct s_PXENV_UDP_WRITE udp_write; - struct s_PXENV_UDP_READ udp_read; - struct s_PXENV_UNDI_STARTUP undi_startup; - struct s_PXENV_UNDI_CLEANUP undi_cleanup; - struct s_PXENV_UNDI_INITIALIZE undi_initialize; - struct s_PXENV_UNDI_RESET undi_reset_adapter; - struct s_PXENV_UNDI_SHUTDOWN undi_shutdown; - struct s_PXENV_UNDI_OPEN undi_open; - struct s_PXENV_UNDI_CLOSE undi_close; - struct s_PXENV_UNDI_TRANSMIT undi_transmit; - struct s_PXENV_UNDI_SET_MCAST_ADDRESS undi_set_mcast_address; - struct s_PXENV_UNDI_SET_STATION_ADDRESS undi_set_station_address; - struct s_PXENV_UNDI_SET_PACKET_FILTER undi_set_packet_filter; - struct s_PXENV_UNDI_GET_INFORMATION undi_get_information; - struct s_PXENV_UNDI_GET_STATISTICS undi_get_statistics; - struct s_PXENV_UNDI_CLEAR_STATISTICS undi_clear_statistics; - struct s_PXENV_UNDI_INITIATE_DIAGS undi_initiate_diags; - struct s_PXENV_UNDI_FORCE_INTERRUPT undi_force_interrupt; - struct s_PXENV_UNDI_GET_MCAST_ADDRESS undi_get_mcast_address; - struct s_PXENV_UNDI_GET_NIC_TYPE undi_get_nic_type; - struct s_PXENV_UNDI_GET_IFACE_INFO undi_get_iface_info; - struct s_PXENV_UNDI_GET_STATE undi_get_state; - struct s_PXENV_UNDI_ISR undi_isr; - struct s_PXENV_FILE_OPEN file_open; - struct s_PXENV_FILE_CLOSE file_close; - struct s_PXENV_FILE_SELECT file_select; - struct s_PXENV_FILE_READ file_read; - struct s_PXENV_GET_FILE_SIZE get_file_size; - struct s_PXENV_FILE_EXEC file_exec; - struct s_PXENV_FILE_API_CHECK file_api_check; - struct s_PXENV_FILE_EXIT_HOOK file_exit_hook; -}; - -typedef union u_PXENV_ANY PXENV_ANY_t; - -/** A PXE API call */ -struct pxe_api_call { - /** Entry point - * - * @v params PXE API call parameters - * @ret exit PXE API call exit code - */ - PXENV_EXIT_t ( * entry ) ( union u_PXENV_ANY *params ); - /** Length of parameters */ - uint16_t params_len; - /** Opcode */ - uint16_t opcode; -}; - -/** PXE API call table */ -#define PXE_API_CALLS __table ( struct pxe_api_call, "pxe_api_calls" ) - -/** Declare a PXE API call */ -#define __pxe_api_call __table_entry ( PXE_API_CALLS, 01 ) - -/** - * Define a PXE API call - * - * @v _opcode Opcode - * @v _entry Entry point - * @v _params_type Type of parameter structure - * @ret call PXE API call - */ -#define PXE_API_CALL( _opcode, _entry, _params_type ) { \ - .entry = ( ( ( ( PXENV_EXIT_t ( * ) ( _params_type *params ) ) NULL ) \ - == ( ( typeof ( _entry ) * ) NULL ) ) \ - ? ( ( PXENV_EXIT_t ( * ) \ - ( union u_PXENV_ANY *params ) ) _entry ) \ - : ( ( PXENV_EXIT_t ( * ) \ - ( union u_PXENV_ANY *params ) ) _entry ) ), \ - .params_len = sizeof ( _params_type ), \ - .opcode = _opcode, \ - } - -/** An UNDI expansion ROM header */ -struct undi_rom_header { - /** Signature - * - * Must be equal to @c ROM_SIGNATURE - */ - UINT16_t Signature; - /** ROM length in 512-byte blocks */ - UINT8_t ROMLength; - /** Unused */ - UINT8_t unused[0x13]; - /** Offset of the PXE ROM ID structure */ - UINT16_t PXEROMID; - /** Offset of the PCI ROM structure */ - UINT16_t PCIRHeader; -} __attribute__ (( packed )); - -/** Signature for an expansion ROM */ -#define ROM_SIGNATURE 0xaa55 - -/** An UNDI ROM ID structure */ -struct undi_rom_id { - /** Signature - * - * Must be equal to @c UNDI_ROM_ID_SIGNATURE - */ - UINT32_t Signature; - /** Length of structure */ - UINT8_t StructLength; - /** Checksum */ - UINT8_t StructCksum; - /** Structure revision - * - * Must be zero. - */ - UINT8_t StructRev; - /** UNDI revision - * - * Version 2.1.0 is encoded as the byte sequence 0x00, 0x01, 0x02. - */ - UINT8_t UNDIRev[3]; - /** Offset to UNDI loader */ - UINT16_t UNDILoader; - /** Minimum required stack segment size */ - UINT16_t StackSize; - /** Minimum required data segment size */ - UINT16_t DataSize; - /** Minimum required code segment size */ - UINT16_t CodeSize; -} __attribute__ (( packed )); - -/** Signature for an UNDI ROM ID structure */ -#define UNDI_ROM_ID_SIGNATURE \ - ( ( 'U' << 0 ) + ( 'N' << 8 ) + ( 'D' << 16 ) + ( 'I' << 24 ) ) - -/** A PCI expansion header */ -struct pcir_header { - /** Signature - * - * Must be equal to @c PCIR_SIGNATURE - */ - uint32_t signature; - /** PCI vendor ID */ - uint16_t vendor_id; - /** PCI device ID */ - uint16_t device_id; -} __attribute__ (( packed )); - -/** Signature for an UNDI ROM ID structure */ -#define PCIR_SIGNATURE \ - ( ( 'P' << 0 ) + ( 'C' << 8 ) + ( 'I' << 16 ) + ( 'R' << 24 ) ) - -extern struct net_device *pxe_netdev; -extern const char *pxe_cmdline; - -extern void pxe_set_netdev ( struct net_device *netdev ); -extern PXENV_EXIT_t pxenv_tftp_read_file ( struct s_PXENV_TFTP_READ_FILE - *tftp_read_file ); -extern PXENV_EXIT_t undi_loader ( struct s_UNDI_LOADER *undi_loader ); - -#endif /* PXE_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/pxe_api.h b/qemu/roms/ipxe/src/arch/i386/include/pxe_api.h deleted file mode 100644 index 3110d26da..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/pxe_api.h +++ /dev/null @@ -1,1823 +0,0 @@ -#ifndef PXE_API_H -#define PXE_API_H - -/* - * 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. - * - * As an alternative, at your option, you may use this file under the - * following terms, known as the "MIT license": - * - * Copyright (c) 2005-2009 Michael Brown <mbrown@fensystems.co.uk> - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** @file - * - * Preboot eXecution Environment (PXE) API - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include "pxe_types.h" - -/** @addtogroup pxe Preboot eXecution Environment (PXE) API - * @{ - */ - -/** @defgroup pxe_api_call PXE entry points - * - * PXE entry points and calling conventions - * - * @{ - */ - -/** The PXENV+ structure */ -struct s_PXENV { - /** Signature - * - * Contains the bytes 'P', 'X', 'E', 'N', 'V', '+'. - */ - UINT8_t Signature[6]; - /** PXE API version - * - * MSB is major version number, LSB is minor version number. - * If the API version number is 0x0201 or greater, the !PXE - * structure pointed to by #PXEPtr should be used instead of - * this data structure. - */ - UINT16_t Version; - UINT8_t Length; /**< Length of this structure */ - /** Checksum - * - * The byte checksum of this structure (using the length in - * #Length) must be zero. - */ - UINT8_t Checksum; - SEGOFF16_t RMEntry; /**< Real-mode PXENV+ entry point */ - /** Protected-mode PXENV+ entry point offset - * - * PXE 2.1 deprecates this entry point. For protected-mode - * API calls, use the !PXE structure pointed to by #PXEPtr - * instead. - */ - UINT32_t PMOffset; - /** Protected-mode PXENV+ entry point segment selector - * - * PXE 2.1 deprecates this entry point. For protected-mode - * API calls, use the !PXE structure pointed to by #PXEPtr - * instead. - */ - SEGSEL_t PMSelector; - SEGSEL_t StackSeg; /**< Stack segment selector */ - UINT16_t StackSize; /**< Stack segment size */ - SEGSEL_t BC_CodeSeg; /**< Base-code code segment selector */ - UINT16_t BC_CodeSize; /**< Base-code code segment size */ - SEGSEL_t BC_DataSeg; /**< Base-code data segment selector */ - UINT16_t BC_DataSize; /**< Base-code data segment size */ - SEGSEL_t UNDIDataSeg; /**< UNDI data segment selector */ - UINT16_t UNDIDataSize; /**< UNDI data segment size */ - SEGSEL_t UNDICodeSeg; /**< UNDI code segment selector */ - UINT16_t UNDICodeSize; /**< UNDI code segment size */ - /** Address of the !PXE structure - * - * This field is present only if #Version is 0x0201 or - * greater. If present, it points to a struct s_PXE. - */ - SEGOFF16_t PXEPtr; -} __attribute__ (( packed )); - -typedef struct s_PXENV PXENV_t; - -/** The !PXE structure */ -struct s_PXE { - /** Signature - * - * Contains the bytes '!', 'P', 'X', 'E'. - */ - UINT8_t Signature[4]; - UINT8_t StructLength; /**< Length of this structure */ - /** Checksum - * - * The byte checksum of this structure (using the length in - * #StructLength) must be zero. - */ - UINT8_t StructCksum; - /** Revision of this structure - * - * For PXE version 2.1, this field must be zero. - */ - UINT8_t StructRev; - UINT8_t reserved_1; /**< Must be zero */ - /** Address of the UNDI ROM ID structure - * - * This is a pointer to a struct s_UNDI_ROM_ID. - */ - SEGOFF16_t UNDIROMID; - /** Address of the Base Code ROM ID structure - * - * This is a pointer to a struct s_BC_ROM_ID. - */ - SEGOFF16_t BaseROMID; - /** 16-bit !PXE entry point - * - * This is the entry point for either real mode, or protected - * mode with a 16-bit stack segment. - */ - SEGOFF16_t EntryPointSP; - /** 32-bit !PXE entry point - * - * This is the entry point for protected mode with a 32-bit - * stack segment. - */ - SEGOFF16_t EntryPointESP; - /** Status call-out function - * - * @v 0 (if in a time-out loop) - * @v n Number of a received TFTP packet - * @ret 0 Continue operation - * @ret 1 Cancel operation - * - * This function will be called whenever the PXE stack is in - * protected mode, is waiting for an event (e.g. a DHCP reply) - * and wishes to allow the user to cancel the operation. - * Parameters are passed in register %ax; the return value - * must also be placed in register %ax. All other registers - * and flags @b must be preserved. - * - * In real mode, an internal function (that checks for a - * keypress) will be used. - * - * If this field is set to -1, no status call-out function - * will be used and consequently the user will not be allowed - * to interrupt operations. - * - * @note The PXE specification version 2.1 defines the - * StatusCallout field, mentions it 11 times, but nowhere - * defines what it actually does or how it gets called. - * Fortunately, the WfM specification version 1.1a deigns to - * inform us of such petty details. - */ - SEGOFF16_t StatusCallout; - UINT8_t reserved_2; /**< Must be zero */ - /** Number of segment descriptors - * - * If this number is greater than 7, the remaining descriptors - * follow immediately after #BC_CodeWrite. - */ - UINT8_t SegDescCnt; - /** First protected-mode selector - * - * This is the segment selector value for the first segment - * assigned to PXE. Protected-mode selectors must be - * consecutive, according to the PXE 2.1 specification, though - * no reason is given. Each #SEGDESC_t includes a field for - * the segment selector, so this information is entirely - * redundant. - */ - SEGSEL_t FirstSelector; - /** Stack segment descriptor */ - SEGDESC_t Stack; - /** UNDI data segment descriptor */ - SEGDESC_t UNDIData; - /** UNDI code segment descriptor */ - SEGDESC_t UNDICode; - /** UNDI writable code segment descriptor */ - SEGDESC_t UNDICodeWrite; - /** Base-code data segment descriptor */ - SEGDESC_t BC_Data; - /** Base-code code segment descriptor */ - SEGDESC_t BC_Code; - /** Base-code writable code segment descriptor */ - SEGDESC_t BC_CodeWrite; -} __attribute__ (( packed )); - -typedef struct s_PXE PXE_t; - -/** @} */ /* pxe_api_call */ - -/** @defgroup pxe_preboot_api PXE Preboot API - * - * General high-level functions: #PXENV_UNLOAD_STACK, #PXENV_START_UNDI etc. - * - * @{ - */ - -/** @defgroup pxenv_unload_stack PXENV_UNLOAD_STACK - * - * UNLOAD BASE CODE STACK - * - * @{ - */ - -/** PXE API function code for pxenv_unload_stack() */ -#define PXENV_UNLOAD_STACK 0x0070 - -/** Parameter block for pxenv_unload_stack() */ -struct s_PXENV_UNLOAD_STACK { - PXENV_STATUS_t Status; /**< PXE status code */ - UINT8_t reserved[10]; /**< Must be zero */ -} __attribute__ (( packed )); - -typedef struct s_PXENV_UNLOAD_STACK PXENV_UNLOAD_STACK_t; - -/** @} */ /* pxenv_unload_stack */ - -/** @defgroup pxenv_get_cached_info PXENV_GET_CACHED_INFO - * - * GET CACHED INFO - * - * @{ - */ - -/** PXE API function code for pxenv_get_cached_info() */ -#define PXENV_GET_CACHED_INFO 0x0071 - -/** The client's DHCPDISCOVER packet */ -#define PXENV_PACKET_TYPE_DHCP_DISCOVER 1 - -/** The DHCP server's DHCPACK packet */ -#define PXENV_PACKET_TYPE_DHCP_ACK 2 - -/** The Boot Server's Discover Reply packet - * - * This packet contains DHCP option 60 set to "PXEClient", a valid - * boot file name, and may or may not contain MTFTP options. - */ -#define PXENV_PACKET_TYPE_CACHED_REPLY 3 - -/** Parameter block for pxenv_get_cached_info() */ -struct s_PXENV_GET_CACHED_INFO { - PXENV_STATUS_t Status; /**< PXE status code */ - /** Packet type. - * - * Valid values are #PXENV_PACKET_TYPE_DHCP_DISCOVER, - * #PXENV_PACKET_TYPE_DHCP_ACK or #PXENV_PACKET_TYPE_CACHED_REPLY - */ - UINT16_t PacketType; - UINT16_t BufferSize; /**< Buffer size */ - SEGOFF16_t Buffer; /**< Buffer address */ - UINT16_t BufferLimit; /**< Maximum buffer size */ -} __attribute__ (( packed )); - -typedef struct s_PXENV_GET_CACHED_INFO PXENV_GET_CACHED_INFO_t; - -#define BOOTP_REQ 1 /**< A BOOTP request packet */ -#define BOOTP_REP 2 /**< A BOOTP reply packet */ - -/** DHCP broadcast flag - * - * Request a broadcast response (DHCPOFFER or DHCPACK) from the DHCP - * server. - */ -#define BOOTP_BCAST 0x8000 - -#define VM_RFC1048 0x63825363L /**< DHCP magic cookie */ - -/** Maximum length of DHCP options */ -#define BOOTP_DHCPVEND 1024 - -/** Format of buffer filled in by pxenv_get_cached_info() - * - * This somewhat convoluted data structure simply describes the layout - * of a DHCP packet. Refer to RFC2131 section 2 for a full - * description. - */ -struct bootph { - /** Message opcode. - * - * Valid values are #BOOTP_REQ and #BOOTP_REP. - */ - UINT8_t opcode; - /** NIC hardware type. - * - * Valid values are as for s_PXENV_UNDI_GET_INFORMATION::HwType. - */ - UINT8_t Hardware; - UINT8_t Hardlen; /**< MAC address length */ - /** Gateway hops - * - * Zero in packets sent by the client. May be non-zero in - * replies from the DHCP server, if the reply comes via a DHCP - * relay agent. - */ - UINT8_t Gatehops; - UINT32_t ident; /**< DHCP transaction id (xid) */ - /** Elapsed time - * - * Number of seconds since the client began the DHCP - * transaction. - */ - UINT16_t seconds; - /** Flags - * - * This is the bitwise-OR of any of the following values: - * #BOOTP_BCAST. - */ - UINT16_t Flags; - /** Client IP address - * - * Set only if the client already has an IP address. - */ - IP4_t cip; - /** Your IP address - * - * This is the IP address that the server assigns to the - * client. - */ - IP4_t yip; - /** Server IP address - * - * This is the IP address of the BOOTP/DHCP server. - */ - IP4_t sip; - /** Gateway IP address - * - * This is the IP address of the BOOTP/DHCP relay agent, if - * any. It is @b not (necessarily) the address of the default - * gateway for routing purposes. - */ - IP4_t gip; - MAC_ADDR_t CAddr; /**< Client MAC address */ - UINT8_t Sname[64]; /**< Server host name */ - UINT8_t bootfile[128]; /**< Boot file name */ - /** DHCP options - * - * Don't ask. Just laugh. Then burn a copy of the PXE - * specification and send Intel an e-mail asking them if - * they've figured out what a "union" does in C yet. - */ - union bootph_vendor { - UINT8_t d[BOOTP_DHCPVEND]; /**< DHCP options */ - /** DHCP options */ - struct bootph_vendor_v { - /** DHCP magic cookie - * - * Should have the value #VM_RFC1048. - */ - UINT8_t magic[4]; - UINT32_t flags; /**< BOOTP flags/opcodes */ - /** "End of BOOTP vendor extensions" - * - * Abandon hope, all ye who consider the - * purpose of this field. - */ - UINT8_t pad[56]; - } v; - } vendor; -} __attribute__ (( packed )); - -typedef struct bootph BOOTPLAYER_t; - -/** @} */ /* pxenv_get_cached_info */ - -/** @defgroup pxenv_restart_tftp PXENV_RESTART_TFTP - * - * RESTART TFTP - * - * @{ - */ - -/** PXE API function code for pxenv_restart_tftp() */ -#define PXENV_RESTART_TFTP 0x0073 - -/** Parameter block for pxenv_restart_tftp() */ -struct s_PXENV_TFTP_READ_FILE; - -typedef struct s_PXENV_RESTART_TFTP PXENV_RESTART_TFTP_t; - -/** @} */ /* pxenv_restart_tftp */ - -/** @defgroup pxenv_start_undi PXENV_START_UNDI - * - * START UNDI - * - * @{ - */ - -/** PXE API function code for pxenv_start_undi() */ -#define PXENV_START_UNDI 0x0000 - -/** Parameter block for pxenv_start_undi() */ -struct s_PXENV_START_UNDI { - PXENV_STATUS_t Status; /**< PXE status code */ - /** %ax register as passed to the Option ROM initialisation routine. - * - * For a PCI device, this should contain the bus:dev:fn value - * that uniquely identifies the PCI device in the system. For - * a non-PCI device, this field is not defined. - */ - UINT16_t AX; - /** %bx register as passed to the Option ROM initialisation routine. - * - * For an ISAPnP device, this should contain the Card Select - * Number assigned to the ISAPnP card. For non-ISAPnP - * devices, this should contain 0xffff. - */ - UINT16_t BX; - /** %dx register as passed to the Option ROM initialisation routine. - * - * For an ISAPnP device, this should contain the ISAPnP Read - * Port address as currently set in all ISAPnP cards. If - * there are no ISAPnP cards, this should contain 0xffff. (If - * this is a non-ISAPnP device, but there are ISAPnP cards in - * the system, this value is not well defined.) - */ - UINT16_t DX; - /** %di register as passed to the Option ROM initialisation routine. - * - * This contains the #OFF16_t portion of a struct #s_SEGOFF16 - * that points to the System BIOS Plug and Play Installation - * Check Structure. (Refer to section 4.4 of the Plug and - * Play BIOS specification for a description of this - * structure.) - * - * @note The PXE specification defines the type of this field - * as #UINT16_t. For x86, #OFF16_t and #UINT16_t are - * equivalent anyway; for other architectures #OFF16_t makes - * more sense. - */ - OFF16_t DI; - /** %es register as passed to the Option ROM initialisation routine. - * - * This contains the #SEGSEL_t portion of a struct #s_SEGOFF16 - * that points to the System BIOS Plug and Play Installation - * Check Structure. (Refer to section 4.4 of the Plug and - * Play BIOS specification for a description of this - * structure.) - * - * @note The PXE specification defines the type of this field - * as #UINT16_t. For x86, #SEGSEL_t and #UINT16_t are - * equivalent anyway; for other architectures #SEGSEL_t makes - * more sense. - */ - SEGSEL_t ES; -} __attribute__ (( packed )); - -typedef struct s_PXENV_START_UNDI PXENV_START_UNDI_t; - -/** @} */ /* pxenv_start_undi */ - -/** @defgroup pxenv_stop_undi PXENV_STOP_UNDI - * - * STOP UNDI - * - * @{ - */ - -/** PXE API function code for pxenv_stop_undi() */ -#define PXENV_STOP_UNDI 0x0015 - -/** Parameter block for pxenv_stop_undi() */ -struct s_PXENV_STOP_UNDI { - PXENV_STATUS_t Status; /**< PXE status code */ -} __attribute__ (( packed )); - -typedef struct s_PXENV_STOP_UNDI PXENV_STOP_UNDI_t; - -/** @} */ /* pxenv_stop_undi */ - -/** @defgroup pxenv_start_base PXENV_START_BASE - * - * START BASE - * - * @{ - */ - -/** PXE API function code for pxenv_start_base() */ -#define PXENV_START_BASE 0x0075 - -/** Parameter block for pxenv_start_base() */ -struct s_PXENV_START_BASE { - PXENV_STATUS_t Status; /**< PXE status code */ -} __attribute__ (( packed )); - -typedef struct s_PXENV_START_BASE PXENV_START_BASE_t; - -/** @} */ /* pxenv_start_base */ - -/** @defgroup pxenv_stop_base PXENV_STOP_BASE - * - * STOP BASE - * - * @{ - */ - -/** PXE API function code for pxenv_stop_base() */ -#define PXENV_STOP_BASE 0x0076 - -/** Parameter block for pxenv_stop_base() */ -struct s_PXENV_STOP_BASE { - PXENV_STATUS_t Status; /**< PXE status code */ -} __attribute__ (( packed )); - -typedef struct s_PXENV_STOP_BASE PXENV_STOP_BASE_t; - -/** @} */ /* pxenv_stop_base */ - -/** @} */ /* pxe_preboot_api */ - -/** @defgroup pxe_tftp_api PXE TFTP API - * - * Download files via TFTP or MTFTP - * - * @{ - */ - -/** @defgroup pxenv_tftp_open PXENV_TFTP_OPEN - * - * TFTP OPEN - * - * @{ - */ - -/** PXE API function code for pxenv_tftp_open() */ -#define PXENV_TFTP_OPEN 0x0020 - -/** Parameter block for pxenv_tftp_open() */ -struct s_PXENV_TFTP_OPEN { - PXENV_STATUS_t Status; /**< PXE status code */ - IP4_t ServerIPAddress; /**< TFTP server IP address */ - IP4_t GatewayIPAddress; /**< Relay agent IP address */ - UINT8_t FileName[128]; /**< File name */ - UDP_PORT_t TFTPPort; /**< TFTP server UDP port */ - /** Requested size of TFTP packets - * - * This is the TFTP "blksize" option. This must be at least - * 512, since servers that do not support TFTP options cannot - * negotiate blocksizes smaller than this. - */ - UINT16_t PacketSize; -} __attribute__ (( packed )); - -typedef struct s_PXENV_TFTP_OPEN PXENV_TFTP_OPEN_t; - -/** @} */ /* pxenv_tftp_open */ - -/** @defgroup pxenv_tftp_close PXENV_TFTP_CLOSE - * - * TFTP CLOSE - * - * @{ - */ - -/** PXE API function code for pxenv_tftp_close() */ -#define PXENV_TFTP_CLOSE 0x0021 - -/** Parameter block for pxenv_tftp_close() */ -struct s_PXENV_TFTP_CLOSE { - PXENV_STATUS_t Status; /**< PXE status code */ -} __attribute__ (( packed )); - -typedef struct s_PXENV_TFTP_CLOSE PXENV_TFTP_CLOSE_t; - -/** @} */ /* pxenv_tftp_close */ - -/** @defgroup pxenv_tftp_read PXENV_TFTP_READ - * - * TFTP READ - * - * @{ - */ - -/** PXE API function code for pxenv_tftp_read() */ -#define PXENV_TFTP_READ 0x0022 - -/** Parameter block for pxenv_tftp_read() */ -struct s_PXENV_TFTP_READ { - PXENV_STATUS_t Status; /**< PXE status code */ - UINT16_t PacketNumber; /**< TFTP packet number */ - UINT16_t BufferSize; /**< Size of data buffer */ - SEGOFF16_t Buffer; /**< Address of data buffer */ -} __attribute__ (( packed )); - -typedef struct s_PXENV_TFTP_READ PXENV_TFTP_READ_t; - -/** @} */ /* pxenv_tftp_read */ - -/** @defgroup pxenv_tftp_read_file PXENV_TFTP_READ_FILE - * - * TFTP/MTFTP READ FILE - * - * @{ - */ - -/** PXE API function code for pxenv_tftp_read_file() */ -#define PXENV_TFTP_READ_FILE 0x0023 - -/** Parameter block for pxenv_tftp_read_file() */ -struct s_PXENV_TFTP_READ_FILE { - PXENV_STATUS_t Status; /**< PXE status code */ - UINT8_t FileName[128]; /**< File name */ - UINT32_t BufferSize; /**< Size of data buffer */ - ADDR32_t Buffer; /**< Address of data buffer */ - IP4_t ServerIPAddress; /**< TFTP server IP address */ - IP4_t GatewayIPAddress; /**< Relay agent IP address */ - /** File multicast IP address */ - IP4_t McastIPAddress; - /** Client multicast listening port */ - UDP_PORT_t TFTPClntPort; - /** Server multicast listening port */ - UDP_PORT_t TFTPSrvPort; - /** TFTP open timeout. - * - * This is the timeout for receiving the first DATA or ACK - * packets during the MTFTP Listen phase. - */ - UINT16_t TFTPOpenTimeOut; - /** TFTP reopen timeout. - * - * This is the timeout for receiving an ACK packet while in - * the MTFTP Listen phase (when at least one ACK packet has - * already been seen). - */ - UINT16_t TFTPReopenDelay; -} __attribute__ (( packed )); - -typedef struct s_PXENV_TFTP_READ_FILE PXENV_TFTP_READ_FILE_t; - -/** @} */ /* pxenv_tftp_read_file */ - -/** @defgroup pxenv_tftp_get_fsize PXENV_TFTP_GET_FSIZE - * - * TFTP GET FILE SIZE - * - * @{ - */ - -/** PXE API function code for pxenv_tftp_get_fsize() */ -#define PXENV_TFTP_GET_FSIZE 0x0025 - -/** Parameter block for pxenv_tftp_get_fsize() */ -struct s_PXENV_TFTP_GET_FSIZE { - PXENV_STATUS_t Status; /**< PXE status code */ - IP4_t ServerIPAddress; /**< TFTP server IP address */ - IP4_t GatewayIPAddress; /**< Relay agent IP address */ - UINT8_t FileName[128]; /**< File name */ - UINT32_t FileSize; /**< Size of the file */ -} __attribute__ (( packed )); - -typedef struct s_PXENV_TFTP_GET_FSIZE PXENV_TFTP_GET_FSIZE_t; - -/** @} */ /* pxenv_tftp_get_fsize */ - -/** @} */ /* pxe_tftp_api */ - -/** @defgroup pxe_udp_api PXE UDP API - * - * Transmit and receive UDP packets - * - * @{ - */ - -/** @defgroup pxenv_udp_open PXENV_UDP_OPEN - * - * UDP OPEN - * - * @{ - */ - -/** PXE API function code for pxenv_udp_open() */ -#define PXENV_UDP_OPEN 0x0030 - -/** Parameter block for pxenv_udp_open() */ -struct s_PXENV_UDP_OPEN { - PXENV_STATUS_t Status; /**< PXE status code */ - IP4_t src_ip; /**< IP address of this station */ -} __attribute__ (( packed )); - -typedef struct s_PXENV_UDP_OPEN PXENV_UDP_OPEN_t; - -/** @} */ /* pxenv_udp_open */ - -/** @defgroup pxenv_udp_close PXENV_UDP_CLOSE - * - * UDP CLOSE - * - * @{ - */ - -/** PXE API function code for pxenv_udp_close() */ -#define PXENV_UDP_CLOSE 0x0031 - -/** Parameter block for pxenv_udp_close() */ -struct s_PXENV_UDP_CLOSE { - PXENV_STATUS_t Status; /**< PXE status code */ -} __attribute__ (( packed )); - -typedef struct s_PXENV_UDP_CLOSE PXENV_UDP_CLOSE_t; - -/** @} */ /* pxenv_udp_close */ - -/** @defgroup pxenv_udp_write PXENV_UDP_WRITE - * - * UDP WRITE - * - * @{ - */ - -/** PXE API function code for pxenv_udp_write() */ -#define PXENV_UDP_WRITE 0x0033 - -/** Parameter block for pxenv_udp_write() */ -struct s_PXENV_UDP_WRITE { - PXENV_STATUS_t Status; /**< PXE status code */ - IP4_t ip; /**< Destination IP address */ - IP4_t gw; /**< Relay agent IP address */ - UDP_PORT_t src_port; /**< Source UDP port */ - UDP_PORT_t dst_port; /**< Destination UDP port */ - UINT16_t buffer_size; /**< UDP payload buffer size */ - SEGOFF16_t buffer; /**< UDP payload buffer address */ -} __attribute__ (( packed )); - -typedef struct s_PXENV_UDP_WRITE PXENV_UDP_WRITE_t; - -/** @} */ /* pxenv_udp_write */ - -/** @defgroup pxenv_udp_read PXENV_UDP_READ - * - * UDP READ - * - * @{ - */ - -/** PXE API function code for pxenv_udp_read() */ -#define PXENV_UDP_READ 0x0032 - -/** Parameter block for pxenv_udp_read() */ -struct s_PXENV_UDP_READ { - PXENV_STATUS_t Status; /**< PXE status code */ - IP4_t src_ip; /**< Source IP address */ - IP4_t dest_ip; /**< Destination IP address */ - UDP_PORT_t s_port; /**< Source UDP port */ - UDP_PORT_t d_port; /**< Destination UDP port */ - UINT16_t buffer_size; /**< UDP payload buffer size */ - SEGOFF16_t buffer; /**< UDP payload buffer address */ -} __attribute__ (( packed )); - -typedef struct s_PXENV_UDP_READ PXENV_UDP_READ_t; - -/** @} */ /* pxenv_udp_read */ - -/** @} */ /* pxe_udp_api */ - -/** @defgroup pxe_undi_api PXE UNDI API - * - * Direct control of the network interface card - * - * @{ - */ - -/** @defgroup pxenv_undi_startup PXENV_UNDI_STARTUP - * - * UNDI STARTUP - * - * @{ - */ - -/** PXE API function code for pxenv_undi_startup() */ -#define PXENV_UNDI_STARTUP 0x0001 - -#define PXENV_BUS_ISA 0 /**< ISA bus type */ -#define PXENV_BUS_EISA 1 /**< EISA bus type */ -#define PXENV_BUS_MCA 2 /**< MCA bus type */ -#define PXENV_BUS_PCI 3 /**< PCI bus type */ -#define PXENV_BUS_VESA 4 /**< VESA bus type */ -#define PXENV_BUS_PCMCIA 5 /**< PCMCIA bus type */ - -/** Parameter block for pxenv_undi_startup() */ -struct s_PXENV_UNDI_STARTUP { - PXENV_STATUS_t Status; /**< PXE status code */ -} __attribute__ (( packed )); - -typedef struct s_PXENV_UNDI_STARTUP PXENV_UNDI_STARTUP_t; - -/** @} */ /* pxenv_undi_startup */ - -/** @defgroup pxenv_undi_cleanup PXENV_UNDI_CLEANUP - * - * UNDI CLEANUP - * - * @{ - */ - -/** PXE API function code for pxenv_undi_cleanup() */ -#define PXENV_UNDI_CLEANUP 0x0002 - -/** Parameter block for pxenv_undi_cleanup() */ -struct s_PXENV_UNDI_CLEANUP { - PXENV_STATUS_t Status; /**< PXE status code */ -} __attribute__ (( packed )); - -typedef struct s_PXENV_UNDI_CLEANUP PXENV_UNDI_CLEANUP_t; - -/** @} */ /* pxenv_undi_cleanup */ - -/** @defgroup pxenv_undi_initialize PXENV_UNDI_INITIALIZE - * - * UNDI INITIALIZE - * - * @{ - */ - -/** PXE API function code for pxenv_undi_initialize() */ -#define PXENV_UNDI_INITIALIZE 0x0003 - -/** Parameter block for pxenv_undi_initialize() */ -struct s_PXENV_UNDI_INITIALIZE { - PXENV_STATUS_t Status; /**< PXE status code */ - /** NDIS 2.0 configuration information, or NULL - * - * This is a pointer to the data structure returned by the - * NDIS 2.0 GetProtocolManagerInfo() API call. The data - * structure is documented, in a rather haphazard way, in - * section 4-17 of the NDIS 2.0 specification. - */ - ADDR32_t ProtocolIni; - UINT8_t reserved[8]; /**< Must be zero */ -} __attribute__ (( packed )); - -typedef struct s_PXENV_UNDI_INITIALIZE PXENV_UNDI_INITIALIZE_t; - -/** @} */ /* pxenv_undi_initialize */ - -/** @defgroup pxenv_undi_reset_adapter PXENV_UNDI_RESET_ADAPTER - * - * UNDI RESET ADAPTER - * - * @{ - */ - -/** PXE API function code for pxenv_undi_reset_adapter() */ -#define PXENV_UNDI_RESET_ADAPTER 0x0004 - -/** Maximum number of multicast MAC addresses */ -#define MAXNUM_MCADDR 8 - -/** List of multicast MAC addresses */ -struct s_PXENV_UNDI_MCAST_ADDRESS { - /** Number of multicast MAC addresses */ - UINT16_t MCastAddrCount; - /** List of up to #MAXNUM_MCADDR multicast MAC addresses */ - MAC_ADDR_t McastAddr[MAXNUM_MCADDR]; -} __attribute__ (( packed )); - -typedef struct s_PXENV_UNDI_MCAST_ADDRESS PXENV_UNDI_MCAST_ADDRESS_t; - -/** Parameter block for pxenv_undi_reset_adapter() */ -struct s_PXENV_UNDI_RESET { - PXENV_STATUS_t Status; /**< PXE status code */ - /** Multicast MAC addresses */ - struct s_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf; -} __attribute__ (( packed )); - -typedef struct s_PXENV_UNDI_RESET PXENV_UNDI_RESET_t; - -/** @} */ /* pxenv_undi_reset_adapter */ - -/** @defgroup pxenv_undi_shutdown PXENV_UNDI_SHUTDOWN - * - * UNDI SHUTDOWN - * - * @{ - */ - -/** PXE API function code for pxenv_undi_shutdown() */ -#define PXENV_UNDI_SHUTDOWN 0x0005 - -/** Parameter block for pxenv_undi_shutdown() */ -struct s_PXENV_UNDI_SHUTDOWN { - PXENV_STATUS_t Status; /**< PXE status code */ -} __attribute__ (( packed )); - -typedef struct s_PXENV_UNDI_SHUTDOWN PXENV_UNDI_SHUTDOWN_t; - -/** @} */ /* pxenv_undi_shutdown */ - -/** @defgroup pxenv_undi_open PXENV_UNDI_OPEN - * - * UNDI OPEN - * - * @{ - */ - -/** PXE API function code for pxenv_undi_open() */ -#define PXENV_UNDI_OPEN 0x0006 - -/** Accept "directed" packets - * - * These are packets addresses to either this adapter's MAC address or - * to any of the configured multicast MAC addresses (see - * #s_PXENV_UNDI_MCAST_ADDRESS). - */ -#define FLTR_DIRECTED 0x0001 -/** Accept broadcast packets */ -#define FLTR_BRDCST 0x0002 -/** Accept all packets; listen in promiscuous mode */ -#define FLTR_PRMSCS 0x0004 -/** Accept source-routed packets */ -#define FLTR_SRC_RTG 0x0008 - -/** Parameter block for pxenv_undi_open() */ -struct s_PXENV_UNDI_OPEN { - PXENV_STATUS_t Status; /**< PXE status code */ - /** Open flags as defined in NDIS 2.0 - * - * This is the OpenOptions field as passed to the NDIS 2.0 - * OpenAdapter() API call. It is defined to be "adapter - * specific", though 0 is guaranteed to be a valid value. - */ - UINT16_t OpenFlag; - /** Receive packet filter - * - * This is the bitwise-OR of any of the following flags: - * #FLTR_DIRECTED, #FLTR_BRDCST, #FLTR_PRMSCS and - * #FLTR_SRC_RTG. - */ - UINT16_t PktFilter; - /** Multicast MAC addresses */ - struct s_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf; -} __attribute__ (( packed )); - -typedef struct s_PXENV_UNDI_OPEN PXENV_UNDI_OPEN_t; - -/** @} */ /* pxenv_undi_open */ - -/** @defgroup pxenv_undi_close PXENV_UNDI_CLOSE - * - * UNDI CLOSE - * - * @{ - */ - -/** PXE API function code for pxenv_undi_close() */ -#define PXENV_UNDI_CLOSE 0x0007 - -/** Parameter block for pxenv_undi_close() */ -struct s_PXENV_UNDI_CLOSE { - PXENV_STATUS_t Status; /**< PXE status code */ -} __attribute__ (( packed )); - -typedef struct s_PXENV_UNDI_CLOSE PXENV_UNDI_CLOSE_t; - -/** @} */ /* pxenv_undi_close */ - -/** @defgroup pxenv_undi_transmit PXENV_UNDI_TRANSMIT - * - * UNDI TRANSMIT PACKET - * - * @{ - */ - -/** PXE API function code for pxenv_undi_transmit() */ -#define PXENV_UNDI_TRANSMIT 0x0008 - -#define P_UNKNOWN 0 /**< Media header already filled in */ -#define P_IP 1 /**< IP protocol */ -#define P_ARP 2 /**< ARP protocol */ -#define P_RARP 3 /**< RARP protocol */ -#define P_OTHER 4 /**< Other protocol */ - -#define XMT_DESTADDR 0x0000 /**< Unicast packet */ -#define XMT_BROADCAST 0x0001 /**< Broadcast packet */ - -/** Maximum number of data blocks in a transmit buffer descriptor */ -#define MAX_DATA_BLKS 8 - -/** A transmit buffer descriptor, as pointed to by s_PXENV_UNDI_TRANSMIT::TBD - */ -struct s_PXENV_UNDI_TBD { - UINT16_t ImmedLength; /**< Length of the transmit buffer */ - SEGOFF16_t Xmit; /**< Address of the transmit buffer */ - UINT16_t DataBlkCount; - /** Array of up to #MAX_DATA_BLKS additional transmit buffers */ - struct DataBlk { - /** Always 1 - * - * A value of 0 would indicate that #TDDataPtr were an - * #ADDR32_t rather than a #SEGOFF16_t. The PXE - * specification version 2.1 explicitly states that - * this is not supported; #TDDataPtr will always be a - * #SEGOFF16_t. - */ - UINT8_t TDPtrType; - UINT8_t TDRsvdByte; /**< Must be zero */ - UINT16_t TDDataLen; /**< Length of this transmit buffer */ - SEGOFF16_t TDDataPtr; /**< Address of this transmit buffer */ - } DataBlock[MAX_DATA_BLKS]; -} __attribute__ (( packed )); - -typedef struct s_PXENV_UNDI_TBD PXENV_UNDI_TBD_t; - -/** Parameter block for pxenv_undi_transmit() */ -struct s_PXENV_UNDI_TRANSMIT { - PXENV_STATUS_t Status; /**< PXE status code */ - /** Protocol - * - * Valid values are #P_UNKNOWN, #P_IP, #P_ARP or #P_RARP. If - * the caller has already filled in the media header, this - * field must be set to #P_UNKNOWN. - */ - UINT8_t Protocol; - /** Unicast/broadcast flag - * - * Valid values are #XMT_DESTADDR or #XMT_BROADCAST. - */ - UINT8_t XmitFlag; - SEGOFF16_t DestAddr; /**< Destination MAC address */ - /** Address of the Transmit Buffer Descriptor - * - * This is a pointer to a struct s_PXENV_UNDI_TBD. - */ - SEGOFF16_t TBD; - UINT32_t Reserved[2]; /**< Must be zero */ -} __attribute__ (( packed )); - -typedef struct s_PXENV_UNDI_TRANSMIT PXENV_UNDI_TRANSMIT_t; - -/** @} */ /* pxenv_undi_transmit */ - -/** @defgroup pxenv_undi_set_mcast_address PXENV_UNDI_SET_MCAST_ADDRESS - * - * UNDI SET MULTICAST ADDRESS - * - * @{ - */ - -/** PXE API function code for pxenv_undi_set_mcast_address() */ -#define PXENV_UNDI_SET_MCAST_ADDRESS 0x0009 - -/** Parameter block for pxenv_undi_set_mcast_address() */ -struct s_PXENV_UNDI_SET_MCAST_ADDRESS { - PXENV_STATUS_t Status; /**< PXE status code */ - /** List of multicast addresses */ - struct s_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf; -} __attribute__ (( packed )); - -typedef struct s_PXENV_UNDI_SET_MCAST_ADDRESS PXENV_UNDI_SET_MCAST_ADDRESS_t; - -/** @} */ /* pxenv_undi_set_mcast_address */ - -/** @defgroup pxenv_undi_set_station_address PXENV_UNDI_SET_STATION_ADDRESS - * - * UNDI SET STATION ADDRESS - * - * @{ - */ - -/** PXE API function code for pxenv_undi_set_station_address() */ -#define PXENV_UNDI_SET_STATION_ADDRESS 0x000a - -/** Parameter block for pxenv_undi_set_station_address() */ -struct s_PXENV_UNDI_SET_STATION_ADDRESS { - PXENV_STATUS_t Status; /**< PXE status code */ - MAC_ADDR_t StationAddress; /**< Station MAC address */ -} __attribute__ (( packed )); - -typedef struct s_PXENV_UNDI_SET_STATION_ADDRESS PXENV_UNDI_SET_STATION_ADDRESS_t; - -/** @} */ /* pxenv_undi_set_station_address */ - -/** @defgroup pxenv_undi_set_packet_filter PXENV_UNDI_SET_PACKET_FILTER - * - * UNDI SET PACKET FILTER - * - * @{ - */ - -/** PXE API function code for pxenv_undi_set_packet_filter() */ -#define PXENV_UNDI_SET_PACKET_FILTER 0x000b - -/** Parameter block for pxenv_undi_set_packet_filter() */ -struct s_PXENV_UNDI_SET_PACKET_FILTER { - PXENV_STATUS_t Status; /**< PXE status code */ - /** Receive packet filter - * - * This field takes the same values as - * s_PXENV_UNDI_OPEN::PktFilter. - * - * @note Yes, this field is a different size to - * s_PXENV_UNDI_OPEN::PktFilter. Blame "the managers at Intel - * who apparently let a consultant come up with the spec - * without any kind of adult supervision" (quote from hpa). - */ - UINT8_t filter; -} __attribute__ (( packed )); - -typedef struct s_PXENV_UNDI_SET_PACKET_FILTER PXENV_UNDI_SET_PACKET_FILTER_t; - -/** @} */ /* pxenv_undi_set_packet_filter */ - -/** @defgroup pxenv_undi_get_information PXENV_UNDI_GET_INFORMATION - * - * UNDI GET INFORMATION - * - * @{ - */ - -/** PXE API function code for pxenv_undi_get_information() */ -#define PXENV_UNDI_GET_INFORMATION 0x000c - -#define ETHER_TYPE 1 /**< Ethernet (10Mb) */ -#define EXP_ETHER_TYPE 2 /**< Experimental Ethernet (3Mb) */ -#define AX25_TYPE 3 /**< Amateur Radio AX.25 */ -#define TOKEN_RING_TYPE 4 /**< Proteon ProNET Token Ring */ -#define CHAOS_TYPE 5 /**< Chaos */ -#define IEEE_TYPE 6 /**< IEEE 802 Networks */ -#define ARCNET_TYPE 7 /**< ARCNET */ - -/** Parameter block for pxenv_undi_get_information() */ -struct s_PXENV_UNDI_GET_INFORMATION { - PXENV_STATUS_t Status; /**< PXE status code */ - UINT16_t BaseIo; /**< I/O base address */ - UINT16_t IntNumber; /**< IRQ number */ - UINT16_t MaxTranUnit; /**< Adapter MTU */ - /** Hardware type - * - * Valid values are defined in RFC1010 ("Assigned numbers"), - * and are #ETHER_TYPE, #EXP_ETHER_TYPE, #AX25_TYPE, - * #TOKEN_RING_TYPE, #CHAOS_TYPE, #IEEE_TYPE or #ARCNET_TYPE. - */ - UINT16_t HwType; - UINT16_t HwAddrLen; /**< MAC address length */ - MAC_ADDR_t CurrentNodeAddress; /**< Current MAC address */ - MAC_ADDR_t PermNodeAddress; /**< Permanent (EEPROM) MAC address */ - SEGSEL_t ROMAddress; /**< Real-mode ROM segment address */ - UINT16_t RxBufCt; /**< Receive queue length */ - UINT16_t TxBufCt; /**< Transmit queue length */ -} __attribute__ (( packed )); - -typedef struct s_PXENV_UNDI_GET_INFORMATION PXENV_UNDI_GET_INFORMATION_t; - -/** @} */ /* pxenv_undi_get_information */ - -/** @defgroup pxenv_undi_get_statistics PXENV_UNDI_GET_STATISTICS - * - * UNDI GET STATISTICS - * - * @{ - */ - -/** PXE API function code for pxenv_undi_get_statistics() */ -#define PXENV_UNDI_GET_STATISTICS 0x000d - -/** Parameter block for pxenv_undi_get_statistics() */ -struct s_PXENV_UNDI_GET_STATISTICS { - PXENV_STATUS_t Status; /**< PXE status code */ - UINT32_t XmtGoodFrames; /**< Successful transmission count */ - UINT32_t RcvGoodFrames; /**< Successful reception count */ - UINT32_t RcvCRCErrors; /**< Receive CRC error count */ - UINT32_t RcvResourceErrors; /**< Receive queue overflow count */ -} __attribute__ (( packed )); - -typedef struct s_PXENV_UNDI_GET_STATISTICS PXENV_UNDI_GET_STATISTICS_t; - -/** @} */ /* pxenv_undi_get_statistics */ - -/** @defgroup pxenv_undi_clear_statistics PXENV_UNDI_CLEAR_STATISTICS - * - * UNDI CLEAR STATISTICS - * - * @{ - */ - -/** PXE API function code for pxenv_undi_clear_statistics() */ -#define PXENV_UNDI_CLEAR_STATISTICS 0x000e - -/** Parameter block for pxenv_undi_clear_statistics() */ -struct s_PXENV_UNDI_CLEAR_STATISTICS { - PXENV_STATUS_t Status; /**< PXE status code */ -} __attribute__ (( packed )); - -typedef struct s_PXENV_UNDI_CLEAR_STATISTICS PXENV_UNDI_CLEAR_STATISTICS_t; - -/** @} */ /* pxenv_undi_clear_statistics */ - -/** @defgroup pxenv_undi_initiate_diags PXENV_UNDI_INITIATE_DIAGS - * - * UNDI INITIATE DIAGS - * - * @{ - */ - -/** PXE API function code for pxenv_undi_initiate_diags() */ -#define PXENV_UNDI_INITIATE_DIAGS 0x000f - -/** Parameter block for pxenv_undi_initiate_diags() */ -struct s_PXENV_UNDI_INITIATE_DIAGS { - PXENV_STATUS_t Status; /**< PXE status code */ -} __attribute__ (( packed )); - -typedef struct s_PXENV_UNDI_INITIATE_DIAGS PXENV_UNDI_INITIATE_DIAGS_t; - -/** @} */ /* pxenv_undi_initiate_diags */ - -/** @defgroup pxenv_undi_force_interrupt PXENV_UNDI_FORCE_INTERRUPT - * - * UNDI FORCE INTERRUPT - * - * @{ - */ - -/** PXE API function code for pxenv_undi_force_interrupt() */ -#define PXENV_UNDI_FORCE_INTERRUPT 0x0010 - -/** Parameter block for pxenv_undi_force_interrupt() */ -struct s_PXENV_UNDI_FORCE_INTERRUPT { - PXENV_STATUS_t Status; /**< PXE status code */ -} __attribute__ (( packed )); - -typedef struct s_PXENV_UNDI_FORCE_INTERRUPT PXENV_UNDI_FORCE_INTERRUPT_t; - -/** @} */ /* pxenv_undi_force_interrupt */ - -/** @defgroup pxenv_undi_get_mcast_address PXENV_UNDI_GET_MCAST_ADDRESS - * - * UNDI GET MULTICAST ADDRESS - * - * @{ - */ - -/** PXE API function code for pxenv_undi_get_mcast_address() */ -#define PXENV_UNDI_GET_MCAST_ADDRESS 0x0011 - -/** Parameter block for pxenv_undi_get_mcast_address() */ -struct s_PXENV_UNDI_GET_MCAST_ADDRESS { - PXENV_STATUS_t Status; /**< PXE status code */ - IP4_t InetAddr; /**< Multicast IP address */ - MAC_ADDR_t MediaAddr; /**< Multicast MAC address */ -} __attribute__ (( packed )); - -typedef struct s_PXENV_UNDI_GET_MCAST_ADDRESS PXENV_UNDI_GET_MCAST_ADDRESS_t; - -/** @} */ /* pxenv_undi_get_mcast_address */ - -/** @defgroup pxenv_undi_get_nic_type PXENV_UNDI_GET_NIC_TYPE - * - * UNDI GET NIC TYPE - * - * @{ - */ - -/** PXE API function code for pxenv_undi_get_nic_type() */ -#define PXENV_UNDI_GET_NIC_TYPE 0x0012 - -#define PCI_NIC 2 /**< PCI network card */ -#define PnP_NIC 3 /**< ISAPnP network card */ -#define CardBus_NIC 4 /**< CardBus network card */ - -/** Information for a PCI or equivalent NIC */ -struct pci_nic_info { - UINT16_t Vendor_ID; /**< PCI vendor ID */ - UINT16_t Dev_ID; /**< PCI device ID */ - UINT8_t Base_Class; /**< PCI base class */ - UINT8_t Sub_Class; /**< PCI sub class */ - UINT8_t Prog_Intf; /**< PCI programming interface */ - UINT8_t Rev; /**< PCI revision */ - UINT16_t BusDevFunc; /**< PCI bus:dev:fn address */ - UINT16_t SubVendor_ID; /**< PCI subvendor ID */ - UINT16_t SubDevice_ID; /**< PCI subdevice ID */ -} __attribute__ (( packed )); - -/** Information for an ISAPnP or equivalent NIC */ -struct pnp_nic_info { - UINT32_t EISA_Dev_ID; /**< EISA device ID */ - UINT8_t Base_Class; /**< Base class */ - UINT8_t Sub_Class; /**< Sub class */ - UINT8_t Prog_Intf; /**< Programming interface */ - /** Card Select Number assigned to card */ - UINT16_t CardSelNum; -} __attribute__ (( packed )); - -/** Parameter block for pxenv_undi_get_nic_type() */ -struct s_PXENV_UNDI_GET_NIC_TYPE { - PXENV_STATUS_t Status; /**< PXE status code */ - /** NIC type - * - * Valid values are #PCI_NIC, #PnP_NIC or #CardBus_NIC. - */ - UINT8_t NicType; - /** NIC information */ - union nic_type_info { - /** NIC information (if #NicType==#PCI_NIC) */ - struct pci_nic_info pci; - /** NIC information (if #NicType==#CardBus_NIC) */ - struct pci_nic_info cardbus; - /** NIC information (if #NicType==#PnP_NIC) */ - struct pnp_nic_info pnp; - } info; -} __attribute__ (( packed )); - -typedef struct s_PXENV_UNDI_GET_NIC_TYPE PXENV_UNDI_GET_NIC_TYPE_t; - -/** @} */ /* pxenv_undi_get_nic_type */ - -/** @defgroup pxenv_undi_get_iface_info PXENV_UNDI_GET_IFACE_INFO - * - * UNDI GET IFACE INFO - * - * @{ - */ - -/** PXE API function code for pxenv_undi_get_iface_info() */ -#define PXENV_UNDI_GET_IFACE_INFO 0x0013 - -/** Broadcast supported */ -#define SUPPORTED_BROADCAST 0x0001 -/** Multicast supported */ -#define SUPPORTED_MULTICAST 0x0002 -/** Functional/group addressing supported */ -#define SUPPORTED_GROUP 0x0004 -/** Promiscuous mode supported */ -#define SUPPORTED_PROMISCUOUS 0x0008 -/** Software settable station address */ -#define SUPPORTED_SET_STATION_ADDRESS 0x0010 -/** InitiateDiagnostics supported */ -#define SUPPORTED_DIAGNOSTICS 0x0040 -/** Reset MAC supported */ -#define SUPPORTED_RESET 0x0400 -/** Open / Close Adapter supported */ -#define SUPPORTED_OPEN_CLOSE 0x0800 -/** Interrupt Request supported */ -#define SUPPORTED_IRQ 0x1000 - -/** Parameter block for pxenv_undi_get_iface_info() */ -struct s_PXENV_UNDI_GET_IFACE_INFO { - PXENV_STATUS_t Status; /**< PXE status code */ - /** Interface type - * - * This is defined in the NDIS 2.0 specification to be one of - * the strings "802.3", "802.4", "802.5", "802.6", "DIX", - * "DIX+802.3", "APPLETALK", "ARCNET", "FDDI", "SDLC", "BSC", - * "HDLC", or "ISDN". - * - * "Normal" Ethernet, for various historical reasons, is - * "DIX+802.3". - */ - UINT8_t IfaceType[16]; - UINT32_t LinkSpeed; /**< Link speed, in bits per second */ - /** Service flags - * - * These are the "service flags" defined in the "MAC - * Service-Specific Characteristics" table in the NDIS 2.0 - * specification. Almost all of them are irrelevant to PXE. - */ - UINT32_t ServiceFlags; - UINT32_t Reserved[4]; /**< Must be zero */ -} __attribute__ (( packed )); - -typedef struct s_PXENV_UNDI_GET_IFACE_INFO PXENV_UNDI_GET_IFACE_INFO_t; - -/** @} */ /* pxenv_undi_get_iface_info */ - -/** @defgroup pxenv_undi_get_state PXENV_UNDI_GET_STATE - * - * UNDI GET STATE - * - * @{ - */ - -/** PXE API function code for pxenv_undi_get_state() */ -#define PXENV_UNDI_GET_STATE 0x0015 - -/** pxenv_start_undi() has been called */ -#define PXE_UNDI_GET_STATE_STARTED 1 -/** pxenv_undi_initialize() has been called */ -#define PXE_UNDI_GET_STATE_INITIALIZED 2 -/** pxenv_undi_open() has been called */ -#define PXE_UNDI_GET_STATE_OPENED 3 - -/** Parameter block for pxenv_undi_get_state() */ -struct s_PXENV_UNDI_GET_STATE { - PXENV_STATUS_t Status; /**< PXE status code */ - /** Current state of the UNDI driver - * - * Valid values are #PXE_UNDI_GET_STATE_STARTED, - * #PXE_UNDI_GET_STATE_INITIALIZED or - * #PXE_UNDI_GET_STATE_OPENED. - */ - UINT8_t UNDIstate; -} __attribute__ (( packed )); - -typedef struct s_PXENV_UNDI_GET_STATE PXENV_UNDI_GET_STATE_t; - -/** @} */ /* pxenv_undi_get_state */ - -/** @defgroup pxenv_undi_isr PXENV_UNDI_ISR - * - * UNDI ISR - * - * @{ - */ - -/** PXE API function code for pxenv_undi_isr() */ -#define PXENV_UNDI_ISR 0x0014 - -/** Determine whether or not this is our interrupt */ -#define PXENV_UNDI_ISR_IN_START 1 -/** Start processing interrupt */ -#define PXENV_UNDI_ISR_IN_PROCESS 2 -/** Continue processing interrupt */ -#define PXENV_UNDI_ISR_IN_GET_NEXT 3 -/** This interrupt was ours */ -#define PXENV_UNDI_ISR_OUT_OURS 0 -/** This interrupt was not ours */ -#define PXENV_UNDI_ISR_OUT_NOT_OURS 1 -/** Finished processing interrupt */ -#define PXENV_UNDI_ISR_OUT_DONE 0 -/** A packet transmission has completed */ -#define PXENV_UNDI_ISR_OUT_TRANSMIT 2 -/** A packet has been received */ -#define PXENV_UNDI_ISR_OUT_RECEIVE 3 -/** We are already in the middle of processing an interrupt */ -#define PXENV_UNDI_ISR_OUT_BUSY 4 - -/** Unicast packet (or packet captured in promiscuous mode) */ -#define P_DIRECTED 0 -/** Broadcast packet */ -#define P_BROADCAST 1 -/** Multicast packet */ -#define P_MULTICAST 2 - -/** Parameter block for pxenv_undi_isr() */ -struct s_PXENV_UNDI_ISR { - PXENV_STATUS_t Status; /**< PXE status code */ - /** Function flag - * - * Valid values are #PXENV_UNDI_ISR_IN_START, - * #PXENV_UNDI_ISR_IN_PROCESS, #PXENV_UNDI_ISR_IN_GET_NEXT, - * #PXENV_UNDI_ISR_OUT_OURS, #PXENV_UNDI_ISR_OUT_NOT_OURS, - * #PXENV_UNDI_ISR_OUT_DONE, #PXENV_UNDI_ISR_OUT_TRANSMIT, - * #PXENV_UNDI_ISR_OUT_RECEIVE or #PXENV_UNDI_ISR_OUT_BUSY. - */ - UINT16_t FuncFlag; - UINT16_t BufferLength; /**< Data buffer length */ - UINT16_t FrameLength; /**< Total frame length */ - UINT16_t FrameHeaderLength; /**< Frame header length */ - SEGOFF16_t Frame; /**< Data buffer address */ - /** Protocol type - * - * Valid values are #P_IP, #P_ARP, #P_RARP or #P_OTHER. - */ - UINT8_t ProtType; - /** Packet type - * - * Valid values are #P_DIRECTED, #P_BROADCAST or #P_MULTICAST. - */ - UINT8_t PktType; -} __attribute__ (( packed )); - -typedef struct s_PXENV_UNDI_ISR PXENV_UNDI_ISR_t; - -/** @} */ /* pxenv_undi_isr */ - -/** @} */ /* pxe_undi_api */ - -/** @defgroup pxe_file_api PXE FILE API - * - * POSIX-like file operations - * - * @{ - */ - -/** Minimum possible opcode used within PXE FILE API */ -#define PXENV_FILE_MIN 0x00e0 - -/** Minimum possible opcode used within PXE FILE API */ -#define PXENV_FILE_MAX 0x00ef - -/** @defgroup pxenv_file_open PXENV_FILE_OPEN - * - * FILE OPEN - * - * @{ - */ - -/** PXE API function code for pxenv_file_open() */ -#define PXENV_FILE_OPEN 0x00e0 - -/** Parameter block for pxenv_file_open() */ -struct s_PXENV_FILE_OPEN { - PXENV_STATUS_t Status; /**< PXE status code */ - UINT16_t FileHandle; /**< File handle */ - SEGOFF16_t FileName; /**< File URL */ - UINT32_t Reserved; /**< Reserved */ -} __attribute__ (( packed )); - -typedef struct s_PXENV_FILE_OPEN PXENV_FILE_OPEN_t; - -/** @} */ /* pxenv_file_open */ - -/** @defgroup pxenv_file_close PXENV_FILE_CLOSE - * - * FILE CLOSE - * - * @{ - */ - -/** PXE API function code for pxenv_file_close() */ -#define PXENV_FILE_CLOSE 0x00e1 - -/** Parameter block for pxenv_file_close() */ -struct s_PXENV_FILE_CLOSE { - PXENV_STATUS_t Status; /**< PXE status code */ - UINT16_t FileHandle; /**< File handle */ -} __attribute__ (( packed )); - -typedef struct s_PXENV_FILE_CLOSE PXENV_FILE_CLOSE_t; - -/** @} */ /* pxenv_file_close */ - -/** @defgroup pxenv_file_select PXENV_FILE_SELECT - * - * FILE SELECT - * - * @{ - */ - -/** PXE API function code for pxenv_file_select() */ -#define PXENV_FILE_SELECT 0x00e2 - -/** File is ready for reading */ -#define RDY_READ 0x0001 - -/** Parameter block for pxenv_file_select() */ -struct s_PXENV_FILE_SELECT { - PXENV_STATUS_t Status; /**< PXE status code */ - UINT16_t FileHandle; /**< File handle */ - UINT16_t Ready; /**< Indication of readiness */ -} __attribute__ (( packed )); - -typedef struct s_PXENV_FILE_SELECT PXENV_FILE_SELECT_t; - -/** @} */ /* pxenv_file_select */ - -/** @defgroup pxenv_file_read PXENV_FILE_READ - * - * FILE READ - * - * @{ - */ - -/** PXE API function code for pxenv_file_read() */ -#define PXENV_FILE_READ 0x00e3 - -/** Parameter block for pxenv_file_read() */ -struct s_PXENV_FILE_READ { - PXENV_STATUS_t Status; /**< PXE status code */ - UINT16_t FileHandle; /**< File handle */ - UINT16_t BufferSize; /**< Data buffer size */ - SEGOFF16_t Buffer; /**< Data buffer */ -} __attribute__ (( packed )); - -typedef struct s_PXENV_FILE_READ PXENV_FILE_READ_t; - -/** @} */ /* pxenv_file_read */ - -/** @defgroup pxenv_get_file_size PXENV_GET_FILE_SIZE - * - * GET FILE SIZE - * - * @{ - */ - -/** PXE API function code for pxenv_get_file_size() */ -#define PXENV_GET_FILE_SIZE 0x00e4 - -/** Parameter block for pxenv_get_file_size() */ -struct s_PXENV_GET_FILE_SIZE { - PXENV_STATUS_t Status; /**< PXE status code */ - UINT16_t FileHandle; /**< File handle */ - UINT32_t FileSize; /**< File size */ -} __attribute__ (( packed )); - -typedef struct s_PXENV_GET_FILE_SIZE PXENV_GET_FILE_SIZE_t; - -/** @} */ /* pxenv_get_file_size */ - -/** @defgroup pxenv_file_exec PXENV_FILE_EXEC - * - * FILE EXEC - * - * @{ - */ - -/** PXE API function code for pxenv_file_exec() */ -#define PXENV_FILE_EXEC 0x00e5 - -/** Parameter block for pxenv_file_exec() */ -struct s_PXENV_FILE_EXEC { - PXENV_STATUS_t Status; /**< PXE status code */ - SEGOFF16_t Command; /**< Command to execute */ -} __attribute__ (( packed )); - -typedef struct s_PXENV_FILE_EXEC PXENV_FILE_EXEC_t; - -/** @} */ /* pxenv_file_exec */ - -/** @defgroup pxenv_file_api_check PXENV_FILE_API_CHECK - * - * FILE API CHECK - * - * @{ - */ - -/** PXE API function code for pxenv_file_api_check() */ -#define PXENV_FILE_API_CHECK 0x00e6 - -/** Parameter block for pxenv_file_api_check() */ -struct s_PXENV_FILE_API_CHECK { - PXENV_STATUS_t Status; /**< PXE status code */ - UINT16_t Size; /**< Size of structure */ - UINT32_t Magic; /**< Magic number */ - UINT32_t Provider; /**< Implementation identifier */ - UINT32_t APIMask; /**< Supported API functions */ - UINT32_t Flags; /**< Reserved for the future */ -} __attribute__ (( packed )); - -typedef struct s_PXENV_FILE_API_CHECK PXENV_FILE_API_CHECK_t; - -/** @} */ /* pxenv_file_api_check */ - -/** @defgroup pxenv_file_exit_hook PXENV_FILE_EXIT_HOOK - * - * FILE EXIT HOOK - * - * @{ - */ - -/** PXE API function code for pxenv_file_exit_hook() */ -#define PXENV_FILE_EXIT_HOOK 0x00e7 - -/** Parameter block for pxenv_file_exit_hook() */ -struct s_PXENV_FILE_EXIT_HOOK { - PXENV_STATUS_t Status; /**< PXE status code */ - SEGOFF16_t Hook; /**< SEG16:OFF16 to jump to */ -} __attribute__ (( packed )); - -typedef struct s_PXENV_FILE_EXIT_HOOK PXENV_FILE_EXIT_HOOK_t; - -/** @} */ /* pxenv_file_exit_hook */ - -/** @defgroup pxenv_file_cmdline PXENV_FILE_CMDLINE - * - * FILE CMDLINE - * - * @{ - */ - -/** PXE API function code for pxenv_file_cmdline() */ -#define PXENV_FILE_CMDLINE 0x00e8 - -/** Parameter block for pxenv_file_cmdline() */ -struct s_PXENV_FILE_CMDLINE { - PXENV_STATUS_t Status; /**< PXE status code */ - UINT16_t BufferSize; /**< Data buffer size */ - SEGOFF16_t Buffer; /**< Data buffer */ -} __attribute__ (( packed )); - -typedef struct s_PXENV_FILE_CMDLINE PXENV_FILE_CMDLINE_t; - -/** @} */ /* pxe_file_cmdline */ - -/** @} */ /* pxe_file_api */ - -/** @defgroup pxe_loader_api PXE Loader API - * - * The UNDI ROM loader API - * - * @{ - */ - -/** Parameter block for undi_loader() */ -struct s_UNDI_LOADER { - /** PXE status code */ - PXENV_STATUS_t Status; - /** %ax register as for PXENV_START_UNDI */ - UINT16_t AX; - /** %bx register as for PXENV_START_UNDI */ - UINT16_t BX; - /** %dx register as for PXENV_START_UNDI */ - UINT16_t DX; - /** %di register as for PXENV_START_UNDI */ - OFF16_t DI; - /** %es register as for PXENV_START_UNDI */ - SEGSEL_t ES; - /** UNDI data segment - * - * @note The PXE specification defines the type of this field - * as #UINT16_t. For x86, #SEGSEL_t and #UINT16_t are - * equivalent anyway; for other architectures #SEGSEL_t makes - * more sense. - */ - SEGSEL_t UNDI_DS; - /** UNDI code segment - * - * @note The PXE specification defines the type of this field - * as #UINT16_t. For x86, #SEGSEL_t and #UINT16_t are - * equivalent anyway; for other architectures #SEGSEL_t makes - * more sense. - */ - SEGSEL_t UNDI_CS; - /** Address of the !PXE structure (a struct s_PXE) */ - SEGOFF16_t PXEptr; - /** Address of the PXENV+ structure (a struct s_PXENV) */ - SEGOFF16_t PXENVptr; -} __attribute__ (( packed )); - -typedef struct s_UNDI_LOADER UNDI_LOADER_t; - -/** @} */ /* pxe_loader_api */ - -/** @} */ /* pxe */ - -/** @page pxe_notes Etherboot PXE implementation notes - -@section pxe_routing IP routing - -Several PXE API calls (e.g. pxenv_tftp_open() and pxenv_udp_write()) -allow for the caller to specify a "relay agent IP address", often in a -field called "gateway" or similar. The PXE specification states that -"The IP layer should provide space for a minimum of four routing -entries obtained from the default router and static route DHCP option -tags in the DHCPACK message, plus any non-zero giaddr field from the -DHCPOFFER message(s) accepted by the client". - -The DHCP static route option ("option static-routes" in dhcpd.conf) -works only for classed IP routing (i.e. it provides no way to specify -a subnet mask). Since virtually everything now uses classless IP -routing, the DHCP static route option is almost totally useless, and -is (according to the dhcp-options man page) not implemented by any of -the popular DHCP clients. - -This leaves the caller-specified "relay agent IP address", the giaddr -field from the DHCPOFFER message(s) and the default gateway(s) -provided via the routers option ("option routers" in dhcpd.conf) in -the DHCPACK message. Each of these is a default gateway address. -It's a fair bet that the routers option should take priority over the -giaddr field, since the routers option has to be explicitly specified -by the DHCP server operator. Similarly, it's fair to assume that the -caller-specified "relay agent IP address", if present, should take -priority over any other routing table entries. - -@bug Etherboot currently ignores all potential sources of routing -information other than the first router provided to it by a DHCP -routers option. - -@section pxe_x86_modes x86 processor mode restrictions - -On the x86 platform, different PXE API calls have different -restrictions on the processor modes (real or protected) that can be -used. See the individual API call descriptions for the restrictions -that apply to any particular call. - -@subsection pxe_x86_pmode16 Real mode, or protected-mode with 16-bit stack - -The PXE specification states that the API function can be called in -protected mode only if the s_PXE::StatusCallout field is set to a -non-zero value, and that the API function cannot be called with a -32-bit stack segment. - -Etherboot does not enforce either of these restrictions; they seem (as -with so much of the PXE specification) to be artifacts of the Intel -implementation. - -*/ - -#endif /* PXE_API_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/pxe_call.h b/qemu/roms/ipxe/src/arch/i386/include/pxe_call.h deleted file mode 100644 index cbd548318..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/pxe_call.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef _PXE_CALL_H -#define _PXE_CALL_H - -/** @file - * - * PXE API entry point - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <pxe_api.h> -#include <realmode.h> -#include <setjmp.h> - -struct net_device; - -/** PXE load address segment */ -#define PXE_LOAD_SEGMENT 0 - -/** PXE load address offset */ -#define PXE_LOAD_OFFSET 0x7c00 - -/** PXE physical load address */ -#define PXE_LOAD_PHYS ( ( PXE_LOAD_SEGMENT << 4 ) + PXE_LOAD_OFFSET ) - -/** !PXE structure */ -extern struct s_PXE __text16 ( ppxe ); -#define ppxe __use_text16 ( ppxe ) - -/** PXENV+ structure */ -extern struct s_PXENV __text16 ( pxenv ); -#define pxenv __use_text16 ( pxenv ) - -/** PXENV_RESTART_TFTP jump buffer */ -extern rmjmp_buf pxe_restart_nbp; - -extern void pxe_activate ( struct net_device *netdev ); -extern int pxe_deactivate ( void ); -extern int pxe_start_nbp ( void ); -extern __asmcall void pxe_api_call ( struct i386_all_regs *ix86 ); -extern int pxe_api_call_weak ( struct i386_all_regs *ix86 ); - -#endif /* _PXE_CALL_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/pxe_error.h b/qemu/roms/ipxe/src/arch/i386/include/pxe_error.h deleted file mode 100644 index 51298e665..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/pxe_error.h +++ /dev/null @@ -1,123 +0,0 @@ -#ifndef PXE_ERROR_H -#define PXE_ERROR_H - -/** @file - * - * Preboot eXecution Environment (PXE) error definitions - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/** - * @defgroup pxeerrors PXE error codes - * - * @{ - */ - -/* Generic errors */ -#define PXENV_STATUS_SUCCESS 0x0000 -#define PXENV_STATUS_FAILURE 0x0001 -#define PXENV_STATUS_BAD_FUNC 0x0002 -#define PXENV_STATUS_UNSUPPORTED 0x0003 -#define PXENV_STATUS_KEEP_UNDI 0x0004 -#define PXENV_STATUS_KEEP_ALL 0x0005 -#define PXENV_STATUS_OUT_OF_RESOURCES 0x0006 - -/* ARP errors (0x0010 to 0x001f) */ -#define PXENV_STATUS_ARP_TIMEOUT 0x0011 - -/* Base-Code state errors */ -#define PXENV_STATUS_UDP_CLOSED 0x0018 -#define PXENV_STATUS_UDP_OPEN 0x0019 -#define PXENV_STATUS_TFTP_CLOSED 0x001a -#define PXENV_STATUS_TFTP_OPEN 0x001b - -/* BIOS/system errors (0x0020 to 0x002f) */ -#define PXENV_STATUS_MCOPY_PROBLEM 0x0020 -#define PXENV_STATUS_BIS_INTEGRITY_FAILURE 0x0021 -#define PXENV_STATUS_BIS_VALIDATE_FAILURE 0x0022 -#define PXENV_STATUS_BIS_INIT_FAILURE 0x0023 -#define PXENV_STATUS_BIS_SHUTDOWN_FAILURE 0x0024 -#define PXENV_STATUS_BIS_GBOA_FAILURE 0x0025 -#define PXENV_STATUS_BIS_FREE_FAILURE 0x0026 -#define PXENV_STATUS_BIS_GSI_FAILURE 0x0027 -#define PXENV_STATUS_BIS_BAD_CKSUM 0x0028 - -/* TFTP/MTFTP errors (0x0030 to 0x003f) */ -#define PXENV_STATUS_TFTP_CANNOT_ARP_ADDRESS 0x0030 -#define PXENV_STATUS_TFTP_OPEN_TIMEOUT 0x0032 -#define PXENV_STATUS_TFTP_UNKNOWN_OPCODE 0x0033 -#define PXENV_STATUS_TFTP_READ_TIMEOUT 0x0035 -#define PXENV_STATUS_TFTP_ERROR_OPCODE 0x0036 -#define PXENV_STATUS_TFTP_CANNOT_OPEN_CONNECTION 0x0038 -#define PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION 0x0039 -#define PXENV_STATUS_TFTP_TOO_MANY_PACKAGES 0x003a -#define PXENV_STATUS_TFTP_FILE_NOT_FOUND 0x003b -#define PXENV_STATUS_TFTP_ACCESS_VIOLATION 0x003c -#define PXENV_STATUS_TFTP_NO_MCAST_ADDRESS 0x003d -#define PXENV_STATUS_TFTP_NO_FILESIZE 0x003e -#define PXENV_STATUS_TFTP_INVALID_PACKET_SIZE 0x003f - -/* Reserved errors 0x0040 to 0x004f) */ - -/* DHCP/BOOTP errors (0x0050 to 0x005f) */ -#define PXENV_STATUS_DHCP_TIMEOUT 0x0051 -#define PXENV_STATUS_DHCP_NO_IP_ADDRESS 0x0052 -#define PXENV_STATUS_DHCP_NO_BOOTFILE_NAME 0x0053 -#define PXENV_STATUS_DHCP_BAD_IP_ADDRESS 0x0054 - -/* Driver errors (0x0060 to 0x006f) */ -#define PXENV_STATUS_UNDI_INVALID_FUNCTION 0x0060 -#define PXENV_STATUS_UNDI_MEDIATEST_FAILED 0x0061 -#define PXENV_STATUS_UNDI_CANNOT_INIT_NIC_FOR_MCAST 0x0062 -#define PXENV_STATUS_UNDI_CANNOT_INITIALIZE_NIC 0x0063 -#define PXENV_STATUS_UNDI_CANNOT_INITIALIZE_PHY 0x0064 -#define PXENV_STATUS_UNDI_CANNOT_READ_CONFIG_DATA 0x0065 -#define PXENV_STATUS_UNDI_CANNOT_READ_INIT_DATA 0x0066 -#define PXENV_STATUS_UNDI_BAD_MAC_ADDRESS 0x0067 -#define PXENV_STATUS_UNDI_BAD_EEPROM_CHECKSUM 0x0068 -#define PXENV_STATUS_UNDI_ERROR_SETTING_ISR 0x0069 -#define PXENV_STATUS_UNDI_INVALID_STATE 0x006a -#define PXENV_STATUS_UNDI_TRANSMIT_ERROR 0x006b -#define PXENV_STATUS_UNDI_INVALID_PARAMETER 0x006c - -/* ROM and NBP bootstrap errors (0x0070 to 0x007f) */ -#define PXENV_STATUS_BSTRAP_PROMPT_MENU 0x0074 -#define PXENV_STATUS_BSTRAP_MCAST_ADDR 0x0076 -#define PXENV_STATUS_BSTRAP_MISSING_LIST 0x0077 -#define PXENV_STATUS_BSTRAP_NO_RESPONSE 0x0078 -#define PXENV_STATUS_BSTRAP_FILE_TOO_BIG 0x0079 - -/* Environment NBP errors (0x0080 to 0x008f) */ - -/* Reserved errors (0x0090 to 0x009f) */ - -/* Miscellaneous errors (0x00a0 to 0x00af) */ -#define PXENV_STATUS_BINL_CANCELED_BY_KEYSTROKE 0x00a0 -#define PXENV_STATUS_BINL_NO_PXE_SERVER 0x00a1 -#define PXENV_STATUS_NOT_AVAILABLE_IN_PMODE 0x00a2 -#define PXENV_STATUS_NOT_AVAILABLE_IN_RMODE 0x00a3 - -/* BUSD errors (0x00b0 to 0x00bf) */ -#define PXENV_STATUS_BUSD_DEVICE_NOT_SUPPORTED 0x00b0 - -/* Loader errors (0x00c0 to 0x00cf) */ -#define PXENV_STATUS_LOADER_NO_FREE_BASE_MEMORY 0x00c0 -#define PXENV_STATUS_LOADER_NO_BC_ROMID 0x00c1 -#define PXENV_STATUS_LOADER_BAD_BC_ROMID 0x00c2 -#define PXENV_STATUS_LOADER_BAD_BC_RUNTIME_IMAGE 0x00c3 -#define PXENV_STATUS_LOADER_NO_UNDI_ROMID 0x00c4 -#define PXENV_STATUS_LOADER_BAD_UNDI_ROMID 0x00c5 -#define PXENV_STATUS_LOADER_BAD_UNDI_DRIVER_IMAGE 0x00c6 -#define PXENV_STATUS_LOADER_NO_PXE_STRUCT 0x00c8 -#define PXENV_STATUS_LOADER_NO_PXENV_STRUCT 0x00c9 -#define PXENV_STATUS_LOADER_UNDI_START 0x00ca -#define PXENV_STATUS_LOADER_BC_START 0x00cb - -/** @} */ - -/** Derive PXENV_STATUS code from iPXE error number */ -#define PXENV_STATUS( rc ) ( (-(rc)) & 0x00ff ) - -#endif /* PXE_ERROR_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/pxe_types.h b/qemu/roms/ipxe/src/arch/i386/include/pxe_types.h deleted file mode 100644 index 483666e33..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/pxe_types.h +++ /dev/null @@ -1,127 +0,0 @@ -#ifndef PXE_TYPES_H -#define PXE_TYPES_H - -/** @file - * - * PXE data types - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdint.h> -#include <errno.h> /* PXE status codes */ - -/** @addtogroup pxe Preboot eXecution Environment (PXE) API - * @{ - */ - -/** @defgroup pxe_types PXE data types - * - * Basic PXE data types such as #UINT16_t, #ADDR32_t, #SEGSEL_t etc. - * - * These definitions are based on Table 1-1 ("Data Type Definitions") - * in the Intel PXE specification version 2.1. They have been - * generalised to non-x86 architectures where possible. - * - * @{ - */ - -/** An 8-bit unsigned integer */ -typedef uint8_t UINT8_t; - -/** A 16-bit unsigned integer */ -typedef uint16_t UINT16_t; - -/** A 32-bit unsigned integer */ -typedef uint32_t UINT32_t; - -/** A PXE exit code. - * - * Permitted values are #PXENV_EXIT_SUCCESS and #PXENV_EXIT_FAILURE. - * - */ -typedef UINT16_t PXENV_EXIT_t; -#define PXENV_EXIT_SUCCESS 0x0000 /**< No error occurred */ -#define PXENV_EXIT_FAILURE 0x0001 /**< An error occurred */ - -/** A PXE status code. - * - * Status codes are defined in errno.h. - * - */ -typedef UINT16_t PXENV_STATUS_t; - -/** An IPv4 address. - * - * @note This data type is in network (big-endian) byte order. - * - */ -typedef UINT32_t IP4_t; - -/** A UDP port. - * - * @note This data type is in network (big-endian) byte order. - * - */ -typedef UINT16_t UDP_PORT_t; - -/** Maximum length of a MAC address */ -#define MAC_ADDR_LEN 16 - -/** A MAC address */ -typedef UINT8_t MAC_ADDR_t[MAC_ADDR_LEN]; - -#ifndef HAVE_ARCH_ADDR32 -/** A physical address. - * - * For x86, this is a 32-bit physical address, and is therefore - * limited to the low 4GB. - * - */ -typedef UINT32_t ADDR32_t; -#endif - -#ifndef HAVE_ARCH_SEGSEL -/** A segment selector. - * - * For x86, this is a real mode segment (0x0000-0xffff), or a - * protected-mode segment selector, such as could be loaded into a - * segment register. - * - */ -typedef UINT16_t SEGSEL_t; -#endif - -#ifndef HAVE_ARCH_OFF16 -/** An offset within a segment identified by #SEGSEL - * - * For x86, this is a 16-bit offset. - * - */ -typedef UINT16_t OFF16_t; -#endif - -/** A segment:offset address - * - * For x86, this is a 16-bit real-mode or protected-mode - * segment:offset address. - * - */ -typedef struct s_SEGOFF16 { - OFF16_t offset; /**< Offset within the segment */ - SEGSEL_t segment; /**< Segment selector */ -} __attribute__ (( packed )) SEGOFF16_t; - -/** A segment descriptor */ -typedef struct s_SEGDESC { - SEGSEL_t segment_address; /**< Segment selector */ - ADDR32_t Physical_address; /**< Segment base address */ - OFF16_t Seg_size; /**< Size of the segment */ -} __attribute__ (( packed )) SEGDESC_t; - -/** @} */ /* pxe_types */ - -/** @} */ /* pxe */ - -#endif /* PXE_TYPES_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/pxeparent.h b/qemu/roms/ipxe/src/arch/i386/include/pxeparent.h deleted file mode 100644 index b31e24a76..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/pxeparent.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef PXEPARENT_H -#define PXEPARENT_H - -FILE_LICENCE ( GPL2_OR_LATER ); - -#include <pxe_types.h> - -extern int pxeparent_call ( SEGOFF16_t entry, unsigned int function, - void *params, size_t params_len ); - -#endif diff --git a/qemu/roms/ipxe/src/arch/i386/include/realmode.h b/qemu/roms/ipxe/src/arch/i386/include/realmode.h deleted file mode 100644 index 4defd3b97..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/realmode.h +++ /dev/null @@ -1,139 +0,0 @@ -#ifndef REALMODE_H -#define REALMODE_H - -#include <stdint.h> -#include <registers.h> -#include <ipxe/uaccess.h> - -/* - * Data structures and type definitions - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/* - * Declaration of variables in .data16 - * - * To place a variable in the .data16 segment, declare it using the - * pattern: - * - * int __data16 ( foo ); - * #define foo __use_data16 ( foo ); - * - * extern uint32_t __data16 ( bar ); - * #define bar __use_data16 ( bar ); - * - * static long __data16 ( baz ) = 0xff000000UL; - * #define baz __use_data16 ( baz ); - * - * i.e. take a normal declaration, add __data16() around the variable - * name, and add a line saying "#define <name> __use_data16 ( <name> ) - * - * You can then access them just like any other variable, for example - * - * int x = foo + bar; - * - * This magic is achieved at a cost of only around 7 extra bytes per - * group of accesses to .data16 variables. When using KEEP_IT_REAL, - * there is no extra cost. - * - * You should place variables in .data16 when they need to be accessed - * by real-mode code. Real-mode assembly (e.g. as created by - * REAL_CODE()) can access these variables via the usual data segment. - * You can therefore write something like - * - * static uint16_t __data16 ( foo ); - * #define foo __use_data16 ( foo ) - * - * int bar ( void ) { - * __asm__ __volatile__ ( REAL_CODE ( "int $0xff\n\t" - * "movw %ax, foo" ) - * : : ); - * return foo; - * } - * - * Variables may also be placed in .text16 using __text16 and - * __use_text16. Some variables (e.g. chained interrupt vectors) fit - * most naturally in .text16; most should be in .data16. - * - * If you have only a pointer to a magic symbol within .data16 or - * .text16, rather than the symbol itself, you can attempt to extract - * the underlying symbol name using __from_data16() or - * __from_text16(). This is not for the faint-hearted; check the - * assembler output to make sure that it's doing the right thing. - */ - -/** - * Convert segment:offset address to user buffer - * - * @v segment Real-mode segment - * @v offset Real-mode offset - * @ret buffer User buffer - */ -static inline __always_inline userptr_t -real_to_user ( unsigned int segment, unsigned int offset ) { - return ( phys_to_user ( ( segment << 4 ) + offset ) ); -} - -/** - * Copy data to base memory - * - * @v dest_seg Destination segment - * @v dest_off Destination offset - * @v src Source - * @v len Length - */ -static inline __always_inline void -copy_to_real ( unsigned int dest_seg, unsigned int dest_off, - void *src, size_t n ) { - copy_to_user ( real_to_user ( dest_seg, dest_off ), 0, src, n ); -} - -/** - * Copy data to base memory - * - * @v dest Destination - * @v src_seg Source segment - * @v src_off Source offset - * @v len Length - */ -static inline __always_inline void -copy_from_real ( void *dest, unsigned int src_seg, - unsigned int src_off, size_t n ) { - copy_from_user ( dest, real_to_user ( src_seg, src_off ), 0, n ); -} - -/** - * Write a single variable to base memory - * - * @v var Variable to write - * @v dest_seg Destination segment - * @v dest_off Destination offset - */ -#define put_real( var, dest_seg, dest_off ) \ - copy_to_real ( (dest_seg), (dest_off), &(var), sizeof (var) ) - -/** - * Read a single variable from base memory - * - * @v var Variable to read - * @v src_seg Source segment - * @v src_off Source offset - */ -#define get_real( var, src_seg, src_off ) \ - copy_from_real ( &(var), (src_seg), (src_off), sizeof (var) ) - -/* - * REAL_CODE ( asm_code_str ) - * - * This can be used in inline assembly to create a fragment of code - * that will execute in real mode. For example: to write a character - * to the BIOS console using INT 10, you would do something like: - * - * __asm__ __volatile__ ( REAL_CODE ( "int $0x16" ) - * : "=a" ( character ) : "a" ( 0x0000 ) ); - * - */ - -#endif /* REALMODE_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/registers.h b/qemu/roms/ipxe/src/arch/i386/include/registers.h deleted file mode 100644 index d9aa3c376..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/registers.h +++ /dev/null @@ -1,198 +0,0 @@ -#ifndef REGISTERS_H -#define REGISTERS_H - -/** @file - * - * i386 registers. - * - * This file defines data structures that allow easy access to i386 - * register dumps. - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdint.h> - -/** - * A 16-bit general register. - * - * This type encapsulates a 16-bit register such as %ax, %bx, %cx, - * %dx, %si, %di, %bp or %sp. - * - */ -typedef union { - struct { - union { - uint8_t l; - uint8_t byte; - }; - uint8_t h; - } __attribute__ (( packed )); - uint16_t word; -} __attribute__ (( packed )) reg16_t; - -/** - * A 32-bit general register. - * - * This type encapsulates a 32-bit register such as %eax, %ebx, %ecx, - * %edx, %esi, %edi, %ebp or %esp. - * - */ -typedef union { - struct { - union { - uint8_t l; - uint8_t byte; - }; - uint8_t h; - } __attribute__ (( packed )); - uint16_t word; - uint32_t dword; -} __attribute__ (( packed )) reg32_t; - -/** - * A 32-bit general register dump. - * - * This is the data structure that is created on the stack by the @c - * pushal instruction, and can be read back using the @c popal - * instruction. - * - */ -struct i386_regs { - union { - uint16_t di; - uint32_t edi; - }; - union { - uint16_t si; - uint32_t esi; - }; - union { - uint16_t bp; - uint32_t ebp; - }; - union { - uint16_t sp; - uint32_t esp; - }; - union { - struct { - uint8_t bl; - uint8_t bh; - } __attribute__ (( packed )); - uint16_t bx; - uint32_t ebx; - }; - union { - struct { - uint8_t dl; - uint8_t dh; - } __attribute__ (( packed )); - uint16_t dx; - uint32_t edx; - }; - union { - struct { - uint8_t cl; - uint8_t ch; - } __attribute__ (( packed )); - uint16_t cx; - uint32_t ecx; - }; - union { - struct { - uint8_t al; - uint8_t ah; - } __attribute__ (( packed )); - uint16_t ax; - uint32_t eax; - }; -} __attribute__ (( packed )); - -/** - * A segment register dump. - * - * The i386 has no equivalent of the @c pushal or @c popal - * instructions for the segment registers. We adopt the convention of - * always using the sequences - * - * @code - * - * pushw %gs ; pushw %fs ; pushw %es ; pushw %ds ; pushw %ss ; pushw %cs - * - * @endcode - * - * and - * - * @code - * - * addw $4, %sp ; popw %ds ; popw %es ; popw %fs ; popw %gs - * - * @endcode - * - * This is the data structure that is created and read back by these - * instruction sequences. - * - */ -struct i386_seg_regs { - uint16_t cs; - uint16_t ss; - uint16_t ds; - uint16_t es; - uint16_t fs; - uint16_t gs; -} __attribute__ (( packed )); - -/** - * A full register dump. - * - * This data structure is created by the instructions - * - * @code - * - * pushfl - * pushal - * pushw %gs ; pushw %fs ; pushw %es ; pushw %ds ; pushw %ss ; pushw %cs - * - * @endcode - * - * and can be read back using the instructions - * - * @code - * - * addw $4, %sp ; popw %ds ; popw %es ; popw %fs ; popw %gs - * popal - * popfl - * - * @endcode - * - * prot_call() and kir_call() create this data structure on the stack - * and pass in a pointer to this structure. - * - */ -struct i386_all_regs { - struct i386_seg_regs segs; - struct i386_regs regs; - uint32_t flags; -} __attribute__ (( packed )); - -/* Flags */ -#define CF ( 1 << 0 ) -#define PF ( 1 << 2 ) -#define AF ( 1 << 4 ) -#define ZF ( 1 << 6 ) -#define SF ( 1 << 7 ) -#define OF ( 1 << 11 ) - -/* Segment:offset structure. Note that the order within the structure - * is offset:segment. - */ -struct segoff { - uint16_t offset; - uint16_t segment; -} __attribute__ (( packed )); - -typedef struct segoff segoff_t; - -#endif /* REGISTERS_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/rtc.h b/qemu/roms/ipxe/src/arch/i386/include/rtc.h deleted file mode 100644 index 6294b63e3..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/rtc.h +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef _RTC_H -#define _RTC_H - -/** @file - * - * CMOS Real-Time Clock (RTC) - * - * The CMOS/RTC registers are documented (with varying degrees of - * accuracy and consistency) at - * - * http://www.nondot.org/sabre/os/files/MiscHW/RealtimeClockFAQ.txt - * http://wiki.osdev.org/RTC - * http://wiki.osdev.org/CMOS - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <pic8259.h> - -/** RTC IRQ */ -#define RTC_IRQ 8 - -/** RTC interrupt vector */ -#define RTC_INT IRQ_INT ( RTC_IRQ ) - -/** CMOS/RTC address (and NMI) register */ -#define CMOS_ADDRESS 0x70 - -/** NMI disable bit */ -#define CMOS_DISABLE_NMI 0x80 - -/** CMOS/RTC data register */ -#define CMOS_DATA 0x71 - -/** RTC seconds */ -#define RTC_SEC 0x00 - -/** RTC minutes */ -#define RTC_MIN 0x02 - -/** RTC hours */ -#define RTC_HOUR 0x04 - -/** RTC weekday */ -#define RTC_WDAY 0x06 - -/** RTC day of month */ -#define RTC_MDAY 0x07 - -/** RTC month */ -#define RTC_MON 0x08 - -/** RTC year */ -#define RTC_YEAR 0x09 - -/** RTC status register A */ -#define RTC_STATUS_A 0x0a - -/** RTC update in progress bit */ -#define RTC_STATUS_A_UPDATE_IN_PROGRESS 0x80 - -/** RTC status register B */ -#define RTC_STATUS_B 0x0b - -/** RTC 24 hour format bit */ -#define RTC_STATUS_B_24_HOUR 0x02 - -/** RTC binary mode bit */ -#define RTC_STATUS_B_BINARY 0x04 - -/** RTC Periodic Interrupt Enabled bit */ -#define RTC_STATUS_B_PIE 0x40 - -/** RTC status register C */ -#define RTC_STATUS_C 0x0c - -/** RTC status register D */ -#define RTC_STATUS_D 0x0d - -/** CMOS default address */ -#define CMOS_DEFAULT_ADDRESS RTC_STATUS_D - -#endif /* _RTC_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/sdi.h b/qemu/roms/ipxe/src/arch/i386/include/sdi.h deleted file mode 100644 index 806c3f194..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/sdi.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef _SDI_H -#define _SDI_H - -/** @file - * - * System Deployment Image (SDI) - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/** SDI image header */ -struct sdi_header { - /** Signature */ - uint32_t magic; - /** Version (as an ASCII string) */ - uint32_t version; - /** Reserved */ - uint8_t reserved[8]; - /** Boot code offset */ - uint64_t boot_offset; - /** Boot code size */ - uint64_t boot_size; -} __attribute__ (( packed )); - -/** SDI image signature */ -#define SDI_MAGIC \ - ( ( '$' << 0 ) | ( 'S' << 8 ) | ( 'D' << 16 ) | ( 'I' << 24 ) ) - -/** SDI boot segment */ -#define SDI_BOOT_SEG 0x0000 - -/** SDI boot offset */ -#define SDI_BOOT_OFF 0x7c00 - -/** Constant to binary-OR with physical address of SDI image */ -#define SDI_WTF 0x41 - -#endif /* _SDI_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/setjmp.h b/qemu/roms/ipxe/src/arch/i386/include/setjmp.h deleted file mode 100644 index fe1a9ef4d..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/setjmp.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef _SETJMP_H -#define _SETJMP_H - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdint.h> -#include <realmode.h> - -/** A jump buffer */ -typedef struct { - /** Saved return address */ - uint32_t retaddr; - /** Saved stack pointer */ - uint32_t stack; - /** Saved %ebx */ - uint32_t ebx; - /** Saved %esi */ - uint32_t esi; - /** Saved %edi */ - uint32_t edi; - /** Saved %ebp */ - uint32_t ebp; -} jmp_buf[1]; - -/** A real-mode-extended jump buffer */ -typedef struct { - /** Jump buffer */ - jmp_buf env; - /** Real-mode stack pointer */ - segoff_t rm_stack; -} rmjmp_buf[1]; - -extern int __asmcall __attribute__ (( returns_twice )) -setjmp ( jmp_buf env ); - -extern void __asmcall __attribute__ (( noreturn )) -longjmp ( jmp_buf env, int val ); - -#define rmsetjmp( _env ) ( { \ - (_env)->rm_stack.segment = rm_ss; \ - (_env)->rm_stack.offset = rm_sp; \ - setjmp ( (_env)->env ); } ) \ - -#define rmlongjmp( _env, _val ) do { \ - rm_ss = (_env)->rm_stack.segment; \ - rm_sp = (_env)->rm_stack.offset; \ - longjmp ( (_env)->env, (_val) ); \ - } while ( 0 ) - -#endif /* _SETJMP_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/undi.h b/qemu/roms/ipxe/src/arch/i386/include/undi.h deleted file mode 100644 index 7a5624f93..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/undi.h +++ /dev/null @@ -1,106 +0,0 @@ -#ifndef _UNDI_H -#define _UNDI_H - -/** @file - * - * UNDI driver - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#ifndef ASSEMBLY - -#include <ipxe/device.h> -#include <pxe_types.h> - -/** An UNDI device - * - * This structure is used by assembly code as well as C; do not alter - * this structure without editing pxeprefix.S to match. - */ -struct undi_device { - /** PXENV+ structure address */ - SEGOFF16_t pxenv; - /** !PXE structure address */ - SEGOFF16_t ppxe; - /** Entry point */ - SEGOFF16_t entry; - /** Free base memory after load */ - UINT16_t fbms; - /** Free base memory prior to load */ - UINT16_t restore_fbms; - /** PCI bus:dev.fn, or @c UNDI_NO_PCI_BUSDEVFN */ - UINT16_t pci_busdevfn; - /** ISAPnP card select number, or @c UNDI_NO_ISAPNP_CSN */ - UINT16_t isapnp_csn; - /** ISAPnP read port, or @c UNDI_NO_ISAPNP_READ_PORT */ - UINT16_t isapnp_read_port; - /** PCI vendor ID - * - * Filled in only for the preloaded UNDI device by pxeprefix.S - */ - UINT16_t pci_vendor; - /** PCI device ID - * - * Filled in only for the preloaded UNDI device by pxeprefix.S - */ - UINT16_t pci_device; - /** Flags - * - * This is the bitwise OR of zero or more UNDI_FL_XXX - * constants. - */ - UINT16_t flags; - - /** Generic device */ - struct device dev; - /** Driver-private data - * - * Use undi_set_drvdata() and undi_get_drvdata() to access this - * field. - */ - void *priv; -} __attribute__ (( packed )); - -/** - * Set UNDI driver-private data - * - * @v undi UNDI device - * @v priv Private data - */ -static inline void undi_set_drvdata ( struct undi_device *undi, void *priv ) { - undi->priv = priv; -} - -/** - * Get UNDI driver-private data - * - * @v undi UNDI device - * @ret priv Private data - */ -static inline void * undi_get_drvdata ( struct undi_device *undi ) { - return undi->priv; -} - -#endif /* ASSEMBLY */ - -/** PCI bus:dev.fn field is invalid */ -#define UNDI_NO_PCI_BUSDEVFN 0xffff - -/** ISAPnP card select number field is invalid */ -#define UNDI_NO_ISAPNP_CSN 0xffff - -/** ISAPnP read port field is invalid */ -#define UNDI_NO_ISAPNP_READ_PORT 0xffff - -/** UNDI flag: START_UNDI has been called */ -#define UNDI_FL_STARTED 0x0001 - -/** UNDI flag: UNDI_STARTUP and UNDI_INITIALIZE have been called */ -#define UNDI_FL_INITIALIZED 0x0002 - -/** UNDI flag: keep stack resident */ -#define UNDI_FL_KEEP_ALL 0x0004 - -#endif /* _UNDI_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/undiload.h b/qemu/roms/ipxe/src/arch/i386/include/undiload.h deleted file mode 100644 index 235e7a79e..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/undiload.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef _UNDILOAD_H -#define _UNDILOAD_H - -/** @file - * - * UNDI load/unload - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -struct undi_device; -struct undi_rom; - -extern int undi_load ( struct undi_device *undi, struct undi_rom *undirom ); -extern int undi_unload ( struct undi_device *undi ); - -/** - * Call UNDI loader to create a pixie - * - * @v undi UNDI device - * @v undirom UNDI ROM - * @v pci_busdevfn PCI bus:dev.fn - * @ret rc Return status code - */ -static inline int undi_load_pci ( struct undi_device *undi, - struct undi_rom *undirom, - unsigned int pci_busdevfn ) { - undi->pci_busdevfn = pci_busdevfn; - undi->isapnp_csn = UNDI_NO_ISAPNP_CSN; - undi->isapnp_read_port = UNDI_NO_ISAPNP_READ_PORT; - return undi_load ( undi, undirom ); -} - -#endif /* _UNDILOAD_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/undinet.h b/qemu/roms/ipxe/src/arch/i386/include/undinet.h deleted file mode 100644 index 2798c4466..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/undinet.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef _UNDINET_H -#define _UNDINET_H - -/** @file - * - * UNDI network device driver - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -struct undi_device; - -extern int undinet_probe ( struct undi_device *undi ); -extern void undinet_remove ( struct undi_device *undi ); - -#endif /* _UNDINET_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/undipreload.h b/qemu/roms/ipxe/src/arch/i386/include/undipreload.h deleted file mode 100644 index 57f493cec..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/undipreload.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _UNDIPRELOAD_H -#define _UNDIPRELOAD_H - -/** @file - * - * Preloaded UNDI stack - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <realmode.h> -#include <undi.h> - -extern struct undi_device __data16 ( preloaded_undi ); -#define preloaded_undi __use_data16 ( preloaded_undi ) - -#endif /* _UNDIPRELOAD_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/undirom.h b/qemu/roms/ipxe/src/arch/i386/include/undirom.h deleted file mode 100644 index 1c530118d..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/undirom.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef _UNDIROM_H -#define _UNDIROM_H - -/** @file - * - * UNDI expansion ROMs - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <pxe_types.h> - -/** An UNDI PCI device ID */ -struct undi_pci_device_id { - /** PCI vendor ID */ - unsigned int vendor_id; - /** PCI device ID */ - unsigned int device_id; -}; - -/** An UNDI device ID */ -union undi_device_id { - /** PCI device ID */ - struct undi_pci_device_id pci; -}; - -/** An UNDI ROM */ -struct undi_rom { - /** List of UNDI ROMs */ - struct list_head list; - /** ROM segment address */ - unsigned int rom_segment; - /** UNDI loader entry point */ - SEGOFF16_t loader_entry; - /** Code segment size */ - size_t code_size; - /** Data segment size */ - size_t data_size; - /** Bus type - * - * Values are as used by @c PXENV_UNDI_GET_NIC_TYPE - */ - unsigned int bus_type; - /** Device ID */ - union undi_device_id bus_id; -}; - -extern struct undi_rom * undirom_find_pci ( unsigned int vendor_id, - unsigned int device_id, - unsigned int rombase ); - -#endif /* _UNDIROM_H */ diff --git a/qemu/roms/ipxe/src/arch/i386/include/vga.h b/qemu/roms/ipxe/src/arch/i386/include/vga.h deleted file mode 100644 index 01fc39d86..000000000 --- a/qemu/roms/ipxe/src/arch/i386/include/vga.h +++ /dev/null @@ -1,228 +0,0 @@ -/* - * - * modified - * by Steve M. Gehlbach <steve@kesa.com> - * - * Originally from linux/drivers/video/vga16.c by - * Ben Pfaff <pfaffben@debian.org> and Petr Vandrovec <VANDROVE@vc.cvut.cz> - * Copyright 1999 Ben Pfaff <pfaffben@debian.org> and Petr Vandrovec <VANDROVE@vc.cvut.cz> - * Based on VGA info at http://www.goodnet.com/~tinara/FreeVGA/home.htm - * Based on VESA framebuffer (c) 1998 Gerd Knorr <kraxel@goldbach.in-berlin.de> - * - */ - -#ifndef VGA_H_INCL -#define VGA_H_INCL 1 - -//#include <cpu/p5/io.h> - -#define u8 unsigned char -#define u16 unsigned short -#define u32 unsigned int -#define __u32 u32 - -#define VERROR -1 -#define CHAR_HEIGHT 16 -#define LINES 25 -#define COLS 80 - -// macros for writing to vga regs -#define write_crtc(data,addr) outb(addr,CRT_IC); outb(data,CRT_DC) -#define write_att(data,addr) inb(IS1_RC); inb(0x80); outb(addr,ATT_IW); inb(0x80); outb(data,ATT_IW); inb(0x80) -#define write_seq(data,addr) outb(addr,SEQ_I); outb(data,SEQ_D) -#define write_gra(data,addr) outb(addr,GRA_I); outb(data,GRA_D) -u8 read_seq_b(u16 addr); -u8 read_gra_b(u16 addr); -u8 read_crtc_b(u16 addr); -u8 read_att_b(u16 addr); - - -#ifdef VGA_HARDWARE_FIXUP -void vga_hardware_fixup(void); -#else -#define vga_hardware_fixup() do{} while(0) -#endif - -#define SYNC_HOR_HIGH_ACT 1 /* horizontal sync high active */ -#define SYNC_VERT_HIGH_ACT 2 /* vertical sync high active */ -#define SYNC_EXT 4 /* external sync */ -#define SYNC_COMP_HIGH_ACT 8 /* composite sync high active */ -#define SYNC_BROADCAST 16 /* broadcast video timings */ - /* vtotal = 144d/288n/576i => PAL */ - /* vtotal = 121d/242n/484i => NTSC */ - -#define SYNC_ON_GREEN 32 /* sync on green */ - -#define VMODE_NONINTERLACED 0 /* non interlaced */ -#define VMODE_INTERLACED 1 /* interlaced */ -#define VMODE_DOUBLE 2 /* double scan */ -#define VMODE_MASK 255 - -#define VMODE_YWRAP 256 /* ywrap instead of panning */ -#define VMODE_SMOOTH_XPAN 512 /* smooth xpan possible (internally used) */ -#define VMODE_CONUPDATE 512 /* don't update x/yoffset */ - -/* VGA data register ports */ -#define CRT_DC 0x3D5 /* CRT Controller Data Register - color emulation */ -#define CRT_DM 0x3B5 /* CRT Controller Data Register - mono emulation */ -#define ATT_R 0x3C1 /* Attribute Controller Data Read Register */ -#define GRA_D 0x3CF /* Graphics Controller Data Register */ -#define SEQ_D 0x3C5 /* Sequencer Data Register */ - -#define MIS_R 0x3CC // Misc Output Read Register -#define MIS_W 0x3C2 // Misc Output Write Register - -#define IS1_RC 0x3DA /* Input Status Register 1 - color emulation */ -#define IS1_RM 0x3BA /* Input Status Register 1 - mono emulation */ -#define PEL_D 0x3C9 /* PEL Data Register */ -#define PEL_MSK 0x3C6 /* PEL mask register */ - -/* EGA-specific registers */ -#define GRA_E0 0x3CC /* Graphics enable processor 0 */ -#define GRA_E1 0x3CA /* Graphics enable processor 1 */ - - -/* VGA index register ports */ -#define CRT_IC 0x3D4 /* CRT Controller Index - color emulation */ -#define CRT_IM 0x3B4 /* CRT Controller Index - mono emulation */ -#define ATT_IW 0x3C0 /* Attribute Controller Index & Data Write Register */ -#define GRA_I 0x3CE /* Graphics Controller Index */ -#define SEQ_I 0x3C4 /* Sequencer Index */ -#define PEL_IW 0x3C8 /* PEL Write Index */ -#define PEL_IR 0x3C7 /* PEL Read Index */ - -/* standard VGA indexes max counts */ -#define CRTC_C 25 /* 25 CRT Controller Registers sequentially set*/ - // the remainder are not in the par array -#define ATT_C 21 /* 21 Attribute Controller Registers */ -#define GRA_C 9 /* 9 Graphics Controller Registers */ -#define SEQ_C 5 /* 5 Sequencer Registers */ -#define MIS_C 1 /* 1 Misc Output Register */ - -#define CRTC_H_TOTAL 0 -#define CRTC_H_DISP 1 -#define CRTC_H_BLANK_START 2 -#define CRTC_H_BLANK_END 3 -#define CRTC_H_SYNC_START 4 -#define CRTC_H_SYNC_END 5 -#define CRTC_V_TOTAL 6 -#define CRTC_OVERFLOW 7 -#define CRTC_PRESET_ROW 8 -#define CRTC_MAX_SCAN 9 -#define CRTC_CURSOR_START 0x0A -#define CRTC_CURSOR_END 0x0B -#define CRTC_START_HI 0x0C -#define CRTC_START_LO 0x0D -#define CRTC_CURSOR_HI 0x0E -#define CRTC_CURSOR_LO 0x0F -#define CRTC_V_SYNC_START 0x10 -#define CRTC_V_SYNC_END 0x11 -#define CRTC_V_DISP_END 0x12 -#define CRTC_OFFSET 0x13 -#define CRTC_UNDERLINE 0x14 -#define CRTC_V_BLANK_START 0x15 -#define CRTC_V_BLANK_END 0x16 -#define CRTC_MODE 0x17 -#define CRTC_LINE_COMPARE 0x18 - -#define ATC_MODE 0x10 -#define ATC_OVERSCAN 0x11 -#define ATC_PLANE_ENABLE 0x12 -#define ATC_PEL 0x13 -#define ATC_COLOR_PAGE 0x14 - -#define SEQ_CLOCK_MODE 0x01 -#define SEQ_PLANE_WRITE 0x02 -#define SEQ_CHARACTER_MAP 0x03 -#define SEQ_MEMORY_MODE 0x04 - -#define GDC_SR_VALUE 0x00 -#define GDC_SR_ENABLE 0x01 -#define GDC_COMPARE_VALUE 0x02 -#define GDC_DATA_ROTATE 0x03 -#define GDC_PLANE_READ 0x04 -#define GDC_MODE 0x05 -#define GDC_MISC 0x06 -#define GDC_COMPARE_MASK 0x07 -#define GDC_BIT_MASK 0x08 - -// text attributes -#define VGA_ATTR_CLR_RED 0x4 -#define VGA_ATTR_CLR_GRN 0x2 -#define VGA_ATTR_CLR_BLU 0x1 -#define VGA_ATTR_CLR_YEL (VGA_ATTR_CLR_RED | VGA_ATTR_CLR_GRN) -#define VGA_ATTR_CLR_CYN (VGA_ATTR_CLR_GRN | VGA_ATTR_CLR_BLU) -#define VGA_ATTR_CLR_MAG (VGA_ATTR_CLR_BLU | VGA_ATTR_CLR_RED) -#define VGA_ATTR_CLR_BLK 0 -#define VGA_ATTR_CLR_WHT (VGA_ATTR_CLR_RED | VGA_ATTR_CLR_GRN | VGA_ATTR_CLR_BLU) -#define VGA_ATTR_BNK 0x80 -#define VGA_ATTR_ITN 0x08 - -/* - * vga register parameters - * these are copied to the - * registers. - * - */ -struct vga_par { - u8 crtc[CRTC_C]; - u8 atc[ATT_C]; - u8 gdc[GRA_C]; - u8 seq[SEQ_C]; - u8 misc; // the misc register, MIS_W - u8 vss; -}; - - -/* Interpretation of offset for color fields: All offsets are from the right, - * inside a "pixel" value, which is exactly 'bits_per_pixel' wide (means: you - * can use the offset as right argument to <<). A pixel afterwards is a bit - * stream and is written to video memory as that unmodified. This implies - * big-endian byte order if bits_per_pixel is greater than 8. - */ -struct fb_bitfield { - __u32 offset; /* beginning of bitfield */ - __u32 length; /* length of bitfield */ - __u32 msb_right; /* != 0 : Most significant bit is */ - /* right */ -}; - -struct screeninfo { - __u32 xres; /* visible resolution */ - __u32 yres; - __u32 xres_virtual; /* virtual resolution */ - __u32 yres_virtual; - __u32 xoffset; /* offset from virtual to visible */ - __u32 yoffset; /* resolution */ - - __u32 bits_per_pixel; /* guess what */ - __u32 grayscale; /* != 0 Graylevels instead of colors */ - - struct fb_bitfield red; /* bitfield in fb mem if true color, */ - struct fb_bitfield green; /* else only length is significant */ - struct fb_bitfield blue; - struct fb_bitfield transp; /* transparency */ - - __u32 nonstd; /* != 0 Non standard pixel format */ - - __u32 activate; /* see FB_ACTIVATE_* */ - - __u32 height; /* height of picture in mm */ - __u32 width; /* width of picture in mm */ - - __u32 accel_flags; /* acceleration flags (hints) */ - - /* Timing: All values in pixclocks, except pixclock (of course) */ - __u32 pixclock; /* pixel clock in ps (pico seconds) */ - __u32 left_margin; /* time from sync to picture */ - __u32 right_margin; /* time from picture to sync */ - __u32 upper_margin; /* time from sync to picture */ - __u32 lower_margin; - __u32 hsync_len; /* length of horizontal sync */ - __u32 vsync_len; /* length of vertical sync */ - __u32 sync; /* sync polarity */ - __u32 vmode; /* interlaced etc */ - __u32 reserved[6]; /* Reserved for future compatibility */ -}; - -#endif diff --git a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/apm.c b/qemu/roms/ipxe/src/arch/i386/interface/pcbios/apm.c deleted file mode 100644 index 50b19cb81..000000000 --- a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/apm.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) 2013 Marin Hannache <ipxe@mareo.fr>. - * - * 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 ); - -/** - * @file - * - * Advanced Power Management - * - */ - -#include <errno.h> -#include <realmode.h> -#include <ipxe/reboot.h> - -/** - * Power off the computer using APM - * - * @ret rc Return status code - */ -static int apm_poweroff ( void ) { - uint16_t apm_version; - uint16_t apm_signature; - uint16_t apm_flags; - uint16_t carry; - - /* APM check */ - __asm__ __volatile__ ( REAL_CODE ( "int $0x15\n\t" - "adc %%edx,0\n\t" ) - : "=a" ( apm_version ), "=b" ( apm_signature ), - "=c" ( apm_flags ), "=d" ( carry ) - : "a" ( 0x5300 ), "b" ( 0x0000 ), - "d" ( 0x0000 ) ); - if ( carry ) { - DBG ( "APM not present\n" ); - return -ENOTSUP; - } - if ( apm_signature != 0x504d ) { /* signature 'PM' */ - DBG ( "APM not present\n" ); - return -ENOTSUP; - } - if ( apm_version < 0x0101 ) { /* Need version 1.1+ */ - DBG ( "APM 1.1+ not supported\n" ); - return -ENOTSUP; - } - if ( ( apm_flags & 0x8 ) == 0x8 ) { - DBG ( "APM power management disabled\n" ); - return -EPERM; - } - DBG2 ( "APM check completed\n" ); - - /* APM initialisation */ - __asm__ __volatile__ ( REAL_CODE ( "int $0x15\n\t" - "adc %%edx,0\n\t" ) - : "=d" ( carry ) - : "a" ( 0x5301 ), "b" ( 0x0000 ), - "d" ( 0x0000 ) ); - if ( carry ) { - DBG ( "APM initialisation failed\n" ); - return -EIO; - } - DBG2 ( "APM initialisation completed\n" ); - - /* Set APM driver version */ - __asm__ __volatile__ ( REAL_CODE ( "int $0x15\n\t" - "adc %%edx,0\n\t" ) - : "=d" ( carry ) - : "a" ( 0x530e ), "b" ( 0x0000 ), - "c" ( 0x0101 ), "d" ( 0x0000 ) ); - if ( carry ) { - DBG ( "APM setting driver version failed\n" ); - return -EIO; - } - DBG2 ( "APM driver version set\n" ); - - /* Setting power state to off */ - __asm__ __volatile__ ( REAL_CODE ( "int $0x15\n\t" - "adc %%edx,0\n\t" ) - : "=d" ( carry ) - : "a" ( 0x5307 ), "b" ( 0x0001 ), - "c" ( 0x0003 ), "d" ( 0x0000) ); - if ( carry ) { - DBG ( "APM setting power state failed\n" ); - return -ENOTTY; - } - - /* Should never happen */ - return -ECANCELED; -} - -PROVIDE_REBOOT ( pcbios, poweroff, apm_poweroff ); diff --git a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/bios_nap.c b/qemu/roms/ipxe/src/arch/i386/interface/pcbios/bios_nap.c deleted file mode 100644 index f1ba8297b..000000000 --- a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/bios_nap.c +++ /dev/null @@ -1,16 +0,0 @@ -#include <ipxe/nap.h> -#include <realmode.h> - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/** - * Save power by halting the CPU until the next interrupt - * - */ -static void bios_cpu_nap ( void ) { - __asm__ __volatile__ ( "sti\n\t" - "hlt\n\t" - "cli\n\t" ); -} - -PROVIDE_NAP ( pcbios, cpu_nap, bios_cpu_nap ); diff --git a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/bios_reboot.c b/qemu/roms/ipxe/src/arch/i386/interface/pcbios/bios_reboot.c deleted file mode 100644 index 10a1ecb89..000000000 --- a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/bios_reboot.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2010 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 ); - -/** @file - * - * Standard PC-BIOS reboot mechanism - * - */ - -#include <ipxe/reboot.h> -#include <realmode.h> -#include <bios.h> - -/** - * Reboot system - * - * @v warm Perform a warm reboot - */ -static void bios_reboot ( int warm ) { - uint16_t flag; - - /* Configure BIOS for cold/warm reboot */ - flag = ( warm ? BDA_REBOOT_WARM : 0 ); - put_real ( flag, BDA_SEG, BDA_REBOOT ); - - /* Jump to system reset vector */ - __asm__ __volatile__ ( REAL_CODE ( "ljmp $0xf000, $0xfff0" ) : : ); -} - -PROVIDE_REBOOT ( pcbios, reboot, bios_reboot ); diff --git a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/bios_smbios.c b/qemu/roms/ipxe/src/arch/i386/interface/pcbios/bios_smbios.c deleted file mode 100644 index a8c0fc325..000000000 --- a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/bios_smbios.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 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 <string.h> -#include <errno.h> -#include <assert.h> -#include <ipxe/uaccess.h> -#include <ipxe/smbios.h> -#include <realmode.h> -#include <pnpbios.h> - -/** @file - * - * System Management BIOS - * - */ - -/** - * Find SMBIOS - * - * @v smbios SMBIOS entry point descriptor structure to fill in - * @ret rc Return status code - */ -static int bios_find_smbios ( struct smbios *smbios ) { - struct smbios_entry entry; - int rc; - - /* Scan through BIOS segment to find SMBIOS entry point */ - if ( ( rc = find_smbios_entry ( real_to_user ( BIOS_SEG, 0 ), 0x10000, - &entry ) ) != 0 ) - return rc; - - /* Fill in entry point descriptor structure */ - smbios->address = phys_to_user ( entry.smbios_address ); - smbios->len = entry.smbios_len; - smbios->count = entry.smbios_count; - smbios->version = SMBIOS_VERSION ( entry.major, entry.minor ); - - return 0; -} - -PROVIDE_SMBIOS ( pcbios, find_smbios, bios_find_smbios ); diff --git a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/bios_timer.c b/qemu/roms/ipxe/src/arch/i386/interface/pcbios/bios_timer.c deleted file mode 100644 index 3299c9aae..000000000 --- a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/bios_timer.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 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 ); - -/** @file - * - * BIOS timer - * - */ - -#include <ipxe/timer.h> -#include <realmode.h> -#include <bios.h> - -/** - * Get current system time in ticks - * - * @ret ticks Current time, in ticks - * - * Use direct memory access to BIOS variables, longword 0040:006C - * (ticks today) and byte 0040:0070 (midnight crossover flag) instead - * of calling timeofday BIOS interrupt. - */ -static unsigned long bios_currticks ( void ) { - static int days = 0; - uint32_t ticks; - uint8_t midnight; - - /* Re-enable interrupts so that the timer interrupt can occur */ - __asm__ __volatile__ ( "sti\n\t" - "nop\n\t" - "nop\n\t" - "cli\n\t" ); - - get_real ( ticks, BDA_SEG, 0x006c ); - get_real ( midnight, BDA_SEG, 0x0070 ); - - if ( midnight ) { - midnight = 0; - put_real ( midnight, BDA_SEG, 0x0070 ); - days += 0x1800b0; - } - - return ( days + ticks ); -} - -PROVIDE_TIMER_INLINE ( pcbios, udelay ); -PROVIDE_TIMER ( pcbios, currticks, bios_currticks ); -PROVIDE_TIMER_INLINE ( pcbios, ticks_per_sec ); diff --git a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/biosint.c b/qemu/roms/ipxe/src/arch/i386/interface/pcbios/biosint.c deleted file mode 100644 index 3b8e80438..000000000 --- a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/biosint.c +++ /dev/null @@ -1,92 +0,0 @@ -#include <errno.h> -#include <realmode.h> -#include <biosint.h> - -/** - * @file BIOS interrupts - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/** - * Hook INT vector - * - * @v interrupt INT number - * @v handler Offset within .text16 to interrupt handler - * @v chain_vector Vector for chaining to previous handler - * - * Hooks in an i386 INT handler. The handler itself must reside - * within the .text16 segment. @c chain_vector will be filled in with - * the address of the previously-installed handler for this interrupt; - * the handler should probably exit by ljmping via this vector. - */ -void hook_bios_interrupt ( unsigned int interrupt, unsigned int handler, - struct segoff *chain_vector ) { - struct segoff vector = { - .segment = rm_cs, - .offset = handler, - }; - - DBG ( "Hooking INT %#02x to %04x:%04x\n", - interrupt, rm_cs, handler ); - - if ( ( chain_vector->segment != 0 ) || - ( chain_vector->offset != 0 ) ) { - /* Already hooked; do nothing */ - DBG ( "...already hooked\n" ); - return; - } - - copy_from_real ( chain_vector, 0, ( interrupt * 4 ), - sizeof ( *chain_vector ) ); - DBG ( "...chaining to %04x:%04x\n", - chain_vector->segment, chain_vector->offset ); - if ( DBG_LOG ) { - char code[64]; - copy_from_real ( code, chain_vector->segment, - chain_vector->offset, sizeof ( code ) ); - DBG_HDA ( *chain_vector, code, sizeof ( code ) ); - } - - copy_to_real ( 0, ( interrupt * 4 ), &vector, sizeof ( vector ) ); - hooked_bios_interrupts++; -} - -/** - * Unhook INT vector - * - * @v interrupt INT number - * @v handler Offset within .text16 to interrupt handler - * @v chain_vector Vector containing address of previous handler - * - * Unhooks an i386 interrupt handler hooked by hook_i386_vector(). - * Note that this operation may fail, if some external code has hooked - * the vector since we hooked in our handler. If it fails, it means - * that it is not possible to unhook our handler, and we must leave it - * (and its chaining vector) resident in memory. - */ -int unhook_bios_interrupt ( unsigned int interrupt, unsigned int handler, - struct segoff *chain_vector ) { - struct segoff vector; - - DBG ( "Unhooking INT %#02x from %04x:%04x\n", - interrupt, rm_cs, handler ); - - copy_from_real ( &vector, 0, ( interrupt * 4 ), sizeof ( vector ) ); - if ( ( vector.segment != rm_cs ) || ( vector.offset != handler ) ) { - DBG ( "...cannot unhook; vector points to %04x:%04x\n", - vector.segment, vector.offset ); - return -EBUSY; - } - - DBG ( "...restoring to %04x:%04x\n", - chain_vector->segment, chain_vector->offset ); - copy_to_real ( 0, ( interrupt * 4 ), chain_vector, - sizeof ( *chain_vector ) ); - - chain_vector->segment = 0; - chain_vector->offset = 0; - hooked_bios_interrupts--; - return 0; -} diff --git a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/int13.c b/qemu/roms/ipxe/src/arch/i386/interface/pcbios/int13.c deleted file mode 100644 index f0450da90..000000000 --- a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/int13.c +++ /dev/null @@ -1,1993 +0,0 @@ -/* - * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 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 <limits.h> -#include <byteswap.h> -#include <errno.h> -#include <assert.h> -#include <ipxe/list.h> -#include <ipxe/blockdev.h> -#include <ipxe/io.h> -#include <ipxe/open.h> -#include <ipxe/uri.h> -#include <ipxe/process.h> -#include <ipxe/xfer.h> -#include <ipxe/retry.h> -#include <ipxe/timer.h> -#include <ipxe/acpi.h> -#include <ipxe/sanboot.h> -#include <ipxe/device.h> -#include <ipxe/pci.h> -#include <ipxe/iso9660.h> -#include <ipxe/eltorito.h> -#include <realmode.h> -#include <bios.h> -#include <biosint.h> -#include <bootsector.h> -#include <int13.h> - -/** @file - * - * INT 13 emulation - * - * This module provides a mechanism for exporting block devices via - * the BIOS INT 13 disk interrupt interface. - * - */ - -/** - * Overall timeout for INT 13 commands (independent of underlying device - * - * Underlying devices should ideally never become totally stuck. - * However, if they do, then the INT 13 mechanism provides no means - * for the caller to cancel the operation, and the machine appears to - * hang. Use an overall timeout for all commands to avoid this - * problem and bounce timeout failures to the caller. - */ -#define INT13_COMMAND_TIMEOUT ( 15 * TICKS_PER_SEC ) - -/** An INT 13 emulated drive */ -struct int13_drive { - /** Reference count */ - struct refcnt refcnt; - /** List of all registered drives */ - struct list_head list; - - /** Block device URI */ - struct uri *uri; - /** Underlying block device interface */ - struct interface block; - - /** BIOS in-use drive number (0x00-0xff) */ - unsigned int drive; - /** BIOS natural drive number (0x00-0xff) - * - * This is the drive number that would have been assigned by - * 'naturally' appending the drive to the end of the BIOS - * drive list. - * - * If the emulated drive replaces a preexisting drive, this is - * the drive number that the preexisting drive gets remapped - * to. - */ - unsigned int natural_drive; - - /** Block device capacity */ - struct block_device_capacity capacity; - /** INT 13 emulated blocksize shift - * - * To allow for emulation of CD-ROM access, this represents - * the left-shift required to translate from INT 13 blocks to - * underlying blocks. - */ - unsigned int blksize_shift; - - /** Number of cylinders - * - * The cylinder number field in an INT 13 call is ten bits - * wide, giving a maximum of 1024 cylinders. Conventionally, - * when the 7.8GB limit of a CHS address is exceeded, it is - * the number of cylinders that is increased beyond the - * addressable limit. - */ - unsigned int cylinders; - /** Number of heads - * - * The head number field in an INT 13 call is eight bits wide, - * giving a maximum of 256 heads. However, apparently all - * versions of MS-DOS up to and including Win95 fail with 256 - * heads, so the maximum encountered in practice is 255. - */ - unsigned int heads; - /** Number of sectors per track - * - * The sector number field in an INT 13 call is six bits wide, - * giving a maximum of 63 sectors, since sector numbering - * (unlike head and cylinder numbering) starts at 1, not 0. - */ - unsigned int sectors_per_track; - - /** Drive is a CD-ROM */ - int is_cdrom; - /** Address of El Torito boot catalog (if any) */ - unsigned int boot_catalog; - - /** Underlying device status, if in error */ - int block_rc; - /** Status of last operation */ - int last_status; -}; - -/** Vector for chaining to other INT 13 handlers */ -static struct segoff __text16 ( int13_vector ); -#define int13_vector __use_text16 ( int13_vector ) - -/** Assembly wrapper */ -extern void int13_wrapper ( void ); - -/** Dummy floppy disk parameter table */ -static struct int13_fdd_parameters __data16 ( int13_fdd_params ) = { - /* 512 bytes per sector */ - .bytes_per_sector = 0x02, - /* Highest sectors per track that we ever return */ - .sectors_per_track = 48, -}; -#define int13_fdd_params __use_data16 ( int13_fdd_params ) - -/** List of registered emulated drives */ -static LIST_HEAD ( int13s ); - -/** - * Equipment word - * - * This is a cached copy of the BIOS Data Area equipment word at - * 40:10. - */ -static uint16_t equipment_word; - -/** - * Number of BIOS floppy disk drives - * - * This is derived from the equipment word. It is held in .text16 to - * allow for easy access by the INT 13,08 wrapper. - */ -static uint8_t __text16 ( num_fdds ); -#define num_fdds __use_text16 ( num_fdds ) - -/** - * Number of BIOS hard disk drives - * - * This is a cached copy of the BIOS Data Area number of hard disk - * drives at 40:75. It is held in .text16 to allow for easy access by - * the INT 13,08 wrapper. - */ -static uint8_t __text16 ( num_drives ); -#define num_drives __use_text16 ( num_drives ) - -/** - * Calculate INT 13 drive sector size - * - * @v int13 Emulated drive - * @ret blksize Sector size - */ -static inline size_t int13_blksize ( struct int13_drive *int13 ) { - return ( int13->capacity.blksize << int13->blksize_shift ); -} - -/** - * Calculate INT 13 drive capacity - * - * @v int13 Emulated drive - * @ret blocks Number of blocks - */ -static inline uint64_t int13_capacity ( struct int13_drive *int13 ) { - return ( int13->capacity.blocks >> int13->blksize_shift ); -} - -/** - * Calculate INT 13 drive capacity (limited to 32 bits) - * - * @v int13 Emulated drive - * @ret blocks Number of blocks - */ -static inline uint32_t int13_capacity32 ( struct int13_drive *int13 ) { - uint64_t capacity = int13_capacity ( int13 ); - return ( ( capacity <= 0xffffffffUL ) ? capacity : 0xffffffff ); -} - -/** - * Test if INT 13 drive is a floppy disk drive - * - * @v int13 Emulated drive - * @ret is_fdd Emulated drive is a floppy disk - */ -static inline int int13_is_fdd ( struct int13_drive *int13 ) { - return ( ! ( int13->drive & 0x80 ) ); -} - -/** An INT 13 command */ -struct int13_command { - /** Status */ - int rc; - /** INT 13 drive */ - struct int13_drive *int13; - /** Underlying block device interface */ - struct interface block; - /** Command timeout timer */ - struct retry_timer timer; -}; - -/** - * Record INT 13 drive capacity - * - * @v command INT 13 command - * @v capacity Block device capacity - */ -static void int13_command_capacity ( struct int13_command *command, - struct block_device_capacity *capacity ) { - memcpy ( &command->int13->capacity, capacity, - sizeof ( command->int13->capacity ) ); -} - -/** - * Close INT 13 command - * - * @v command INT 13 command - * @v rc Reason for close - */ -static void int13_command_close ( struct int13_command *command, int rc ) { - intf_restart ( &command->block, rc ); - stop_timer ( &command->timer ); - command->rc = rc; -} - -/** - * Handle INT 13 command timer expiry - * - * @v timer Timer - */ -static void int13_command_expired ( struct retry_timer *timer, - int over __unused ) { - struct int13_command *command = - container_of ( timer, struct int13_command, timer ); - - int13_command_close ( command, -ETIMEDOUT ); -} - -/** INT 13 command interface operations */ -static struct interface_operation int13_command_op[] = { - INTF_OP ( intf_close, struct int13_command *, int13_command_close ), - INTF_OP ( block_capacity, struct int13_command *, - int13_command_capacity ), -}; - -/** INT 13 command interface descriptor */ -static struct interface_descriptor int13_command_desc = - INTF_DESC ( struct int13_command, block, int13_command_op ); - -/** - * Open (or reopen) INT 13 emulated drive underlying block device - * - * @v int13 Emulated drive - * @ret rc Return status code - */ -static int int13_reopen_block ( struct int13_drive *int13 ) { - int rc; - - /* Close any existing block device */ - intf_restart ( &int13->block, -ECONNRESET ); - - /* Open block device */ - if ( ( rc = xfer_open_uri ( &int13->block, int13->uri ) ) != 0 ) { - DBGC ( int13, "INT13 drive %02x could not reopen block " - "device: %s\n", int13->drive, strerror ( rc ) ); - int13->block_rc = rc; - return rc; - } - - /* Clear block device error status */ - int13->block_rc = 0; - - return 0; -} - -/** - * Prepare to issue INT 13 command - * - * @v command INT 13 command - * @v int13 Emulated drive - * @ret rc Return status code - */ -static int int13_command_start ( struct int13_command *command, - struct int13_drive *int13 ) { - int rc; - - /* Sanity check */ - assert ( command->int13 == NULL ); - assert ( ! timer_running ( &command->timer ) ); - - /* Reopen block device if necessary */ - if ( ( int13->block_rc != 0 ) && - ( ( rc = int13_reopen_block ( int13 ) ) != 0 ) ) - return rc; - - /* Initialise command */ - command->rc = -EINPROGRESS; - command->int13 = int13; - start_timer_fixed ( &command->timer, INT13_COMMAND_TIMEOUT ); - - /* Wait for block control interface to become ready */ - while ( ( command->rc == -EINPROGRESS ) && - ( xfer_window ( &int13->block ) == 0 ) ) { - step(); - } - - return ( ( command->rc == -EINPROGRESS ) ? - int13->block_rc : command->rc ); -} - -/** - * Wait for INT 13 command to complete - * - * @v command INT 13 command - * @ret rc Return status code - */ -static int int13_command_wait ( struct int13_command *command ) { - - /* Sanity check */ - assert ( timer_running ( &command->timer ) ); - - /* Wait for command to complete */ - while ( command->rc == -EINPROGRESS ) - step(); - - assert ( ! timer_running ( &command->timer ) ); - return command->rc; -} - -/** - * Terminate INT 13 command - * - * @v command INT 13 command - */ -static void int13_command_stop ( struct int13_command *command ) { - stop_timer ( &command->timer ); - command->int13 = NULL; -} - -/** The single active INT 13 command */ -static struct int13_command int13_command = { - .block = INTF_INIT ( int13_command_desc ), - .timer = TIMER_INIT ( int13_command_expired ), -}; - -/** - * Read from or write to INT 13 drive - * - * @v int13 Emulated drive - * @v lba Starting logical block address - * @v count Number of logical blocks - * @v buffer Data buffer - * @v block_rw Block read/write method - * @ret rc Return status code - */ -static int int13_rw ( struct int13_drive *int13, uint64_t lba, - unsigned int count, userptr_t buffer, - int ( * block_rw ) ( struct interface *control, - struct interface *data, - uint64_t lba, unsigned int count, - userptr_t buffer, size_t len ) ) { - struct int13_command *command = &int13_command; - unsigned int frag_count; - size_t frag_len; - int rc; - - /* Translate to underlying blocksize */ - lba <<= int13->blksize_shift; - count <<= int13->blksize_shift; - - while ( count ) { - - /* Determine fragment length */ - frag_count = count; - if ( frag_count > int13->capacity.max_count ) - frag_count = int13->capacity.max_count; - frag_len = ( int13->capacity.blksize * frag_count ); - - /* Issue command */ - if ( ( ( rc = int13_command_start ( command, int13 ) ) != 0 ) || - ( ( rc = block_rw ( &int13->block, &command->block, lba, - frag_count, buffer, - frag_len ) ) != 0 ) || - ( ( rc = int13_command_wait ( command ) ) != 0 ) ) { - int13_command_stop ( command ); - return rc; - } - int13_command_stop ( command ); - - /* Move to next fragment */ - lba += frag_count; - count -= frag_count; - buffer = userptr_add ( buffer, frag_len ); - } - - return 0; -} - -/** - * Read INT 13 drive capacity - * - * @v int13 Emulated drive - * @ret rc Return status code - */ -static int int13_read_capacity ( struct int13_drive *int13 ) { - struct int13_command *command = &int13_command; - int rc; - - /* Issue command */ - if ( ( ( rc = int13_command_start ( command, int13 ) ) != 0 ) || - ( ( rc = block_read_capacity ( &int13->block, - &command->block ) ) != 0 ) || - ( ( rc = int13_command_wait ( command ) ) != 0 ) ) { - int13_command_stop ( command ); - return rc; - } - - int13_command_stop ( command ); - return 0; -} - -/** - * Parse ISO9660 parameters - * - * @v int13 Emulated drive - * @v scratch Scratch area for single-sector reads - * @ret rc Return status code - * - * Reads and parses ISO9660 parameters, if present. - */ -static int int13_parse_iso9660 ( struct int13_drive *int13, void *scratch ) { - static const struct iso9660_primary_descriptor_fixed primary_check = { - .type = ISO9660_TYPE_PRIMARY, - .id = ISO9660_ID, - }; - struct iso9660_primary_descriptor *primary = scratch; - static const struct eltorito_descriptor_fixed boot_check = { - .type = ISO9660_TYPE_BOOT, - .id = ISO9660_ID, - .version = 1, - .system_id = "EL TORITO SPECIFICATION", - }; - struct eltorito_descriptor *boot = scratch; - unsigned int blksize; - unsigned int blksize_shift; - int rc; - - /* Calculate required blocksize shift */ - blksize = int13_blksize ( int13 ); - blksize_shift = 0; - while ( blksize < ISO9660_BLKSIZE ) { - blksize <<= 1; - blksize_shift++; - } - if ( blksize > ISO9660_BLKSIZE ) { - /* Do nothing if the blksize is invalid for CD-ROM access */ - return 0; - } - - /* Read primary volume descriptor */ - if ( ( rc = int13_rw ( int13, - ( ISO9660_PRIMARY_LBA << blksize_shift ), 1, - virt_to_user ( primary ), block_read ) ) != 0 ){ - DBGC ( int13, "INT13 drive %02x could not read ISO9660 " - "primary volume descriptor: %s\n", - int13->drive, strerror ( rc ) ); - return rc; - } - - /* Do nothing unless this is an ISO image */ - if ( memcmp ( primary, &primary_check, sizeof ( primary_check ) ) != 0 ) - return 0; - DBGC ( int13, "INT13 drive %02x contains an ISO9660 filesystem; " - "treating as CD-ROM\n", int13->drive ); - int13->is_cdrom = 1; - - /* Read boot record volume descriptor */ - if ( ( rc = int13_rw ( int13, - ( ELTORITO_LBA << blksize_shift ), 1, - virt_to_user ( boot ), block_read ) ) != 0 ) { - DBGC ( int13, "INT13 drive %02x could not read El Torito boot " - "record volume descriptor: %s\n", - int13->drive, strerror ( rc ) ); - return rc; - } - - /* Check for an El Torito boot catalog */ - if ( memcmp ( boot, &boot_check, sizeof ( boot_check ) ) == 0 ) { - int13->boot_catalog = boot->sector; - DBGC ( int13, "INT13 drive %02x has an El Torito boot catalog " - "at LBA %08x\n", int13->drive, int13->boot_catalog ); - } else { - DBGC ( int13, "INT13 drive %02x has no El Torito boot " - "catalog\n", int13->drive ); - } - - /* Configure drive for no-emulation CD-ROM access */ - int13->blksize_shift += blksize_shift; - - return 0; -} - -/** - * Guess INT 13 hard disk drive geometry - * - * @v int13 Emulated drive - * @v scratch Scratch area for single-sector reads - * @ret heads Guessed number of heads - * @ret sectors Guessed number of sectors per track - * @ret rc Return status code - * - * Guesses the drive geometry by inspecting the partition table. - */ -static int int13_guess_geometry_hdd ( struct int13_drive *int13, void *scratch, - unsigned int *heads, - unsigned int *sectors ) { - struct master_boot_record *mbr = scratch; - struct partition_table_entry *partition; - unsigned int i; - int rc; - - /* Default guess is xx/255/63 */ - *heads = 255; - *sectors = 63; - - /* Read partition table */ - if ( ( rc = int13_rw ( int13, 0, 1, virt_to_user ( mbr ), - block_read ) ) != 0 ) { - DBGC ( int13, "INT13 drive %02x could not read " - "partition table to guess geometry: %s\n", - int13->drive, strerror ( rc ) ); - return rc; - } - DBGC2 ( int13, "INT13 drive %02x has MBR:\n", int13->drive ); - DBGC2_HDA ( int13, 0, mbr, sizeof ( *mbr ) ); - DBGC ( int13, "INT13 drive %02x has signature %08x\n", - int13->drive, mbr->signature ); - - /* Scan through partition table and modify guesses for - * heads and sectors_per_track if we find any used - * partitions. - */ - for ( i = 0 ; i < 4 ; i++ ) { - partition = &mbr->partitions[i]; - if ( ! partition->type ) - continue; - *heads = ( PART_HEAD ( partition->chs_end ) + 1 ); - *sectors = PART_SECTOR ( partition->chs_end ); - DBGC ( int13, "INT13 drive %02x guessing C/H/S xx/%d/%d based " - "on partition %d\n", - int13->drive, *heads, *sectors, ( i + 1 ) ); - } - - return 0; -} - -/** Recognised floppy disk geometries */ -static const struct int13_fdd_geometry int13_fdd_geometries[] = { - INT13_FDD_GEOMETRY ( 40, 1, 8 ), - INT13_FDD_GEOMETRY ( 40, 1, 9 ), - INT13_FDD_GEOMETRY ( 40, 2, 8 ), - INT13_FDD_GEOMETRY ( 40, 1, 9 ), - INT13_FDD_GEOMETRY ( 80, 2, 8 ), - INT13_FDD_GEOMETRY ( 80, 2, 9 ), - INT13_FDD_GEOMETRY ( 80, 2, 15 ), - INT13_FDD_GEOMETRY ( 80, 2, 18 ), - INT13_FDD_GEOMETRY ( 80, 2, 20 ), - INT13_FDD_GEOMETRY ( 80, 2, 21 ), - INT13_FDD_GEOMETRY ( 82, 2, 21 ), - INT13_FDD_GEOMETRY ( 83, 2, 21 ), - INT13_FDD_GEOMETRY ( 80, 2, 22 ), - INT13_FDD_GEOMETRY ( 80, 2, 23 ), - INT13_FDD_GEOMETRY ( 80, 2, 24 ), - INT13_FDD_GEOMETRY ( 80, 2, 36 ), - INT13_FDD_GEOMETRY ( 80, 2, 39 ), - INT13_FDD_GEOMETRY ( 80, 2, 40 ), - INT13_FDD_GEOMETRY ( 80, 2, 44 ), - INT13_FDD_GEOMETRY ( 80, 2, 48 ), -}; - -/** - * Guess INT 13 floppy disk drive geometry - * - * @v int13 Emulated drive - * @ret heads Guessed number of heads - * @ret sectors Guessed number of sectors per track - * @ret rc Return status code - * - * Guesses the drive geometry by inspecting the disk size. - */ -static int int13_guess_geometry_fdd ( struct int13_drive *int13, - unsigned int *heads, - unsigned int *sectors ) { - unsigned int blocks = int13_capacity ( int13 ); - const struct int13_fdd_geometry *geometry; - unsigned int cylinders; - unsigned int i; - - /* Look for a match against a known geometry */ - for ( i = 0 ; i < ( sizeof ( int13_fdd_geometries ) / - sizeof ( int13_fdd_geometries[0] ) ) ; i++ ) { - geometry = &int13_fdd_geometries[i]; - cylinders = INT13_FDD_CYLINDERS ( geometry ); - *heads = INT13_FDD_HEADS ( geometry ); - *sectors = INT13_FDD_SECTORS ( geometry ); - if ( ( cylinders * (*heads) * (*sectors) ) == blocks ) { - DBGC ( int13, "INT13 drive %02x guessing C/H/S " - "%d/%d/%d based on size %dK\n", int13->drive, - cylinders, *heads, *sectors, ( blocks / 2 ) ); - return 0; - } - } - - /* Otherwise, assume a partial disk image in the most common - * format (1440K, 80/2/18). - */ - *heads = 2; - *sectors = 18; - DBGC ( int13, "INT13 drive %02x guessing C/H/S xx/%d/%d based on size " - "%dK\n", int13->drive, *heads, *sectors, ( blocks / 2 ) ); - return 0; -} - -/** - * Guess INT 13 drive geometry - * - * @v int13 Emulated drive - * @v scratch Scratch area for single-sector reads - * @ret rc Return status code - */ -static int int13_guess_geometry ( struct int13_drive *int13, void *scratch ) { - unsigned int guessed_heads; - unsigned int guessed_sectors; - unsigned int blocks; - unsigned int blocks_per_cyl; - int rc; - - /* Don't even try when the blksize is invalid for C/H/S access */ - if ( int13_blksize ( int13 ) != INT13_BLKSIZE ) - return 0; - - /* Guess geometry according to drive type */ - if ( int13_is_fdd ( int13 ) ) { - if ( ( rc = int13_guess_geometry_fdd ( int13, &guessed_heads, - &guessed_sectors )) != 0) - return rc; - } else { - if ( ( rc = int13_guess_geometry_hdd ( int13, scratch, - &guessed_heads, - &guessed_sectors )) != 0) - return rc; - } - - /* Apply guesses if no geometry already specified */ - if ( ! int13->heads ) - int13->heads = guessed_heads; - if ( ! int13->sectors_per_track ) - int13->sectors_per_track = guessed_sectors; - if ( ! int13->cylinders ) { - /* Avoid attempting a 64-bit divide on a 32-bit system */ - blocks = int13_capacity32 ( int13 ); - blocks_per_cyl = ( int13->heads * int13->sectors_per_track ); - assert ( blocks_per_cyl != 0 ); - int13->cylinders = ( blocks / blocks_per_cyl ); - if ( int13->cylinders > 1024 ) - int13->cylinders = 1024; - } - - return 0; -} - -/** - * Update BIOS drive count - */ -static void int13_sync_num_drives ( void ) { - struct int13_drive *int13; - uint8_t *counter; - uint8_t max_drive; - uint8_t required; - - /* Get current drive counts */ - get_real ( equipment_word, BDA_SEG, BDA_EQUIPMENT_WORD ); - get_real ( num_drives, BDA_SEG, BDA_NUM_DRIVES ); - num_fdds = ( ( equipment_word & 0x0001 ) ? - ( ( ( equipment_word >> 6 ) & 0x3 ) + 1 ) : 0 ); - - /* Ensure count is large enough to cover all of our emulated drives */ - list_for_each_entry ( int13, &int13s, list ) { - counter = ( int13_is_fdd ( int13 ) ? &num_fdds : &num_drives ); - max_drive = int13->drive; - if ( max_drive < int13->natural_drive ) - max_drive = int13->natural_drive; - required = ( ( max_drive & 0x7f ) + 1 ); - if ( *counter < required ) { - *counter = required; - DBGC ( int13, "INT13 drive %02x added to drive count: " - "%d HDDs, %d FDDs\n", - int13->drive, num_drives, num_fdds ); - } - } - - /* Update current drive count */ - equipment_word &= ~( ( 0x3 << 6 ) | 0x0001 ); - if ( num_fdds ) { - equipment_word |= ( 0x0001 | - ( ( ( num_fdds - 1 ) & 0x3 ) << 6 ) ); - } - put_real ( equipment_word, BDA_SEG, BDA_EQUIPMENT_WORD ); - put_real ( num_drives, BDA_SEG, BDA_NUM_DRIVES ); -} - -/** - * Check number of drives - */ -static void int13_check_num_drives ( void ) { - uint16_t check_equipment_word; - uint8_t check_num_drives; - - get_real ( check_equipment_word, BDA_SEG, BDA_EQUIPMENT_WORD ); - get_real ( check_num_drives, BDA_SEG, BDA_NUM_DRIVES ); - if ( ( check_equipment_word != equipment_word ) || - ( check_num_drives != num_drives ) ) { - int13_sync_num_drives(); - } -} - -/** - * INT 13, 00 - Reset disk system - * - * @v int13 Emulated drive - * @ret status Status code - */ -static int int13_reset ( struct int13_drive *int13, - struct i386_all_regs *ix86 __unused ) { - int rc; - - DBGC2 ( int13, "Reset drive\n" ); - - /* Reopen underlying block device */ - if ( ( rc = int13_reopen_block ( int13 ) ) != 0 ) - return -INT13_STATUS_RESET_FAILED; - - /* Check that block device is functional */ - if ( ( rc = int13_read_capacity ( int13 ) ) != 0 ) - return -INT13_STATUS_RESET_FAILED; - - return 0; -} - -/** - * INT 13, 01 - Get status of last operation - * - * @v int13 Emulated drive - * @ret status Status code - */ -static int int13_get_last_status ( struct int13_drive *int13, - struct i386_all_regs *ix86 __unused ) { - DBGC2 ( int13, "Get status of last operation\n" ); - return int13->last_status; -} - -/** - * Read / write sectors - * - * @v int13 Emulated drive - * @v al Number of sectors to read or write (must be nonzero) - * @v ch Low bits of cylinder number - * @v cl (bits 7:6) High bits of cylinder number - * @v cl (bits 5:0) Sector number - * @v dh Head number - * @v es:bx Data buffer - * @v block_rw Block read/write method - * @ret status Status code - * @ret al Number of sectors read or written - */ -static int int13_rw_sectors ( struct int13_drive *int13, - struct i386_all_regs *ix86, - int ( * block_rw ) ( struct interface *control, - struct interface *data, - uint64_t lba, - unsigned int count, - userptr_t buffer, - size_t len ) ) { - unsigned int cylinder, head, sector; - unsigned long lba; - unsigned int count; - userptr_t buffer; - int rc; - - /* Validate blocksize */ - if ( int13_blksize ( int13 ) != INT13_BLKSIZE ) { - DBGC ( int13, "\nINT 13 drive %02x invalid blocksize (%zd) " - "for non-extended read/write\n", - int13->drive, int13_blksize ( int13 ) ); - return -INT13_STATUS_INVALID; - } - - /* Calculate parameters */ - cylinder = ( ( ( ix86->regs.cl & 0xc0 ) << 2 ) | ix86->regs.ch ); - head = ix86->regs.dh; - sector = ( ix86->regs.cl & 0x3f ); - if ( ( cylinder >= int13->cylinders ) || - ( head >= int13->heads ) || - ( sector < 1 ) || ( sector > int13->sectors_per_track ) ) { - DBGC ( int13, "C/H/S %d/%d/%d out of range for geometry " - "%d/%d/%d\n", cylinder, head, sector, int13->cylinders, - int13->heads, int13->sectors_per_track ); - return -INT13_STATUS_INVALID; - } - lba = ( ( ( ( cylinder * int13->heads ) + head ) - * int13->sectors_per_track ) + sector - 1 ); - count = ix86->regs.al; - buffer = real_to_user ( ix86->segs.es, ix86->regs.bx ); - - DBGC2 ( int13, "C/H/S %d/%d/%d = LBA %08lx <-> %04x:%04x (count %d)\n", - cylinder, head, sector, lba, ix86->segs.es, ix86->regs.bx, - count ); - - /* Read from / write to block device */ - if ( ( rc = int13_rw ( int13, lba, count, buffer, block_rw ) ) != 0 ) { - DBGC ( int13, "INT13 drive %02x I/O failed: %s\n", - int13->drive, strerror ( rc ) ); - return -INT13_STATUS_READ_ERROR; - } - - return 0; -} - -/** - * INT 13, 02 - Read sectors - * - * @v int13 Emulated drive - * @v al Number of sectors to read (must be nonzero) - * @v ch Low bits of cylinder number - * @v cl (bits 7:6) High bits of cylinder number - * @v cl (bits 5:0) Sector number - * @v dh Head number - * @v es:bx Data buffer - * @ret status Status code - * @ret al Number of sectors read - */ -static int int13_read_sectors ( struct int13_drive *int13, - struct i386_all_regs *ix86 ) { - DBGC2 ( int13, "Read: " ); - return int13_rw_sectors ( int13, ix86, block_read ); -} - -/** - * INT 13, 03 - Write sectors - * - * @v int13 Emulated drive - * @v al Number of sectors to write (must be nonzero) - * @v ch Low bits of cylinder number - * @v cl (bits 7:6) High bits of cylinder number - * @v cl (bits 5:0) Sector number - * @v dh Head number - * @v es:bx Data buffer - * @ret status Status code - * @ret al Number of sectors written - */ -static int int13_write_sectors ( struct int13_drive *int13, - struct i386_all_regs *ix86 ) { - DBGC2 ( int13, "Write: " ); - return int13_rw_sectors ( int13, ix86, block_write ); -} - -/** - * INT 13, 08 - Get drive parameters - * - * @v int13 Emulated drive - * @ret status Status code - * @ret ch Low bits of maximum cylinder number - * @ret cl (bits 7:6) High bits of maximum cylinder number - * @ret cl (bits 5:0) Maximum sector number - * @ret dh Maximum head number - * @ret dl Number of drives - */ -static int int13_get_parameters ( struct int13_drive *int13, - struct i386_all_regs *ix86 ) { - unsigned int max_cylinder = int13->cylinders - 1; - unsigned int max_head = int13->heads - 1; - unsigned int max_sector = int13->sectors_per_track; /* sic */ - - DBGC2 ( int13, "Get drive parameters\n" ); - - /* Validate blocksize */ - if ( int13_blksize ( int13 ) != INT13_BLKSIZE ) { - DBGC ( int13, "\nINT 13 drive %02x invalid blocksize (%zd) " - "for non-extended parameters\n", - int13->drive, int13_blksize ( int13 ) ); - return -INT13_STATUS_INVALID; - } - - /* Common parameters */ - ix86->regs.ch = ( max_cylinder & 0xff ); - ix86->regs.cl = ( ( ( max_cylinder >> 8 ) << 6 ) | max_sector ); - ix86->regs.dh = max_head; - ix86->regs.dl = ( int13_is_fdd ( int13 ) ? num_fdds : num_drives ); - - /* Floppy-specific parameters */ - if ( int13_is_fdd ( int13 ) ) { - ix86->regs.bl = INT13_FDD_TYPE_1M44; - ix86->segs.es = rm_ds; - ix86->regs.di = __from_data16 ( &int13_fdd_params ); - } - - return 0; -} - -/** - * INT 13, 15 - Get disk type - * - * @v int13 Emulated drive - * @ret ah Type code - * @ret cx:dx Sector count - * @ret status Status code / disk type - */ -static int int13_get_disk_type ( struct int13_drive *int13, - struct i386_all_regs *ix86 ) { - uint32_t blocks; - - DBGC2 ( int13, "Get disk type\n" ); - - if ( int13_is_fdd ( int13 ) ) { - return INT13_DISK_TYPE_FDD; - } else { - blocks = int13_capacity32 ( int13 ); - ix86->regs.cx = ( blocks >> 16 ); - ix86->regs.dx = ( blocks & 0xffff ); - return INT13_DISK_TYPE_HDD; - } -} - -/** - * INT 13, 41 - Extensions installation check - * - * @v int13 Emulated drive - * @v bx 0x55aa - * @ret bx 0xaa55 - * @ret cx Extensions API support bitmap - * @ret status Status code / API version - */ -static int int13_extension_check ( struct int13_drive *int13 __unused, - struct i386_all_regs *ix86 ) { - if ( ix86->regs.bx == 0x55aa ) { - DBGC2 ( int13, "INT13 extensions installation check\n" ); - ix86->regs.bx = 0xaa55; - ix86->regs.cx = ( INT13_EXTENSION_LINEAR | - INT13_EXTENSION_EDD | - INT13_EXTENSION_64BIT ); - return INT13_EXTENSION_VER_3_0; - } else { - return -INT13_STATUS_INVALID; - } -} - -/** - * Extended read / write - * - * @v int13 Emulated drive - * @v ds:si Disk address packet - * @v block_rw Block read/write method - * @ret status Status code - */ -static int int13_extended_rw ( struct int13_drive *int13, - struct i386_all_regs *ix86, - int ( * block_rw ) ( struct interface *control, - struct interface *data, - uint64_t lba, - unsigned int count, - userptr_t buffer, - size_t len ) ) { - struct int13_disk_address addr; - uint8_t bufsize; - uint64_t lba; - unsigned long count; - userptr_t buffer; - int rc; - - /* Extended reads are not allowed on floppy drives. - * ELTORITO.SYS seems to assume that we are really a CD-ROM if - * we support extended reads for a floppy drive. - */ - if ( int13_is_fdd ( int13 ) ) - return -INT13_STATUS_INVALID; - - /* Get buffer size */ - get_real ( bufsize, ix86->segs.ds, - ( ix86->regs.si + offsetof ( typeof ( addr ), bufsize ) ) ); - if ( bufsize < offsetof ( typeof ( addr ), buffer_phys ) ) { - DBGC2 ( int13, "<invalid buffer size %#02x\n>\n", bufsize ); - return -INT13_STATUS_INVALID; - } - - /* Read parameters from disk address structure */ - memset ( &addr, 0, sizeof ( addr ) ); - copy_from_real ( &addr, ix86->segs.ds, ix86->regs.si, bufsize ); - lba = addr.lba; - DBGC2 ( int13, "LBA %08llx <-> ", ( ( unsigned long long ) lba ) ); - if ( ( addr.count == 0xff ) || - ( ( addr.buffer.segment == 0xffff ) && - ( addr.buffer.offset == 0xffff ) ) ) { - buffer = phys_to_user ( addr.buffer_phys ); - DBGC2 ( int13, "%08llx", - ( ( unsigned long long ) addr.buffer_phys ) ); - } else { - buffer = real_to_user ( addr.buffer.segment, - addr.buffer.offset ); - DBGC2 ( int13, "%04x:%04x", addr.buffer.segment, - addr.buffer.offset ); - } - if ( addr.count <= 0x7f ) { - count = addr.count; - } else if ( addr.count == 0xff ) { - count = addr.long_count; - } else { - DBGC2 ( int13, " <invalid count %#02x>\n", addr.count ); - return -INT13_STATUS_INVALID; - } - DBGC2 ( int13, " (count %ld)\n", count ); - - /* Read from / write to block device */ - if ( ( rc = int13_rw ( int13, lba, count, buffer, block_rw ) ) != 0 ) { - DBGC ( int13, "INT13 drive %02x extended I/O failed: %s\n", - int13->drive, strerror ( rc ) ); - /* Record that no blocks were transferred successfully */ - addr.count = 0; - put_real ( addr.count, ix86->segs.ds, - ( ix86->regs.si + - offsetof ( typeof ( addr ), count ) ) ); - return -INT13_STATUS_READ_ERROR; - } - - return 0; -} - -/** - * INT 13, 42 - Extended read - * - * @v int13 Emulated drive - * @v ds:si Disk address packet - * @ret status Status code - */ -static int int13_extended_read ( struct int13_drive *int13, - struct i386_all_regs *ix86 ) { - DBGC2 ( int13, "Extended read: " ); - return int13_extended_rw ( int13, ix86, block_read ); -} - -/** - * INT 13, 43 - Extended write - * - * @v int13 Emulated drive - * @v ds:si Disk address packet - * @ret status Status code - */ -static int int13_extended_write ( struct int13_drive *int13, - struct i386_all_regs *ix86 ) { - DBGC2 ( int13, "Extended write: " ); - return int13_extended_rw ( int13, ix86, block_write ); -} - -/** - * INT 13, 44 - Verify sectors - * - * @v int13 Emulated drive - * @v ds:si Disk address packet - * @ret status Status code - */ -static int int13_extended_verify ( struct int13_drive *int13, - struct i386_all_regs *ix86 ) { - struct int13_disk_address addr; - uint64_t lba; - unsigned long count; - - /* Read parameters from disk address structure */ - if ( DBG_EXTRA ) { - copy_from_real ( &addr, ix86->segs.ds, ix86->regs.si, - sizeof ( addr )); - lba = addr.lba; - count = addr.count; - DBGC2 ( int13, "Verify: LBA %08llx (count %ld)\n", - ( ( unsigned long long ) lba ), count ); - } - - /* We have no mechanism for verifying sectors */ - return -INT13_STATUS_INVALID; -} - -/** - * INT 13, 44 - Extended seek - * - * @v int13 Emulated drive - * @v ds:si Disk address packet - * @ret status Status code - */ -static int int13_extended_seek ( struct int13_drive *int13, - struct i386_all_regs *ix86 ) { - struct int13_disk_address addr; - uint64_t lba; - unsigned long count; - - /* Read parameters from disk address structure */ - if ( DBG_EXTRA ) { - copy_from_real ( &addr, ix86->segs.ds, ix86->regs.si, - sizeof ( addr )); - lba = addr.lba; - count = addr.count; - DBGC2 ( int13, "Seek: LBA %08llx (count %ld)\n", - ( ( unsigned long long ) lba ), count ); - } - - /* Ignore and return success */ - return 0; -} - -/** - * Build device path information - * - * @v int13 Emulated drive - * @v dpi Device path information - * @ret rc Return status code - */ -static int int13_device_path_info ( struct int13_drive *int13, - struct edd_device_path_information *dpi ) { - struct device *device; - struct device_description *desc; - unsigned int i; - uint8_t sum = 0; - int rc; - - /* Reopen block device if necessary */ - if ( ( int13->block_rc != 0 ) && - ( ( rc = int13_reopen_block ( int13 ) ) != 0 ) ) - return rc; - - /* Get underlying hardware device */ - device = identify_device ( &int13->block ); - if ( ! device ) { - DBGC ( int13, "INT13 drive %02x cannot identify hardware " - "device\n", int13->drive ); - return -ENODEV; - } - - /* Fill in bus type and interface path */ - desc = &device->desc; - switch ( desc->bus_type ) { - case BUS_TYPE_PCI: - dpi->host_bus_type.type = EDD_BUS_TYPE_PCI; - dpi->interface_path.pci.bus = PCI_BUS ( desc->location ); - dpi->interface_path.pci.slot = PCI_SLOT ( desc->location ); - dpi->interface_path.pci.function = PCI_FUNC ( desc->location ); - dpi->interface_path.pci.channel = 0xff; /* unused */ - break; - default: - DBGC ( int13, "INT13 drive %02x unrecognised bus type %d\n", - int13->drive, desc->bus_type ); - return -ENOTSUP; - } - - /* Get EDD block device description */ - if ( ( rc = edd_describe ( &int13->block, &dpi->interface_type, - &dpi->device_path ) ) != 0 ) { - DBGC ( int13, "INT13 drive %02x cannot identify block device: " - "%s\n", int13->drive, strerror ( rc ) ); - return rc; - } - - /* Fill in common fields and fix checksum */ - dpi->key = EDD_DEVICE_PATH_INFO_KEY; - dpi->len = sizeof ( *dpi ); - for ( i = 0 ; i < sizeof ( *dpi ) ; i++ ) - sum += *( ( ( uint8_t * ) dpi ) + i ); - dpi->checksum -= sum; - - return 0; -} - -/** - * INT 13, 48 - Get extended parameters - * - * @v int13 Emulated drive - * @v ds:si Drive parameter table - * @ret status Status code - */ -static int int13_get_extended_parameters ( struct int13_drive *int13, - struct i386_all_regs *ix86 ) { - struct int13_disk_parameters params; - struct segoff address; - size_t len = sizeof ( params ); - uint16_t bufsize; - int rc; - - /* Get buffer size */ - get_real ( bufsize, ix86->segs.ds, - ( ix86->regs.si + offsetof ( typeof ( params ), bufsize ))); - - DBGC2 ( int13, "Get extended drive parameters to %04x:%04x+%02x\n", - ix86->segs.ds, ix86->regs.si, bufsize ); - - /* Build drive parameters */ - memset ( ¶ms, 0, sizeof ( params ) ); - params.flags = INT13_FL_DMA_TRANSPARENT; - if ( ( int13->cylinders < 1024 ) && - ( int13_capacity ( int13 ) <= INT13_MAX_CHS_SECTORS ) ) { - params.flags |= INT13_FL_CHS_VALID; - } - params.cylinders = int13->cylinders; - params.heads = int13->heads; - params.sectors_per_track = int13->sectors_per_track; - params.sectors = int13_capacity ( int13 ); - params.sector_size = int13_blksize ( int13 ); - memset ( ¶ms.dpte, 0xff, sizeof ( params.dpte ) ); - if ( ( rc = int13_device_path_info ( int13, ¶ms.dpi ) ) != 0 ) { - DBGC ( int13, "INT13 drive %02x could not provide device " - "path information: %s\n", - int13->drive, strerror ( rc ) ); - len = offsetof ( typeof ( params ), dpi ); - } - - /* Calculate returned "buffer size" (which will be less than - * the length actually copied if device path information is - * present). - */ - if ( bufsize < offsetof ( typeof ( params ), dpte ) ) - return -INT13_STATUS_INVALID; - if ( bufsize < offsetof ( typeof ( params ), dpi ) ) { - params.bufsize = offsetof ( typeof ( params ), dpte ); - } else { - params.bufsize = offsetof ( typeof ( params ), dpi ); - } - - DBGC ( int13, "INT 13 drive %02x described using extended " - "parameters:\n", int13->drive ); - address.segment = ix86->segs.ds; - address.offset = ix86->regs.si; - DBGC_HDA ( int13, address, ¶ms, len ); - - /* Return drive parameters */ - if ( len > bufsize ) - len = bufsize; - copy_to_real ( ix86->segs.ds, ix86->regs.si, ¶ms, len ); - - return 0; -} - -/** - * INT 13, 4b - Get status or terminate CD-ROM emulation - * - * @v int13 Emulated drive - * @v ds:si Specification packet - * @ret status Status code - */ -static int int13_cdrom_status_terminate ( struct int13_drive *int13, - struct i386_all_regs *ix86 ) { - struct int13_cdrom_specification specification; - - DBGC2 ( int13, "Get CD-ROM emulation status to %04x:%04x%s\n", - ix86->segs.ds, ix86->regs.si, - ( ix86->regs.al ? "" : " and terminate" ) ); - - /* Fail if we are not a CD-ROM */ - if ( ! int13->is_cdrom ) { - DBGC ( int13, "INT13 drive %02x is not a CD-ROM\n", - int13->drive ); - return -INT13_STATUS_INVALID; - } - - /* Build specification packet */ - memset ( &specification, 0, sizeof ( specification ) ); - specification.size = sizeof ( specification ); - specification.drive = int13->drive; - - /* Return specification packet */ - copy_to_real ( ix86->segs.ds, ix86->regs.si, &specification, - sizeof ( specification ) ); - - return 0; -} - - -/** - * INT 13, 4d - Read CD-ROM boot catalog - * - * @v int13 Emulated drive - * @v ds:si Command packet - * @ret status Status code - */ -static int int13_cdrom_read_boot_catalog ( struct int13_drive *int13, - struct i386_all_regs *ix86 ) { - struct int13_cdrom_boot_catalog_command command; - int rc; - - /* Read parameters from command packet */ - copy_from_real ( &command, ix86->segs.ds, ix86->regs.si, - sizeof ( command ) ); - DBGC2 ( int13, "Read CD-ROM boot catalog to %08x\n", command.buffer ); - - /* Fail if we have no boot catalog */ - if ( ! int13->boot_catalog ) { - DBGC ( int13, "INT13 drive %02x has no boot catalog\n", - int13->drive ); - return -INT13_STATUS_INVALID; - } - - /* Read from boot catalog */ - if ( ( rc = int13_rw ( int13, ( int13->boot_catalog + command.start ), - command.count, phys_to_user ( command.buffer ), - block_read ) ) != 0 ) { - DBGC ( int13, "INT13 drive %02x could not read boot catalog: " - "%s\n", int13->drive, strerror ( rc ) ); - return -INT13_STATUS_READ_ERROR; - } - - return 0; -} - -/** - * INT 13 handler - * - */ -static __asmcall void int13 ( struct i386_all_regs *ix86 ) { - int command = ix86->regs.ah; - unsigned int bios_drive = ix86->regs.dl; - struct int13_drive *int13; - int status; - - /* Check BIOS hasn't killed off our drive */ - int13_check_num_drives(); - - list_for_each_entry ( int13, &int13s, list ) { - - if ( bios_drive != int13->drive ) { - /* Remap any accesses to this drive's natural number */ - if ( bios_drive == int13->natural_drive ) { - DBGC2 ( int13, "INT13,%02x (%02x) remapped to " - "(%02x)\n", ix86->regs.ah, - bios_drive, int13->drive ); - ix86->regs.dl = int13->drive; - return; - } else if ( ( ( bios_drive & 0x7f ) == 0x7f ) && - ( command == INT13_CDROM_STATUS_TERMINATE ) - && int13->is_cdrom ) { - /* Catch non-drive-specific CD-ROM calls */ - } else { - continue; - } - } - - DBGC2 ( int13, "INT13,%02x (%02x): ", - ix86->regs.ah, bios_drive ); - - switch ( command ) { - case INT13_RESET: - status = int13_reset ( int13, ix86 ); - break; - case INT13_GET_LAST_STATUS: - status = int13_get_last_status ( int13, ix86 ); - break; - case INT13_READ_SECTORS: - status = int13_read_sectors ( int13, ix86 ); - break; - case INT13_WRITE_SECTORS: - status = int13_write_sectors ( int13, ix86 ); - break; - case INT13_GET_PARAMETERS: - status = int13_get_parameters ( int13, ix86 ); - break; - case INT13_GET_DISK_TYPE: - status = int13_get_disk_type ( int13, ix86 ); - break; - case INT13_EXTENSION_CHECK: - status = int13_extension_check ( int13, ix86 ); - break; - case INT13_EXTENDED_READ: - status = int13_extended_read ( int13, ix86 ); - break; - case INT13_EXTENDED_WRITE: - status = int13_extended_write ( int13, ix86 ); - break; - case INT13_EXTENDED_VERIFY: - status = int13_extended_verify ( int13, ix86 ); - break; - case INT13_EXTENDED_SEEK: - status = int13_extended_seek ( int13, ix86 ); - break; - case INT13_GET_EXTENDED_PARAMETERS: - status = int13_get_extended_parameters ( int13, ix86 ); - break; - case INT13_CDROM_STATUS_TERMINATE: - status = int13_cdrom_status_terminate ( int13, ix86 ); - break; - case INT13_CDROM_READ_BOOT_CATALOG: - status = int13_cdrom_read_boot_catalog ( int13, ix86 ); - break; - default: - DBGC2 ( int13, "*** Unrecognised INT13 ***\n" ); - status = -INT13_STATUS_INVALID; - break; - } - - /* Store status for INT 13,01 */ - int13->last_status = status; - - /* Negative status indicates an error */ - if ( status < 0 ) { - status = -status; - DBGC ( int13, "INT13,%02x (%02x) failed with status " - "%02x\n", ix86->regs.ah, int13->drive, status ); - } else { - ix86->flags &= ~CF; - } - ix86->regs.ah = status; - - /* Set OF to indicate to wrapper not to chain this call */ - ix86->flags |= OF; - - return; - } -} - -/** - * Hook INT 13 handler - * - */ -static void int13_hook_vector ( void ) { - /* Assembly wrapper to call int13(). int13() sets OF if we - * should not chain to the previous handler. (The wrapper - * clears CF and OF before calling int13()). - */ - __asm__ __volatile__ ( - TEXT16_CODE ( "\nint13_wrapper:\n\t" - /* Preserve %ax and %dx for future reference */ - "pushw %%bp\n\t" - "movw %%sp, %%bp\n\t" - "pushw %%ax\n\t" - "pushw %%dx\n\t" - /* Clear OF, set CF, call int13() */ - "orb $0, %%al\n\t" - "stc\n\t" - "pushl %0\n\t" - "pushw %%cs\n\t" - "call prot_call\n\t" - /* Chain if OF not set */ - "jo 1f\n\t" - "pushfw\n\t" - "lcall *%%cs:int13_vector\n\t" - "\n1:\n\t" - /* Overwrite flags for iret */ - "pushfw\n\t" - "popw 6(%%bp)\n\t" - /* Fix up %dl: - * - * INT 13,15 : do nothing if hard disk - * INT 13,08 : load with number of drives - * all others: restore original value - */ - "cmpb $0x15, -1(%%bp)\n\t" - "jne 2f\n\t" - "testb $0x80, -4(%%bp)\n\t" - "jnz 3f\n\t" - "\n2:\n\t" - "movb -4(%%bp), %%dl\n\t" - "cmpb $0x08, -1(%%bp)\n\t" - "jne 3f\n\t" - "testb $0x80, %%dl\n\t" - "movb %%cs:num_drives, %%dl\n\t" - "jnz 3f\n\t" - "movb %%cs:num_fdds, %%dl\n\t" - /* Return */ - "\n3:\n\t" - "movw %%bp, %%sp\n\t" - "popw %%bp\n\t" - "iret\n\t" ) - : : "i" ( int13 ) ); - - hook_bios_interrupt ( 0x13, ( unsigned int ) int13_wrapper, - &int13_vector ); -} - -/** - * Unhook INT 13 handler - */ -static void int13_unhook_vector ( void ) { - unhook_bios_interrupt ( 0x13, ( unsigned int ) int13_wrapper, - &int13_vector ); -} - -/** - * Check INT13 emulated drive flow control window - * - * @v int13 Emulated drive - */ -static size_t int13_block_window ( struct int13_drive *int13 __unused ) { - - /* We are never ready to receive data via this interface. - * This prevents objects that support both block and stream - * interfaces from attempting to send us stream data. - */ - return 0; -} - -/** - * Handle INT 13 emulated drive underlying block device closing - * - * @v int13 Emulated drive - * @v rc Reason for close - */ -static void int13_block_close ( struct int13_drive *int13, int rc ) { - - /* Any closing is an error from our point of view */ - if ( rc == 0 ) - rc = -ENOTCONN; - - DBGC ( int13, "INT13 drive %02x went away: %s\n", - int13->drive, strerror ( rc ) ); - - /* Record block device error code */ - int13->block_rc = rc; - - /* Shut down interfaces */ - intf_restart ( &int13->block, rc ); -} - -/** INT 13 drive interface operations */ -static struct interface_operation int13_block_op[] = { - INTF_OP ( xfer_window, struct int13_drive *, int13_block_window ), - INTF_OP ( intf_close, struct int13_drive *, int13_block_close ), -}; - -/** INT 13 drive interface descriptor */ -static struct interface_descriptor int13_block_desc = - INTF_DESC ( struct int13_drive, block, int13_block_op ); - -/** - * Free INT 13 emulated drive - * - * @v refcnt Reference count - */ -static void int13_free ( struct refcnt *refcnt ) { - struct int13_drive *int13 = - container_of ( refcnt, struct int13_drive, refcnt ); - - uri_put ( int13->uri ); - free ( int13 ); -} - -/** - * Hook INT 13 emulated drive - * - * @v uri URI - * @v drive Drive number - * @ret rc Return status code - * - * Registers the drive with the INT 13 emulation subsystem, and hooks - * the INT 13 interrupt vector (if not already hooked). - */ -static int int13_hook ( struct uri *uri, unsigned int drive ) { - struct int13_drive *int13; - unsigned int natural_drive; - void *scratch; - int rc; - - /* Calculate natural drive number */ - int13_sync_num_drives(); - natural_drive = ( ( drive & 0x80 ) ? ( num_drives | 0x80 ) : num_fdds ); - - /* Check that drive number is not in use */ - list_for_each_entry ( int13, &int13s, list ) { - if ( int13->drive == drive ) { - rc = -EADDRINUSE; - goto err_in_use; - } - } - - /* Allocate and initialise structure */ - int13 = zalloc ( sizeof ( *int13 ) ); - if ( ! int13 ) { - rc = -ENOMEM; - goto err_zalloc; - } - ref_init ( &int13->refcnt, int13_free ); - intf_init ( &int13->block, &int13_block_desc, &int13->refcnt ); - int13->uri = uri_get ( uri ); - int13->drive = drive; - int13->natural_drive = natural_drive; - - /* Open block device interface */ - if ( ( rc = int13_reopen_block ( int13 ) ) != 0 ) - goto err_reopen_block; - - /* Read device capacity */ - if ( ( rc = int13_read_capacity ( int13 ) ) != 0 ) - goto err_read_capacity; - - /* Allocate scratch area */ - scratch = malloc ( int13_blksize ( int13 ) ); - if ( ! scratch ) - goto err_alloc_scratch; - - /* Parse parameters, if present */ - if ( ( rc = int13_parse_iso9660 ( int13, scratch ) ) != 0 ) - goto err_parse_iso9660; - - /* Give drive a default geometry */ - if ( ( rc = int13_guess_geometry ( int13, scratch ) ) != 0 ) - goto err_guess_geometry; - - DBGC ( int13, "INT13 drive %02x (naturally %02x) registered with C/H/S " - "geometry %d/%d/%d\n", int13->drive, int13->natural_drive, - int13->cylinders, int13->heads, int13->sectors_per_track ); - - /* Hook INT 13 vector if not already hooked */ - if ( list_empty ( &int13s ) ) { - int13_hook_vector(); - devices_get(); - } - - /* Add to list of emulated drives */ - list_add ( &int13->list, &int13s ); - - /* Update BIOS drive count */ - int13_sync_num_drives(); - - free ( scratch ); - return 0; - - err_guess_geometry: - err_parse_iso9660: - free ( scratch ); - err_alloc_scratch: - err_read_capacity: - err_reopen_block: - intf_shutdown ( &int13->block, rc ); - ref_put ( &int13->refcnt ); - err_zalloc: - err_in_use: - return rc; -} - -/** - * Find INT 13 emulated drive by drive number - * - * @v drive Drive number - * @ret int13 Emulated drive, or NULL - */ -static struct int13_drive * int13_find ( unsigned int drive ) { - struct int13_drive *int13; - - list_for_each_entry ( int13, &int13s, list ) { - if ( int13->drive == drive ) - return int13; - } - return NULL; -} - -/** - * Unhook INT 13 emulated drive - * - * @v drive Drive number - * - * Unregisters the drive from the INT 13 emulation subsystem. If this - * is the last emulated drive, the INT 13 vector is unhooked (if - * possible). - */ -static void int13_unhook ( unsigned int drive ) { - struct int13_drive *int13; - - /* Find drive */ - int13 = int13_find ( drive ); - if ( ! int13 ) { - DBG ( "INT13 cannot find emulated drive %02x\n", drive ); - return; - } - - /* Shut down interfaces */ - intf_shutdown ( &int13->block, 0 ); - - /* Remove from list of emulated drives */ - list_del ( &int13->list ); - - /* Should adjust BIOS drive count, but it's difficult - * to do so reliably. - */ - - DBGC ( int13, "INT13 drive %02x unregistered\n", int13->drive ); - - /* Unhook INT 13 vector if no more drives */ - if ( list_empty ( &int13s ) ) { - devices_put(); - int13_unhook_vector(); - } - - /* Drop list's reference to drive */ - ref_put ( &int13->refcnt ); -} - -/** - * Load and verify master boot record from INT 13 drive - * - * @v drive Drive number - * @v address Boot code address to fill in - * @ret rc Return status code - */ -static int int13_load_mbr ( unsigned int drive, struct segoff *address ) { - uint8_t status; - int discard_b, discard_c, discard_d; - uint16_t magic; - - /* Use INT 13, 02 to read the MBR */ - address->segment = 0; - address->offset = 0x7c00; - __asm__ __volatile__ ( REAL_CODE ( "pushw %%es\n\t" - "pushl %%ebx\n\t" - "popw %%bx\n\t" - "popw %%es\n\t" - "stc\n\t" - "sti\n\t" - "int $0x13\n\t" - "sti\n\t" /* BIOS bugs */ - "jc 1f\n\t" - "xorw %%ax, %%ax\n\t" - "\n1:\n\t" - "popw %%es\n\t" ) - : "=a" ( status ), "=b" ( discard_b ), - "=c" ( discard_c ), "=d" ( discard_d ) - : "a" ( 0x0201 ), "b" ( *address ), - "c" ( 1 ), "d" ( drive ) ); - if ( status ) { - DBG ( "INT13 drive %02x could not read MBR (status %02x)\n", - drive, status ); - return -EIO; - } - - /* Check magic signature */ - get_real ( magic, address->segment, - ( address->offset + - offsetof ( struct master_boot_record, magic ) ) ); - if ( magic != INT13_MBR_MAGIC ) { - DBG ( "INT13 drive %02x does not contain a valid MBR\n", - drive ); - return -ENOEXEC; - } - - return 0; -} - -/** El Torito boot catalog command packet */ -static struct int13_cdrom_boot_catalog_command __data16 ( eltorito_cmd ) = { - .size = sizeof ( struct int13_cdrom_boot_catalog_command ), - .count = 1, - .buffer = 0x7c00, - .start = 0, -}; -#define eltorito_cmd __use_data16 ( eltorito_cmd ) - -/** El Torito disk address packet */ -static struct int13_disk_address __bss16 ( eltorito_address ); -#define eltorito_address __use_data16 ( eltorito_address ) - -/** - * Load and verify El Torito boot record from INT 13 drive - * - * @v drive Drive number - * @v address Boot code address to fill in - * @ret rc Return status code - */ -static int int13_load_eltorito ( unsigned int drive, struct segoff *address ) { - struct { - struct eltorito_validation_entry valid; - struct eltorito_boot_entry boot; - } __attribute__ (( packed )) catalog; - uint8_t status; - - /* Use INT 13, 4d to read the boot catalog */ - __asm__ __volatile__ ( REAL_CODE ( "stc\n\t" - "sti\n\t" - "int $0x13\n\t" - "sti\n\t" /* BIOS bugs */ - "jc 1f\n\t" - "xorw %%ax, %%ax\n\t" - "\n1:\n\t" ) - : "=a" ( status ) - : "a" ( 0x4d00 ), "d" ( drive ), - "S" ( __from_data16 ( &eltorito_cmd ) ) ); - if ( status ) { - DBG ( "INT13 drive %02x could not read El Torito boot catalog " - "(status %02x)\n", drive, status ); - return -EIO; - } - copy_from_user ( &catalog, phys_to_user ( eltorito_cmd.buffer ), 0, - sizeof ( catalog ) ); - - /* Sanity checks */ - if ( catalog.valid.platform_id != ELTORITO_PLATFORM_X86 ) { - DBG ( "INT13 drive %02x El Torito specifies unknown platform " - "%02x\n", drive, catalog.valid.platform_id ); - return -ENOEXEC; - } - if ( catalog.boot.indicator != ELTORITO_BOOTABLE ) { - DBG ( "INT13 drive %02x El Torito is not bootable\n", drive ); - return -ENOEXEC; - } - if ( catalog.boot.media_type != ELTORITO_NO_EMULATION ) { - DBG ( "INT13 drive %02x El Torito requires emulation " - "type %02x\n", drive, catalog.boot.media_type ); - return -ENOTSUP; - } - DBG ( "INT13 drive %02x El Torito boot image at LBA %08x (count %d)\n", - drive, catalog.boot.start, catalog.boot.length ); - address->segment = ( catalog.boot.load_segment ? - catalog.boot.load_segment : 0x7c0 ); - address->offset = 0; - DBG ( "INT13 drive %02x El Torito boot image loads at %04x:%04x\n", - drive, address->segment, address->offset ); - - /* Use INT 13, 42 to read the boot image */ - eltorito_address.bufsize = - offsetof ( typeof ( eltorito_address ), buffer_phys ); - eltorito_address.count = catalog.boot.length; - eltorito_address.buffer = *address; - eltorito_address.lba = catalog.boot.start; - __asm__ __volatile__ ( REAL_CODE ( "stc\n\t" - "sti\n\t" - "int $0x13\n\t" - "sti\n\t" /* BIOS bugs */ - "jc 1f\n\t" - "xorw %%ax, %%ax\n\t" - "\n1:\n\t" ) - : "=a" ( status ) - : "a" ( 0x4200 ), "d" ( drive ), - "S" ( __from_data16 ( &eltorito_address ) ) ); - if ( status ) { - DBG ( "INT13 drive %02x could not read El Torito boot image " - "(status %02x)\n", drive, status ); - return -EIO; - } - - return 0; -} - -/** - * Attempt to boot from an INT 13 drive - * - * @v drive Drive number - * @ret rc Return status code - * - * This boots from the specified INT 13 drive by loading the Master - * Boot Record to 0000:7c00 and jumping to it. INT 18 is hooked to - * capture an attempt by the MBR to boot the next device. (This is - * the closest thing to a return path from an MBR). - * - * Note that this function can never return success, by definition. - */ -static int int13_boot ( unsigned int drive ) { - struct memory_map memmap; - struct segoff address; - int rc; - - /* Look for a usable boot sector */ - if ( ( ( rc = int13_load_mbr ( drive, &address ) ) != 0 ) && - ( ( rc = int13_load_eltorito ( drive, &address ) ) != 0 ) ) - return rc; - - /* Dump out memory map prior to boot, if memmap debugging is - * enabled. Not required for program flow, but we have so - * many problems that turn out to be memory-map related that - * it's worth doing. - */ - get_memmap ( &memmap ); - - /* Jump to boot sector */ - if ( ( rc = call_bootsector ( address.segment, address.offset, - drive ) ) != 0 ) { - DBG ( "INT13 drive %02x boot returned: %s\n", - drive, strerror ( rc ) ); - return rc; - } - - return -ECANCELED; /* -EIMPOSSIBLE */ -} - -/** A boot firmware table generated by iPXE */ -union xbft_table { - /** ACPI header */ - struct acpi_description_header acpi; - /** Padding */ - char pad[768]; -}; - -/** The boot firmware table generated by iPXE */ -static union xbft_table __bss16 ( xbftab ) __attribute__ (( aligned ( 16 ) )); -#define xbftab __use_data16 ( xbftab ) - -/** - * Describe INT 13 emulated drive for SAN-booted operating system - * - * @v drive Drive number - * @ret rc Return status code - */ -static int int13_describe ( unsigned int drive ) { - struct int13_drive *int13; - struct segoff xbft_address; - int rc; - - /* Find drive */ - int13 = int13_find ( drive ); - if ( ! int13 ) { - DBG ( "INT13 cannot find emulated drive %02x\n", drive ); - return -ENODEV; - } - - /* Reopen block device if necessary */ - if ( ( int13->block_rc != 0 ) && - ( ( rc = int13_reopen_block ( int13 ) ) != 0 ) ) - return rc; - - /* Clear table */ - memset ( &xbftab, 0, sizeof ( xbftab ) ); - - /* Fill in common parameters */ - strncpy ( xbftab.acpi.oem_id, "FENSYS", - sizeof ( xbftab.acpi.oem_id ) ); - strncpy ( xbftab.acpi.oem_table_id, "iPXE", - sizeof ( xbftab.acpi.oem_table_id ) ); - - /* Fill in remaining parameters */ - if ( ( rc = acpi_describe ( &int13->block, &xbftab.acpi, - sizeof ( xbftab ) ) ) != 0 ) { - DBGC ( int13, "INT13 drive %02x could not create ACPI " - "description: %s\n", int13->drive, strerror ( rc ) ); - return rc; - } - - /* Fix up ACPI checksum */ - acpi_fix_checksum ( &xbftab.acpi ); - xbft_address.segment = rm_ds; - xbft_address.offset = __from_data16 ( &xbftab ); - DBGC ( int13, "INT13 drive %02x described using boot firmware " - "table:\n", int13->drive ); - DBGC_HDA ( int13, xbft_address, &xbftab, - le32_to_cpu ( xbftab.acpi.length ) ); - - return 0; -} - -PROVIDE_SANBOOT_INLINE ( pcbios, san_default_drive ); -PROVIDE_SANBOOT ( pcbios, san_hook, int13_hook ); -PROVIDE_SANBOOT ( pcbios, san_unhook, int13_unhook ); -PROVIDE_SANBOOT ( pcbios, san_boot, int13_boot ); -PROVIDE_SANBOOT ( pcbios, san_describe, int13_describe ); diff --git a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/int13con.c b/qemu/roms/ipxe/src/arch/i386/interface/pcbios/int13con.c deleted file mode 100644 index 2414c6909..000000000 --- a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/int13con.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright (C) 2015 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 (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 <string.h> -#include <errno.h> -#include <ipxe/console.h> -#include <ipxe/init.h> -#include <realmode.h> -#include <int13.h> -#include <config/console.h> - -/** @file - * - * INT13 disk log console - * - */ - -/* Set default console usage if applicable */ -#if ! ( defined ( CONSOLE_INT13 ) && CONSOLE_EXPLICIT ( CONSOLE_INT13 ) ) -#undef CONSOLE_INT13 -#define CONSOLE_INT13 ( CONSOLE_USAGE_ALL & ~CONSOLE_USAGE_LOG ) -#endif - -/** Disk drive number */ -#define INT13CON_DRIVE 0x80 - -/** Log partition type */ -#define INT13CON_PARTITION_TYPE 0xe0 - -/** Maximum number of outstanding unwritten characters */ -#define INT13CON_MAX_UNWRITTEN 64 - -/** Log partition header */ -struct int13con_header { - /** Magic signature */ - char magic[10]; -} __attribute__ (( packed )); - -/** Log partition magic signature */ -#define INT13CON_MAGIC "iPXE LOG\n\n" - -/** Sector buffer */ -static uint8_t __bss16_array ( int13con_buffer, [INT13_BLKSIZE] ); -#define int13con_buffer __use_data16 ( int13con_buffer ) - -/** Disk address packet */ -static struct int13_disk_address __bss16 ( int13con_address ); -#define int13con_address __use_data16 ( int13con_address ) - -/** Current LBA */ -static uint64_t int13con_lba; - -/** Maximum LBA */ -static uint64_t int13con_max_lba; - -/** Current offset within sector */ -static size_t int13con_offset; - -/** Number of unwritten characters */ -static size_t int13con_unwritten; - -struct console_driver int13con __console_driver; - -/** - * Read/write disk sector - * - * @v op Operation - * @v lba Logical block address - * @ret rc Return status code - */ -static int int13con_rw ( unsigned int op, uint64_t lba ) { - uint8_t error; - - /* Construct disk address packet */ - int13con_address.bufsize = sizeof ( int13con_address ); - int13con_address.count = 1; - int13con_address.buffer.segment = rm_ds; - int13con_address.buffer.offset = __from_data16 ( int13con_buffer ); - int13con_address.lba = lba; - - /* Issue INT13 */ - __asm__ ( REAL_CODE ( "int $0x13\n\t" ) - : "=a" ( error ) - : "0" ( op << 8 ), "d" ( INT13CON_DRIVE ), - "S" ( __from_data16 ( &int13con_address ) ) ); - if ( error ) { - DBG ( "INT13CON operation %04x failed: %02x\n", - op, error ); - return -EIO; - } - - return 0; -} - -/** - * Write character to console - * - * @v character Character - */ -static void int13con_putchar ( int character ) { - static int busy; - int rc; - - /* Ignore if we are already mid-logging */ - if ( busy ) - return; - busy = 1; - - /* Write character to buffer */ - int13con_buffer[int13con_offset++] = character; - int13con_unwritten++; - - /* Write sector to disk, if applicable */ - if ( ( int13con_offset == INT13_BLKSIZE ) || - ( int13con_unwritten == INT13CON_MAX_UNWRITTEN ) || - ( character == '\n' ) ) { - - /* Write sector to disk */ - if ( ( rc = int13con_rw ( INT13_EXTENDED_WRITE, - int13con_lba ) ) != 0 ) { - DBG ( "INT13CON could not write log\n" ); - /* Ignore and continue; there's nothing we can do */ - } - - /* Reset count of unwritten characters */ - int13con_unwritten = 0; - } - - /* Move to next sector, if applicable */ - if ( int13con_offset == INT13_BLKSIZE ) { - - /* Disable console if we have run out of space */ - if ( int13con_lba >= int13con_max_lba ) - int13con.disabled = 1; - - /* Clear log buffer */ - memset ( int13con_buffer, 0, sizeof ( int13con_buffer ) ); - int13con_offset = 0; - - /* Move to next sector */ - int13con_lba++; - } - - /* Clear busy flag */ - busy = 0; -} - -/** - * Find log partition - * - * @ret rc Return status code - */ -static int int13con_find ( void ) { - struct master_boot_record *mbr = - ( ( struct master_boot_record * ) int13con_buffer ); - struct int13con_header *hdr = - ( ( struct int13con_header * ) int13con_buffer ); - struct partition_table_entry part[4]; - unsigned int i; - int rc; - - /* Read MBR */ - if ( ( rc = int13con_rw ( INT13_EXTENDED_READ, 0 ) ) != 0 ) { - DBG ( "INT13CON could not read MBR: %s\n", strerror ( rc ) ); - return rc; - } - - /* Check MBR magic */ - if ( mbr->magic != INT13_MBR_MAGIC ) { - DBG ( "INT13CON incorrect MBR magic\n" ); - DBG2_HDA ( 0, mbr, sizeof ( *mbr ) ); - return -EINVAL; - } - - /* Look for magic partition */ - memcpy ( part, mbr->partitions, sizeof ( part ) ); - for ( i = 0 ; i < ( sizeof ( part ) / sizeof ( part[0] ) ) ; i++ ) { - - /* Skip partitions of the wrong type */ - if ( part[i].type != INT13CON_PARTITION_TYPE ) - continue; - - /* Read partition header */ - if ( ( rc = int13con_rw ( INT13_EXTENDED_READ, - part[i].start ) ) != 0 ) { - DBG ( "INT13CON partition %d could not read header: " - "%s\n", ( i + 1 ), strerror ( rc ) ); - continue; - } - - /* Check partition header */ - if ( memcmp ( hdr->magic, INT13CON_MAGIC, - sizeof ( hdr->magic ) ) != 0 ) { - DBG ( "INT13CON partition %d bad magic\n", ( i + 1 ) ); - DBG2_HDA ( 0, hdr, sizeof ( *hdr ) ); - continue; - } - - /* Found log partition */ - DBG ( "INT13CON partition %d at [%08x,%08x)\n", ( i + 1 ), - part[i].start, ( part[i].start + part[i].length ) ); - int13con_lba = part[i].start; - int13con_max_lba = ( part[i].start + part[i].length - 1 ); - - /* Initialise log buffer */ - memset ( &int13con_buffer[ sizeof ( *hdr ) ], 0, - ( sizeof ( int13con_buffer ) - sizeof ( *hdr ) ) ); - int13con_offset = sizeof ( hdr->magic ); - - return 0; - } - - DBG ( "INT13CON found no log partition\n" ); - return -ENOENT; -} - -/** - * Initialise INT13 console - * - */ -static void int13con_init ( void ) { - uint8_t error; - uint16_t check; - unsigned int discard_c; - unsigned int discard_d; - int rc; - - /* Check for INT13 extensions */ - __asm__ __volatile__ ( REAL_CODE ( "int $0x13\n\t" - "setc %%al\n\t" ) - : "=a" ( error ), "=b" ( check ), - "=c" ( discard_c ), "=d" ( discard_d ) - : "0" ( INT13_EXTENSION_CHECK << 8 ), - "1" ( 0x55aa ), "3" ( INT13CON_DRIVE ) ); - if ( error || ( check != 0xaa55 ) ) { - DBG ( "INT13CON missing extensions (%02x,%04x)\n", - error, check ); - return; - } - - /* Locate log partition */ - if ( ( rc = int13con_find() ) != 0) - return; - - /* Enable console */ - int13con.disabled = 0; -} - -/** - * INT13 console initialisation function - */ -struct init_fn int13con_init_fn __init_fn ( INIT_CONSOLE ) = { - .initialise = int13con_init, -}; - -/** INT13 console driver */ -struct console_driver int13con __console_driver = { - .putchar = int13con_putchar, - .disabled = CONSOLE_DISABLED, - .usage = CONSOLE_INT13, -}; diff --git a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/memtop_umalloc.c b/qemu/roms/ipxe/src/arch/i386/interface/pcbios/memtop_umalloc.c deleted file mode 100644 index 957f8e324..000000000 --- a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/memtop_umalloc.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 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 ); - -/** - * @file - * - * External memory allocation - * - */ - -#include <limits.h> -#include <errno.h> -#include <ipxe/uaccess.h> -#include <ipxe/hidemem.h> -#include <ipxe/io.h> -#include <ipxe/memblock.h> -#include <ipxe/umalloc.h> - -/** Alignment of external allocated memory */ -#define EM_ALIGN ( 4 * 1024 ) - -/** Equivalent of NOWHERE for user pointers */ -#define UNOWHERE ( ~UNULL ) - -/** An external memory block */ -struct external_memory { - /** Size of this memory block (excluding this header) */ - size_t size; - /** Block is currently in use */ - int used; -}; - -/** Top of heap */ -static userptr_t top = UNULL; - -/** Bottom of heap (current lowest allocated block) */ -static userptr_t bottom = UNULL; - -/** Remaining space on heap */ -static size_t heap_size; - -/** - * Initialise external heap - * - */ -static void init_eheap ( void ) { - userptr_t base; - - heap_size = largest_memblock ( &base ); - bottom = top = userptr_add ( base, heap_size ); - DBG ( "External heap grows downwards from %lx (size %zx)\n", - user_to_phys ( top, 0 ), heap_size ); -} - -/** - * Collect free blocks - * - */ -static void ecollect_free ( void ) { - struct external_memory extmem; - size_t len; - - /* Walk the free list and collect empty blocks */ - while ( bottom != top ) { - copy_from_user ( &extmem, bottom, -sizeof ( extmem ), - sizeof ( extmem ) ); - if ( extmem.used ) - break; - DBG ( "EXTMEM freeing [%lx,%lx)\n", user_to_phys ( bottom, 0 ), - user_to_phys ( bottom, extmem.size ) ); - len = ( extmem.size + sizeof ( extmem ) ); - bottom = userptr_add ( bottom, len ); - heap_size += len; - } -} - -/** - * Reallocate external memory - * - * @v old_ptr Memory previously allocated by umalloc(), or UNULL - * @v new_size Requested size - * @ret new_ptr Allocated memory, or UNULL - * - * Calling realloc() with a new size of zero is a valid way to free a - * memory block. - */ -static userptr_t memtop_urealloc ( userptr_t ptr, size_t new_size ) { - struct external_memory extmem; - userptr_t new = ptr; - size_t align; - - /* (Re)initialise external memory allocator if necessary */ - if ( bottom == top ) - init_eheap(); - - /* Get block properties into extmem */ - if ( ptr && ( ptr != UNOWHERE ) ) { - /* Determine old size */ - copy_from_user ( &extmem, ptr, -sizeof ( extmem ), - sizeof ( extmem ) ); - } else { - /* Create a zero-length block */ - if ( heap_size < sizeof ( extmem ) ) { - DBG ( "EXTMEM out of space\n" ); - return UNULL; - } - ptr = bottom = userptr_add ( bottom, -sizeof ( extmem ) ); - heap_size -= sizeof ( extmem ); - DBG ( "EXTMEM allocating [%lx,%lx)\n", - user_to_phys ( ptr, 0 ), user_to_phys ( ptr, 0 ) ); - extmem.size = 0; - } - extmem.used = ( new_size > 0 ); - - /* Expand/shrink block if possible */ - if ( ptr == bottom ) { - /* Update block */ - if ( new_size > ( heap_size - extmem.size ) ) { - DBG ( "EXTMEM out of space\n" ); - return UNULL; - } - new = userptr_add ( ptr, - ( new_size - extmem.size ) ); - align = ( user_to_phys ( new, 0 ) & ( EM_ALIGN - 1 ) ); - new_size += align; - new = userptr_add ( new, -align ); - DBG ( "EXTMEM expanding [%lx,%lx) to [%lx,%lx)\n", - user_to_phys ( ptr, 0 ), - user_to_phys ( ptr, extmem.size ), - user_to_phys ( new, 0 ), - user_to_phys ( new, new_size )); - memmove_user ( new, 0, ptr, 0, ( ( extmem.size < new_size ) ? - extmem.size : new_size ) ); - bottom = new; - heap_size -= ( new_size - extmem.size ); - extmem.size = new_size; - } else { - /* Cannot expand; can only pretend to shrink */ - if ( new_size > extmem.size ) { - /* Refuse to expand */ - DBG ( "EXTMEM cannot expand [%lx,%lx)\n", - user_to_phys ( ptr, 0 ), - user_to_phys ( ptr, extmem.size ) ); - return UNULL; - } - } - - /* Write back block properties */ - copy_to_user ( new, -sizeof ( extmem ), &extmem, - sizeof ( extmem ) ); - - /* Collect any free blocks and update hidden memory region */ - ecollect_free(); - hide_umalloc ( user_to_phys ( bottom, ( ( bottom == top ) ? - 0 : -sizeof ( extmem ) ) ), - user_to_phys ( top, 0 ) ); - - return ( new_size ? new : UNOWHERE ); -} - -PROVIDE_UMALLOC ( memtop, urealloc, memtop_urealloc ); diff --git a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/pcibios.c b/qemu/roms/ipxe/src/arch/i386/interface/pcbios/pcibios.c deleted file mode 100644 index 34efa0b39..000000000 --- a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/pcibios.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 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/pci.h> -#include <realmode.h> - -/** @file - * - * PCI configuration space access via PCI BIOS - * - */ - -/** - * Determine number of PCI buses within system - * - * @ret num_bus Number of buses - */ -static int pcibios_num_bus ( void ) { - int discard_a, discard_D; - uint8_t max_bus; - - /* We issue this call using flat real mode, to work around a - * bug in some HP BIOSes. - */ - __asm__ __volatile__ ( REAL_CODE ( "call flatten_real_mode\n\t" - "stc\n\t" - "int $0x1a\n\t" - "jnc 1f\n\t" - "xorw %%cx, %%cx\n\t" - "\n1:\n\t" ) - : "=c" ( max_bus ), "=a" ( discard_a ), - "=D" ( discard_D ) - : "a" ( PCIBIOS_INSTALLATION_CHECK >> 16 ), - "D" ( 0 ) - : "ebx", "edx" ); - - return ( max_bus + 1 ); -} - -/** - * Read configuration space via PCI BIOS - * - * @v pci PCI device - * @v command PCI BIOS command - * @v value Value read - * @ret rc Return status code - */ -int pcibios_read ( struct pci_device *pci, uint32_t command, uint32_t *value ){ - int discard_b, discard_D; - int status; - - __asm__ __volatile__ ( REAL_CODE ( "stc\n\t" - "int $0x1a\n\t" - "jnc 1f\n\t" - "xorl %%eax, %%eax\n\t" - "decl %%eax\n\t" - "movl %%eax, %%ecx\n\t" - "\n1:\n\t" ) - : "=a" ( status ), "=b" ( discard_b ), - "=c" ( *value ), "=D" ( discard_D ) - : "a" ( command >> 16 ), "D" ( command ), - "b" ( pci->busdevfn ) - : "edx" ); - - return ( ( status >> 8 ) & 0xff ); -} - -/** - * Write configuration space via PCI BIOS - * - * @v pci PCI device - * @v command PCI BIOS command - * @v value Value to be written - * @ret rc Return status code - */ -int pcibios_write ( struct pci_device *pci, uint32_t command, uint32_t value ){ - int discard_b, discard_c, discard_D; - int status; - - __asm__ __volatile__ ( REAL_CODE ( "stc\n\t" - "int $0x1a\n\t" - "jnc 1f\n\t" - "movb $0xff, %%ah\n\t" - "\n1:\n\t" ) - : "=a" ( status ), "=b" ( discard_b ), - "=c" ( discard_c ), "=D" ( discard_D ) - : "a" ( command >> 16 ), "D" ( command ), - "b" ( pci->busdevfn ), "c" ( value ) - : "edx" ); - - return ( ( status >> 8 ) & 0xff ); -} - -PROVIDE_PCIAPI ( pcbios, pci_num_bus, pcibios_num_bus ); -PROVIDE_PCIAPI_INLINE ( pcbios, pci_read_config_byte ); -PROVIDE_PCIAPI_INLINE ( pcbios, pci_read_config_word ); -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 ); diff --git a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/rtc_entropy.c b/qemu/roms/ipxe/src/arch/i386/interface/pcbios/rtc_entropy.c deleted file mode 100644 index 9aab03c03..000000000 --- a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/rtc_entropy.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (C) 2012 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 ); - -/** @file - * - * RTC-based entropy source - * - */ - -#include <stdint.h> -#include <string.h> -#include <biosint.h> -#include <pic8259.h> -#include <rtc.h> -#include <ipxe/entropy.h> - -/** RTC "interrupt triggered" flag */ -static uint8_t __text16 ( rtc_flag ); -#define rtc_flag __use_text16 ( rtc_flag ) - -/** RTC interrupt handler */ -extern void rtc_isr ( void ); - -/** Previous RTC interrupt handler */ -static struct segoff rtc_old_handler; - -/** - * Hook RTC interrupt handler - * - */ -static void rtc_hook_isr ( void ) { - - /* RTC interrupt handler */ - __asm__ __volatile__ ( - TEXT16_CODE ( "\nrtc_isr:\n\t" - /* Preserve registers */ - "pushw %%ax\n\t" - /* Set "interrupt triggered" flag */ - "cs movb $0x01, %c0\n\t" - /* Read RTC status register C to - * acknowledge interrupt - */ - "movb %3, %%al\n\t" - "outb %%al, %1\n\t" - "inb %2\n\t" - /* Send EOI */ - "movb $0x20, %%al\n\t" - "outb %%al, $0xa0\n\t" - "outb %%al, $0x20\n\t" - /* Restore registers and return */ - "popw %%ax\n\t" - "iret\n\t" ) - : - : "p" ( __from_text16 ( &rtc_flag ) ), - "i" ( CMOS_ADDRESS ), "i" ( CMOS_DATA ), - "i" ( RTC_STATUS_C ) ); - - hook_bios_interrupt ( RTC_INT, ( unsigned int ) rtc_isr, - &rtc_old_handler ); -} - -/** - * Unhook RTC interrupt handler - * - */ -static void rtc_unhook_isr ( void ) { - int rc; - - rc = unhook_bios_interrupt ( RTC_INT, ( unsigned int ) rtc_isr, - &rtc_old_handler ); - assert ( rc == 0 ); /* Should always be able to unhook */ -} - -/** - * Enable RTC interrupts - * - */ -static void rtc_enable_int ( void ) { - uint8_t status_b; - - /* Set Periodic Interrupt Enable bit in status register B */ - outb ( ( RTC_STATUS_B | CMOS_DISABLE_NMI ), CMOS_ADDRESS ); - status_b = inb ( CMOS_DATA ); - outb ( ( RTC_STATUS_B | CMOS_DISABLE_NMI ), CMOS_ADDRESS ); - outb ( ( status_b | RTC_STATUS_B_PIE ), CMOS_DATA ); - - /* Re-enable NMI and reset to default address */ - outb ( CMOS_DEFAULT_ADDRESS, CMOS_ADDRESS ); - inb ( CMOS_DATA ); /* Discard; may be needed on some platforms */ -} - -/** - * Disable RTC interrupts - * - */ -static void rtc_disable_int ( void ) { - uint8_t status_b; - - /* Clear Periodic Interrupt Enable bit in status register B */ - outb ( ( RTC_STATUS_B | CMOS_DISABLE_NMI ), CMOS_ADDRESS ); - status_b = inb ( CMOS_DATA ); - outb ( ( RTC_STATUS_B | CMOS_DISABLE_NMI ), CMOS_ADDRESS ); - outb ( ( status_b & ~RTC_STATUS_B_PIE ), CMOS_DATA ); - - /* Re-enable NMI and reset to default address */ - outb ( CMOS_DEFAULT_ADDRESS, CMOS_ADDRESS ); - inb ( CMOS_DATA ); /* Discard; may be needed on some platforms */ -} - -/** - * Enable entropy gathering - * - * @ret rc Return status code - */ -static int rtc_entropy_enable ( void ) { - - rtc_hook_isr(); - enable_irq ( RTC_IRQ ); - rtc_enable_int(); - - return 0; -} - -/** - * Disable entropy gathering - * - */ -static void rtc_entropy_disable ( void ) { - - rtc_disable_int(); - disable_irq ( RTC_IRQ ); - rtc_unhook_isr(); -} - -/** - * Measure a single RTC tick - * - * @ret delta Length of RTC tick (in TSC units) - */ -uint8_t rtc_sample ( void ) { - uint32_t before; - uint32_t after; - uint32_t temp; - - __asm__ __volatile__ ( - REAL_CODE ( /* Enable interrupts */ - "sti\n\t" - /* Wait for RTC interrupt */ - "cs movb %b2, %c4\n\t" - "\n1:\n\t" - "cs xchgb %b2, %c4\n\t" /* Serialize */ - "testb %b2, %b2\n\t" - "jz 1b\n\t" - /* Read "before" TSC */ - "rdtsc\n\t" - /* Store "before" TSC on stack */ - "pushl %0\n\t" - /* Wait for another RTC interrupt */ - "xorb %b2, %b2\n\t" - "cs movb %b2, %c4\n\t" - "\n1:\n\t" - "cs xchgb %b2, %c4\n\t" /* Serialize */ - "testb %b2, %b2\n\t" - "jz 1b\n\t" - /* Read "after" TSC */ - "rdtsc\n\t" - /* Retrieve "before" TSC on stack */ - "popl %1\n\t" - /* Disable interrupts */ - "cli\n\t" - ) - : "=a" ( after ), "=d" ( before ), "=q" ( temp ) - : "2" ( 0 ), "p" ( __from_text16 ( &rtc_flag ) ) ); - - return ( after - before ); -} - -PROVIDE_ENTROPY_INLINE ( rtc, min_entropy_per_sample ); -PROVIDE_ENTROPY ( rtc, entropy_enable, rtc_entropy_enable ); -PROVIDE_ENTROPY ( rtc, entropy_disable, rtc_entropy_disable ); -PROVIDE_ENTROPY_INLINE ( rtc, get_noise ); diff --git a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/rtc_time.c b/qemu/roms/ipxe/src/arch/i386/interface/pcbios/rtc_time.c deleted file mode 100644 index cdbeac8d5..000000000 --- a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/rtc_time.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (C) 2012 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 ); - -/** @file - * - * RTC-based time source - * - */ - -#include <stdint.h> -#include <time.h> -#include <rtc.h> -#include <ipxe/time.h> - -/** - * Read RTC register - * - * @v address Register address - * @ret data Data - */ -static unsigned int rtc_readb ( int address ) { - outb ( address, CMOS_ADDRESS ); - return inb ( CMOS_DATA ); -} - -/** - * Check if RTC update is in progress - * - * @ret is_busy RTC update is in progress - */ -static int rtc_is_busy ( void ) { - return ( rtc_readb ( RTC_STATUS_A ) & RTC_STATUS_A_UPDATE_IN_PROGRESS ); -} - -/** - * Read RTC BCD register - * - * @v address Register address - * @ret value Value - */ -static unsigned int rtc_readb_bcd ( int address ) { - unsigned int bcd; - - bcd = rtc_readb ( address ); - return ( bcd - ( 6 * ( bcd >> 4 ) ) ); -} - -/** - * Read RTC time - * - * @ret time Time, in seconds - */ -static time_t rtc_read_time ( void ) { - unsigned int status_b; - int is_binary; - int is_24hour; - unsigned int ( * read_component ) ( int address ); - struct tm tm; - int is_pm; - unsigned int hour; - time_t time; - - /* Wait for any in-progress update to complete */ - while ( rtc_is_busy() ) {} - - /* Determine RTC mode */ - status_b = rtc_readb ( RTC_STATUS_B ); - is_binary = ( status_b & RTC_STATUS_B_BINARY ); - is_24hour = ( status_b & RTC_STATUS_B_24_HOUR ); - read_component = ( is_binary ? rtc_readb : rtc_readb_bcd ); - - /* Read time values */ - tm.tm_sec = read_component ( RTC_SEC ); - tm.tm_min = read_component ( RTC_MIN ); - hour = read_component ( RTC_HOUR ); - if ( ! is_24hour ) { - is_pm = ( hour >= 80 ); - hour = ( ( ( ( hour & 0x7f ) % 80 ) % 12 ) + - ( is_pm ? 12 : 0 ) ); - } - tm.tm_hour = hour; - tm.tm_mday = read_component ( RTC_MDAY ); - tm.tm_mon = ( read_component ( RTC_MON ) - 1 ); - tm.tm_year = ( read_component ( RTC_YEAR ) + - 100 /* Assume we are in the 21st century, since - * this code was written in 2012 */ ); - - DBGC ( RTC_STATUS_A, "RTCTIME is %04d-%02d-%02d %02d:%02d:%02d " - "(%s,%d-hour)\n", ( tm.tm_year + 1900 ), ( tm.tm_mon + 1 ), - tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, - ( is_binary ? "binary" : "BCD" ), ( is_24hour ? 24 : 12 ) ); - - /* Convert to seconds since the Epoch */ - time = mktime ( &tm ); - - return time; -} - -/** - * Get current time in seconds - * - * @ret time Time, in seconds - */ -static time_t rtc_now ( void ) { - time_t time = 0; - time_t last_time; - - /* Read time until we get two matching values in a row, in - * case we end up reading a corrupted value in the middle of - * an update. - */ - do { - last_time = time; - time = rtc_read_time(); - } while ( time != last_time ); - - return time; -} - -PROVIDE_TIME ( rtc, time_now, rtc_now ); diff --git a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/vesafb.c b/qemu/roms/ipxe/src/arch/i386/interface/pcbios/vesafb.c deleted file mode 100644 index 9cf2bf29e..000000000 --- a/qemu/roms/ipxe/src/arch/i386/interface/pcbios/vesafb.c +++ /dev/null @@ -1,542 +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 ); - -/** @file - * - * VESA frame buffer console - * - */ - -#include <stdlib.h> -#include <errno.h> -#include <limits.h> -#include <realmode.h> -#include <ipxe/console.h> -#include <ipxe/io.h> -#include <ipxe/ansicol.h> -#include <ipxe/fbcon.h> -#include <ipxe/vesafb.h> -#include <config/console.h> - -/* Avoid dragging in BIOS console if not otherwise used */ -extern struct console_driver bios_console; -struct console_driver bios_console __attribute__ (( weak )); - -/* Disambiguate the various error causes */ -#define EIO_FAILED __einfo_error ( EINFO_EIO_FAILED ) -#define EINFO_EIO_FAILED \ - __einfo_uniqify ( EINFO_EIO, 0x01, \ - "Function call failed" ) -#define EIO_HARDWARE __einfo_error ( EINFO_EIO_HARDWARE ) -#define EINFO_EIO_HARDWARE \ - __einfo_uniqify ( EINFO_EIO, 0x02, \ - "Not supported in current configuration" ) -#define EIO_MODE __einfo_error ( EINFO_EIO_MODE ) -#define EINFO_EIO_MODE \ - __einfo_uniqify ( EINFO_EIO, 0x03, \ - "Invalid in current video mode" ) -#define EIO_VBE( code ) \ - EUNIQ ( EINFO_EIO, (code), EIO_FAILED, EIO_HARDWARE, EIO_MODE ) - -/* Set default console usage if applicable */ -#if ! ( defined ( CONSOLE_VESAFB ) && CONSOLE_EXPLICIT ( CONSOLE_VESAFB ) ) -#undef CONSOLE_VESAFB -#define CONSOLE_VESAFB ( CONSOLE_USAGE_ALL & ~CONSOLE_USAGE_LOG ) -#endif - -/** Font corresponding to selected character width and height */ -#define VESAFB_FONT VBE_FONT_8x16 - -/* Forward declaration */ -struct console_driver vesafb_console __console_driver; - -/** A VESA frame buffer */ -struct vesafb { - /** Frame buffer console */ - struct fbcon fbcon; - /** Physical start address */ - physaddr_t start; - /** Pixel geometry */ - struct fbcon_geometry pixel; - /** Margin */ - struct fbcon_margin margin; - /** Colour mapping */ - struct fbcon_colour_map map; - /** Font definition */ - struct fbcon_font font; - /** Saved VGA mode */ - uint8_t saved_mode; -}; - -/** The VESA frame buffer */ -static struct vesafb vesafb; - -/** Base memory buffer used for VBE calls */ -union vbe_buffer { - /** VBE controller information block */ - struct vbe_controller_info controller; - /** VBE mode information block */ - struct vbe_mode_info mode; -}; -static union vbe_buffer __bss16 ( vbe_buf ); -#define vbe_buf __use_data16 ( vbe_buf ) - -/** - * Convert VBE status code to iPXE status code - * - * @v status VBE status code - * @ret rc Return status code - */ -static int vesafb_rc ( unsigned int status ) { - unsigned int code; - - if ( ( status & 0xff ) != 0x4f ) - return -ENOTSUP; - code = ( ( status >> 8 ) & 0xff ); - return ( code ? -EIO_VBE ( code ) : 0 ); -} - -/** - * Get font definition - * - */ -static void vesafb_font ( void ) { - struct segoff font; - - /* Get font information - * - * Working around gcc bugs is icky here. The value we want is - * returned in %ebp, but there's no way to specify %ebp in an - * output constraint. We can't put %ebp in the clobber list, - * because this tends to cause random build failures on some - * gcc versions. We can't manually push/pop %ebp and return - * the value via a generic register output constraint, because - * gcc might choose to use %ebp to satisfy that constraint - * (and we have no way to prevent it from so doing). - * - * Work around this hideous mess by using %ecx and %edx as the - * output registers, since they get clobbered anyway. - */ - __asm__ __volatile__ ( REAL_CODE ( "pushw %%bp\n\t" /* gcc bug */ - "int $0x10\n\t" - "movw %%es, %%cx\n\t" - "movw %%bp, %%dx\n\t" - "popw %%bp\n\t" /* gcc bug */ ) - : "=c" ( font.segment ), - "=d" ( font.offset ) - : "a" ( VBE_GET_FONT ), - "b" ( VESAFB_FONT ) ); - DBGC ( &vbe_buf, "VESAFB has font %04x at %04x:%04x\n", - VESAFB_FONT, font.segment, font.offset ); - vesafb.font.start = real_to_user ( font.segment, font.offset ); -} - -/** - * Get VBE mode list - * - * @ret mode_numbers Mode number list (terminated with VBE_MODE_END) - * @ret rc Return status code - * - * The caller is responsible for eventually freeing the mode list. - */ -static int vesafb_mode_list ( uint16_t **mode_numbers ) { - struct vbe_controller_info *controller = &vbe_buf.controller; - userptr_t video_mode_ptr; - uint16_t mode_number; - uint16_t status; - size_t len; - int rc; - - /* Avoid returning uninitialised data on error */ - *mode_numbers = NULL; - - /* Get controller information block */ - controller->vbe_signature = 0; - __asm__ __volatile__ ( REAL_CODE ( "int $0x10" ) - : "=a" ( status ) - : "a" ( VBE_CONTROLLER_INFO ), - "D" ( __from_data16 ( controller ) ) - : "memory", "ebx", "edx" ); - if ( ( rc = vesafb_rc ( status ) ) != 0 ) { - DBGC ( &vbe_buf, "VESAFB could not get controller information: " - "[%04x] %s\n", status, strerror ( rc ) ); - return rc; - } - if ( controller->vbe_signature != VBE_CONTROLLER_SIGNATURE ) { - DBGC ( &vbe_buf, "VESAFB invalid controller signature " - "\"%c%c%c%c\"\n", ( controller->vbe_signature >> 0 ), - ( controller->vbe_signature >> 8 ), - ( controller->vbe_signature >> 16 ), - ( controller->vbe_signature >> 24 ) ); - DBGC_HDA ( &vbe_buf, 0, controller, sizeof ( *controller ) ); - return -EINVAL; - } - DBGC ( &vbe_buf, "VESAFB found VBE version %d.%d with mode list at " - "%04x:%04x\n", controller->vbe_major_version, - controller->vbe_minor_version, - controller->video_mode_ptr.segment, - controller->video_mode_ptr.offset ); - - /* Calculate length of mode list */ - video_mode_ptr = real_to_user ( controller->video_mode_ptr.segment, - controller->video_mode_ptr.offset ); - len = 0; - do { - copy_from_user ( &mode_number, video_mode_ptr, len, - sizeof ( mode_number ) ); - len += sizeof ( mode_number ); - } while ( mode_number != VBE_MODE_END ); - - /* Allocate and fill mode list */ - *mode_numbers = malloc ( len ); - if ( ! *mode_numbers ) - return -ENOMEM; - copy_from_user ( *mode_numbers, video_mode_ptr, 0, len ); - - return 0; -} - -/** - * Get video mode information - * - * @v mode_number Mode number - * @ret rc Return status code - */ -static int vesafb_mode_info ( unsigned int mode_number ) { - struct vbe_mode_info *mode = &vbe_buf.mode; - uint16_t status; - int rc; - - /* Get mode information */ - __asm__ __volatile__ ( REAL_CODE ( "int $0x10" ) - : "=a" ( status ) - : "a" ( VBE_MODE_INFO ), - "c" ( mode_number ), - "D" ( __from_data16 ( mode ) ) - : "memory" ); - if ( ( rc = vesafb_rc ( status ) ) != 0 ) { - DBGC ( &vbe_buf, "VESAFB could not get mode %04x information: " - "[%04x] %s\n", mode_number, status, strerror ( rc ) ); - return rc; - } - DBGC ( &vbe_buf, "VESAFB mode %04x %dx%d %dbpp(%d:%d:%d:%d) model " - "%02x [x%d]%s%s%s%s%s\n", mode_number, mode->x_resolution, - mode->y_resolution, mode->bits_per_pixel, mode->rsvd_mask_size, - mode->red_mask_size, mode->green_mask_size, mode->blue_mask_size, - mode->memory_model, ( mode->number_of_image_pages + 1 ), - ( ( mode->mode_attributes & VBE_MODE_ATTR_SUPPORTED ) ? - "" : " [unsupported]" ), - ( ( mode->mode_attributes & VBE_MODE_ATTR_TTY ) ? - " [tty]" : "" ), - ( ( mode->mode_attributes & VBE_MODE_ATTR_GRAPHICS ) ? - "" : " [text]" ), - ( ( mode->mode_attributes & VBE_MODE_ATTR_LINEAR ) ? - "" : " [nonlinear]" ), - ( ( mode->mode_attributes & VBE_MODE_ATTR_TRIPLE_BUF ) ? - " [buf]" : "" ) ); - - return 0; -} - -/** - * Set video mode - * - * @v mode_number Mode number - * @ret rc Return status code - */ -static int vesafb_set_mode ( unsigned int mode_number ) { - struct vbe_mode_info *mode = &vbe_buf.mode; - uint16_t status; - int rc; - - /* Get mode information */ - if ( ( rc = vesafb_mode_info ( mode_number ) ) != 0 ) - return rc; - - /* Record mode parameters */ - vesafb.start = mode->phys_base_ptr; - vesafb.pixel.width = mode->x_resolution; - vesafb.pixel.height = mode->y_resolution; - vesafb.pixel.len = ( ( mode->bits_per_pixel + 7 ) / 8 ); - vesafb.pixel.stride = mode->bytes_per_scan_line; - DBGC ( &vbe_buf, "VESAFB mode %04x has frame buffer at %08x\n", - mode_number, mode->phys_base_ptr ); - - /* Initialise font colours */ - vesafb.map.red_scale = ( 8 - mode->red_mask_size ); - vesafb.map.green_scale = ( 8 - mode->green_mask_size ); - vesafb.map.blue_scale = ( 8 - mode->blue_mask_size ); - vesafb.map.red_lsb = mode->red_field_position; - vesafb.map.green_lsb = mode->green_field_position; - vesafb.map.blue_lsb = mode->blue_field_position; - - /* Select this mode */ - __asm__ __volatile__ ( REAL_CODE ( "int $0x10" ) - : "=a" ( status ) - : "a" ( VBE_SET_MODE ), - "b" ( mode_number ) ); - if ( ( rc = vesafb_rc ( status ) ) != 0 ) { - DBGC ( &vbe_buf, "VESAFB could not set mode %04x: [%04x] %s\n", - mode_number, status, strerror ( rc ) ); - return rc; - } - - return 0; -} - -/** - * Select video mode - * - * @v mode_numbers Mode number list (terminated with VBE_MODE_END) - * @v min_width Minimum required width (in pixels) - * @v min_height Minimum required height (in pixels) - * @v min_bpp Minimum required colour depth (in bits per pixel) - * @ret mode_number Mode number, or negative error - */ -static int vesafb_select_mode ( const uint16_t *mode_numbers, - unsigned int min_width, unsigned int min_height, - unsigned int min_bpp ) { - struct vbe_mode_info *mode = &vbe_buf.mode; - int best_mode_number = -ENOENT; - unsigned int best_score = INT_MAX; - unsigned int score; - uint16_t mode_number; - int rc; - - /* Find the first suitable mode */ - while ( ( mode_number = *(mode_numbers++) ) != VBE_MODE_END ) { - - /* Force linear mode variant */ - mode_number |= VBE_MODE_LINEAR; - - /* Get mode information */ - if ( ( rc = vesafb_mode_info ( mode_number ) ) != 0 ) - continue; - - /* Skip unusable modes */ - if ( ( mode->mode_attributes & ( VBE_MODE_ATTR_SUPPORTED | - VBE_MODE_ATTR_GRAPHICS | - VBE_MODE_ATTR_LINEAR ) ) != - ( VBE_MODE_ATTR_SUPPORTED | VBE_MODE_ATTR_GRAPHICS | - VBE_MODE_ATTR_LINEAR ) ) { - continue; - } - if ( mode->memory_model != VBE_MODE_MODEL_DIRECT_COLOUR ) - continue; - - /* Skip modes not meeting the requirements */ - if ( ( mode->x_resolution < min_width ) || - ( mode->y_resolution < min_height ) || - ( mode->bits_per_pixel < min_bpp ) ) { - continue; - } - - /* Select this mode if it has the best (i.e. lowest) - * score. We choose the scoring system to favour - * modes close to the specified width and height; - * within modes of the same width and height we prefer - * a higher colour depth. - */ - score = ( ( mode->x_resolution * mode->y_resolution ) - - mode->bits_per_pixel ); - if ( score < best_score ) { - best_mode_number = mode_number; - best_score = score; - } - } - - if ( best_mode_number >= 0 ) { - DBGC ( &vbe_buf, "VESAFB selected mode %04x\n", - best_mode_number ); - } else { - DBGC ( &vbe_buf, "VESAFB found no suitable mode\n" ); - } - - return best_mode_number; -} - -/** - * Restore video mode - * - */ -static void vesafb_restore ( void ) { - uint32_t discard_a; - - /* Restore saved VGA mode */ - __asm__ __volatile__ ( REAL_CODE ( "int $0x10" ) - : "=a" ( discard_a ) - : "a" ( VBE_SET_VGA_MODE | vesafb.saved_mode ) ); - DBGC ( &vbe_buf, "VESAFB restored VGA mode %#02x\n", - vesafb.saved_mode ); -} - -/** - * Initialise VESA frame buffer - * - * @v config Console configuration, or NULL to reset - * @ret rc Return status code - */ -static int vesafb_init ( struct console_configuration *config ) { - uint32_t discard_b; - uint16_t *mode_numbers; - unsigned int xgap; - unsigned int ygap; - unsigned int left; - unsigned int right; - unsigned int top; - unsigned int bottom; - int mode_number; - int rc; - - /* Record current VGA mode */ - __asm__ __volatile__ ( REAL_CODE ( "int $0x10" ) - : "=a" ( vesafb.saved_mode ), "=b" ( discard_b ) - : "a" ( VBE_GET_VGA_MODE ) ); - DBGC ( &vbe_buf, "VESAFB saved VGA mode %#02x\n", vesafb.saved_mode ); - - /* Get VESA mode list */ - if ( ( rc = vesafb_mode_list ( &mode_numbers ) ) != 0 ) - goto err_mode_list; - - /* Select mode */ - if ( ( mode_number = vesafb_select_mode ( mode_numbers, config->width, - config->height, - config->depth ) ) < 0 ) { - rc = mode_number; - goto err_select_mode; - } - - /* Set mode */ - if ( ( rc = vesafb_set_mode ( mode_number ) ) != 0 ) - goto err_set_mode; - - /* Calculate margin. If the actual screen size is larger than - * the requested screen size, then update the margins so that - * the margin remains relative to the requested screen size. - * (As an exception, if a zero margin was specified then treat - * this as meaning "expand to edge of actual screen".) - */ - xgap = ( vesafb.pixel.width - config->width ); - ygap = ( vesafb.pixel.height - config->height ); - left = ( xgap / 2 ); - right = ( xgap - left ); - top = ( ygap / 2 ); - bottom = ( ygap - top ); - vesafb.margin.left = ( config->left + ( config->left ? left : 0 ) ); - vesafb.margin.right = ( config->right + ( config->right ? right : 0 ) ); - vesafb.margin.top = ( config->top + ( config->top ? top : 0 ) ); - vesafb.margin.bottom = - ( config->bottom + ( config->bottom ? bottom : 0 ) ); - - /* Get font data */ - vesafb_font(); - - /* Initialise frame buffer console */ - if ( ( rc = fbcon_init ( &vesafb.fbcon, phys_to_user ( vesafb.start ), - &vesafb.pixel, &vesafb.margin, &vesafb.map, - &vesafb.font, config->pixbuf ) ) != 0 ) - goto err_fbcon_init; - - free ( mode_numbers ); - return 0; - - fbcon_fini ( &vesafb.fbcon ); - err_fbcon_init: - err_set_mode: - vesafb_restore(); - err_select_mode: - free ( mode_numbers ); - err_mode_list: - return rc; -} - -/** - * Finalise VESA frame buffer - * - */ -static void vesafb_fini ( void ) { - - /* Finalise frame buffer console */ - fbcon_fini ( &vesafb.fbcon ); - - /* Restore saved VGA mode */ - vesafb_restore(); -} - -/** - * Print a character to current cursor position - * - * @v character Character - */ -static void vesafb_putchar ( int character ) { - - fbcon_putchar ( &vesafb.fbcon, character ); -} - -/** - * Configure console - * - * @v config Console configuration, or NULL to reset - * @ret rc Return status code - */ -static int vesafb_configure ( struct console_configuration *config ) { - int rc; - - /* Reset console, if applicable */ - if ( ! vesafb_console.disabled ) { - vesafb_fini(); - bios_console.disabled &= ~CONSOLE_DISABLED_OUTPUT; - ansicol_reset_magic(); - } - vesafb_console.disabled = CONSOLE_DISABLED; - - /* Do nothing more unless we have a usable configuration */ - if ( ( config == NULL ) || - ( config->width == 0 ) || ( config->height == 0 ) ) { - return 0; - } - - /* Initialise VESA frame buffer */ - if ( ( rc = vesafb_init ( config ) ) != 0 ) - return rc; - - /* Mark console as enabled */ - vesafb_console.disabled = 0; - bios_console.disabled |= CONSOLE_DISABLED_OUTPUT; - - /* Set magic colour to transparent if we have a background picture */ - if ( config->pixbuf ) - ansicol_set_magic_transparent(); - - return 0; -} - -/** VESA frame buffer console driver */ -struct console_driver vesafb_console __console_driver = { - .usage = CONSOLE_VESAFB, - .putchar = vesafb_putchar, - .configure = vesafb_configure, - .disabled = CONSOLE_DISABLED, -}; diff --git a/qemu/roms/ipxe/src/arch/i386/interface/pxe/pxe_call.c b/qemu/roms/ipxe/src/arch/i386/interface/pxe/pxe_call.c deleted file mode 100644 index 104313666..000000000 --- a/qemu/roms/ipxe/src/arch/i386/interface/pxe/pxe_call.c +++ /dev/null @@ -1,354 +0,0 @@ -/* - * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 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 <ipxe/uaccess.h> -#include <ipxe/init.h> -#include <ipxe/profile.h> -#include <setjmp.h> -#include <registers.h> -#include <biosint.h> -#include <pxe.h> -#include <pxe_call.h> - -/** @file - * - * PXE API entry point - */ - -/* Disambiguate the various error causes */ -#define EINFO_EPXENBP \ - __einfo_uniqify ( EINFO_EPLATFORM, 0x01, \ - "External PXE NBP error" ) -#define EPXENBP( status ) EPLATFORM ( EINFO_EPXENBP, status ) - -/** Vector for chaining INT 1A */ -extern struct segoff __text16 ( pxe_int_1a_vector ); -#define pxe_int_1a_vector __use_text16 ( pxe_int_1a_vector ) - -/** INT 1A handler */ -extern void pxe_int_1a ( void ); - -/** INT 1A hooked flag */ -static int int_1a_hooked = 0; - -/** PXENV_UNDI_TRANSMIT API call profiler */ -static struct profiler pxe_api_tx_profiler __profiler = - { .name = "pxeapi.tx" }; - -/** PXENV_UNDI_ISR API call profiler */ -static struct profiler pxe_api_isr_profiler __profiler = - { .name = "pxeapi.isr" }; - -/** PXE unknown API call profiler - * - * This profiler can be used to measure the overhead of a dummy PXE - * API call. - */ -static struct profiler pxe_api_unknown_profiler __profiler = - { .name = "pxeapi.unknown" }; - -/** Miscellaneous PXE API call profiler */ -static struct profiler pxe_api_misc_profiler __profiler = - { .name = "pxeapi.misc" }; - -/** - * Handle an unknown PXE API call - * - * @v pxenv_unknown Pointer to a struct s_PXENV_UNKNOWN - * @ret #PXENV_EXIT_FAILURE Always - * @err #PXENV_STATUS_UNSUPPORTED Always - */ -static PXENV_EXIT_t pxenv_unknown ( struct s_PXENV_UNKNOWN *pxenv_unknown ) { - pxenv_unknown->Status = PXENV_STATUS_UNSUPPORTED; - return PXENV_EXIT_FAILURE; -} - -/** Unknown PXE API call list */ -struct pxe_api_call pxenv_unknown_api __pxe_api_call = - PXE_API_CALL ( PXENV_UNKNOWN, pxenv_unknown, struct s_PXENV_UNKNOWN ); - -/** - * Locate PXE API call - * - * @v opcode Opcode - * @ret call PXE API call, or NULL - */ -static struct pxe_api_call * find_pxe_api_call ( uint16_t opcode ) { - struct pxe_api_call *call; - - for_each_table_entry ( call, PXE_API_CALLS ) { - if ( call->opcode == opcode ) - return call; - } - return NULL; -} - -/** - * Determine applicable profiler (for debugging) - * - * @v opcode PXE opcode - * @ret profiler Profiler - */ -static struct profiler * pxe_api_profiler ( unsigned int opcode ) { - - /* Determine applicable profiler */ - switch ( opcode ) { - case PXENV_UNDI_TRANSMIT: - return &pxe_api_tx_profiler; - case PXENV_UNDI_ISR: - return &pxe_api_isr_profiler; - case PXENV_UNKNOWN: - return &pxe_api_unknown_profiler; - default: - return &pxe_api_misc_profiler; - } -} - -/** - * Dispatch PXE API call - * - * @v bx PXE opcode - * @v es:di Address of PXE parameter block - * @ret ax PXE exit code - */ -__asmcall void pxe_api_call ( struct i386_all_regs *ix86 ) { - uint16_t opcode = ix86->regs.bx; - userptr_t uparams = real_to_user ( ix86->segs.es, ix86->regs.di ); - struct profiler *profiler = pxe_api_profiler ( opcode ); - struct pxe_api_call *call; - union u_PXENV_ANY params; - PXENV_EXIT_t ret; - - /* Start profiling */ - profile_start ( profiler ); - - /* Locate API call */ - call = find_pxe_api_call ( opcode ); - if ( ! call ) { - DBGC ( &pxe_netdev, "PXENV_UNKNOWN_%04x\n", opcode ); - call = &pxenv_unknown_api; - } - - /* Copy parameter block from caller */ - copy_from_user ( ¶ms, uparams, 0, call->params_len ); - - /* Set default status in case child routine fails to do so */ - params.Status = PXENV_STATUS_FAILURE; - - /* Hand off to relevant API routine */ - ret = call->entry ( ¶ms ); - - /* Copy modified parameter block back to caller and return */ - copy_to_user ( uparams, 0, ¶ms, call->params_len ); - ix86->regs.ax = ret; - - /* Stop profiling, if applicable */ - profile_stop ( profiler ); -} - -/** - * Dispatch weak PXE API call with PXE stack available - * - * @v ix86 Registers for PXE call - * @ret present Zero (PXE stack present) - */ -int pxe_api_call_weak ( struct i386_all_regs *ix86 ) { - pxe_api_call ( ix86 ); - return 0; -} - -/** - * Dispatch PXE loader call - * - * @v es:di Address of PXE parameter block - * @ret ax PXE exit code - */ -__asmcall void pxe_loader_call ( struct i386_all_regs *ix86 ) { - userptr_t uparams = real_to_user ( ix86->segs.es, ix86->regs.di ); - struct s_UNDI_LOADER params; - PXENV_EXIT_t ret; - - /* Copy parameter block from caller */ - copy_from_user ( ¶ms, uparams, 0, sizeof ( params ) ); - - /* Fill in ROM segment address */ - ppxe.UNDIROMID.segment = ix86->segs.ds; - - /* Set default status in case child routine fails to do so */ - params.Status = PXENV_STATUS_FAILURE; - - /* Call UNDI loader */ - ret = undi_loader ( ¶ms ); - - /* Copy modified parameter block back to caller and return */ - copy_to_user ( uparams, 0, ¶ms, sizeof ( params ) ); - ix86->regs.ax = ret; -} - -/** - * Calculate byte checksum as used by PXE - * - * @v data Data - * @v size Length of data - * @ret sum Checksum - */ -static uint8_t pxe_checksum ( void *data, size_t size ) { - uint8_t *bytes = data; - uint8_t sum = 0; - - while ( size-- ) { - sum += *bytes++; - } - return sum; -} - -/** - * Initialise !PXE and PXENV+ structures - * - */ -static void pxe_init_structures ( void ) { - uint32_t rm_cs_phys = ( rm_cs << 4 ); - uint32_t rm_ds_phys = ( rm_ds << 4 ); - - /* Fill in missing segment fields */ - ppxe.EntryPointSP.segment = rm_cs; - ppxe.EntryPointESP.segment = rm_cs; - ppxe.Stack.segment_address = rm_ds; - ppxe.Stack.Physical_address = rm_ds_phys; - ppxe.UNDIData.segment_address = rm_ds; - ppxe.UNDIData.Physical_address = rm_ds_phys; - ppxe.UNDICode.segment_address = rm_cs; - ppxe.UNDICode.Physical_address = rm_cs_phys; - ppxe.UNDICodeWrite.segment_address = rm_cs; - ppxe.UNDICodeWrite.Physical_address = rm_cs_phys; - pxenv.RMEntry.segment = rm_cs; - pxenv.StackSeg = rm_ds; - pxenv.UNDIDataSeg = rm_ds; - pxenv.UNDICodeSeg = rm_cs; - pxenv.PXEPtr.segment = rm_cs; - - /* Update checksums */ - ppxe.StructCksum -= pxe_checksum ( &ppxe, sizeof ( ppxe ) ); - pxenv.Checksum -= pxe_checksum ( &pxenv, sizeof ( pxenv ) ); -} - -/** PXE structure initialiser */ -struct init_fn pxe_init_fn __init_fn ( INIT_NORMAL ) = { - .initialise = pxe_init_structures, -}; - -/** - * Activate PXE stack - * - * @v netdev Net device to use as PXE net device - */ -void pxe_activate ( struct net_device *netdev ) { - - /* Ensure INT 1A is hooked */ - if ( ! int_1a_hooked ) { - hook_bios_interrupt ( 0x1a, ( unsigned int ) pxe_int_1a, - &pxe_int_1a_vector ); - devices_get(); - int_1a_hooked = 1; - } - - /* Set PXE network device */ - pxe_set_netdev ( netdev ); -} - -/** - * Deactivate PXE stack - * - * @ret rc Return status code - */ -int pxe_deactivate ( void ) { - int rc; - - /* Clear PXE network device */ - pxe_set_netdev ( NULL ); - - /* Ensure INT 1A is unhooked, if possible */ - if ( int_1a_hooked ) { - if ( ( rc = unhook_bios_interrupt ( 0x1a, - (unsigned int) pxe_int_1a, - &pxe_int_1a_vector ))!= 0){ - DBG ( "Could not unhook INT 1A: %s\n", - strerror ( rc ) ); - return rc; - } - devices_put(); - int_1a_hooked = 0; - } - - return 0; -} - -/** Jump buffer for PXENV_RESTART_TFTP */ -rmjmp_buf pxe_restart_nbp; - -/** - * Start PXE NBP at 0000:7c00 - * - * @ret rc Return status code - */ -int pxe_start_nbp ( void ) { - int jmp; - int discard_b, discard_c, discard_d, discard_D; - uint16_t status; - - /* Allow restarting NBP via PXENV_RESTART_TFTP */ - jmp = rmsetjmp ( pxe_restart_nbp ); - if ( jmp ) - DBG ( "Restarting NBP (%x)\n", jmp ); - - /* Far call to PXE NBP */ - __asm__ __volatile__ ( REAL_CODE ( "pushl %%ebp\n\t" /* gcc bug */ - "movw %%cx, %%es\n\t" - "pushw %%es\n\t" - "pushw %%di\n\t" - "sti\n\t" - "lcall $0, $0x7c00\n\t" - "popl %%ebp\n\t" /* discard */ - "popl %%ebp\n\t" /* gcc bug */ ) - : "=a" ( status ), "=b" ( discard_b ), - "=c" ( discard_c ), "=d" ( discard_d ), - "=D" ( discard_D ) - : "a" ( 0 ), "b" ( __from_text16 ( &pxenv ) ), - "c" ( rm_cs ), - "d" ( virt_to_phys ( &pxenv ) ), - "D" ( __from_text16 ( &ppxe ) ) - : "esi", "memory" ); - if ( status ) - return -EPXENBP ( status ); - - return 0; -} - -REQUIRING_SYMBOL ( pxe_api_call ); -REQUIRE_OBJECT ( pxe_preboot ); -REQUIRE_OBJECT ( pxe_undi ); -REQUIRE_OBJECT ( pxe_udp ); -REQUIRE_OBJECT ( pxe_tftp ); -REQUIRE_OBJECT ( pxe_file ); diff --git a/qemu/roms/ipxe/src/arch/i386/interface/pxe/pxe_entry.S b/qemu/roms/ipxe/src/arch/i386/interface/pxe/pxe_entry.S deleted file mode 100644 index 07852cd50..000000000 --- a/qemu/roms/ipxe/src/arch/i386/interface/pxe/pxe_entry.S +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 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 ) - - .arch i386 - -/**************************************************************************** - * !PXE structure - **************************************************************************** - */ - .section ".text16.data", "aw", @progbits - .globl ppxe - .align 16 -ppxe: - .ascii "!PXE" /* Signature */ - .byte pxe_length /* StructLength */ - .byte 0 /* StructCksum */ - .byte 0 /* StructRev */ - .byte 0 /* reserved_1 */ - .word undiheader, 0 /* UNDIROMID */ - .word 0, 0 /* BaseROMID */ - .word pxe_entry_sp, 0 /* EntryPointSP */ - .word pxe_entry_esp, 0 /* EntryPointESP */ - .word -1, -1 /* StatusCallout */ - .byte 0 /* reserved_2 */ - .byte SegDescCnt /* SegDescCnt */ - .word 0 /* FirstSelector */ -pxe_segments: - .word 0, 0, 0, _data16_memsz /* Stack */ - .word 0, 0, 0, _data16_memsz /* UNDIData */ - .word 0, 0, 0, _text16_memsz /* UNDICode */ - .word 0, 0, 0, _text16_memsz /* UNDICodeWrite */ - .word 0, 0, 0, 0 /* BC_Data */ - .word 0, 0, 0, 0 /* BC_Code */ - .word 0, 0, 0, 0 /* BC_CodeWrite */ - .equ SegDescCnt, ( ( . - pxe_segments ) / 8 ) - .equ pxe_length, . - ppxe - .size ppxe, . - ppxe - - /* Define undiheader=0 as a weak symbol for non-ROM builds */ - .section ".weak", "a", @nobits - .weak undiheader -undiheader: - -/**************************************************************************** - * PXENV+ structure - **************************************************************************** - */ - .section ".text16.data", "aw", @progbits - .globl pxenv - .align 16 -pxenv: - .ascii "PXENV+" /* Signature */ - .word 0x0201 /* Version */ - .byte pxenv_length /* Length */ - .byte 0 /* Checksum */ - .word pxenv_entry, 0 /* RMEntry */ - .long 0 /* PMEntry */ - .word 0 /* PMSelector */ - .word 0 /* StackSeg */ - .word _data16_memsz /* StackSize */ - .word 0 /* BC_CodeSeg */ - .word 0 /* BC_CodeSize */ - .word 0 /* BC_DataSeg */ - .word 0 /* BC_DataSize */ - .word 0 /* UNDIDataSeg */ - .word _data16_memsz /* UNDIDataSize */ - .word 0 /* UNDICodeSeg */ - .word _text16_memsz /* UNDICodeSize */ - .word ppxe, 0 /* PXEPtr */ - .equ pxenv_length, . - pxenv - .size pxenv, . - pxenv - -/**************************************************************************** - * pxenv_entry (16-bit far call) - * - * PXE API call PXENV+ entry point - * - * Parameters: - * %es:di : Far pointer to PXE parameter structure - * %bx : PXE API call - * Returns: - * %ax : PXE exit status - * Corrupts: - * none - **************************************************************************** - */ - /* Wyse Streaming Manager server (WLDRM13.BIN) assumes that - * the PXENV+ entry point is at UNDI_CS:0000; apparently, - * somebody at Wyse has difficulty distinguishing between the - * words "may" and "must"... - */ - .section ".text16.null", "ax", @progbits - .code16 -pxenv_null_entry: - jmp pxenv_entry - - .section ".text16", "ax", @progbits - .code16 -pxenv_entry: - pushl $pxe_api_call - pushw %cs - call prot_call - addl $4, %esp - lret - .size pxenv_entry, . - pxenv_entry - -/**************************************************************************** - * pxe_entry - * - * PXE API call !PXE entry point - * - * Parameters: - * stack : Far pointer to PXE parameter structure - * stack : PXE API call - * Returns: - * %ax : PXE exit status - * Corrupts: - * none - **************************************************************************** - */ - .section ".text16", "ax", @progbits - .code16 -pxe_entry: -pxe_entry_sp: - /* Preserve original %esp */ - pushl %esp - /* Zero high word of %esp to allow use of common code */ - movzwl %sp, %esp - jmp pxe_entry_common -pxe_entry_esp: - /* Preserve %esp to match behaviour of pxe_entry_sp */ - pushl %esp -pxe_entry_common: - /* Save PXENV+ API call registers */ - pushw %es - pushw %di - pushw %bx - /* Load !PXE parameters from stack into PXENV+ registers */ - addr32 movw 18(%esp), %bx - movw %bx, %es - addr32 movw 16(%esp), %di - addr32 movw 14(%esp), %bx - /* Make call as for PXENV+ */ - pushw %cs - call pxenv_entry - /* Restore PXENV+ registers */ - popw %bx - popw %di - popw %es - /* Restore original %esp and return */ - popl %esp - lret - .size pxe_entry, . - pxe_entry - -/**************************************************************************** - * pxe_int_1a - * - * PXE INT 1A handler - * - * Parameters: - * %ax : 0x5650 - * Returns: - * %ax : 0x564e - * %es:bx : Far pointer to the PXENV+ structure - * %edx : Physical address of the PXENV+ structure - * CF cleared - * Corrupts: - * none - **************************************************************************** - */ - .section ".text16", "ax", @progbits - .code16 - .globl pxe_int_1a -pxe_int_1a: - pushfw - cmpw $0x5650, %ax - jne 1f - /* INT 1A,5650 - PXE installation check */ - xorl %edx, %edx - movw %cs, %dx - movw %dx, %es - movw $pxenv, %bx - shll $4, %edx - addl $pxenv, %edx - movw $0x564e, %ax - pushw %bp - movw %sp, %bp - andb $~0x01, 8(%bp) /* Clear CF on return */ - popw %bp - popfw - iret -1: /* INT 1A,other - pass through */ - popfw - ljmp *%cs:pxe_int_1a_vector - - .section ".text16.data", "aw", @progbits - .globl pxe_int_1a_vector -pxe_int_1a_vector: .long 0 diff --git a/qemu/roms/ipxe/src/arch/i386/interface/pxe/pxe_exit_hook.c b/qemu/roms/ipxe/src/arch/i386/interface/pxe/pxe_exit_hook.c deleted file mode 100644 index f92dae0d1..000000000 --- a/qemu/roms/ipxe/src/arch/i386/interface/pxe/pxe_exit_hook.c +++ /dev/null @@ -1,65 +0,0 @@ -/** @file - * - * PXE exit hook - * - */ - -/* - * Copyright (C) 2010 Shao Miller <shao.miller@yrdsb.edu.on.ca>. - * - * 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 <realmode.h> -#include <pxe.h> - -/** PXE exit hook */ -extern segoff_t __data16 ( pxe_exit_hook ); -#define pxe_exit_hook __use_data16 ( pxe_exit_hook ) - -/** - * FILE EXIT HOOK - * - * @v file_exit_hook Pointer to a struct - * s_PXENV_FILE_EXIT_HOOK - * @v s_PXENV_FILE_EXIT_HOOK::Hook SEG16:OFF16 to jump to - * @ret #PXENV_EXIT_SUCCESS Successfully set hook - * @ret #PXENV_EXIT_FAILURE We're not an NBP build - * @ret s_PXENV_FILE_EXIT_HOOK::Status PXE status code - * - */ -static PXENV_EXIT_t -pxenv_file_exit_hook ( struct s_PXENV_FILE_EXIT_HOOK *file_exit_hook ) { - DBG ( "PXENV_FILE_EXIT_HOOK" ); - - /* We'll jump to the specified SEG16:OFF16 during exit */ - pxe_exit_hook.segment = file_exit_hook->Hook.segment; - pxe_exit_hook.offset = file_exit_hook->Hook.offset; - file_exit_hook->Status = PXENV_STATUS_SUCCESS; - return PXENV_EXIT_SUCCESS; -} - -/** PXE file API */ -struct pxe_api_call pxe_file_api_exit_hook __pxe_api_call = - PXE_API_CALL ( PXENV_FILE_EXIT_HOOK, pxenv_file_exit_hook, - struct s_PXENV_FILE_EXIT_HOOK ); diff --git a/qemu/roms/ipxe/src/arch/i386/interface/pxe/pxe_file.c b/qemu/roms/ipxe/src/arch/i386/interface/pxe/pxe_file.c deleted file mode 100644 index 456ffb5fd..000000000 --- a/qemu/roms/ipxe/src/arch/i386/interface/pxe/pxe_file.c +++ /dev/null @@ -1,346 +0,0 @@ -/** @file - * - * PXE FILE API - * - */ - -#include <stdlib.h> -#include <stdio.h> -#include <errno.h> -#include <byteswap.h> -#include <ipxe/uaccess.h> -#include <ipxe/posix_io.h> -#include <ipxe/features.h> -#include <pxe.h> -#include <realmode.h> - -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 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 ); - -FEATURE ( FEATURE_MISC, "PXEXT", DHCP_EB_FEATURE_PXE_EXT, 2 ); - -/** - * FILE OPEN - * - * @v file_open Pointer to a struct s_PXENV_FILE_OPEN - * @v s_PXENV_FILE_OPEN::FileName URL of file to open - * @ret #PXENV_EXIT_SUCCESS File was opened - * @ret #PXENV_EXIT_FAILURE File was not opened - * @ret s_PXENV_FILE_OPEN::Status PXE status code - * @ret s_PXENV_FILE_OPEN::FileHandle Handle of opened file - * - */ -static PXENV_EXIT_t pxenv_file_open ( struct s_PXENV_FILE_OPEN *file_open ) { - userptr_t filename; - size_t filename_len; - int fd; - - DBG ( "PXENV_FILE_OPEN" ); - - /* Copy name from external program, and open it */ - filename = real_to_user ( file_open->FileName.segment, - file_open->FileName.offset ); - filename_len = strlen_user ( filename, 0 ); - { - char uri_string[ filename_len + 1 ]; - - copy_from_user ( uri_string, filename, 0, - sizeof ( uri_string ) ); - DBG ( " %s", uri_string ); - fd = open ( uri_string ); - } - - if ( fd < 0 ) { - file_open->Status = PXENV_STATUS ( fd ); - return PXENV_EXIT_FAILURE; - } - - DBG ( " as file %d", fd ); - - file_open->FileHandle = fd; - file_open->Status = PXENV_STATUS_SUCCESS; - return PXENV_EXIT_SUCCESS; -} - -/** - * FILE CLOSE - * - * @v file_close Pointer to a struct s_PXENV_FILE_CLOSE - * @v s_PXENV_FILE_CLOSE::FileHandle File handle - * @ret #PXENV_EXIT_SUCCESS File was closed - * @ret #PXENV_EXIT_FAILURE File was not closed - * @ret s_PXENV_FILE_CLOSE::Status PXE status code - * - */ -static PXENV_EXIT_t pxenv_file_close ( struct s_PXENV_FILE_CLOSE *file_close ) { - - DBG ( "PXENV_FILE_CLOSE %d", file_close->FileHandle ); - - close ( file_close->FileHandle ); - file_close->Status = PXENV_STATUS_SUCCESS; - return PXENV_EXIT_SUCCESS; -} - -/** - * FILE SELECT - * - * @v file_select Pointer to a struct s_PXENV_FILE_SELECT - * @v s_PXENV_FILE_SELECT::FileHandle File handle - * @ret #PXENV_EXIT_SUCCESS File has been checked for readiness - * @ret #PXENV_EXIT_FAILURE File has not been checked for readiness - * @ret s_PXENV_FILE_SELECT::Status PXE status code - * @ret s_PXENV_FILE_SELECT::Ready Indication of readiness - * - */ -static PXENV_EXIT_t -pxenv_file_select ( struct s_PXENV_FILE_SELECT *file_select ) { - fd_set fdset; - int ready; - - DBG ( "PXENV_FILE_SELECT %d", file_select->FileHandle ); - - FD_ZERO ( &fdset ); - FD_SET ( file_select->FileHandle, &fdset ); - if ( ( ready = select ( &fdset, 0 ) ) < 0 ) { - file_select->Status = PXENV_STATUS ( ready ); - return PXENV_EXIT_FAILURE; - } - - file_select->Ready = ( ready ? RDY_READ : 0 ); - file_select->Status = PXENV_STATUS_SUCCESS; - return PXENV_EXIT_SUCCESS; -} - -/** - * FILE READ - * - * @v file_read Pointer to a struct s_PXENV_FILE_READ - * @v s_PXENV_FILE_READ::FileHandle File handle - * @v s_PXENV_FILE_READ::BufferSize Size of data buffer - * @v s_PXENV_FILE_READ::Buffer Data buffer - * @ret #PXENV_EXIT_SUCCESS Data has been read from file - * @ret #PXENV_EXIT_FAILURE Data has not been read from file - * @ret s_PXENV_FILE_READ::Status PXE status code - * @ret s_PXENV_FILE_READ::Ready Indication of readiness - * @ret s_PXENV_FILE_READ::BufferSize Length of data read - * - */ -static PXENV_EXIT_t pxenv_file_read ( struct s_PXENV_FILE_READ *file_read ) { - userptr_t buffer; - ssize_t len; - - DBG ( "PXENV_FILE_READ %d to %04x:%04x+%04x", file_read->FileHandle, - file_read->Buffer.segment, file_read->Buffer.offset, - file_read->BufferSize ); - - buffer = real_to_user ( file_read->Buffer.segment, - file_read->Buffer.offset ); - if ( ( len = read_user ( file_read->FileHandle, buffer, 0, - file_read->BufferSize ) ) < 0 ) { - file_read->Status = PXENV_STATUS ( len ); - return PXENV_EXIT_FAILURE; - } - - DBG ( " read %04zx", ( ( size_t ) len ) ); - - file_read->BufferSize = len; - file_read->Status = PXENV_STATUS_SUCCESS; - return PXENV_EXIT_SUCCESS; -} - -/** - * GET FILE SIZE - * - * @v get_file_size Pointer to a struct s_PXENV_GET_FILE_SIZE - * @v s_PXENV_GET_FILE_SIZE::FileHandle File handle - * @ret #PXENV_EXIT_SUCCESS File size has been determined - * @ret #PXENV_EXIT_FAILURE File size has not been determined - * @ret s_PXENV_GET_FILE_SIZE::Status PXE status code - * @ret s_PXENV_GET_FILE_SIZE::FileSize Size of file - */ -static PXENV_EXIT_t -pxenv_get_file_size ( struct s_PXENV_GET_FILE_SIZE *get_file_size ) { - ssize_t filesize; - - DBG ( "PXENV_GET_FILE_SIZE %d", get_file_size->FileHandle ); - - filesize = fsize ( get_file_size->FileHandle ); - if ( filesize < 0 ) { - get_file_size->Status = PXENV_STATUS ( filesize ); - return PXENV_EXIT_FAILURE; - } - - DBG ( " is %zd", ( ( size_t ) filesize ) ); - - get_file_size->FileSize = filesize; - get_file_size->Status = PXENV_STATUS_SUCCESS; - return PXENV_EXIT_SUCCESS; -} - -/** - * FILE EXEC - * - * @v file_exec Pointer to a struct s_PXENV_FILE_EXEC - * @v s_PXENV_FILE_EXEC::Command Command to execute - * @ret #PXENV_EXIT_SUCCESS Command was executed successfully - * @ret #PXENV_EXIT_FAILURE Command was not executed successfully - * @ret s_PXENV_FILE_EXEC::Status PXE status code - * - */ -static PXENV_EXIT_t pxenv_file_exec ( struct s_PXENV_FILE_EXEC *file_exec ) { - userptr_t command; - size_t command_len; - int rc; - - DBG ( "PXENV_FILE_EXEC" ); - - /* Copy name from external program, and exec it */ - command = real_to_user ( file_exec->Command.segment, - file_exec->Command.offset ); - command_len = strlen_user ( command, 0 ); - { - char command_string[ command_len + 1 ]; - - copy_from_user ( command_string, command, 0, - sizeof ( command_string ) ); - DBG ( " %s", command_string ); - - if ( ( rc = system ( command_string ) ) != 0 ) { - file_exec->Status = PXENV_STATUS ( rc ); - return PXENV_EXIT_FAILURE; - } - } - - file_exec->Status = PXENV_STATUS_SUCCESS; - return PXENV_EXIT_SUCCESS; -} - -/** - * FILE CMDLINE - * - * @v file_cmdline Pointer to a struct s_PXENV_FILE_CMDLINE - * @v s_PXENV_FILE_CMDLINE::Buffer Buffer to contain command line - * @v s_PXENV_FILE_CMDLINE::BufferSize Size of buffer - * @ret #PXENV_EXIT_SUCCESS Command was executed successfully - * @ret #PXENV_EXIT_FAILURE Command was not executed successfully - * @ret s_PXENV_FILE_EXEC::Status PXE status code - * @ret s_PXENV_FILE_EXEC::BufferSize Length of command line (including NUL) - * - */ -static PXENV_EXIT_t -pxenv_file_cmdline ( struct s_PXENV_FILE_CMDLINE *file_cmdline ) { - userptr_t buffer; - size_t max_len; - size_t len; - - DBG ( "PXENV_FILE_CMDLINE to %04x:%04x+%04x \"%s\"\n", - file_cmdline->Buffer.segment, file_cmdline->Buffer.offset, - file_cmdline->BufferSize, pxe_cmdline ); - - buffer = real_to_user ( file_cmdline->Buffer.segment, - file_cmdline->Buffer.offset ); - len = file_cmdline->BufferSize; - max_len = ( pxe_cmdline ? - ( strlen ( pxe_cmdline ) + 1 /* NUL */ ) : 0 ); - if ( len > max_len ) - len = max_len; - copy_to_user ( buffer, 0, pxe_cmdline, len ); - file_cmdline->BufferSize = max_len; - - file_cmdline->Status = PXENV_STATUS_SUCCESS; - return PXENV_EXIT_SUCCESS; -} - -/** - * FILE API CHECK - * - * @v file_exec Pointer to a struct s_PXENV_FILE_API_CHECK - * @v s_PXENV_FILE_API_CHECK::Magic Inbound magic number (0x91d447b2) - * @ret #PXENV_EXIT_SUCCESS Command was executed successfully - * @ret #PXENV_EXIT_FAILURE Command was not executed successfully - * @ret s_PXENV_FILE_API_CHECK::Status PXE status code - * @ret s_PXENV_FILE_API_CHECK::Magic Outbound magic number (0xe9c17b20) - * @ret s_PXENV_FILE_API_CHECK::Provider "iPXE" (0x45585067) - * @ret s_PXENV_FILE_API_CHECK::APIMask API function bitmask - * @ret s_PXENV_FILE_API_CHECK::Flags Reserved - * - */ -static PXENV_EXIT_t -pxenv_file_api_check ( struct s_PXENV_FILE_API_CHECK *file_api_check ) { - struct pxe_api_call *call; - unsigned int mask = 0; - unsigned int offset; - - DBG ( "PXENV_FILE_API_CHECK" ); - - /* Check for magic value */ - if ( file_api_check->Magic != 0x91d447b2 ) { - file_api_check->Status = PXENV_STATUS_BAD_FUNC; - return PXENV_EXIT_FAILURE; - } - - /* Check for required parameter size */ - if ( file_api_check->Size < sizeof ( *file_api_check ) ) { - file_api_check->Status = PXENV_STATUS_OUT_OF_RESOURCES; - return PXENV_EXIT_FAILURE; - } - - /* Determine supported calls */ - for_each_table_entry ( call, PXE_API_CALLS ) { - offset = ( call->opcode - PXENV_FILE_MIN ); - if ( offset <= ( PXENV_FILE_MAX - PXENV_FILE_MIN ) ) - mask |= ( 1 << offset ); - } - - /* Fill in parameters */ - file_api_check->Size = sizeof ( *file_api_check ); - file_api_check->Magic = 0xe9c17b20; - file_api_check->Provider = 0x45585067; /* "iPXE" */ - file_api_check->APIMask = mask; - file_api_check->Flags = 0; /* None defined */ - - file_api_check->Status = PXENV_STATUS_SUCCESS; - return PXENV_EXIT_SUCCESS; -} - -/** PXE file API */ -struct pxe_api_call pxe_file_api[] __pxe_api_call = { - PXE_API_CALL ( PXENV_FILE_OPEN, pxenv_file_open, - struct s_PXENV_FILE_OPEN ), - PXE_API_CALL ( PXENV_FILE_CLOSE, pxenv_file_close, - struct s_PXENV_FILE_CLOSE ), - PXE_API_CALL ( PXENV_FILE_SELECT, pxenv_file_select, - struct s_PXENV_FILE_SELECT ), - PXE_API_CALL ( PXENV_FILE_READ, pxenv_file_read, - struct s_PXENV_FILE_READ ), - PXE_API_CALL ( PXENV_GET_FILE_SIZE, pxenv_get_file_size, - struct s_PXENV_GET_FILE_SIZE ), - PXE_API_CALL ( PXENV_FILE_EXEC, pxenv_file_exec, - struct s_PXENV_FILE_EXEC ), - PXE_API_CALL ( PXENV_FILE_CMDLINE, pxenv_file_cmdline, - struct s_PXENV_FILE_CMDLINE ), - PXE_API_CALL ( PXENV_FILE_API_CHECK, pxenv_file_api_check, - struct s_PXENV_FILE_API_CHECK ), -}; diff --git a/qemu/roms/ipxe/src/arch/i386/interface/pxe/pxe_loader.c b/qemu/roms/ipxe/src/arch/i386/interface/pxe/pxe_loader.c deleted file mode 100644 index e6a2e072a..000000000 --- a/qemu/roms/ipxe/src/arch/i386/interface/pxe/pxe_loader.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 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 <ipxe/init.h> -#include "pxe.h" -#include "pxe_call.h" - -/** @file - * - * PXE UNDI loader - * - */ - -/* PXENV_UNDI_LOADER - * - */ -PXENV_EXIT_t undi_loader ( struct s_UNDI_LOADER *undi_loader ) { - - /* Perform one-time initialisation (e.g. heap) */ - initialise(); - - DBG ( "[PXENV_UNDI_LOADER to CS %04x DS %04x]", - undi_loader->UNDI_CS, undi_loader->UNDI_DS ); - - /* Fill in UNDI loader structure */ - undi_loader->PXEptr.segment = rm_cs; - undi_loader->PXEptr.offset = __from_text16 ( &ppxe ); - undi_loader->PXENVptr.segment = rm_cs; - undi_loader->PXENVptr.offset = __from_text16 ( &pxenv ); - - undi_loader->Status = PXENV_STATUS_SUCCESS; - return PXENV_EXIT_SUCCESS; -} diff --git a/qemu/roms/ipxe/src/arch/i386/interface/pxe/pxe_preboot.c b/qemu/roms/ipxe/src/arch/i386/interface/pxe/pxe_preboot.c deleted file mode 100644 index 6e09080bc..000000000 --- a/qemu/roms/ipxe/src/arch/i386/interface/pxe/pxe_preboot.c +++ /dev/null @@ -1,387 +0,0 @@ -/** @file - * - * PXE Preboot API - * - */ - -/* PXE API interface for Etherboot. - * - * Copyright (C) 2004 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 <string.h> -#include <stdlib.h> -#include <setjmp.h> -#include <ipxe/uaccess.h> -#include <ipxe/dhcp.h> -#include <ipxe/fakedhcp.h> -#include <ipxe/device.h> -#include <ipxe/netdevice.h> -#include <ipxe/isapnp.h> -#include <ipxe/init.h> -#include <ipxe/if_ether.h> -#include <basemem_packet.h> -#include <biosint.h> -#include "pxe.h" -#include "pxe_call.h" - -/* Avoid dragging in isapnp.o unnecessarily */ -uint16_t isapnp_read_port; - -/** Zero-based versions of PXENV_GET_CACHED_INFO::PacketType */ -enum pxe_cached_info_indices { - CACHED_INFO_DHCPDISCOVER = ( PXENV_PACKET_TYPE_DHCP_DISCOVER - 1 ), - CACHED_INFO_DHCPACK = ( PXENV_PACKET_TYPE_DHCP_ACK - 1 ), - CACHED_INFO_BINL = ( PXENV_PACKET_TYPE_CACHED_REPLY - 1 ), - NUM_CACHED_INFOS -}; - -/** A cached DHCP packet */ -union pxe_cached_info { - struct dhcphdr dhcphdr; - /* This buffer must be *exactly* the size of a BOOTPLAYER_t - * structure, otherwise WinPE will die horribly. It takes the - * size of *our* buffer and feeds it in to us as the size of - * one of *its* buffers. If our buffer is larger than it - * expects, we therefore end up overwriting part of its data - * segment, since it tells us to do so. (D'oh!) - * - * Note that a BOOTPLAYER_t is not necessarily large enough to - * hold a DHCP packet; this is a flaw in the PXE spec. - */ - BOOTPLAYER_t packet; -} __attribute__ (( packed )); - -/** A PXE DHCP packet creator */ -struct pxe_dhcp_packet_creator { - /** Create DHCP packet - * - * @v netdev Network device - * @v data Buffer for DHCP packet - * @v max_len Size of DHCP packet buffer - * @ret rc Return status code - */ - int ( * create ) ( struct net_device *netdev, void *data, - size_t max_len ); -}; - -/** PXE DHCP packet creators */ -static struct pxe_dhcp_packet_creator pxe_dhcp_packet_creators[] = { - [CACHED_INFO_DHCPDISCOVER] = { create_fakedhcpdiscover }, - [CACHED_INFO_DHCPACK] = { create_fakedhcpack }, - [CACHED_INFO_BINL] = { create_fakepxebsack }, -}; - -/** - * Name PXENV_GET_CACHED_INFO packet type - * - * @v packet_type Packet type - * @ret name Name of packet type - */ -static inline __attribute__ (( always_inline )) const char * -pxenv_get_cached_info_name ( int packet_type ) { - switch ( packet_type ) { - case PXENV_PACKET_TYPE_DHCP_DISCOVER: - return "DHCPDISCOVER"; - case PXENV_PACKET_TYPE_DHCP_ACK: - return "DHCPACK"; - case PXENV_PACKET_TYPE_CACHED_REPLY: - return "BINL"; - default: - return "<INVALID>"; - } -} - -/* The case in which the caller doesn't supply a buffer is really - * awkward to support given that we have multiple sources of options, - * and that we don't actually store the DHCP packets. (We may not - * even have performed DHCP; we may have obtained all configuration - * from non-volatile stored options or from the command line.) - * - * Some NBPs rely on the buffers we provide being persistent, so we - * can't just use the temporary packet buffer. 4.5kB of base memory - * always wasted just because some clients are too lazy to provide - * their own buffers... - */ -static union pxe_cached_info __bss16_array ( cached_info, [NUM_CACHED_INFOS] ); -#define cached_info __use_data16 ( cached_info ) - -/** - * UNLOAD BASE CODE STACK - * - * @v None - - * @ret ... - * - */ -static PXENV_EXIT_t -pxenv_unload_stack ( struct s_PXENV_UNLOAD_STACK *unload_stack ) { - DBGC ( &pxe_netdev, "PXENV_UNLOAD_STACK\n" ); - - unload_stack->Status = PXENV_STATUS_SUCCESS; - return PXENV_EXIT_SUCCESS; -} - -/* PXENV_GET_CACHED_INFO - * - * Status: working - */ -static PXENV_EXIT_t -pxenv_get_cached_info ( struct s_PXENV_GET_CACHED_INFO *get_cached_info ) { - struct pxe_dhcp_packet_creator *creator; - union pxe_cached_info *info; - unsigned int idx; - size_t len; - userptr_t buffer; - int rc; - - DBGC ( &pxe_netdev, "PXENV_GET_CACHED_INFO %s to %04x:%04x+%x", - pxenv_get_cached_info_name ( get_cached_info->PacketType ), - get_cached_info->Buffer.segment, - get_cached_info->Buffer.offset, get_cached_info->BufferSize ); - - /* Sanity check */ - if ( ! pxe_netdev ) { - DBGC ( &pxe_netdev, "PXENV_GET_CACHED_INFO called with no " - "network device\n" ); - get_cached_info->Status = PXENV_STATUS_UNDI_INVALID_STATE; - return PXENV_EXIT_FAILURE; - } - - /* Sanity check */ - idx = ( get_cached_info->PacketType - 1 ); - if ( idx >= NUM_CACHED_INFOS ) { - DBGC ( &pxe_netdev, " bad PacketType %d\n", - get_cached_info->PacketType ); - goto err; - } - info = &cached_info[idx]; - - /* Construct DHCP packet */ - creator = &pxe_dhcp_packet_creators[idx]; - if ( ( rc = creator->create ( pxe_netdev, info, - sizeof ( *info ) ) ) != 0 ) { - DBGC ( &pxe_netdev, " failed to build packet: %s\n", - strerror ( rc ) ); - goto err; - } - - /* Copy packet (if applicable) */ - len = get_cached_info->BufferSize; - if ( len == 0 ) { - /* Point client at our cached buffer. - * - * To add to the fun, Intel decided at some point in - * the evolution of the PXE specification to add the - * BufferLimit field, which we are meant to fill in - * with the length of our packet buffer, so that the - * caller can safely modify the boot server reply - * packet stored therein. However, this field was not - * present in earlier versions of the PXE spec, and - * there is at least one PXE NBP (Altiris) which - * allocates only exactly enough space for this - * earlier, shorter version of the structure. If we - * actually fill in the BufferLimit field, we - * therefore risk trashing random areas of the - * caller's memory. If we *don't* fill it in, then - * the caller is at liberty to assume that whatever - * random value happened to be in that location - * represents the length of the buffer we've just - * passed back to it. - * - * Since older PXE stacks won't fill this field in - * anyway, it's probably safe to assume that no - * callers actually rely on it, so we choose to not - * fill it in. - */ - get_cached_info->Buffer.segment = rm_ds; - get_cached_info->Buffer.offset = __from_data16 ( info ); - get_cached_info->BufferSize = sizeof ( *info ); - DBGC ( &pxe_netdev, " using %04x:%04x+%04x['%x']", - get_cached_info->Buffer.segment, - get_cached_info->Buffer.offset, - get_cached_info->BufferSize, - get_cached_info->BufferLimit ); - } else { - /* Copy packet to client buffer */ - if ( len > sizeof ( *info ) ) - len = sizeof ( *info ); - if ( len < sizeof ( *info ) ) - DBGC ( &pxe_netdev, " buffer may be too short" ); - buffer = real_to_user ( get_cached_info->Buffer.segment, - get_cached_info->Buffer.offset ); - copy_to_user ( buffer, 0, info, len ); - get_cached_info->BufferSize = len; - } - - DBGC ( &pxe_netdev, "\n" ); - get_cached_info->Status = PXENV_STATUS_SUCCESS; - return PXENV_EXIT_SUCCESS; - - err: - get_cached_info->Status = PXENV_STATUS_OUT_OF_RESOURCES; - return PXENV_EXIT_FAILURE; -} - -/* PXENV_RESTART_TFTP - * - * Status: working - */ -static PXENV_EXIT_t -pxenv_restart_tftp ( struct s_PXENV_TFTP_READ_FILE *restart_tftp ) { - PXENV_EXIT_t tftp_exit; - - DBGC ( &pxe_netdev, "PXENV_RESTART_TFTP\n" ); - - /* Words cannot describe the complete mismatch between the PXE - * specification and any possible version of reality... - */ - restart_tftp->Buffer = PXE_LOAD_PHYS; /* Fixed by spec, apparently */ - restart_tftp->BufferSize = ( 0xa0000 - PXE_LOAD_PHYS ); /* Near enough */ - tftp_exit = pxenv_tftp_read_file ( restart_tftp ); - if ( tftp_exit != PXENV_EXIT_SUCCESS ) - return tftp_exit; - - /* Restart NBP */ - rmlongjmp ( pxe_restart_nbp, PXENV_RESTART_TFTP ); -} - -/* PXENV_START_UNDI - * - * Status: working - */ -static PXENV_EXIT_t pxenv_start_undi ( struct s_PXENV_START_UNDI *start_undi ) { - unsigned int bus_type; - unsigned int location; - struct net_device *netdev; - - DBGC ( &pxe_netdev, "PXENV_START_UNDI %04x:%04x:%04x\n", - start_undi->AX, start_undi->BX, start_undi->DX ); - - /* Determine bus type and location. Use a heuristic to decide - * whether we are PCI or ISAPnP - */ - if ( ( start_undi->DX >= ISAPNP_READ_PORT_MIN ) && - ( start_undi->DX <= ISAPNP_READ_PORT_MAX ) && - ( start_undi->BX >= ISAPNP_CSN_MIN ) && - ( start_undi->BX <= ISAPNP_CSN_MAX ) ) { - bus_type = BUS_TYPE_ISAPNP; - location = start_undi->BX; - /* Record ISAPnP read port for use by isapnp.c */ - isapnp_read_port = start_undi->DX; - } else { - bus_type = BUS_TYPE_PCI; - location = start_undi->AX; - } - - /* Probe for devices, etc. */ - startup(); - - /* Look for a matching net device */ - netdev = find_netdev_by_location ( bus_type, location ); - if ( ! netdev ) { - DBGC ( &pxe_netdev, "PXENV_START_UNDI could not find matching " - "net device\n" ); - start_undi->Status = PXENV_STATUS_UNDI_CANNOT_INITIALIZE_NIC; - return PXENV_EXIT_FAILURE; - } - DBGC ( &pxe_netdev, "PXENV_START_UNDI found net device %s\n", - netdev->name ); - - /* Activate PXE */ - pxe_activate ( netdev ); - - start_undi->Status = PXENV_STATUS_SUCCESS; - return PXENV_EXIT_SUCCESS; -} - -/* PXENV_STOP_UNDI - * - * Status: working - */ -static PXENV_EXIT_t pxenv_stop_undi ( struct s_PXENV_STOP_UNDI *stop_undi ) { - DBGC ( &pxe_netdev, "PXENV_STOP_UNDI\n" ); - - /* Deactivate PXE */ - pxe_deactivate(); - - /* Prepare for unload */ - shutdown_boot(); - - /* Check to see if we still have any hooked interrupts */ - if ( hooked_bios_interrupts != 0 ) { - DBGC ( &pxe_netdev, "PXENV_STOP_UNDI failed: %d interrupts " - "still hooked\n", hooked_bios_interrupts ); - stop_undi->Status = PXENV_STATUS_KEEP_UNDI; - return PXENV_EXIT_FAILURE; - } - - stop_undi->Status = PXENV_STATUS_SUCCESS; - return PXENV_EXIT_SUCCESS; -} - -/* PXENV_START_BASE - * - * Status: won't implement (requires major structural changes) - */ -static PXENV_EXIT_t pxenv_start_base ( struct s_PXENV_START_BASE *start_base ) { - DBGC ( &pxe_netdev, "PXENV_START_BASE\n" ); - - start_base->Status = PXENV_STATUS_UNSUPPORTED; - return PXENV_EXIT_FAILURE; -} - -/* PXENV_STOP_BASE - * - * Status: working - */ -static PXENV_EXIT_t pxenv_stop_base ( struct s_PXENV_STOP_BASE *stop_base ) { - DBGC ( &pxe_netdev, "PXENV_STOP_BASE\n" ); - - /* The only time we will be called is when the NBP is trying - * to shut down the PXE stack. There's nothing we need to do - * in this call. - */ - - stop_base->Status = PXENV_STATUS_SUCCESS; - return PXENV_EXIT_SUCCESS; -} - -/** PXE preboot API */ -struct pxe_api_call pxe_preboot_api[] __pxe_api_call = { - PXE_API_CALL ( PXENV_UNLOAD_STACK, pxenv_unload_stack, - struct s_PXENV_UNLOAD_STACK ), - PXE_API_CALL ( PXENV_GET_CACHED_INFO, pxenv_get_cached_info, - struct s_PXENV_GET_CACHED_INFO ), - PXE_API_CALL ( PXENV_RESTART_TFTP, pxenv_restart_tftp, - struct s_PXENV_TFTP_READ_FILE ), - PXE_API_CALL ( PXENV_START_UNDI, pxenv_start_undi, - struct s_PXENV_START_UNDI ), - PXE_API_CALL ( PXENV_STOP_UNDI, pxenv_stop_undi, - struct s_PXENV_STOP_UNDI ), - PXE_API_CALL ( PXENV_START_BASE, pxenv_start_base, - struct s_PXENV_START_BASE ), - PXE_API_CALL ( PXENV_STOP_BASE, pxenv_stop_base, - struct s_PXENV_STOP_BASE ), -}; diff --git a/qemu/roms/ipxe/src/arch/i386/interface/pxe/pxe_tftp.c b/qemu/roms/ipxe/src/arch/i386/interface/pxe/pxe_tftp.c deleted file mode 100644 index 068d8a7b2..000000000 --- a/qemu/roms/ipxe/src/arch/i386/interface/pxe/pxe_tftp.c +++ /dev/null @@ -1,597 +0,0 @@ -/** @file - * - * PXE TFTP API - * - */ - -/* - * Copyright (C) 2004 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 <stdlib.h> -#include <stdio.h> -#include <errno.h> -#include <byteswap.h> -#include <ipxe/uaccess.h> -#include <ipxe/in.h> -#include <ipxe/tftp.h> -#include <ipxe/iobuf.h> -#include <ipxe/xfer.h> -#include <ipxe/open.h> -#include <ipxe/process.h> -#include <ipxe/uri.h> -#include <realmode.h> -#include <pxe.h> - -/** A PXE TFTP connection */ -struct pxe_tftp_connection { - /** Data transfer interface */ - struct interface xfer; - /** Data buffer */ - userptr_t buffer; - /** Size of data buffer */ - size_t size; - /** Starting offset of data buffer */ - size_t start; - /** File position */ - size_t offset; - /** Maximum file position */ - size_t max_offset; - /** Block size */ - size_t blksize; - /** Block index */ - unsigned int blkidx; - /** Overall return status code */ - int rc; -}; - -/** - * Close PXE TFTP connection - * - * @v pxe_tftp PXE TFTP connection - * @v rc Final status code - */ -static void pxe_tftp_close ( struct pxe_tftp_connection *pxe_tftp, int rc ) { - intf_shutdown ( &pxe_tftp->xfer, rc ); - pxe_tftp->rc = rc; -} - -/** - * Check flow control window - * - * @v pxe_tftp PXE TFTP connection - * @ret len Length of window - */ -static size_t pxe_tftp_xfer_window ( struct pxe_tftp_connection *pxe_tftp ) { - - return pxe_tftp->blksize; -} - -/** - * Receive new data - * - * @v pxe_tftp PXE TFTP connection - * @v iobuf I/O buffer - * @v meta Transfer metadata - * @ret rc Return status code - */ -static int pxe_tftp_xfer_deliver ( struct pxe_tftp_connection *pxe_tftp, - struct io_buffer *iobuf, - struct xfer_metadata *meta ) { - size_t len = iob_len ( iobuf ); - int rc = 0; - - /* Calculate new buffer position */ - if ( meta->flags & XFER_FL_ABS_OFFSET ) - pxe_tftp->offset = 0; - pxe_tftp->offset += meta->offset; - - /* Copy data block to buffer */ - if ( len == 0 ) { - /* No data (pure seek); treat as success */ - } else if ( pxe_tftp->offset < pxe_tftp->start ) { - DBG ( " buffer underrun at %zx (min %zx)", - pxe_tftp->offset, pxe_tftp->start ); - rc = -ENOBUFS; - } else if ( ( pxe_tftp->offset + len ) > - ( pxe_tftp->start + pxe_tftp->size ) ) { - DBG ( " buffer overrun at %zx (max %zx)", - ( pxe_tftp->offset + len ), - ( pxe_tftp->start + pxe_tftp->size ) ); - rc = -ENOBUFS; - } else { - copy_to_user ( pxe_tftp->buffer, - ( pxe_tftp->offset - pxe_tftp->start ), - iobuf->data, len ); - } - - /* Calculate new buffer position */ - pxe_tftp->offset += len; - - /* Record maximum offset as the file size */ - if ( pxe_tftp->max_offset < pxe_tftp->offset ) - pxe_tftp->max_offset = pxe_tftp->offset; - - /* Terminate transfer on error */ - if ( rc != 0 ) - pxe_tftp_close ( pxe_tftp, rc ); - - free_iob ( iobuf ); - return rc; -} - -/** PXE TFTP connection interface operations */ -static struct interface_operation pxe_tftp_xfer_ops[] = { - INTF_OP ( xfer_deliver, struct pxe_tftp_connection *, - pxe_tftp_xfer_deliver ), - INTF_OP ( xfer_window, struct pxe_tftp_connection *, - pxe_tftp_xfer_window ), - INTF_OP ( intf_close, struct pxe_tftp_connection *, pxe_tftp_close ), -}; - -/** PXE TFTP connection interface descriptor */ -static struct interface_descriptor pxe_tftp_xfer_desc = - INTF_DESC ( struct pxe_tftp_connection, xfer, pxe_tftp_xfer_ops ); - -/** The PXE TFTP connection */ -static struct pxe_tftp_connection pxe_tftp = { - .xfer = INTF_INIT ( pxe_tftp_xfer_desc ), -}; - -/** - * Maximum length of a PXE TFTP URI - * - * The PXE TFTP API provides 128 characters for the filename; the - * extra 128 bytes allow for the remainder of the URI. - */ -#define PXE_TFTP_URI_LEN 256 - -/** - * Open PXE TFTP connection - * - * @v ipaddress IP address - * @v port TFTP server port - * @v filename File name - * @v blksize Requested block size - * @ret rc Return status code - */ -static int pxe_tftp_open ( IP4_t ipaddress, UDP_PORT_t port, - UINT8_t *filename, UINT16_t blksize ) { - struct in_addr address; - struct uri *uri; - int rc; - - /* Reset PXE TFTP connection structure */ - memset ( &pxe_tftp, 0, sizeof ( pxe_tftp ) ); - intf_init ( &pxe_tftp.xfer, &pxe_tftp_xfer_desc, NULL ); - if ( blksize < TFTP_DEFAULT_BLKSIZE ) - blksize = TFTP_DEFAULT_BLKSIZE; - pxe_tftp.blksize = blksize; - pxe_tftp.rc = -EINPROGRESS; - - /* Construct URI */ - address.s_addr = ipaddress; - DBG ( " %s", inet_ntoa ( address ) ); - if ( port ) - DBG ( ":%d", ntohs ( port ) ); - DBG ( ":%s", filename ); - uri = tftp_uri ( address, ntohs ( port ), ( ( char * ) filename ) ); - if ( ! uri ) { - DBG ( " could not create URI\n" ); - return -ENOMEM; - } - - /* Open PXE TFTP connection */ - if ( ( rc = xfer_open_uri ( &pxe_tftp.xfer, uri ) ) != 0 ) { - DBG ( " could not open (%s)\n", strerror ( rc ) ); - return rc; - } - - return 0; -} - -/** - * TFTP OPEN - * - * @v tftp_open Pointer to a struct s_PXENV_TFTP_OPEN - * @v s_PXENV_TFTP_OPEN::ServerIPAddress TFTP server IP address - * @v s_PXENV_TFTP_OPEN::GatewayIPAddress Relay agent IP address, or 0.0.0.0 - * @v s_PXENV_TFTP_OPEN::FileName Name of file to open - * @v s_PXENV_TFTP_OPEN::TFTPPort TFTP server UDP port - * @v s_PXENV_TFTP_OPEN::PacketSize TFTP blksize option to request - * @ret #PXENV_EXIT_SUCCESS File was opened - * @ret #PXENV_EXIT_FAILURE File was not opened - * @ret s_PXENV_TFTP_OPEN::Status PXE status code - * @ret s_PXENV_TFTP_OPEN::PacketSize Negotiated blksize - * @err #PXENV_STATUS_TFTP_INVALID_PACKET_SIZE Requested blksize too small - * - * Opens a TFTP connection for downloading a file a block at a time - * using pxenv_tftp_read(). - * - * If s_PXENV_TFTP_OPEN::GatewayIPAddress is 0.0.0.0, normal IP - * routing will take place. See the relevant - * @ref pxe_routing "implementation note" for more details. - * - * On x86, you must set the s_PXE::StatusCallout field to a nonzero - * value before calling this function in protected mode. You cannot - * call this function with a 32-bit stack segment. (See the relevant - * @ref pxe_x86_pmode16 "implementation note" for more details.) - * - * @note According to the PXE specification version 2.1, this call - * "opens a file for reading/writing", though how writing is to be - * achieved without the existence of an API call %pxenv_tftp_write() - * is not made clear. - * - * @note Despite the existence of the numerous statements within the - * PXE specification of the form "...if a TFTP/MTFTP or UDP connection - * is active...", you cannot use pxenv_tftp_open() and - * pxenv_tftp_read() to read a file via MTFTP; only via plain old - * TFTP. If you want to use MTFTP, use pxenv_tftp_read_file() - * instead. Astute readers will note that, since - * pxenv_tftp_read_file() is an atomic operation from the point of - * view of the PXE API, it is conceptually impossible to issue any - * other PXE API call "if an MTFTP connection is active". - */ -static PXENV_EXIT_t pxenv_tftp_open ( struct s_PXENV_TFTP_OPEN *tftp_open ) { - int rc; - - DBG ( "PXENV_TFTP_OPEN" ); - - /* Guard against callers that fail to close before re-opening */ - pxe_tftp_close ( &pxe_tftp, 0 ); - - /* Open connection */ - if ( ( rc = pxe_tftp_open ( tftp_open->ServerIPAddress, - tftp_open->TFTPPort, - tftp_open->FileName, - tftp_open->PacketSize ) ) != 0 ) { - tftp_open->Status = PXENV_STATUS ( rc ); - return PXENV_EXIT_FAILURE; - } - - /* Wait for OACK to arrive so that we have the block size */ - while ( ( ( rc = pxe_tftp.rc ) == -EINPROGRESS ) && - ( pxe_tftp.max_offset == 0 ) ) { - step(); - } - pxe_tftp.blksize = xfer_window ( &pxe_tftp.xfer ); - tftp_open->PacketSize = pxe_tftp.blksize; - DBG ( " blksize=%d", tftp_open->PacketSize ); - - /* EINPROGRESS is normal; we don't wait for the whole transfer */ - if ( rc == -EINPROGRESS ) - rc = 0; - - tftp_open->Status = PXENV_STATUS ( rc ); - return ( rc ? PXENV_EXIT_FAILURE : PXENV_EXIT_SUCCESS ); -} - -/** - * TFTP CLOSE - * - * @v tftp_close Pointer to a struct s_PXENV_TFTP_CLOSE - * @ret #PXENV_EXIT_SUCCESS File was closed successfully - * @ret #PXENV_EXIT_FAILURE File was not closed - * @ret s_PXENV_TFTP_CLOSE::Status PXE status code - * @err None - - * - * Close a connection previously opened with pxenv_tftp_open(). You - * must have previously opened a connection with pxenv_tftp_open(). - * - * On x86, you must set the s_PXE::StatusCallout field to a nonzero - * value before calling this function in protected mode. You cannot - * call this function with a 32-bit stack segment. (See the relevant - * @ref pxe_x86_pmode16 "implementation note" for more details.) - */ -static PXENV_EXIT_t pxenv_tftp_close ( struct s_PXENV_TFTP_CLOSE *tftp_close ) { - DBG ( "PXENV_TFTP_CLOSE" ); - - pxe_tftp_close ( &pxe_tftp, 0 ); - tftp_close->Status = PXENV_STATUS_SUCCESS; - return PXENV_EXIT_SUCCESS; -} - -/** - * TFTP READ - * - * @v tftp_read Pointer to a struct s_PXENV_TFTP_READ - * @v s_PXENV_TFTP_READ::Buffer Address of data buffer - * @ret #PXENV_EXIT_SUCCESS Data was read successfully - * @ret #PXENV_EXIT_FAILURE Data was not read - * @ret s_PXENV_TFTP_READ::Status PXE status code - * @ret s_PXENV_TFTP_READ::PacketNumber TFTP packet number - * @ret s_PXENV_TFTP_READ::BufferSize Length of data written into buffer - * - * Reads a single packet from a connection previously opened with - * pxenv_tftp_open() into the data buffer pointed to by - * s_PXENV_TFTP_READ::Buffer. You must have previously opened a - * connection with pxenv_tftp_open(). The data written into - * s_PXENV_TFTP_READ::Buffer is just the file data; the various - * network headers have already been removed. - * - * The buffer must be large enough to contain a packet of the size - * negotiated via the s_PXENV_TFTP_OPEN::PacketSize field in the - * pxenv_tftp_open() call. It is worth noting that the PXE - * specification does @b not require the caller to fill in - * s_PXENV_TFTP_READ::BufferSize before calling pxenv_tftp_read(), so - * the PXE stack is free to ignore whatever value the caller might - * place there and just assume that the buffer is large enough. That - * said, it may be worth the caller always filling in - * s_PXENV_TFTP_READ::BufferSize to guard against PXE stacks that - * mistake it for an input parameter. - * - * The length of the TFTP data packet will be returned via - * s_PXENV_TFTP_READ::BufferSize. If this length is less than the - * blksize negotiated via s_PXENV_TFTP_OPEN::PacketSize in the call to - * pxenv_tftp_open(), this indicates that the block is the last block - * in the file. Note that zero is a valid length for - * s_PXENV_TFTP_READ::BufferSize, and will occur when the length of - * the file is a multiple of the blksize. - * - * The PXE specification doesn't actually state that calls to - * pxenv_tftp_read() will return the data packets in strict sequential - * order, though most PXE stacks will probably do so. The sequence - * number of the packet will be returned in - * s_PXENV_TFTP_READ::PacketNumber. The first packet in the file has - * a sequence number of one, not zero. - * - * To guard against flawed PXE stacks, the caller should probably set - * s_PXENV_TFTP_READ::PacketNumber to one less than the expected - * returned value (i.e. set it to zero for the first call to - * pxenv_tftp_read() and then re-use the returned s_PXENV_TFTP_READ - * parameter block for subsequent calls without modifying - * s_PXENV_TFTP_READ::PacketNumber between calls). The caller should - * also guard against potential problems caused by flawed - * implementations returning the occasional duplicate packet, by - * checking that the value returned in s_PXENV_TFTP_READ::PacketNumber - * is as expected (i.e. one greater than that returned from the - * previous call to pxenv_tftp_read()). - * - * On x86, you must set the s_PXE::StatusCallout field to a nonzero - * value before calling this function in protected mode. You cannot - * call this function with a 32-bit stack segment. (See the relevant - * @ref pxe_x86_pmode16 "implementation note" for more details.) - */ -static PXENV_EXIT_t pxenv_tftp_read ( struct s_PXENV_TFTP_READ *tftp_read ) { - int rc; - - DBG ( "PXENV_TFTP_READ to %04x:%04x", - tftp_read->Buffer.segment, tftp_read->Buffer.offset ); - - /* Read single block into buffer */ - pxe_tftp.buffer = real_to_user ( tftp_read->Buffer.segment, - tftp_read->Buffer.offset ); - pxe_tftp.size = pxe_tftp.blksize; - pxe_tftp.start = pxe_tftp.offset; - while ( ( ( rc = pxe_tftp.rc ) == -EINPROGRESS ) && - ( pxe_tftp.offset == pxe_tftp.start ) ) - step(); - pxe_tftp.buffer = UNULL; - tftp_read->BufferSize = ( pxe_tftp.offset - pxe_tftp.start ); - tftp_read->PacketNumber = ++pxe_tftp.blkidx; - - /* EINPROGRESS is normal if we haven't reached EOF yet */ - if ( rc == -EINPROGRESS ) - rc = 0; - - tftp_read->Status = PXENV_STATUS ( rc ); - return ( rc ? PXENV_EXIT_FAILURE : PXENV_EXIT_SUCCESS ); -} - -/** - * TFTP/MTFTP read file - * - * @v tftp_read_file Pointer to a struct s_PXENV_TFTP_READ_FILE - * @v s_PXENV_TFTP_READ_FILE::FileName File name - * @v s_PXENV_TFTP_READ_FILE::BufferSize Size of the receive buffer - * @v s_PXENV_TFTP_READ_FILE::Buffer Address of the receive buffer - * @v s_PXENV_TFTP_READ_FILE::ServerIPAddress TFTP server IP address - * @v s_PXENV_TFTP_READ_FILE::GatewayIPAddress Relay agent IP address - * @v s_PXENV_TFTP_READ_FILE::McastIPAddress File's multicast IP address - * @v s_PXENV_TFTP_READ_FILE::TFTPClntPort Client multicast UDP port - * @v s_PXENV_TFTP_READ_FILE::TFTPSrvPort Server multicast UDP port - * @v s_PXENV_TFTP_READ_FILE::TFTPOpenTimeOut Time to wait for first packet - * @v s_PXENV_TFTP_READ_FILE::TFTPReopenDelay MTFTP inactivity timeout - * @ret #PXENV_EXIT_SUCCESS File downloaded successfully - * @ret #PXENV_EXIT_FAILURE File not downloaded - * @ret s_PXENV_TFTP_READ_FILE::Status PXE status code - * @ret s_PXENV_TFTP_READ_FILE::BufferSize Length of downloaded file - * - * Downloads an entire file via either TFTP or MTFTP into the buffer - * pointed to by s_PXENV_TFTP_READ_FILE::Buffer. - * - * The PXE specification does not make it clear how the caller - * requests that MTFTP be used rather than TFTP (or vice versa). One - * reasonable guess is that setting - * s_PXENV_TFTP_READ_FILE::McastIPAddress to 0.0.0.0 would cause TFTP - * to be used instead of MTFTP, though it is conceivable that some PXE - * stacks would interpret that as "use the DHCP-provided multicast IP - * address" instead. Some PXE stacks will not implement MTFTP at all, - * and will always use TFTP. - * - * It is not specified whether or not - * s_PXENV_TFTP_READ_FILE::TFTPSrvPort will be used as the TFTP server - * port for TFTP (rather than MTFTP) downloads. Callers should assume - * that the only way to access a TFTP server on a non-standard port is - * to use pxenv_tftp_open() and pxenv_tftp_read(). - * - * If s_PXENV_TFTP_READ_FILE::GatewayIPAddress is 0.0.0.0, normal IP - * routing will take place. See the relevant - * @ref pxe_routing "implementation note" for more details. - * - * It is interesting to note that s_PXENV_TFTP_READ_FILE::Buffer is an - * #ADDR32_t type, i.e. nominally a flat physical address. Some PXE - * NBPs (e.g. NTLDR) are known to call pxenv_tftp_read_file() in real - * mode with s_PXENV_TFTP_READ_FILE::Buffer set to an address above - * 1MB. This means that PXE stacks must be prepared to write to areas - * outside base memory. Exactly how this is to be achieved is not - * specified, though using INT 15,87 is as close to a standard method - * as any, and should probably be used. Switching to protected-mode - * in order to access high memory will fail if pxenv_tftp_read_file() - * is called in V86 mode; it is reasonably to expect that a V86 - * monitor would intercept the relatively well-defined INT 15,87 if it - * wants the PXE stack to be able to write to high memory. - * - * Things get even more interesting if pxenv_tftp_read_file() is - * called in protected mode, because there is then absolutely no way - * for the PXE stack to write to an absolute physical address. You - * can't even get around the problem by creating a special "access - * everything" segment in the s_PXE data structure, because the - * #SEGDESC_t descriptors are limited to 64kB in size. - * - * Previous versions of the PXE specification (e.g. WfM 1.1a) provide - * a separate API call, %pxenv_tftp_read_file_pmode(), specifically to - * work around this problem. The s_PXENV_TFTP_READ_FILE_PMODE - * parameter block splits s_PXENV_TFTP_READ_FILE::Buffer into - * s_PXENV_TFTP_READ_FILE_PMODE::BufferSelector and - * s_PXENV_TFTP_READ_FILE_PMODE::BufferOffset, i.e. it provides a - * protected-mode segment:offset address for the data buffer. This - * API call is no longer present in version 2.1 of the PXE - * specification. - * - * Etherboot makes the assumption that s_PXENV_TFTP_READ_FILE::Buffer - * is an offset relative to the caller's data segment, when - * pxenv_tftp_read_file() is called in protected mode. - * - * On x86, you must set the s_PXE::StatusCallout field to a nonzero - * value before calling this function in protected mode. You cannot - * call this function with a 32-bit stack segment. (See the relevant - * @ref pxe_x86_pmode16 "implementation note" for more details.) - */ -PXENV_EXIT_t pxenv_tftp_read_file ( struct s_PXENV_TFTP_READ_FILE - *tftp_read_file ) { - int rc; - - DBG ( "PXENV_TFTP_READ_FILE to %08x+%x", tftp_read_file->Buffer, - tftp_read_file->BufferSize ); - - /* Open TFTP file */ - if ( ( rc = pxe_tftp_open ( tftp_read_file->ServerIPAddress, 0, - tftp_read_file->FileName, 0 ) ) != 0 ) { - tftp_read_file->Status = PXENV_STATUS ( rc ); - return PXENV_EXIT_FAILURE; - } - - /* Read entire file */ - pxe_tftp.buffer = phys_to_user ( tftp_read_file->Buffer ); - pxe_tftp.size = tftp_read_file->BufferSize; - while ( ( rc = pxe_tftp.rc ) == -EINPROGRESS ) - step(); - pxe_tftp.buffer = UNULL; - tftp_read_file->BufferSize = pxe_tftp.max_offset; - - /* Close TFTP file */ - pxe_tftp_close ( &pxe_tftp, rc ); - - tftp_read_file->Status = PXENV_STATUS ( rc ); - return ( rc ? PXENV_EXIT_FAILURE : PXENV_EXIT_SUCCESS ); -} - -/** - * TFTP GET FILE SIZE - * - * @v tftp_get_fsize Pointer to a struct s_PXENV_TFTP_GET_FSIZE - * @v s_PXENV_TFTP_GET_FSIZE::ServerIPAddress TFTP server IP address - * @v s_PXENV_TFTP_GET_FSIZE::GatewayIPAddress Relay agent IP address - * @v s_PXENV_TFTP_GET_FSIZE::FileName File name - * @ret #PXENV_EXIT_SUCCESS File size was determined successfully - * @ret #PXENV_EXIT_FAILURE File size was not determined - * @ret s_PXENV_TFTP_GET_FSIZE::Status PXE status code - * @ret s_PXENV_TFTP_GET_FSIZE::FileSize File size - * - * Determine the size of a file on a TFTP server. This uses the - * "tsize" TFTP option, and so will not work with a TFTP server that - * does not support TFTP options, or that does not support the "tsize" - * option. - * - * The PXE specification states that this API call will @b not open a - * TFTP connection for subsequent use with pxenv_tftp_read(). (This - * is somewhat daft, since the only way to obtain the file size via - * the "tsize" option involves issuing a TFTP open request, but that's - * life.) - * - * You cannot call pxenv_tftp_get_fsize() while a TFTP or UDP - * connection is open. - * - * If s_PXENV_TFTP_GET_FSIZE::GatewayIPAddress is 0.0.0.0, normal IP - * routing will take place. See the relevant - * @ref pxe_routing "implementation note" for more details. - * - * On x86, you must set the s_PXE::StatusCallout field to a nonzero - * value before calling this function in protected mode. You cannot - * call this function with a 32-bit stack segment. (See the relevant - * @ref pxe_x86_pmode16 "implementation note" for more details.) - * - * @note There is no way to specify the TFTP server port with this API - * call. Though you can open a file using a non-standard TFTP server - * port (via s_PXENV_TFTP_OPEN::TFTPPort or, potentially, - * s_PXENV_TFTP_READ_FILE::TFTPSrvPort), you can only get the size of - * a file from a TFTP server listening on the standard TFTP port. - * "Consistency" is not a word in Intel's vocabulary. - */ -static PXENV_EXIT_t pxenv_tftp_get_fsize ( struct s_PXENV_TFTP_GET_FSIZE - *tftp_get_fsize ) { - int rc; - - DBG ( "PXENV_TFTP_GET_FSIZE" ); - - /* Open TFTP file */ - if ( ( rc = pxe_tftp_open ( tftp_get_fsize->ServerIPAddress, 0, - tftp_get_fsize->FileName, 0 ) ) != 0 ) { - tftp_get_fsize->Status = PXENV_STATUS ( rc ); - return PXENV_EXIT_FAILURE; - } - - /* Wait for initial seek to arrive, and record size */ - while ( ( ( rc = pxe_tftp.rc ) == -EINPROGRESS ) && - ( pxe_tftp.max_offset == 0 ) ) { - step(); - } - tftp_get_fsize->FileSize = pxe_tftp.max_offset; - DBG ( " fsize=%d", tftp_get_fsize->FileSize ); - - /* EINPROGRESS is normal; we don't wait for the whole transfer */ - if ( rc == -EINPROGRESS ) - rc = 0; - - /* Close TFTP file */ - pxe_tftp_close ( &pxe_tftp, rc ); - - tftp_get_fsize->Status = PXENV_STATUS ( rc ); - return ( rc ? PXENV_EXIT_FAILURE : PXENV_EXIT_SUCCESS ); -} - -/** PXE TFTP API */ -struct pxe_api_call pxe_tftp_api[] __pxe_api_call = { - PXE_API_CALL ( PXENV_TFTP_OPEN, pxenv_tftp_open, - struct s_PXENV_TFTP_OPEN ), - PXE_API_CALL ( PXENV_TFTP_CLOSE, pxenv_tftp_close, - struct s_PXENV_TFTP_CLOSE ), - PXE_API_CALL ( PXENV_TFTP_READ, pxenv_tftp_read, - struct s_PXENV_TFTP_READ ), - PXE_API_CALL ( PXENV_TFTP_READ_FILE, pxenv_tftp_read_file, - struct s_PXENV_TFTP_READ_FILE ), - PXE_API_CALL ( PXENV_TFTP_GET_FSIZE, pxenv_tftp_get_fsize, - struct s_PXENV_TFTP_GET_FSIZE ), -}; diff --git a/qemu/roms/ipxe/src/arch/i386/interface/pxe/pxe_udp.c b/qemu/roms/ipxe/src/arch/i386/interface/pxe/pxe_udp.c deleted file mode 100644 index 071cb59db..000000000 --- a/qemu/roms/ipxe/src/arch/i386/interface/pxe/pxe_udp.c +++ /dev/null @@ -1,474 +0,0 @@ -/** @file - * - * PXE UDP API - * - */ - -#include <string.h> -#include <byteswap.h> -#include <ipxe/iobuf.h> -#include <ipxe/xfer.h> -#include <ipxe/udp.h> -#include <ipxe/uaccess.h> -#include <ipxe/process.h> -#include <realmode.h> -#include <pxe.h> - -/* - * Copyright (C) 2004 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 ); - -/** A PXE UDP pseudo-header */ -struct pxe_udp_pseudo_header { - /** Source IP address */ - IP4_t src_ip; - /** Source port */ - UDP_PORT_t s_port; - /** Destination IP address */ - IP4_t dest_ip; - /** Destination port */ - UDP_PORT_t d_port; -} __attribute__ (( packed )); - -/** A PXE UDP connection */ -struct pxe_udp_connection { - /** Data transfer interface to UDP stack */ - struct interface xfer; - /** Local address */ - struct sockaddr_in local; - /** List of received packets */ - struct list_head list; -}; - -/** - * Receive PXE UDP data - * - * @v pxe_udp PXE UDP connection - * @v iobuf I/O buffer - * @v meta Data transfer metadata - * @ret rc Return status code - * - * Receives a packet as part of the current pxenv_udp_read() - * operation. - */ -static int pxe_udp_deliver ( struct pxe_udp_connection *pxe_udp, - struct io_buffer *iobuf, - struct xfer_metadata *meta ) { - struct pxe_udp_pseudo_header *pshdr; - struct sockaddr_in *sin_src; - struct sockaddr_in *sin_dest; - int rc; - - /* Extract metadata */ - assert ( meta ); - sin_src = ( struct sockaddr_in * ) meta->src; - assert ( sin_src ); - assert ( sin_src->sin_family == AF_INET ); - sin_dest = ( struct sockaddr_in * ) meta->dest; - assert ( sin_dest ); - assert ( sin_dest->sin_family == AF_INET ); - - /* Construct pseudo-header */ - if ( ( rc = iob_ensure_headroom ( iobuf, sizeof ( *pshdr ) ) ) != 0 ) { - DBG ( "PXE could not prepend pseudo-header\n" ); - rc = -ENOMEM; - goto drop; - } - pshdr = iob_push ( iobuf, sizeof ( *pshdr ) ); - pshdr->src_ip = sin_src->sin_addr.s_addr; - pshdr->s_port = sin_src->sin_port; - pshdr->dest_ip = sin_dest->sin_addr.s_addr; - pshdr->d_port = sin_dest->sin_port; - - /* Add to queue */ - list_add_tail ( &iobuf->list, &pxe_udp->list ); - - return 0; - - drop: - free_iob ( iobuf ); - return rc; -} - -/** PXE UDP data transfer interface operations */ -static struct interface_operation pxe_udp_xfer_operations[] = { - INTF_OP ( xfer_deliver, struct pxe_udp_connection *, pxe_udp_deliver ), -}; - -/** PXE UDP data transfer interface descriptor */ -static struct interface_descriptor pxe_udp_xfer_desc = - INTF_DESC ( struct pxe_udp_connection, xfer, pxe_udp_xfer_operations ); - -/** The PXE UDP connection */ -static struct pxe_udp_connection pxe_udp = { - .xfer = INTF_INIT ( pxe_udp_xfer_desc ), - .local = { - .sin_family = AF_INET, - }, - .list = LIST_HEAD_INIT ( pxe_udp.list ), -}; - -/** - * UDP OPEN - * - * @v pxenv_udp_open Pointer to a struct s_PXENV_UDP_OPEN - * @v s_PXENV_UDP_OPEN::src_ip IP address of this station, or 0.0.0.0 - * @ret #PXENV_EXIT_SUCCESS Always - * @ret s_PXENV_UDP_OPEN::Status PXE status code - * @err #PXENV_STATUS_UDP_OPEN UDP connection already open - * @err #PXENV_STATUS_OUT_OF_RESOURCES Could not open connection - * - * Prepares the PXE stack for communication using pxenv_udp_write() - * and pxenv_udp_read(). - * - * The IP address supplied in s_PXENV_UDP_OPEN::src_ip will be - * recorded and used as the local station's IP address for all further - * communication, including communication by means other than - * pxenv_udp_write() and pxenv_udp_read(). (If - * s_PXENV_UDP_OPEN::src_ip is 0.0.0.0, the local station's IP address - * will remain unchanged.) - * - * You can only have one open UDP connection at a time. This is not a - * meaningful restriction, since pxenv_udp_write() and - * pxenv_udp_read() allow you to specify arbitrary local and remote - * ports and an arbitrary remote address for each packet. According - * to the PXE specifiation, you cannot have a UDP connection open at - * the same time as a TFTP connection; this restriction does not apply - * to Etherboot. - * - * On x86, you must set the s_PXE::StatusCallout field to a nonzero - * value before calling this function in protected mode. You cannot - * call this function with a 32-bit stack segment. (See the relevant - * @ref pxe_x86_pmode16 "implementation note" for more details.) - * - * @note The PXE specification does not make it clear whether the IP - * address supplied in s_PXENV_UDP_OPEN::src_ip should be used only - * for this UDP connection, or retained for all future communication. - * The latter seems more consistent with typical PXE stack behaviour. - * - * @note Etherboot currently ignores the s_PXENV_UDP_OPEN::src_ip - * parameter. - * - */ -static PXENV_EXIT_t pxenv_udp_open ( struct s_PXENV_UDP_OPEN *pxenv_udp_open ) { - int rc; - - DBG ( "PXENV_UDP_OPEN" ); - - /* Record source IP address */ - pxe_udp.local.sin_addr.s_addr = pxenv_udp_open->src_ip; - DBG ( " %s\n", inet_ntoa ( pxe_udp.local.sin_addr ) ); - - /* Open promiscuous UDP connection */ - intf_restart ( &pxe_udp.xfer, 0 ); - if ( ( rc = udp_open_promisc ( &pxe_udp.xfer ) ) != 0 ) { - DBG ( "PXENV_UDP_OPEN could not open promiscuous socket: %s\n", - strerror ( rc ) ); - pxenv_udp_open->Status = PXENV_STATUS ( rc ); - return PXENV_EXIT_FAILURE; - } - - pxenv_udp_open->Status = PXENV_STATUS_SUCCESS; - return PXENV_EXIT_SUCCESS; -} - -/** - * UDP CLOSE - * - * @v pxenv_udp_close Pointer to a struct s_PXENV_UDP_CLOSE - * @ret #PXENV_EXIT_SUCCESS Always - * @ret s_PXENV_UDP_CLOSE::Status PXE status code - * @err None - - * - * Closes a UDP connection opened with pxenv_udp_open(). - * - * You can only have one open UDP connection at a time. You cannot - * have a UDP connection open at the same time as a TFTP connection. - * You cannot use pxenv_udp_close() to close a TFTP connection; use - * pxenv_tftp_close() instead. - * - * On x86, you must set the s_PXE::StatusCallout field to a nonzero - * value before calling this function in protected mode. You cannot - * call this function with a 32-bit stack segment. (See the relevant - * @ref pxe_x86_pmode16 "implementation note" for more details.) - * - */ -static PXENV_EXIT_t -pxenv_udp_close ( struct s_PXENV_UDP_CLOSE *pxenv_udp_close ) { - struct io_buffer *iobuf; - struct io_buffer *tmp; - - DBG ( "PXENV_UDP_CLOSE\n" ); - - /* Close UDP connection */ - intf_restart ( &pxe_udp.xfer, 0 ); - - /* Discard any received packets */ - list_for_each_entry_safe ( iobuf, tmp, &pxe_udp.list, list ) { - list_del ( &iobuf->list ); - free_iob ( iobuf ); - } - - pxenv_udp_close->Status = PXENV_STATUS_SUCCESS; - return PXENV_EXIT_SUCCESS; -} - -/** - * UDP WRITE - * - * @v pxenv_udp_write Pointer to a struct s_PXENV_UDP_WRITE - * @v s_PXENV_UDP_WRITE::ip Destination IP address - * @v s_PXENV_UDP_WRITE::gw Relay agent IP address, or 0.0.0.0 - * @v s_PXENV_UDP_WRITE::src_port Source UDP port, or 0 - * @v s_PXENV_UDP_WRITE::dst_port Destination UDP port - * @v s_PXENV_UDP_WRITE::buffer_size Length of the UDP payload - * @v s_PXENV_UDP_WRITE::buffer Address of the UDP payload - * @ret #PXENV_EXIT_SUCCESS Packet was transmitted successfully - * @ret #PXENV_EXIT_FAILURE Packet could not be transmitted - * @ret s_PXENV_UDP_WRITE::Status PXE status code - * @err #PXENV_STATUS_UDP_CLOSED UDP connection is not open - * @err #PXENV_STATUS_UNDI_TRANSMIT_ERROR Could not transmit packet - * - * Transmits a single UDP packet. A valid IP and UDP header will be - * prepended to the payload in s_PXENV_UDP_WRITE::buffer; the buffer - * should not contain precomputed IP and UDP headers, nor should it - * contain space allocated for these headers. The first byte of the - * buffer will be transmitted as the first byte following the UDP - * header. - * - * If s_PXENV_UDP_WRITE::gw is 0.0.0.0, normal IP routing will take - * place. See the relevant @ref pxe_routing "implementation note" for - * more details. - * - * If s_PXENV_UDP_WRITE::src_port is 0, port 2069 will be used. - * - * You must have opened a UDP connection with pxenv_udp_open() before - * calling pxenv_udp_write(). - * - * On x86, you must set the s_PXE::StatusCallout field to a nonzero - * value before calling this function in protected mode. You cannot - * call this function with a 32-bit stack segment. (See the relevant - * @ref pxe_x86_pmode16 "implementation note" for more details.) - * - * @note Etherboot currently ignores the s_PXENV_UDP_WRITE::gw - * parameter. - * - */ -static PXENV_EXIT_t -pxenv_udp_write ( struct s_PXENV_UDP_WRITE *pxenv_udp_write ) { - struct sockaddr_in dest; - struct xfer_metadata meta = { - .src = ( struct sockaddr * ) &pxe_udp.local, - .dest = ( struct sockaddr * ) &dest, - .netdev = pxe_netdev, - }; - size_t len; - struct io_buffer *iobuf; - userptr_t buffer; - int rc; - - DBG ( "PXENV_UDP_WRITE" ); - - /* Construct destination socket address */ - memset ( &dest, 0, sizeof ( dest ) ); - dest.sin_family = AF_INET; - dest.sin_addr.s_addr = pxenv_udp_write->ip; - dest.sin_port = pxenv_udp_write->dst_port; - - /* Set local (source) port. PXE spec says source port is 2069 - * if not specified. Really, this ought to be set at UDP open - * time but hey, we didn't design this API. - */ - pxe_udp.local.sin_port = pxenv_udp_write->src_port; - if ( ! pxe_udp.local.sin_port ) - pxe_udp.local.sin_port = htons ( 2069 ); - - /* FIXME: we ignore the gateway specified, since we're - * confident of being able to do our own routing. We should - * probably allow for multiple gateways. - */ - - /* Allocate and fill data buffer */ - len = pxenv_udp_write->buffer_size; - iobuf = xfer_alloc_iob ( &pxe_udp.xfer, len ); - if ( ! iobuf ) { - DBG ( " out of memory\n" ); - pxenv_udp_write->Status = PXENV_STATUS_OUT_OF_RESOURCES; - return PXENV_EXIT_FAILURE; - } - buffer = real_to_user ( pxenv_udp_write->buffer.segment, - pxenv_udp_write->buffer.offset ); - copy_from_user ( iob_put ( iobuf, len ), buffer, 0, len ); - - DBG ( " %04x:%04x+%x %d->%s:%d\n", pxenv_udp_write->buffer.segment, - pxenv_udp_write->buffer.offset, pxenv_udp_write->buffer_size, - ntohs ( pxenv_udp_write->src_port ), - inet_ntoa ( dest.sin_addr ), - ntohs ( pxenv_udp_write->dst_port ) ); - - /* Transmit packet */ - if ( ( rc = xfer_deliver ( &pxe_udp.xfer, iobuf, &meta ) ) != 0 ) { - DBG ( "PXENV_UDP_WRITE could not transmit: %s\n", - strerror ( rc ) ); - pxenv_udp_write->Status = PXENV_STATUS ( rc ); - return PXENV_EXIT_FAILURE; - } - - pxenv_udp_write->Status = PXENV_STATUS_SUCCESS; - return PXENV_EXIT_SUCCESS; -} - -/** - * UDP READ - * - * @v pxenv_udp_read Pointer to a struct s_PXENV_UDP_READ - * @v s_PXENV_UDP_READ::dest_ip Destination IP address, or 0.0.0.0 - * @v s_PXENV_UDP_READ::d_port Destination UDP port, or 0 - * @v s_PXENV_UDP_READ::buffer_size Size of the UDP payload buffer - * @v s_PXENV_UDP_READ::buffer Address of the UDP payload buffer - * @ret #PXENV_EXIT_SUCCESS A packet has been received - * @ret #PXENV_EXIT_FAILURE No packet has been received - * @ret s_PXENV_UDP_READ::Status PXE status code - * @ret s_PXENV_UDP_READ::src_ip Source IP address - * @ret s_PXENV_UDP_READ::dest_ip Destination IP address - * @ret s_PXENV_UDP_READ::s_port Source UDP port - * @ret s_PXENV_UDP_READ::d_port Destination UDP port - * @ret s_PXENV_UDP_READ::buffer_size Length of UDP payload - * @err #PXENV_STATUS_UDP_CLOSED UDP connection is not open - * @err #PXENV_STATUS_FAILURE No packet was ready to read - * - * Receive a single UDP packet. This is a non-blocking call; if no - * packet is ready to read, the call will return instantly with - * s_PXENV_UDP_READ::Status==PXENV_STATUS_FAILURE. - * - * If s_PXENV_UDP_READ::dest_ip is 0.0.0.0, UDP packets addressed to - * any IP address will be accepted and may be returned to the caller. - * - * If s_PXENV_UDP_READ::d_port is 0, UDP packets addressed to any UDP - * port will be accepted and may be returned to the caller. - * - * You must have opened a UDP connection with pxenv_udp_open() before - * calling pxenv_udp_read(). - * - * On x86, you must set the s_PXE::StatusCallout field to a nonzero - * value before calling this function in protected mode. You cannot - * call this function with a 32-bit stack segment. (See the relevant - * @ref pxe_x86_pmode16 "implementation note" for more details.) - * - * @note The PXE specification (version 2.1) does not state that we - * should fill in s_PXENV_UDP_READ::dest_ip and - * s_PXENV_UDP_READ::d_port, but Microsoft Windows' NTLDR program - * expects us to do so, and will fail if we don't. - * - */ -static PXENV_EXIT_t pxenv_udp_read ( struct s_PXENV_UDP_READ *pxenv_udp_read ) { - struct in_addr dest_ip_wanted = { .s_addr = pxenv_udp_read->dest_ip }; - struct in_addr dest_ip; - struct io_buffer *iobuf; - struct pxe_udp_pseudo_header *pshdr; - uint16_t d_port_wanted = pxenv_udp_read->d_port; - uint16_t d_port; - userptr_t buffer; - size_t len; - - /* Try receiving a packet, if the queue is empty */ - if ( list_empty ( &pxe_udp.list ) ) - step(); - - /* Remove first packet from the queue */ - iobuf = list_first_entry ( &pxe_udp.list, struct io_buffer, list ); - if ( ! iobuf ) { - /* No packet received */ - DBG2 ( "PXENV_UDP_READ\n" ); - goto no_packet; - } - list_del ( &iobuf->list ); - - /* Strip pseudo-header */ - assert ( iob_len ( iobuf ) >= sizeof ( *pshdr ) ); - pshdr = iobuf->data; - iob_pull ( iobuf, sizeof ( *pshdr ) ); - dest_ip.s_addr = pshdr->dest_ip; - d_port = pshdr->d_port; - DBG ( "PXENV_UDP_READ" ); - - /* Filter on destination address and/or port */ - if ( dest_ip_wanted.s_addr && - ( dest_ip_wanted.s_addr != dest_ip.s_addr ) ) { - DBG ( " wrong IP %s", inet_ntoa ( dest_ip ) ); - DBG ( " (wanted %s)\n", inet_ntoa ( dest_ip_wanted ) ); - goto drop; - } - if ( d_port_wanted && ( d_port_wanted != d_port ) ) { - DBG ( " wrong port %d", htons ( d_port ) ); - DBG ( " (wanted %d)\n", htons ( d_port_wanted ) ); - goto drop; - } - - /* Copy packet to buffer and record length */ - buffer = real_to_user ( pxenv_udp_read->buffer.segment, - pxenv_udp_read->buffer.offset ); - len = iob_len ( iobuf ); - if ( len > pxenv_udp_read->buffer_size ) - len = pxenv_udp_read->buffer_size; - copy_to_user ( buffer, 0, iobuf->data, len ); - pxenv_udp_read->buffer_size = len; - - /* Fill in source/dest information */ - pxenv_udp_read->src_ip = pshdr->src_ip; - pxenv_udp_read->s_port = pshdr->s_port; - pxenv_udp_read->dest_ip = pshdr->dest_ip; - pxenv_udp_read->d_port = pshdr->d_port; - - DBG ( " %04x:%04x+%x %s:", pxenv_udp_read->buffer.segment, - pxenv_udp_read->buffer.offset, pxenv_udp_read->buffer_size, - inet_ntoa ( *( ( struct in_addr * ) &pxenv_udp_read->src_ip ) )); - DBG ( "%d<-%s:%d\n", ntohs ( pxenv_udp_read->s_port ), - inet_ntoa ( *( ( struct in_addr * ) &pxenv_udp_read->dest_ip ) ), - ntohs ( pxenv_udp_read->d_port ) ); - - /* Free I/O buffer */ - free_iob ( iobuf ); - - pxenv_udp_read->Status = PXENV_STATUS_SUCCESS; - return PXENV_EXIT_SUCCESS; - - drop: - free_iob ( iobuf ); - no_packet: - pxenv_udp_read->Status = PXENV_STATUS_FAILURE; - return PXENV_EXIT_FAILURE; -} - -/** PXE UDP API */ -struct pxe_api_call pxe_udp_api[] __pxe_api_call = { - PXE_API_CALL ( PXENV_UDP_OPEN, pxenv_udp_open, - struct s_PXENV_UDP_OPEN ), - PXE_API_CALL ( PXENV_UDP_CLOSE, pxenv_udp_close, - struct s_PXENV_UDP_CLOSE ), - PXE_API_CALL ( PXENV_UDP_WRITE, pxenv_udp_write, - struct s_PXENV_UDP_WRITE ), - PXE_API_CALL ( PXENV_UDP_READ, pxenv_udp_read, - struct s_PXENV_UDP_READ ), -}; diff --git a/qemu/roms/ipxe/src/arch/i386/interface/pxe/pxe_undi.c b/qemu/roms/ipxe/src/arch/i386/interface/pxe/pxe_undi.c deleted file mode 100644 index 2eb68178a..000000000 --- a/qemu/roms/ipxe/src/arch/i386/interface/pxe/pxe_undi.c +++ /dev/null @@ -1,1084 +0,0 @@ -/** @file - * - * PXE UNDI API - * - */ - -/* - * Copyright (C) 2004 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 <stdio.h> -#include <string.h> -#include <byteswap.h> -#include <basemem_packet.h> -#include <ipxe/netdevice.h> -#include <ipxe/iobuf.h> -#include <ipxe/device.h> -#include <ipxe/pci.h> -#include <ipxe/if_ether.h> -#include <ipxe/ip.h> -#include <ipxe/arp.h> -#include <ipxe/rarp.h> -#include <ipxe/profile.h> -#include "pxe.h" - -/** - * Count of outstanding transmitted packets - * - * This is incremented each time PXENV_UNDI_TRANSMIT is called, and - * decremented each time that PXENV_UNDI_ISR is called with the TX - * queue empty, stopping when the count reaches zero. This allows us - * to provide a pessimistic approximation of TX completion events to - * the PXE NBP simply by monitoring the netdev's TX queue. - */ -static int undi_tx_count = 0; - -struct net_device *pxe_netdev = NULL; - -/** Transmit profiler */ -static struct profiler undi_tx_profiler __profiler = { .name = "undi.tx" }; - -/** - * Set network device as current PXE network device - * - * @v netdev Network device, or NULL - */ -void pxe_set_netdev ( struct net_device *netdev ) { - - if ( pxe_netdev ) { - netdev_rx_unfreeze ( pxe_netdev ); - netdev_put ( pxe_netdev ); - } - - pxe_netdev = NULL; - - if ( netdev ) - pxe_netdev = netdev_get ( netdev ); -} - -/** - * Open PXE network device - * - * @ret rc Return status code - */ -static int pxe_netdev_open ( void ) { - int rc; - - assert ( pxe_netdev != NULL ); - - if ( ( rc = netdev_open ( pxe_netdev ) ) != 0 ) - return rc; - - netdev_rx_freeze ( pxe_netdev ); - netdev_irq ( pxe_netdev, 1 ); - - return 0; -} - -/** - * Close PXE network device - * - */ -static void pxe_netdev_close ( void ) { - - assert ( pxe_netdev != NULL ); - netdev_rx_unfreeze ( pxe_netdev ); - netdev_irq ( pxe_netdev, 0 ); - netdev_close ( pxe_netdev ); - undi_tx_count = 0; -} - -/** - * Dump multicast address list - * - * @v mcast PXE multicast address list - */ -static void pxe_dump_mcast_list ( struct s_PXENV_UNDI_MCAST_ADDRESS *mcast ) { - struct ll_protocol *ll_protocol = pxe_netdev->ll_protocol; - unsigned int i; - - for ( i = 0 ; i < mcast->MCastAddrCount ; i++ ) { - DBGC ( &pxe_netdev, " %s", - ll_protocol->ntoa ( mcast->McastAddr[i] ) ); - } -} - -/* PXENV_UNDI_STARTUP - * - * Status: working - */ -static PXENV_EXIT_t -pxenv_undi_startup ( struct s_PXENV_UNDI_STARTUP *undi_startup ) { - DBGC ( &pxe_netdev, "PXENV_UNDI_STARTUP\n" ); - - /* Sanity check */ - if ( ! pxe_netdev ) { - DBGC ( &pxe_netdev, "PXENV_UNDI_STARTUP called with no " - "network device\n" ); - undi_startup->Status = PXENV_STATUS_UNDI_INVALID_STATE; - return PXENV_EXIT_FAILURE; - } - - undi_startup->Status = PXENV_STATUS_SUCCESS; - return PXENV_EXIT_SUCCESS; -} - -/* PXENV_UNDI_CLEANUP - * - * Status: working - */ -static PXENV_EXIT_t -pxenv_undi_cleanup ( struct s_PXENV_UNDI_CLEANUP *undi_cleanup ) { - DBGC ( &pxe_netdev, "PXENV_UNDI_CLEANUP\n" ); - - /* Sanity check */ - if ( ! pxe_netdev ) { - DBGC ( &pxe_netdev, "PXENV_UNDI_CLEANUP called with no " - "network device\n" ); - undi_cleanup->Status = PXENV_STATUS_UNDI_INVALID_STATE; - return PXENV_EXIT_FAILURE; - } - - /* Close network device */ - pxe_netdev_close(); - - undi_cleanup->Status = PXENV_STATUS_SUCCESS; - return PXENV_EXIT_SUCCESS; -} - -/* PXENV_UNDI_INITIALIZE - * - * Status: working - */ -static PXENV_EXIT_t -pxenv_undi_initialize ( struct s_PXENV_UNDI_INITIALIZE *undi_initialize ) { - DBGC ( &pxe_netdev, "PXENV_UNDI_INITIALIZE protocolini %08x\n", - undi_initialize->ProtocolIni ); - - /* Sanity check */ - if ( ! pxe_netdev ) { - DBGC ( &pxe_netdev, "PXENV_UNDI_INITIALIZE called with no " - "network device\n" ); - undi_initialize->Status = PXENV_STATUS_UNDI_INVALID_STATE; - return PXENV_EXIT_FAILURE; - } - - undi_initialize->Status = PXENV_STATUS_SUCCESS; - return PXENV_EXIT_SUCCESS; -} - -/* PXENV_UNDI_RESET_ADAPTER - * - * Status: working - */ -static PXENV_EXIT_t -pxenv_undi_reset_adapter ( struct s_PXENV_UNDI_RESET *undi_reset_adapter ) { - int rc; - - DBGC ( &pxe_netdev, "PXENV_UNDI_RESET_ADAPTER" ); - pxe_dump_mcast_list ( &undi_reset_adapter->R_Mcast_Buf ); - DBGC ( &pxe_netdev, "\n" ); - - /* Sanity check */ - if ( ! pxe_netdev ) { - DBGC ( &pxe_netdev, "PXENV_UNDI_RESET_ADAPTER called with no " - "network device\n" ); - undi_reset_adapter->Status = PXENV_STATUS_UNDI_INVALID_STATE; - return PXENV_EXIT_FAILURE; - } - - /* Close and reopen network device */ - pxe_netdev_close(); - if ( ( rc = pxe_netdev_open() ) != 0 ) { - DBGC ( &pxe_netdev, "PXENV_UNDI_RESET_ADAPTER could not " - "reopen %s: %s\n", pxe_netdev->name, strerror ( rc ) ); - undi_reset_adapter->Status = PXENV_STATUS ( rc ); - return PXENV_EXIT_FAILURE; - } - - undi_reset_adapter->Status = PXENV_STATUS_SUCCESS; - return PXENV_EXIT_SUCCESS; -} - -/* PXENV_UNDI_SHUTDOWN - * - * Status: working - */ -static PXENV_EXIT_t -pxenv_undi_shutdown ( struct s_PXENV_UNDI_SHUTDOWN *undi_shutdown ) { - DBGC ( &pxe_netdev, "PXENV_UNDI_SHUTDOWN\n" ); - - /* Sanity check */ - if ( ! pxe_netdev ) { - DBGC ( &pxe_netdev, "PXENV_UNDI_SHUTDOWN called with no " - "network device\n" ); - undi_shutdown->Status = PXENV_STATUS_UNDI_INVALID_STATE; - return PXENV_EXIT_FAILURE; - } - - /* Close network device */ - pxe_netdev_close(); - - undi_shutdown->Status = PXENV_STATUS_SUCCESS; - return PXENV_EXIT_SUCCESS; -} - -/* PXENV_UNDI_OPEN - * - * Status: working - */ -static PXENV_EXIT_t pxenv_undi_open ( struct s_PXENV_UNDI_OPEN *undi_open ) { - int rc; - - DBGC ( &pxe_netdev, "PXENV_UNDI_OPEN flag %04x filter %04x", - undi_open->OpenFlag, undi_open->PktFilter ); - pxe_dump_mcast_list ( &undi_open->R_Mcast_Buf ); - DBGC ( &pxe_netdev, "\n" ); - - /* Sanity check */ - if ( ! pxe_netdev ) { - DBGC ( &pxe_netdev, "PXENV_UNDI_OPEN called with no " - "network device\n" ); - undi_open->Status = PXENV_STATUS_UNDI_INVALID_STATE; - return PXENV_EXIT_FAILURE; - } - - /* Open network device */ - if ( ( rc = pxe_netdev_open() ) != 0 ) { - DBGC ( &pxe_netdev, "PXENV_UNDI_OPEN could not open %s: %s\n", - pxe_netdev->name, strerror ( rc ) ); - undi_open->Status = PXENV_STATUS ( rc ); - return PXENV_EXIT_FAILURE; - } - - undi_open->Status = PXENV_STATUS_SUCCESS; - return PXENV_EXIT_SUCCESS; -} - -/* PXENV_UNDI_CLOSE - * - * Status: working - */ -static PXENV_EXIT_t pxenv_undi_close ( struct s_PXENV_UNDI_CLOSE *undi_close ) { - DBGC ( &pxe_netdev, "PXENV_UNDI_CLOSE\n" ); - - /* Sanity check */ - if ( ! pxe_netdev ) { - DBGC ( &pxe_netdev, "PXENV_UNDI_CLOSE called with no " - "network device\n" ); - undi_close->Status = PXENV_STATUS_UNDI_INVALID_STATE; - return PXENV_EXIT_FAILURE; - } - - /* Close network device */ - pxe_netdev_close(); - - undi_close->Status = PXENV_STATUS_SUCCESS; - return PXENV_EXIT_SUCCESS; -} - -/* PXENV_UNDI_TRANSMIT - * - * Status: working - */ -static PXENV_EXIT_t -pxenv_undi_transmit ( struct s_PXENV_UNDI_TRANSMIT *undi_transmit ) { - struct s_PXENV_UNDI_TBD tbd; - struct DataBlk *datablk; - struct io_buffer *iobuf; - struct net_protocol *net_protocol; - struct ll_protocol *ll_protocol; - char destaddr[MAX_LL_ADDR_LEN]; - const void *ll_dest; - size_t len; - unsigned int i; - int rc; - - /* Start profiling */ - profile_start ( &undi_tx_profiler ); - - /* Sanity check */ - if ( ! pxe_netdev ) { - DBGC ( &pxe_netdev, "PXENV_UNDI_TRANSMIT called with no " - "network device\n" ); - undi_transmit->Status = PXENV_STATUS_UNDI_INVALID_STATE; - return PXENV_EXIT_FAILURE; - } - - DBGC2 ( &pxe_netdev, "PXENV_UNDI_TRANSMIT" ); - - /* Forcibly enable interrupts and freeze receive queue - * processing at this point, to work around callers that never - * call PXENV_UNDI_OPEN before attempting to use the UNDI API. - */ - if ( ! netdev_rx_frozen ( pxe_netdev ) ) { - netdev_rx_freeze ( pxe_netdev ); - netdev_irq ( pxe_netdev, 1 ); - } - - /* Identify network-layer protocol */ - switch ( undi_transmit->Protocol ) { - case P_IP: net_protocol = &ipv4_protocol; break; - case P_ARP: net_protocol = &arp_protocol; break; - case P_RARP: net_protocol = &rarp_protocol; break; - case P_UNKNOWN: - net_protocol = NULL; - break; - default: - DBGC2 ( &pxe_netdev, " %02x invalid protocol\n", - undi_transmit->Protocol ); - undi_transmit->Status = PXENV_STATUS_UNDI_INVALID_PARAMETER; - return PXENV_EXIT_FAILURE; - } - DBGC2 ( &pxe_netdev, " %s", - ( net_protocol ? net_protocol->name : "RAW" ) ); - - /* Calculate total packet length */ - copy_from_real ( &tbd, undi_transmit->TBD.segment, - undi_transmit->TBD.offset, sizeof ( tbd ) ); - len = tbd.ImmedLength; - DBGC2 ( &pxe_netdev, " %04x:%04x+%x", tbd.Xmit.segment, tbd.Xmit.offset, - tbd.ImmedLength ); - for ( i = 0 ; i < tbd.DataBlkCount ; i++ ) { - datablk = &tbd.DataBlock[i]; - len += datablk->TDDataLen; - DBGC2 ( &pxe_netdev, " %04x:%04x+%x", - datablk->TDDataPtr.segment, datablk->TDDataPtr.offset, - datablk->TDDataLen ); - } - - /* Allocate and fill I/O buffer */ - iobuf = alloc_iob ( MAX_LL_HEADER_LEN + - ( ( len > IOB_ZLEN ) ? len : IOB_ZLEN ) ); - if ( ! iobuf ) { - DBGC2 ( &pxe_netdev, " could not allocate iobuf\n" ); - undi_transmit->Status = PXENV_STATUS_OUT_OF_RESOURCES; - return PXENV_EXIT_FAILURE; - } - iob_reserve ( iobuf, MAX_LL_HEADER_LEN ); - copy_from_real ( iob_put ( iobuf, tbd.ImmedLength ), tbd.Xmit.segment, - tbd.Xmit.offset, tbd.ImmedLength ); - for ( i = 0 ; i < tbd.DataBlkCount ; i++ ) { - datablk = &tbd.DataBlock[i]; - copy_from_real ( iob_put ( iobuf, datablk->TDDataLen ), - datablk->TDDataPtr.segment, - datablk->TDDataPtr.offset, - datablk->TDDataLen ); - } - - /* Add link-layer header, if required to do so */ - if ( net_protocol != NULL ) { - - /* Calculate destination address */ - ll_protocol = pxe_netdev->ll_protocol; - if ( undi_transmit->XmitFlag == XMT_DESTADDR ) { - copy_from_real ( destaddr, - undi_transmit->DestAddr.segment, - undi_transmit->DestAddr.offset, - ll_protocol->ll_addr_len ); - ll_dest = destaddr; - DBGC2 ( &pxe_netdev, " DEST %s", - ll_protocol->ntoa ( ll_dest ) ); - } else { - ll_dest = pxe_netdev->ll_broadcast; - DBGC2 ( &pxe_netdev, " BCAST" ); - } - - /* Add link-layer header */ - if ( ( rc = ll_protocol->push ( pxe_netdev, iobuf, ll_dest, - pxe_netdev->ll_addr, - net_protocol->net_proto ))!=0){ - DBGC2 ( &pxe_netdev, " could not add link-layer " - "header: %s\n", strerror ( rc ) ); - free_iob ( iobuf ); - undi_transmit->Status = PXENV_STATUS ( rc ); - return PXENV_EXIT_FAILURE; - } - } - - /* Flag transmission as in-progress. Do this before starting - * to transmit the packet, because the ISR may trigger before - * we return from netdev_tx(). - */ - undi_tx_count++; - - /* Transmit packet */ - DBGC2 ( &pxe_netdev, "\n" ); - if ( ( rc = netdev_tx ( pxe_netdev, iobuf ) ) != 0 ) { - DBGC2 ( &pxe_netdev, "PXENV_UNDI_TRANSMIT could not transmit: " - "%s\n", strerror ( rc ) ); - undi_tx_count--; - undi_transmit->Status = PXENV_STATUS ( rc ); - return PXENV_EXIT_FAILURE; - } - - profile_stop ( &undi_tx_profiler ); - undi_transmit->Status = PXENV_STATUS_SUCCESS; - return PXENV_EXIT_SUCCESS; -} - -/* PXENV_UNDI_SET_MCAST_ADDRESS - * - * Status: working (for NICs that support receive-all-multicast) - */ -static PXENV_EXIT_t -pxenv_undi_set_mcast_address ( struct s_PXENV_UNDI_SET_MCAST_ADDRESS - *undi_set_mcast_address ) { - DBGC ( &pxe_netdev, "PXENV_UNDI_SET_MCAST_ADDRESS" ); - pxe_dump_mcast_list ( &undi_set_mcast_address->R_Mcast_Buf ); - DBGC ( &pxe_netdev, "\n" ); - - /* Sanity check */ - if ( ! pxe_netdev ) { - DBGC ( &pxe_netdev, "PXENV_UNDI_SET_MCAST_ADDRESS called with " - "no network device\n" ); - undi_set_mcast_address->Status = - PXENV_STATUS_UNDI_INVALID_STATE; - return PXENV_EXIT_FAILURE; - } - - undi_set_mcast_address->Status = PXENV_STATUS_SUCCESS; - return PXENV_EXIT_SUCCESS; -} - -/* PXENV_UNDI_SET_STATION_ADDRESS - * - * Status: working - */ -static PXENV_EXIT_t -pxenv_undi_set_station_address ( struct s_PXENV_UNDI_SET_STATION_ADDRESS - *undi_set_station_address ) { - struct ll_protocol *ll_protocol; - - /* Sanity check */ - if ( ! pxe_netdev ) { - DBGC ( &pxe_netdev, "PXENV_UNDI_SET_STATION_ADDRESS called " - "with no network device\n" ); - undi_set_station_address->Status = - PXENV_STATUS_UNDI_INVALID_STATE; - return PXENV_EXIT_FAILURE; - } - - ll_protocol = pxe_netdev->ll_protocol; - DBGC ( &pxe_netdev, "PXENV_UNDI_SET_STATION_ADDRESS %s", - ll_protocol->ntoa ( undi_set_station_address->StationAddress ) ); - - /* If adapter is open, the change will have no effect; return - * an error - */ - if ( netdev_is_open ( pxe_netdev ) ) { - DBGC ( &pxe_netdev, " failed: netdev is open\n" ); - undi_set_station_address->Status = - PXENV_STATUS_UNDI_INVALID_STATE; - return PXENV_EXIT_FAILURE; - } - - /* Update MAC address */ - memcpy ( pxe_netdev->ll_addr, - &undi_set_station_address->StationAddress, - ll_protocol->ll_addr_len ); - - DBGC ( &pxe_netdev, "\n" ); - undi_set_station_address->Status = PXENV_STATUS_SUCCESS; - return PXENV_EXIT_SUCCESS; -} - -/* PXENV_UNDI_SET_PACKET_FILTER - * - * Status: won't implement (would require driver API changes for no - * real benefit) - */ -static PXENV_EXIT_t -pxenv_undi_set_packet_filter ( struct s_PXENV_UNDI_SET_PACKET_FILTER - *undi_set_packet_filter ) { - - DBGC ( &pxe_netdev, "PXENV_UNDI_SET_PACKET_FILTER %02x\n", - undi_set_packet_filter->filter ); - - /* Sanity check */ - if ( ! pxe_netdev ) { - DBGC ( &pxe_netdev, "PXENV_UNDI_SET_PACKET_FILTER called with " - "no network device\n" ); - undi_set_packet_filter->Status = - PXENV_STATUS_UNDI_INVALID_STATE; - return PXENV_EXIT_FAILURE; - } - - /* Pretend that we succeeded, otherwise the 3Com DOS UNDI - * driver refuses to load. (We ignore the filter value in the - * PXENV_UNDI_OPEN call anyway.) - */ - undi_set_packet_filter->Status = PXENV_STATUS_SUCCESS; - - return PXENV_EXIT_SUCCESS; -} - -/* PXENV_UNDI_GET_INFORMATION - * - * Status: working - */ -static PXENV_EXIT_t -pxenv_undi_get_information ( struct s_PXENV_UNDI_GET_INFORMATION - *undi_get_information ) { - struct device *dev; - struct ll_protocol *ll_protocol; - - /* Sanity check */ - if ( ! pxe_netdev ) { - DBGC ( &pxe_netdev, "PXENV_UNDI_GET_INFORMATION called with no " - "network device\n" ); - undi_get_information->Status = PXENV_STATUS_UNDI_INVALID_STATE; - return PXENV_EXIT_FAILURE; - } - - DBGC ( &pxe_netdev, "PXENV_UNDI_GET_INFORMATION" ); - - /* Fill in information */ - dev = pxe_netdev->dev; - ll_protocol = pxe_netdev->ll_protocol; - undi_get_information->BaseIo = dev->desc.ioaddr; - undi_get_information->IntNumber = - ( netdev_irq_supported ( pxe_netdev ) ? dev->desc.irq : 0 ); - /* Cheat: assume all cards can cope with this */ - undi_get_information->MaxTranUnit = ETH_MAX_MTU; - undi_get_information->HwType = ntohs ( ll_protocol->ll_proto ); - undi_get_information->HwAddrLen = ll_protocol->ll_addr_len; - assert ( ll_protocol->ll_addr_len <= - sizeof ( undi_get_information->CurrentNodeAddress ) ); - memcpy ( &undi_get_information->CurrentNodeAddress, - pxe_netdev->ll_addr, - sizeof ( undi_get_information->CurrentNodeAddress ) ); - ll_protocol->init_addr ( pxe_netdev->hw_addr, - &undi_get_information->PermNodeAddress ); - undi_get_information->ROMAddress = 0; - /* nic.rom_info->rom_segment; */ - /* We only provide the ability to receive or transmit a single - * packet at a time. This is a bootloader, not an OS. - */ - undi_get_information->RxBufCt = 1; - undi_get_information->TxBufCt = 1; - - DBGC ( &pxe_netdev, " io %04x irq %d mtu %d %s %s\n", - undi_get_information->BaseIo, undi_get_information->IntNumber, - undi_get_information->MaxTranUnit, ll_protocol->name, - ll_protocol->ntoa ( &undi_get_information->CurrentNodeAddress )); - undi_get_information->Status = PXENV_STATUS_SUCCESS; - return PXENV_EXIT_SUCCESS; -} - -/* PXENV_UNDI_GET_STATISTICS - * - * Status: working - */ -static PXENV_EXIT_t -pxenv_undi_get_statistics ( struct s_PXENV_UNDI_GET_STATISTICS - *undi_get_statistics ) { - - /* Sanity check */ - if ( ! pxe_netdev ) { - DBGC ( &pxe_netdev, "PXENV_UNDI_GET_STATISTICS called with no " - "network device\n" ); - undi_get_statistics->Status = PXENV_STATUS_UNDI_INVALID_STATE; - return PXENV_EXIT_FAILURE; - } - - DBGC ( &pxe_netdev, "PXENV_UNDI_GET_STATISTICS" ); - - /* Report statistics */ - undi_get_statistics->XmtGoodFrames = pxe_netdev->tx_stats.good; - undi_get_statistics->RcvGoodFrames = pxe_netdev->rx_stats.good; - undi_get_statistics->RcvCRCErrors = pxe_netdev->rx_stats.bad; - undi_get_statistics->RcvResourceErrors = pxe_netdev->rx_stats.bad; - DBGC ( &pxe_netdev, " txok %d rxok %d rxcrc %d rxrsrc %d\n", - undi_get_statistics->XmtGoodFrames, - undi_get_statistics->RcvGoodFrames, - undi_get_statistics->RcvCRCErrors, - undi_get_statistics->RcvResourceErrors ); - - undi_get_statistics->Status = PXENV_STATUS_SUCCESS; - return PXENV_EXIT_SUCCESS; -} - -/* PXENV_UNDI_CLEAR_STATISTICS - * - * Status: working - */ -static PXENV_EXIT_t -pxenv_undi_clear_statistics ( struct s_PXENV_UNDI_CLEAR_STATISTICS - *undi_clear_statistics ) { - DBGC ( &pxe_netdev, "PXENV_UNDI_CLEAR_STATISTICS\n" ); - - /* Sanity check */ - if ( ! pxe_netdev ) { - DBGC ( &pxe_netdev, "PXENV_UNDI_CLEAR_STATISTICS called with " - "no network device\n" ); - undi_clear_statistics->Status = PXENV_STATUS_UNDI_INVALID_STATE; - return PXENV_EXIT_FAILURE; - } - - /* Clear statistics */ - memset ( &pxe_netdev->tx_stats, 0, sizeof ( pxe_netdev->tx_stats ) ); - memset ( &pxe_netdev->rx_stats, 0, sizeof ( pxe_netdev->rx_stats ) ); - - undi_clear_statistics->Status = PXENV_STATUS_SUCCESS; - return PXENV_EXIT_SUCCESS; -} - -/* PXENV_UNDI_INITIATE_DIAGS - * - * Status: won't implement (would require driver API changes for no - * real benefit) - */ -static PXENV_EXIT_t -pxenv_undi_initiate_diags ( struct s_PXENV_UNDI_INITIATE_DIAGS - *undi_initiate_diags ) { - DBGC ( &pxe_netdev, "PXENV_UNDI_INITIATE_DIAGS failed: unsupported\n" ); - - /* Sanity check */ - if ( ! pxe_netdev ) { - DBGC ( &pxe_netdev, "PXENV_UNDI_INITIATE_DIAGS called with no " - "network device\n" ); - undi_initiate_diags->Status = PXENV_STATUS_UNDI_INVALID_STATE; - return PXENV_EXIT_FAILURE; - } - - undi_initiate_diags->Status = PXENV_STATUS_UNSUPPORTED; - return PXENV_EXIT_FAILURE; -} - -/* PXENV_UNDI_FORCE_INTERRUPT - * - * Status: won't implement (would require driver API changes for no - * perceptible benefit) - */ -static PXENV_EXIT_t -pxenv_undi_force_interrupt ( struct s_PXENV_UNDI_FORCE_INTERRUPT - *undi_force_interrupt ) { - DBGC ( &pxe_netdev, - "PXENV_UNDI_FORCE_INTERRUPT failed: unsupported\n" ); - - /* Sanity check */ - if ( ! pxe_netdev ) { - DBGC ( &pxe_netdev, "PXENV_UNDI_FORCE_INTERRUPT called with no " - "network device\n" ); - undi_force_interrupt->Status = PXENV_STATUS_UNDI_INVALID_STATE; - return PXENV_EXIT_FAILURE; - } - - undi_force_interrupt->Status = PXENV_STATUS_UNSUPPORTED; - return PXENV_EXIT_FAILURE; -} - -/* PXENV_UNDI_GET_MCAST_ADDRESS - * - * Status: working - */ -static PXENV_EXIT_t -pxenv_undi_get_mcast_address ( struct s_PXENV_UNDI_GET_MCAST_ADDRESS - *undi_get_mcast_address ) { - struct ll_protocol *ll_protocol; - struct in_addr ip = { .s_addr = undi_get_mcast_address->InetAddr }; - int rc; - - /* Sanity check */ - if ( ! pxe_netdev ) { - DBGC ( &pxe_netdev, "PXENV_UNDI_GET_MCAST_ADDRESS called with " - "no network device\n" ); - undi_get_mcast_address->Status = - PXENV_STATUS_UNDI_INVALID_STATE; - return PXENV_EXIT_FAILURE; - } - - DBGC ( &pxe_netdev, "PXENV_UNDI_GET_MCAST_ADDRESS %s", - inet_ntoa ( ip ) ); - - /* Hash address using the network device's link-layer protocol */ - ll_protocol = pxe_netdev->ll_protocol; - if ( ( rc = ll_protocol->mc_hash ( AF_INET, &ip, - undi_get_mcast_address->MediaAddr ))!=0){ - DBGC ( &pxe_netdev, " failed: %s\n", strerror ( rc ) ); - undi_get_mcast_address->Status = PXENV_STATUS ( rc ); - return PXENV_EXIT_FAILURE; - } - DBGC ( &pxe_netdev, "=>%s\n", - ll_protocol->ntoa ( undi_get_mcast_address->MediaAddr ) ); - - undi_get_mcast_address->Status = PXENV_STATUS_SUCCESS; - return PXENV_EXIT_SUCCESS; -} - -/* PXENV_UNDI_GET_NIC_TYPE - * - * Status: working - */ -static PXENV_EXIT_t pxenv_undi_get_nic_type ( struct s_PXENV_UNDI_GET_NIC_TYPE - *undi_get_nic_type ) { - struct device *dev; - - /* Sanity check */ - if ( ! pxe_netdev ) { - DBGC ( &pxe_netdev, "PXENV_UNDI_GET_NIC_TYPE called with " - "no network device\n" ); - undi_get_nic_type->Status = PXENV_STATUS_UNDI_INVALID_STATE; - return PXENV_EXIT_FAILURE; - } - - DBGC ( &pxe_netdev, "PXENV_UNDI_GET_NIC_TYPE" ); - - /* Fill in information */ - memset ( &undi_get_nic_type->info, 0, - sizeof ( undi_get_nic_type->info ) ); - dev = pxe_netdev->dev; - switch ( dev->desc.bus_type ) { - case BUS_TYPE_PCI: { - struct pci_nic_info *info = &undi_get_nic_type->info.pci; - - undi_get_nic_type->NicType = PCI_NIC; - info->Vendor_ID = dev->desc.vendor; - info->Dev_ID = dev->desc.device; - info->Base_Class = PCI_BASE_CLASS ( dev->desc.class ); - info->Sub_Class = PCI_SUB_CLASS ( dev->desc.class ); - info->Prog_Intf = PCI_PROG_INTF ( dev->desc.class ); - info->BusDevFunc = dev->desc.location; - /* Earlier versions of the PXE specification do not - * have the SubVendor_ID and SubDevice_ID fields. It - * is possible that some NBPs will not provide space - * for them, and so we must not fill them in. - */ - DBGC ( &pxe_netdev, " PCI %02x:%02x.%x %04x:%04x " - "('%04x:%04x') %02x%02x%02x rev %02x\n", - PCI_BUS ( info->BusDevFunc ), - PCI_SLOT ( info->BusDevFunc ), - PCI_FUNC ( info->BusDevFunc ), info->Vendor_ID, - info->Dev_ID, info->SubVendor_ID, info->SubDevice_ID, - info->Base_Class, info->Sub_Class, info->Prog_Intf, - info->Rev ); - break; } - case BUS_TYPE_ISAPNP: { - struct pnp_nic_info *info = &undi_get_nic_type->info.pnp; - - undi_get_nic_type->NicType = PnP_NIC; - info->EISA_Dev_ID = ( ( dev->desc.vendor << 16 ) | - dev->desc.device ); - info->CardSelNum = dev->desc.location; - /* Cheat: remaining fields are probably unnecessary, - * and would require adding extra code to isapnp.c. - */ - DBGC ( &pxe_netdev, " ISAPnP CSN %04x %08x %02x%02x%02x\n", - info->CardSelNum, info->EISA_Dev_ID, - info->Base_Class, info->Sub_Class, info->Prog_Intf ); - break; } - default: - DBGC ( &pxe_netdev, " failed: unknown bus type\n" ); - undi_get_nic_type->Status = PXENV_STATUS_FAILURE; - return PXENV_EXIT_FAILURE; - } - - undi_get_nic_type->Status = PXENV_STATUS_SUCCESS; - return PXENV_EXIT_SUCCESS; -} - -/* PXENV_UNDI_GET_IFACE_INFO - * - * Status: working - */ -static PXENV_EXIT_t -pxenv_undi_get_iface_info ( struct s_PXENV_UNDI_GET_IFACE_INFO - *undi_get_iface_info ) { - - /* Sanity check */ - if ( ! pxe_netdev ) { - DBGC ( &pxe_netdev, "PXENV_UNDI_GET_IFACE_INFO called with " - "no network device\n" ); - undi_get_iface_info->Status = PXENV_STATUS_UNDI_INVALID_STATE; - return PXENV_EXIT_FAILURE; - } - - DBGC ( &pxe_netdev, "PXENV_UNDI_GET_IFACE_INFO" ); - - /* Just hand back some info, doesn't really matter what it is. - * Most PXE stacks seem to take this approach. - */ - snprintf ( ( char * ) undi_get_iface_info->IfaceType, - sizeof ( undi_get_iface_info->IfaceType ), "DIX+802.3" ); - undi_get_iface_info->LinkSpeed = 10000000; /* 10 Mbps */ - undi_get_iface_info->ServiceFlags = - ( SUPPORTED_BROADCAST | SUPPORTED_MULTICAST | - SUPPORTED_SET_STATION_ADDRESS | SUPPORTED_RESET | - SUPPORTED_OPEN_CLOSE ); - if ( netdev_irq_supported ( pxe_netdev ) ) - undi_get_iface_info->ServiceFlags |= SUPPORTED_IRQ; - memset ( undi_get_iface_info->Reserved, 0, - sizeof(undi_get_iface_info->Reserved) ); - - DBGC ( &pxe_netdev, " %s %dbps flags %08x\n", - undi_get_iface_info->IfaceType, undi_get_iface_info->LinkSpeed, - undi_get_iface_info->ServiceFlags ); - undi_get_iface_info->Status = PXENV_STATUS_SUCCESS; - return PXENV_EXIT_SUCCESS; -} - -/* PXENV_UNDI_GET_STATE - * - * Status: impossible due to opcode collision - */ - -/* PXENV_UNDI_ISR - * - * Status: working - */ -static PXENV_EXIT_t pxenv_undi_isr ( struct s_PXENV_UNDI_ISR *undi_isr ) { - struct io_buffer *iobuf; - size_t len; - struct ll_protocol *ll_protocol; - const void *ll_dest; - const void *ll_source; - uint16_t net_proto; - unsigned int flags; - size_t ll_hlen; - struct net_protocol *net_protocol; - unsigned int prottype; - int rc; - - /* Use a different debug colour, since UNDI ISR messages are - * likely to be interspersed amongst other UNDI messages. - */ - - /* Sanity check */ - if ( ! pxe_netdev ) { - DBGC ( &pxenv_undi_isr, "PXENV_UNDI_ISR called with " - "no network device\n" ); - undi_isr->Status = PXENV_STATUS_UNDI_INVALID_STATE; - return PXENV_EXIT_FAILURE; - } - - DBGC2 ( &pxenv_undi_isr, "PXENV_UNDI_ISR" ); - - /* Just in case some idiot actually looks at these fields when - * we weren't meant to fill them in... - */ - undi_isr->BufferLength = 0; - undi_isr->FrameLength = 0; - undi_isr->FrameHeaderLength = 0; - undi_isr->ProtType = 0; - undi_isr->PktType = 0; - - switch ( undi_isr->FuncFlag ) { - case PXENV_UNDI_ISR_IN_START : - DBGC2 ( &pxenv_undi_isr, " START" ); - - /* Call poll(). This should acknowledge the device - * interrupt and queue up any received packet. - */ - net_poll(); - - /* A 100% accurate determination of "OURS" vs "NOT - * OURS" is difficult to achieve without invasive and - * unpleasant changes to the driver model. We settle - * for always returning "OURS" if interrupts are - * currently enabled. - * - * Returning "NOT OURS" when interrupts are disabled - * allows us to avoid a potential interrupt storm when - * we are on a shared interrupt line; if we were to - * always return "OURS" then the other device's ISR - * may never be called. - */ - if ( netdev_irq_enabled ( pxe_netdev ) ) { - DBGC2 ( &pxenv_undi_isr, " OURS" ); - undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_OURS; - } else { - DBGC2 ( &pxenv_undi_isr, " NOT OURS" ); - undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_NOT_OURS; - } - - /* Disable interrupts */ - netdev_irq ( pxe_netdev, 0 ); - - break; - case PXENV_UNDI_ISR_IN_PROCESS : - case PXENV_UNDI_ISR_IN_GET_NEXT : - DBGC2 ( &pxenv_undi_isr, " %s", - ( ( undi_isr->FuncFlag == PXENV_UNDI_ISR_IN_PROCESS ) ? - "PROCESS" : "GET_NEXT" ) ); - - /* Some dumb NBPs (e.g. emBoot's winBoot/i) never call - * PXENV_UNDI_ISR with FuncFlag=PXENV_UNDI_ISR_START; - * they just sit in a tight polling loop merrily - * violating the PXE spec with repeated calls to - * PXENV_UNDI_ISR_IN_PROCESS. Force extra polls to - * cope with these out-of-spec clients. - */ - net_poll(); - - /* If we have not yet marked a TX as complete, and the - * netdev TX queue is empty, report the TX completion. - */ - if ( undi_tx_count && list_empty ( &pxe_netdev->tx_queue ) ) { - DBGC2 ( &pxenv_undi_isr, " TXC" ); - undi_tx_count--; - undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_TRANSMIT; - break; - } - - /* Remove first packet from netdev RX queue */ - iobuf = netdev_rx_dequeue ( pxe_netdev ); - if ( ! iobuf ) { - DBGC2 ( &pxenv_undi_isr, " DONE" ); - /* No more packets remaining */ - undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_DONE; - /* Re-enable interrupts */ - netdev_irq ( pxe_netdev, 1 ); - break; - } - - /* Copy packet to base memory buffer */ - len = iob_len ( iobuf ); - DBGC2 ( &pxenv_undi_isr, " RX" ); - if ( len > sizeof ( basemem_packet ) ) { - /* Should never happen */ - DBGC2 ( &pxenv_undi_isr, " overlength (%zx)", len ); - len = sizeof ( basemem_packet ); - } - memcpy ( basemem_packet, iobuf->data, len ); - - /* Strip link-layer header */ - ll_protocol = pxe_netdev->ll_protocol; - if ( ( rc = ll_protocol->pull ( pxe_netdev, iobuf, &ll_dest, - &ll_source, &net_proto, - &flags ) ) != 0 ) { - /* Assume unknown net_proto and no ll_source */ - net_proto = 0; - ll_source = NULL; - } - ll_hlen = ( len - iob_len ( iobuf ) ); - - /* Determine network-layer protocol */ - switch ( net_proto ) { - case htons ( ETH_P_IP ): - net_protocol = &ipv4_protocol; - prottype = P_IP; - break; - case htons ( ETH_P_ARP ): - net_protocol = &arp_protocol; - prottype = P_ARP; - break; - case htons ( ETH_P_RARP ): - net_protocol = &rarp_protocol; - prottype = P_RARP; - break; - default: - net_protocol = NULL; - prottype = P_UNKNOWN; - break; - } - - /* Fill in UNDI_ISR structure */ - undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_RECEIVE; - undi_isr->BufferLength = len; - undi_isr->FrameLength = len; - undi_isr->FrameHeaderLength = ll_hlen; - undi_isr->Frame.segment = rm_ds; - undi_isr->Frame.offset = __from_data16 ( basemem_packet ); - undi_isr->ProtType = prottype; - if ( flags & LL_BROADCAST ) { - undi_isr->PktType = P_BROADCAST; - } else if ( flags & LL_MULTICAST ) { - undi_isr->PktType = P_MULTICAST; - } else { - undi_isr->PktType = P_DIRECTED; - } - DBGC2 ( &pxenv_undi_isr, " %04x:%04x+%x(%x) %s hlen %d", - undi_isr->Frame.segment, undi_isr->Frame.offset, - undi_isr->BufferLength, undi_isr->FrameLength, - ( net_protocol ? net_protocol->name : "RAW" ), - undi_isr->FrameHeaderLength ); - - /* Free packet */ - free_iob ( iobuf ); - break; - default : - DBGC2 ( &pxenv_undi_isr, " INVALID(%04x)\n", - undi_isr->FuncFlag ); - - /* Should never happen */ - undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_DONE; - undi_isr->Status = PXENV_STATUS_UNDI_INVALID_PARAMETER; - return PXENV_EXIT_FAILURE; - } - - DBGC2 ( &pxenv_undi_isr, "\n" ); - undi_isr->Status = PXENV_STATUS_SUCCESS; - return PXENV_EXIT_SUCCESS; -} - -/** PXE UNDI API */ -struct pxe_api_call pxe_undi_api[] __pxe_api_call = { - PXE_API_CALL ( PXENV_UNDI_STARTUP, pxenv_undi_startup, - struct s_PXENV_UNDI_STARTUP ), - PXE_API_CALL ( PXENV_UNDI_CLEANUP, pxenv_undi_cleanup, - struct s_PXENV_UNDI_CLEANUP ), - PXE_API_CALL ( PXENV_UNDI_INITIALIZE, pxenv_undi_initialize, - struct s_PXENV_UNDI_INITIALIZE ), - PXE_API_CALL ( PXENV_UNDI_RESET_ADAPTER, pxenv_undi_reset_adapter, - struct s_PXENV_UNDI_RESET ), - PXE_API_CALL ( PXENV_UNDI_SHUTDOWN, pxenv_undi_shutdown, - struct s_PXENV_UNDI_SHUTDOWN ), - PXE_API_CALL ( PXENV_UNDI_OPEN, pxenv_undi_open, - struct s_PXENV_UNDI_OPEN ), - PXE_API_CALL ( PXENV_UNDI_CLOSE, pxenv_undi_close, - struct s_PXENV_UNDI_CLOSE ), - PXE_API_CALL ( PXENV_UNDI_TRANSMIT, pxenv_undi_transmit, - struct s_PXENV_UNDI_TRANSMIT ), - PXE_API_CALL ( PXENV_UNDI_SET_MCAST_ADDRESS, - pxenv_undi_set_mcast_address, - struct s_PXENV_UNDI_SET_MCAST_ADDRESS ), - PXE_API_CALL ( PXENV_UNDI_SET_STATION_ADDRESS, - pxenv_undi_set_station_address, - struct s_PXENV_UNDI_SET_STATION_ADDRESS ), - PXE_API_CALL ( PXENV_UNDI_SET_PACKET_FILTER, - pxenv_undi_set_packet_filter, - struct s_PXENV_UNDI_SET_PACKET_FILTER ), - PXE_API_CALL ( PXENV_UNDI_GET_INFORMATION, pxenv_undi_get_information, - struct s_PXENV_UNDI_GET_INFORMATION ), - PXE_API_CALL ( PXENV_UNDI_GET_STATISTICS, pxenv_undi_get_statistics, - struct s_PXENV_UNDI_GET_STATISTICS ), - PXE_API_CALL ( PXENV_UNDI_CLEAR_STATISTICS, pxenv_undi_clear_statistics, - struct s_PXENV_UNDI_CLEAR_STATISTICS ), - PXE_API_CALL ( PXENV_UNDI_INITIATE_DIAGS, pxenv_undi_initiate_diags, - struct s_PXENV_UNDI_INITIATE_DIAGS ), - PXE_API_CALL ( PXENV_UNDI_FORCE_INTERRUPT, pxenv_undi_force_interrupt, - struct s_PXENV_UNDI_FORCE_INTERRUPT ), - PXE_API_CALL ( PXENV_UNDI_GET_MCAST_ADDRESS, - pxenv_undi_get_mcast_address, - struct s_PXENV_UNDI_GET_MCAST_ADDRESS ), - PXE_API_CALL ( PXENV_UNDI_GET_NIC_TYPE, pxenv_undi_get_nic_type, - struct s_PXENV_UNDI_GET_NIC_TYPE ), - PXE_API_CALL ( PXENV_UNDI_GET_IFACE_INFO, pxenv_undi_get_iface_info, - struct s_PXENV_UNDI_GET_IFACE_INFO ), - PXE_API_CALL ( PXENV_UNDI_ISR, pxenv_undi_isr, - struct s_PXENV_UNDI_ISR ), -}; diff --git a/qemu/roms/ipxe/src/arch/i386/interface/pxeparent/pxeparent.c b/qemu/roms/ipxe/src/arch/i386/interface/pxeparent/pxeparent.c deleted file mode 100644 index 0b6be9a03..000000000 --- a/qemu/roms/ipxe/src/arch/i386/interface/pxeparent/pxeparent.c +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -FILE_LICENCE ( GPL2_OR_LATER ); - -#include <ipxe/dhcp.h> -#include <ipxe/profile.h> -#include <pxeparent.h> -#include <pxe_api.h> -#include <pxe_types.h> -#include <pxe.h> - -/** @file - * - * Call interface to parent PXE stack - * - */ - -/* Disambiguate the various error causes */ -#define EINFO_EPXECALL \ - __einfo_uniqify ( EINFO_EPLATFORM, 0x01, \ - "External PXE API error" ) -#define EPXECALL( status ) EPLATFORM ( EINFO_EPXECALL, status ) - -/** A parent PXE API call profiler */ -struct pxeparent_profiler { - /** Total time spent performing REAL_CALL() */ - struct profiler total; - /** Time spent transitioning to real mode */ - struct profiler p2r; - /** Time spent in external code */ - struct profiler ext; - /** Time spent transitioning back to protected mode */ - struct profiler r2p; -}; - -/** PXENV_UNDI_TRANSMIT profiler */ -static struct pxeparent_profiler pxeparent_tx_profiler __profiler = { - { .name = "pxeparent.tx" }, - { .name = "pxeparent.tx_p2r" }, - { .name = "pxeparent.tx_ext" }, - { .name = "pxeparent.tx_r2p" }, -}; - -/** PXENV_UNDI_ISR profiler - * - * Note that this profiler will not see calls to - * PXENV_UNDI_ISR_IN_START, which are handled by the UNDI ISR and do - * not go via pxeparent_call(). - */ -static struct pxeparent_profiler pxeparent_isr_profiler __profiler = { - { .name = "pxeparent.isr" }, - { .name = "pxeparent.isr_p2r" }, - { .name = "pxeparent.isr_ext" }, - { .name = "pxeparent.isr_r2p" }, -}; - -/** PXE unknown API call profiler - * - * This profiler can be used to measure the overhead of a dummy PXE - * API call. - */ -static struct pxeparent_profiler pxeparent_unknown_profiler __profiler = { - { .name = "pxeparent.unknown" }, - { .name = "pxeparent.unknown_p2r" }, - { .name = "pxeparent.unknown_ext" }, - { .name = "pxeparent.unknown_r2p" }, -}; - -/** Miscellaneous PXE API call profiler */ -static struct pxeparent_profiler pxeparent_misc_profiler __profiler = { - { .name = "pxeparent.misc" }, - { .name = "pxeparent.misc_p2r" }, - { .name = "pxeparent.misc_ext" }, - { .name = "pxeparent.misc_r2p" }, -}; - -/** - * Name PXE API call - * - * @v function API call number - * @ret name API call name - */ -static inline __attribute__ (( always_inline )) const char * -pxeparent_function_name ( unsigned int function ) { - switch ( function ) { - case PXENV_START_UNDI: - return "PXENV_START_UNDI"; - case PXENV_STOP_UNDI: - return "PXENV_STOP_UNDI"; - case PXENV_UNDI_STARTUP: - return "PXENV_UNDI_STARTUP"; - case PXENV_UNDI_CLEANUP: - return "PXENV_UNDI_CLEANUP"; - case PXENV_UNDI_INITIALIZE: - return "PXENV_UNDI_INITIALIZE"; - case PXENV_UNDI_RESET_ADAPTER: - return "PXENV_UNDI_RESET_ADAPTER"; - case PXENV_UNDI_SHUTDOWN: - return "PXENV_UNDI_SHUTDOWN"; - case PXENV_UNDI_OPEN: - return "PXENV_UNDI_OPEN"; - case PXENV_UNDI_CLOSE: - return "PXENV_UNDI_CLOSE"; - case PXENV_UNDI_TRANSMIT: - return "PXENV_UNDI_TRANSMIT"; - case PXENV_UNDI_SET_MCAST_ADDRESS: - return "PXENV_UNDI_SET_MCAST_ADDRESS"; - case PXENV_UNDI_SET_STATION_ADDRESS: - return "PXENV_UNDI_SET_STATION_ADDRESS"; - case PXENV_UNDI_SET_PACKET_FILTER: - return "PXENV_UNDI_SET_PACKET_FILTER"; - case PXENV_UNDI_GET_INFORMATION: - return "PXENV_UNDI_GET_INFORMATION"; - case PXENV_UNDI_GET_STATISTICS: - return "PXENV_UNDI_GET_STATISTICS"; - case PXENV_UNDI_CLEAR_STATISTICS: - return "PXENV_UNDI_CLEAR_STATISTICS"; - case PXENV_UNDI_INITIATE_DIAGS: - return "PXENV_UNDI_INITIATE_DIAGS"; - case PXENV_UNDI_FORCE_INTERRUPT: - return "PXENV_UNDI_FORCE_INTERRUPT"; - case PXENV_UNDI_GET_MCAST_ADDRESS: - return "PXENV_UNDI_GET_MCAST_ADDRESS"; - case PXENV_UNDI_GET_NIC_TYPE: - return "PXENV_UNDI_GET_NIC_TYPE"; - case PXENV_UNDI_GET_IFACE_INFO: - return "PXENV_UNDI_GET_IFACE_INFO"; - /* - * Duplicate case value; this is a bug in the PXE specification. - * - * case PXENV_UNDI_GET_STATE: - * return "PXENV_UNDI_GET_STATE"; - */ - case PXENV_UNDI_ISR: - return "PXENV_UNDI_ISR"; - case PXENV_GET_CACHED_INFO: - return "PXENV_GET_CACHED_INFO"; - default: - return "UNKNOWN API CALL"; - } -} - -/** - * Determine applicable profiler pair (for debugging) - * - * @v function API call number - * @ret profiler Profiler - */ -static struct pxeparent_profiler * pxeparent_profiler ( unsigned int function ){ - - /* Determine applicable profiler */ - switch ( function ) { - case PXENV_UNDI_TRANSMIT: - return &pxeparent_tx_profiler; - case PXENV_UNDI_ISR: - return &pxeparent_isr_profiler; - case PXENV_UNKNOWN: - return &pxeparent_unknown_profiler; - default: - return &pxeparent_misc_profiler; - } -} - -/** - * PXE parent parameter block - * - * Used as the parameter block for all parent PXE API calls. Resides - * in base memory. - */ -static union u_PXENV_ANY __bss16 ( pxeparent_params ); -#define pxeparent_params __use_data16 ( pxeparent_params ) - -/** PXE parent entry point - * - * Used as the indirection vector for all parent PXE API calls. Resides in - * base memory. - */ -SEGOFF16_t __bss16 ( pxeparent_entry_point ); -#define pxeparent_entry_point __use_data16 ( pxeparent_entry_point ) - -/** - * Issue parent PXE API call - * - * @v entry Parent PXE stack entry point - * @v function API call number - * @v params PXE parameter block - * @v params_len Length of PXE parameter block - * @ret rc Return status code - */ -int pxeparent_call ( SEGOFF16_t entry, unsigned int function, - void *params, size_t params_len ) { - struct pxeparent_profiler *profiler = pxeparent_profiler ( function ); - PXENV_EXIT_t exit; - unsigned long started; - unsigned long stopped; - int discard_D; - int rc; - - /* Copy parameter block and entry point */ - assert ( params_len <= sizeof ( pxeparent_params ) ); - memcpy ( &pxeparent_params, params, params_len ); - memcpy ( &pxeparent_entry_point, &entry, sizeof ( entry ) ); - - /* Call real-mode entry point. This calling convention will - * work with both the !PXE and the PXENV+ entry points. - */ - profile_start ( &profiler->total ); - __asm__ __volatile__ ( REAL_CODE ( "pushl %%ebp\n\t" /* gcc bug */ - "rdtsc\n\t" - "pushl %%eax\n\t" - "pushw %%es\n\t" - "pushw %%di\n\t" - "pushw %%bx\n\t" - "lcall *pxeparent_entry_point\n\t" - "movw %%ax, %%bx\n\t" - "rdtsc\n\t" - "addw $6, %%sp\n\t" - "popl %%edx\n\t" - "popl %%ebp\n\t" /* gcc bug */ ) - : "=a" ( stopped ), "=d" ( started ), - "=b" ( exit ), "=D" ( discard_D ) - : "b" ( function ), - "D" ( __from_data16 ( &pxeparent_params ) ) - : "ecx", "esi" ); - profile_stop ( &profiler->total ); - profile_start_at ( &profiler->p2r, profile_started ( &profiler->total)); - profile_stop_at ( &profiler->p2r, started ); - profile_start_at ( &profiler->ext, started ); - profile_stop_at ( &profiler->ext, stopped ); - profile_start_at ( &profiler->r2p, stopped ); - profile_stop_at ( &profiler->r2p, profile_stopped ( &profiler->total )); - - /* Determine return status code based on PXENV_EXIT and - * PXENV_STATUS - */ - rc = ( ( exit == PXENV_EXIT_SUCCESS ) ? - 0 : -EPXECALL ( pxeparent_params.Status ) ); - - /* If anything goes wrong, print as much debug information as - * it's possible to give. - */ - if ( rc != 0 ) { - SEGOFF16_t rm_params = { - .segment = rm_ds, - .offset = __from_data16 ( &pxeparent_params ), - }; - - DBG ( "PXEPARENT %s failed: %s\n", - pxeparent_function_name ( function ), strerror ( rc ) ); - DBG ( "PXEPARENT parameters at %04x:%04x length " - "%#02zx, entry point at %04x:%04x\n", - rm_params.segment, rm_params.offset, params_len, - pxeparent_entry_point.segment, - pxeparent_entry_point.offset ); - DBG ( "PXEPARENT parameters provided:\n" ); - DBG_HDA ( rm_params, params, params_len ); - DBG ( "PXEPARENT parameters returned:\n" ); - DBG_HDA ( rm_params, &pxeparent_params, params_len ); - } - - /* Copy parameter block back */ - memcpy ( params, &pxeparent_params, params_len ); - - return rc; -} - diff --git a/qemu/roms/ipxe/src/arch/i386/interface/syslinux/com32_call.c b/qemu/roms/ipxe/src/arch/i386/interface/syslinux/com32_call.c deleted file mode 100644 index 75dcc238f..000000000 --- a/qemu/roms/ipxe/src/arch/i386/interface/syslinux/com32_call.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (C) 2008 Daniel Verkamp <daniel@drv.nu>. - * - * 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. - */ - -/** - * @file SYSLINUX COM32 helpers - * - */ - -FILE_LICENCE ( GPL2_OR_LATER ); - -#include <stdint.h> -#include <realmode.h> -#include <comboot.h> -#include <assert.h> -#include <ipxe/uaccess.h> - -static com32sys_t __bss16 ( com32_regs ); -#define com32_regs __use_data16 ( com32_regs ) - -static uint8_t __bss16 ( com32_int_vector ); -#define com32_int_vector __use_data16 ( com32_int_vector ) - -static uint32_t __bss16 ( com32_farcall_proc ); -#define com32_farcall_proc __use_data16 ( com32_farcall_proc ) - -uint16_t __bss16 ( com32_saved_sp ); - -/** - * Interrupt call helper - */ -void __asmcall com32_intcall ( uint8_t interrupt, physaddr_t inregs_phys, physaddr_t outregs_phys ) { - - memcpy_user ( virt_to_user( &com32_regs ), 0, - phys_to_user ( inregs_phys ), 0, - sizeof(com32sys_t) ); - - com32_int_vector = interrupt; - - __asm__ __volatile__ ( - REAL_CODE ( /* Save all registers */ - "pushal\n\t" - "pushw %%ds\n\t" - "pushw %%es\n\t" - "pushw %%fs\n\t" - "pushw %%gs\n\t" - /* Mask off unsafe flags */ - "movl (com32_regs + 40), %%eax\n\t" - "andl $0x200cd7, %%eax\n\t" - "movl %%eax, (com32_regs + 40)\n\t" - /* Load com32_regs into the actual registers */ - "movw %%sp, %%ss:(com32_saved_sp)\n\t" - "movw $com32_regs, %%sp\n\t" - "popw %%gs\n\t" - "popw %%fs\n\t" - "popw %%es\n\t" - "popw %%ds\n\t" - "popal\n\t" - "popfl\n\t" - "movw %%ss:(com32_saved_sp), %%sp\n\t" - /* patch INT instruction */ - "pushw %%ax\n\t" - "movb %%ss:(com32_int_vector), %%al\n\t" - "movb %%al, %%cs:(com32_intcall_instr + 1)\n\t" - /* perform a jump to avoid problems with cache - * consistency in self-modifying code on some CPUs (486) - */ - "jmp 1f\n" - "1:\n\t" - "popw %%ax\n\t" - "com32_intcall_instr:\n\t" - /* INT instruction to be patched */ - "int $0xFF\n\t" - /* Copy regs back to com32_regs */ - "movw %%sp, %%ss:(com32_saved_sp)\n\t" - "movw $(com32_regs + 44), %%sp\n\t" - "pushfl\n\t" - "pushal\n\t" - "pushw %%ds\n\t" - "pushw %%es\n\t" - "pushw %%fs\n\t" - "pushw %%gs\n\t" - "movw %%ss:(com32_saved_sp), %%sp\n\t" - /* Restore registers */ - "popw %%gs\n\t" - "popw %%fs\n\t" - "popw %%es\n\t" - "popw %%ds\n\t" - "popal\n\t") - : : ); - - if ( outregs_phys ) { - memcpy_user ( phys_to_user ( outregs_phys ), 0, - virt_to_user( &com32_regs ), 0, - sizeof(com32sys_t) ); - } -} - -/** - * Farcall helper - */ -void __asmcall com32_farcall ( uint32_t proc, physaddr_t inregs_phys, physaddr_t outregs_phys ) { - - memcpy_user ( virt_to_user( &com32_regs ), 0, - phys_to_user ( inregs_phys ), 0, - sizeof(com32sys_t) ); - - com32_farcall_proc = proc; - - __asm__ __volatile__ ( - REAL_CODE ( /* Save all registers */ - "pushal\n\t" - "pushw %%ds\n\t" - "pushw %%es\n\t" - "pushw %%fs\n\t" - "pushw %%gs\n\t" - /* Mask off unsafe flags */ - "movl (com32_regs + 40), %%eax\n\t" - "andl $0x200cd7, %%eax\n\t" - "movl %%eax, (com32_regs + 40)\n\t" - /* Load com32_regs into the actual registers */ - "movw %%sp, %%ss:(com32_saved_sp)\n\t" - "movw $com32_regs, %%sp\n\t" - "popw %%gs\n\t" - "popw %%fs\n\t" - "popw %%es\n\t" - "popw %%ds\n\t" - "popal\n\t" - "popfl\n\t" - "movw %%ss:(com32_saved_sp), %%sp\n\t" - /* Call procedure */ - "lcall *%%ss:(com32_farcall_proc)\n\t" - /* Copy regs back to com32_regs */ - "movw %%sp, %%ss:(com32_saved_sp)\n\t" - "movw $(com32_regs + 44), %%sp\n\t" - "pushfl\n\t" - "pushal\n\t" - "pushw %%ds\n\t" - "pushw %%es\n\t" - "pushw %%fs\n\t" - "pushw %%gs\n\t" - "movw %%ss:(com32_saved_sp), %%sp\n\t" - /* Restore registers */ - "popw %%gs\n\t" - "popw %%fs\n\t" - "popw %%es\n\t" - "popw %%ds\n\t" - "popal\n\t") - : : ); - - if ( outregs_phys ) { - memcpy_user ( phys_to_user ( outregs_phys ), 0, - virt_to_user( &com32_regs ), 0, - sizeof(com32sys_t) ); - } -} - -/** - * CDECL farcall helper - */ -int __asmcall com32_cfarcall ( uint32_t proc, physaddr_t stack, size_t stacksz ) { - int32_t eax; - - copy_user_to_rm_stack ( phys_to_user ( stack ), stacksz ); - com32_farcall_proc = proc; - - __asm__ __volatile__ ( - REAL_CODE ( "lcall *%%ss:(com32_farcall_proc)\n\t" ) - : "=a" (eax) - : - : "ecx", "edx" ); - - remove_user_from_rm_stack ( 0, stacksz ); - - return eax; -} diff --git a/qemu/roms/ipxe/src/arch/i386/interface/syslinux/com32_wrapper.S b/qemu/roms/ipxe/src/arch/i386/interface/syslinux/com32_wrapper.S deleted file mode 100644 index c9d1452b4..000000000 --- a/qemu/roms/ipxe/src/arch/i386/interface/syslinux/com32_wrapper.S +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2008 Daniel Verkamp <daniel@drv.nu>. - * - * 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. - */ - -FILE_LICENCE ( GPL2_OR_LATER ) - - .text - .arch i386 - .code32 - - .globl com32_farcall_wrapper -com32_farcall_wrapper: - - movl $com32_farcall, %eax - jmp com32_wrapper - - - .globl com32_cfarcall_wrapper -com32_cfarcall_wrapper: - - movl $com32_cfarcall, %eax - jmp com32_wrapper - - - .globl com32_intcall_wrapper -com32_intcall_wrapper: - - movl $com32_intcall, %eax - /*jmp com32_wrapper*/ /* fall through */ - -com32_wrapper: - cli - - /* Switch to internal virtual address space */ - call _phys_to_virt - - mov %eax, (com32_helper_function) - - /* Save external COM32 stack pointer */ - movl %esp, (com32_external_esp) - - /* Copy arguments to caller-save registers */ - movl 12(%esp), %eax - movl 8(%esp), %ecx - movl 4(%esp), %edx - - /* Switch to internal stack */ - movl (com32_internal_esp), %esp - - /* Copy arguments to internal stack */ - pushl %eax - pushl %ecx - pushl %edx - - call *(com32_helper_function) - - /* Clean up stack */ - addl $12, %esp - - /* Save internal stack pointer and restore external stack pointer */ - movl %esp, (com32_internal_esp) - movl (com32_external_esp), %esp - - /* Switch to external flat physical address space */ - call _virt_to_phys - - sti - ret - - - .data - -/* Internal iPXE virtual address space %esp */ -.globl com32_internal_esp -.lcomm com32_internal_esp, 4 - -/* External flat physical address space %esp */ -.globl com32_external_esp -.lcomm com32_external_esp, 4 - -/* Function pointer of helper to call */ -.lcomm com32_helper_function, 4 diff --git a/qemu/roms/ipxe/src/arch/i386/interface/syslinux/comboot_call.c b/qemu/roms/ipxe/src/arch/i386/interface/syslinux/comboot_call.c deleted file mode 100644 index 69d94c407..000000000 --- a/qemu/roms/ipxe/src/arch/i386/interface/syslinux/comboot_call.c +++ /dev/null @@ -1,717 +0,0 @@ -/* - * Copyright (C) 2008 Daniel Verkamp <daniel@drv.nu>. - * - * 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. - */ - -/** - * @file SYSLINUX COMBOOT API - * - */ - -FILE_LICENCE ( GPL2_OR_LATER ); - -#include <errno.h> -#include <realmode.h> -#include <biosint.h> -#include <ipxe/console.h> -#include <stdlib.h> -#include <comboot.h> -#include <bzimage.h> -#include <pxe_call.h> -#include <setjmp.h> -#include <string.h> -#include <ipxe/posix_io.h> -#include <ipxe/process.h> -#include <ipxe/serial.h> -#include <ipxe/init.h> -#include <ipxe/image.h> -#include <ipxe/version.h> -#include <usr/imgmgmt.h> - -/** The "SYSLINUX" version string */ -static char __bss16_array ( syslinux_version, [32] ); -#define syslinux_version __use_data16 ( syslinux_version ) - -/** The "SYSLINUX" copyright string */ -static char __data16_array ( syslinux_copyright, [] ) = " http://ipxe.org"; -#define syslinux_copyright __use_data16 ( syslinux_copyright ) - -static char __data16_array ( syslinux_configuration_file, [] ) = ""; -#define syslinux_configuration_file __use_data16 ( syslinux_configuration_file ) - -/** Feature flags */ -static uint8_t __data16 ( comboot_feature_flags ) = COMBOOT_FEATURE_IDLE_LOOP; -#define comboot_feature_flags __use_data16 ( comboot_feature_flags ) - -typedef union { - syslinux_pm_regs pm; syslinux_rm_regs rm; -} syslinux_regs; - -/** Initial register values for INT 22h AX=1Ah and 1Bh */ -static syslinux_regs __text16 ( comboot_initial_regs ); -#define comboot_initial_regs __use_text16 ( comboot_initial_regs ) - -static struct segoff __text16 ( int20_vector ); -#define int20_vector __use_text16 ( int20_vector ) - -static struct segoff __text16 ( int21_vector ); -#define int21_vector __use_text16 ( int21_vector ) - -static struct segoff __text16 ( int22_vector ); -#define int22_vector __use_text16 ( int22_vector ) - -extern void int20_wrapper ( void ); -extern void int21_wrapper ( void ); -extern void int22_wrapper ( void ); - -/* setjmp/longjmp context buffer used to return after loading an image */ -rmjmp_buf comboot_return; - -/* Mode flags set by INT 22h AX=0017h */ -static uint16_t comboot_graphics_mode = 0; - -/** - * Print a string with a particular terminator - */ -static void print_user_string ( unsigned int segment, unsigned int offset, char terminator ) { - int i = 0; - char c; - userptr_t str = real_to_user ( segment, offset ); - for ( ; ; ) { - copy_from_user ( &c, str, i, 1 ); - if ( c == terminator ) break; - putchar ( c ); - i++; - } -} - - -/** - * Perform a series of memory copies from a list in low memory - */ -static void shuffle ( unsigned int list_segment, unsigned int list_offset, unsigned int count ) -{ - comboot_shuffle_descriptor shuf[COMBOOT_MAX_SHUFFLE_DESCRIPTORS]; - unsigned int i; - - /* Copy shuffle descriptor list so it doesn't get overwritten */ - copy_from_user ( shuf, real_to_user ( list_segment, list_offset ), 0, - count * sizeof( comboot_shuffle_descriptor ) ); - - /* Do the copies */ - for ( i = 0; i < count; i++ ) { - userptr_t src_u = phys_to_user ( shuf[ i ].src ); - userptr_t dest_u = phys_to_user ( shuf[ i ].dest ); - - if ( shuf[ i ].src == 0xFFFFFFFF ) { - /* Fill with 0 instead of copying */ - memset_user ( dest_u, 0, 0, shuf[ i ].len ); - } else if ( shuf[ i ].dest == 0xFFFFFFFF ) { - /* Copy new list of descriptors */ - count = shuf[ i ].len / sizeof( comboot_shuffle_descriptor ); - assert ( count <= COMBOOT_MAX_SHUFFLE_DESCRIPTORS ); - copy_from_user ( shuf, src_u, 0, shuf[ i ].len ); - i = -1; - } else { - /* Regular copy */ - memmove_user ( dest_u, 0, src_u, 0, shuf[ i ].len ); - } - } -} - - -/** - * Set default text mode - */ -void comboot_force_text_mode ( void ) { - if ( comboot_graphics_mode & COMBOOT_VIDEO_VESA ) { - /* Set VGA mode 3 via VESA VBE mode set */ - __asm__ __volatile__ ( - REAL_CODE ( - "mov $0x4F02, %%ax\n\t" - "mov $0x03, %%bx\n\t" - "int $0x10\n\t" - ) - : : ); - } else if ( comboot_graphics_mode & COMBOOT_VIDEO_GRAPHICS ) { - /* Set VGA mode 3 via standard VGA mode set */ - __asm__ __volatile__ ( - REAL_CODE ( - "mov $0x03, %%ax\n\t" - "int $0x10\n\t" - ) - : : ); - } - - comboot_graphics_mode = 0; -} - - -/** - * Fetch kernel and optional initrd - */ -static int comboot_fetch_kernel ( char *kernel_file, char *cmdline ) { - struct image *kernel; - struct image *initrd; - char *initrd_file; - int rc; - - /* Find initrd= parameter, if any */ - if ( ( initrd_file = strstr ( cmdline, "initrd=" ) ) != NULL ) { - char *initrd_end; - - /* skip "initrd=" */ - initrd_file += 7; - - /* Find terminating space, if any, and replace with NUL */ - initrd_end = strchr ( initrd_file, ' ' ); - if ( initrd_end ) - *initrd_end = '\0'; - - DBG ( "COMBOOT: fetching initrd '%s'\n", initrd_file ); - - /* Fetch initrd */ - if ( ( rc = imgdownload_string ( initrd_file, 0, - &initrd ) ) != 0 ) { - DBG ( "COMBOOT: could not fetch initrd: %s\n", - strerror ( rc ) ); - return rc; - } - - /* Restore space after initrd name, if applicable */ - if ( initrd_end ) - *initrd_end = ' '; - } - - DBG ( "COMBOOT: fetching kernel '%s'\n", kernel_file ); - - /* Fetch kernel */ - if ( ( rc = imgdownload_string ( kernel_file, 0, &kernel ) ) != 0 ) { - DBG ( "COMBOOT: could not fetch kernel: %s\n", - strerror ( rc ) ); - return rc; - } - - /* Replace comboot image with kernel */ - if ( ( rc = image_replace ( kernel ) ) != 0 ) { - DBG ( "COMBOOT: could not replace with kernel: %s\n", - strerror ( rc ) ); - return rc; - } - - return 0; -} - - -/** - * Terminate program interrupt handler - */ -static __asmcall void int20 ( struct i386_all_regs *ix86 __unused ) { - rmlongjmp ( comboot_return, COMBOOT_EXIT ); -} - - -/** - * DOS-compatible API - */ -static __asmcall void int21 ( struct i386_all_regs *ix86 ) { - ix86->flags |= CF; - - switch ( ix86->regs.ah ) { - case 0x00: - case 0x4C: /* Terminate program */ - rmlongjmp ( comboot_return, COMBOOT_EXIT ); - break; - - case 0x01: /* Get Key with Echo */ - case 0x08: /* Get Key without Echo */ - /* TODO: handle extended characters? */ - ix86->regs.al = getchar( ); - - /* Enter */ - if ( ix86->regs.al == 0x0A ) - ix86->regs.al = 0x0D; - - if ( ix86->regs.ah == 0x01 ) - putchar ( ix86->regs.al ); - - ix86->flags &= ~CF; - break; - - case 0x02: /* Write Character */ - putchar ( ix86->regs.dl ); - ix86->flags &= ~CF; - break; - - case 0x04: /* Write Character to Serial Port */ - if ( serial_console.base ) { - uart_transmit ( &serial_console, ix86->regs.dl ); - ix86->flags &= ~CF; - } - break; - - case 0x09: /* Write DOS String to Console */ - print_user_string ( ix86->segs.ds, ix86->regs.dx, '$' ); - ix86->flags &= ~CF; - break; - - case 0x0B: /* Check Keyboard */ - if ( iskey() ) - ix86->regs.al = 0xFF; - else - ix86->regs.al = 0x00; - - ix86->flags &= ~CF; - break; - - case 0x30: /* Check DOS Version */ - /* Bottom halves all 0; top halves spell "SYSLINUX" */ - ix86->regs.eax = 0x59530000; - ix86->regs.ebx = 0x4C530000; - ix86->regs.ecx = 0x4E490000; - ix86->regs.edx = 0x58550000; - ix86->flags &= ~CF; - break; - - default: - DBG ( "COMBOOT unknown int21 function %02x\n", ix86->regs.ah ); - break; - } -} - - -/** - * Dispatch PXE API call weakly - * - * @v ix86 Registers for PXE call - * @ret present Zero if the PXE stack is present, nonzero if not - * - * A successful return only indicates that the PXE stack was available - * for dispatching the call; it says nothing about the success of - * whatever the call asked for. - */ -__weak int pxe_api_call_weak ( struct i386_all_regs *ix86 __unused ) { - return -1; -} - -/** - * SYSLINUX API - */ -static __asmcall void int22 ( struct i386_all_regs *ix86 ) { - ix86->flags |= CF; - - switch ( ix86->regs.ax ) { - case 0x0001: /* Get Version */ - - /* Number of INT 22h API functions available */ - ix86->regs.ax = 0x001D; - - /* SYSLINUX version number */ - ix86->regs.ch = 0; /* major */ - ix86->regs.cl = 0; /* minor */ - - /* SYSLINUX derivative ID */ - ix86->regs.dl = BZI_LOADER_TYPE_IPXE; - - /* SYSLINUX version */ - snprintf ( syslinux_version, sizeof ( syslinux_version ), - "\r\niPXE %s", product_version ); - - /* SYSLINUX version and copyright strings */ - ix86->segs.es = rm_ds; - ix86->regs.si = ( ( unsigned ) __from_data16 ( syslinux_version ) ); - ix86->regs.di = ( ( unsigned ) __from_data16 ( syslinux_copyright ) ); - - ix86->flags &= ~CF; - break; - - case 0x0002: /* Write String */ - print_user_string ( ix86->segs.es, ix86->regs.bx, '\0' ); - ix86->flags &= ~CF; - break; - - case 0x0003: /* Run command */ - { - userptr_t cmd_u = real_to_user ( ix86->segs.es, ix86->regs.bx ); - int len = strlen_user ( cmd_u, 0 ); - char cmd[len + 1]; - copy_from_user ( cmd, cmd_u, 0, len + 1 ); - DBG ( "COMBOOT: executing command '%s'\n", cmd ); - system ( cmd ); - DBG ( "COMBOOT: exiting after executing command...\n" ); - rmlongjmp ( comboot_return, COMBOOT_EXIT_COMMAND ); - } - break; - - case 0x0004: /* Run default command */ - /* FIXME: just exit for now */ - rmlongjmp ( comboot_return, COMBOOT_EXIT_COMMAND ); - break; - - case 0x0005: /* Force text mode */ - comboot_force_text_mode ( ); - ix86->flags &= ~CF; - break; - - case 0x0006: /* Open file */ - { - int fd; - userptr_t file_u = real_to_user ( ix86->segs.es, ix86->regs.si ); - int len = strlen_user ( file_u, 0 ); - char file[len + 1]; - - copy_from_user ( file, file_u, 0, len + 1 ); - - if ( file[0] == '\0' ) { - DBG ( "COMBOOT: attempted open with empty file name\n" ); - break; - } - - DBG ( "COMBOOT: opening file '%s'\n", file ); - - fd = open ( file ); - - if ( fd < 0 ) { - DBG ( "COMBOOT: error opening file %s\n", file ); - break; - } - - /* This relies on the fact that a iPXE POSIX fd will - * always fit in 16 bits. - */ -#if (POSIX_FD_MAX > 65535) -#error POSIX_FD_MAX too large -#endif - ix86->regs.si = (uint16_t) fd; - - ix86->regs.cx = COMBOOT_FILE_BLOCKSZ; - ix86->regs.eax = fsize ( fd ); - ix86->flags &= ~CF; - } - break; - - case 0x0007: /* Read file */ - { - int fd = ix86->regs.si; - int len = ix86->regs.cx * COMBOOT_FILE_BLOCKSZ; - int rc; - fd_set fds; - userptr_t buf = real_to_user ( ix86->segs.es, ix86->regs.bx ); - - /* Wait for data ready to read */ - FD_ZERO ( &fds ); - FD_SET ( fd, &fds ); - - select ( &fds, 1 ); - - rc = read_user ( fd, buf, 0, len ); - if ( rc < 0 ) { - DBG ( "COMBOOT: read failed\n" ); - ix86->regs.si = 0; - break; - } - - ix86->regs.ecx = rc; - ix86->flags &= ~CF; - } - break; - - case 0x0008: /* Close file */ - { - int fd = ix86->regs.si; - close ( fd ); - ix86->flags &= ~CF; - } - break; - - case 0x0009: /* Call PXE Stack */ - if ( pxe_api_call_weak ( ix86 ) != 0 ) - ix86->flags |= CF; - else - ix86->flags &= ~CF; - break; - - case 0x000A: /* Get Derivative-Specific Information */ - - /* iPXE has its own derivative ID, so there is no defined - * output here; just return AL for now */ - ix86->regs.al = BZI_LOADER_TYPE_IPXE; - ix86->flags &= ~CF; - break; - - case 0x000B: /* Get Serial Console Configuration */ - if ( serial_console.base ) { - ix86->regs.dx = ( ( intptr_t ) serial_console.base ); - ix86->regs.cx = serial_console.divisor; - ix86->regs.bx = 0; - ix86->flags &= ~CF; - } - break; - - case 0x000C: /* Perform final cleanup */ - shutdown_boot(); - break; - - case 0x000E: /* Get configuration file name */ - /* FIXME: stub */ - ix86->segs.es = rm_ds; - ix86->regs.bx = ( ( unsigned ) __from_data16 ( syslinux_configuration_file ) ); - ix86->flags &= ~CF; - break; - - case 0x000F: /* Get IPAPPEND strings */ - /* FIXME: stub */ - ix86->regs.cx = 0; - ix86->segs.es = 0; - ix86->regs.bx = 0; - ix86->flags &= ~CF; - break; - - case 0x0010: /* Resolve hostname */ - { - userptr_t hostname_u = real_to_user ( ix86->segs.es, ix86->regs.bx ); - int len = strlen_user ( hostname_u, 0 ); - char hostname[len]; - struct in_addr addr; - - copy_from_user ( hostname, hostname_u, 0, len + 1 ); - - /* TODO: - * "If the hostname does not contain a dot (.), the - * local domain name is automatically appended." - */ - - comboot_resolv ( hostname, &addr ); - - ix86->regs.eax = addr.s_addr; - ix86->flags &= ~CF; - } - break; - - case 0x0011: /* Maximum number of shuffle descriptors */ - ix86->regs.cx = COMBOOT_MAX_SHUFFLE_DESCRIPTORS; - ix86->flags &= ~CF; - break; - - case 0x0012: /* Cleanup, shuffle and boot */ - if ( ix86->regs.cx > COMBOOT_MAX_SHUFFLE_DESCRIPTORS ) - break; - - /* Perform final cleanup */ - shutdown_boot(); - - /* Perform sequence of copies */ - shuffle ( ix86->segs.es, ix86->regs.di, ix86->regs.cx ); - - /* Jump to real-mode entry point */ - __asm__ __volatile__ ( - REAL_CODE ( - "pushw %0\n\t" - "popw %%ds\n\t" - "pushl %1\n\t" - "lret\n\t" - ) - : - : "r" ( ix86->segs.ds ), - "r" ( ix86->regs.ebp ), - "d" ( ix86->regs.ebx ), - "S" ( ix86->regs.esi ) ); - - assert ( 0 ); /* Execution should never reach this point */ - - break; - - case 0x0013: /* Idle loop call */ - step ( ); - ix86->flags &= ~CF; - break; - - case 0x0015: /* Get feature flags */ - ix86->segs.es = rm_ds; - ix86->regs.bx = ( ( unsigned ) __from_data16 ( &comboot_feature_flags ) ); - ix86->regs.cx = 1; /* Number of feature flag bytes */ - ix86->flags &= ~CF; - break; - - case 0x0016: /* Run kernel image */ - { - userptr_t file_u = real_to_user ( ix86->segs.ds, ix86->regs.si ); - userptr_t cmd_u = real_to_user ( ix86->segs.es, ix86->regs.bx ); - int file_len = strlen_user ( file_u, 0 ); - int cmd_len = strlen_user ( cmd_u, 0 ); - char file[file_len + 1]; - char cmd[cmd_len + 1]; - - copy_from_user ( file, file_u, 0, file_len + 1 ); - copy_from_user ( cmd, cmd_u, 0, cmd_len + 1 ); - - DBG ( "COMBOOT: run kernel %s %s\n", file, cmd ); - comboot_fetch_kernel ( file, cmd ); - /* Technically, we should return if we - * couldn't load the kernel, but it's not safe - * to do that since we have just overwritten - * part of the COMBOOT program's memory space. - */ - DBG ( "COMBOOT: exiting to run kernel...\n" ); - rmlongjmp ( comboot_return, COMBOOT_EXIT_RUN_KERNEL ); - } - break; - - case 0x0017: /* Report video mode change */ - comboot_graphics_mode = ix86->regs.bx; - ix86->flags &= ~CF; - break; - - case 0x0018: /* Query custom font */ - /* FIXME: stub */ - ix86->regs.al = 0; - ix86->segs.es = 0; - ix86->regs.bx = 0; - ix86->flags &= ~CF; - break; - - case 0x001B: /* Cleanup, shuffle and boot to real mode */ - if ( ix86->regs.cx > COMBOOT_MAX_SHUFFLE_DESCRIPTORS ) - break; - - /* Perform final cleanup */ - shutdown_boot(); - - /* Perform sequence of copies */ - shuffle ( ix86->segs.es, ix86->regs.di, ix86->regs.cx ); - - /* Copy initial register values to .text16 */ - memcpy_user ( real_to_user ( rm_cs, (unsigned) __from_text16 ( &comboot_initial_regs ) ), 0, - real_to_user ( ix86->segs.ds, ix86->regs.si ), 0, - sizeof(syslinux_rm_regs) ); - - /* Load initial register values */ - __asm__ __volatile__ ( - REAL_CODE ( - /* Point SS:SP at the register value structure */ - "pushw %%cs\n\t" - "popw %%ss\n\t" - "movw $comboot_initial_regs, %%sp\n\t" - - /* Segment registers */ - "popw %%es\n\t" - "popw %%ax\n\t" /* Skip CS */ - "popw %%ds\n\t" - "popw %%ax\n\t" /* Skip SS for now */ - "popw %%fs\n\t" - "popw %%gs\n\t" - - /* GP registers */ - "popl %%eax\n\t" - "popl %%ecx\n\t" - "popl %%edx\n\t" - "popl %%ebx\n\t" - "popl %%ebp\n\t" /* Skip ESP for now */ - "popl %%ebp\n\t" - "popl %%esi\n\t" - "popl %%edi\n\t" - - /* Load correct SS:ESP */ - "movw $(comboot_initial_regs + 6), %%sp\n\t" - "popw %%ss\n\t" - "movl %%cs:(comboot_initial_regs + 28), %%esp\n\t" - - "ljmp *%%cs:(comboot_initial_regs + 44)\n\t" - ) - : : ); - - break; - - case 0x001C: /* Get pointer to auxilliary data vector */ - /* FIXME: stub */ - ix86->regs.cx = 0; /* Size of the ADV */ - ix86->flags &= ~CF; - break; - - case 0x001D: /* Write auxilliary data vector */ - /* FIXME: stub */ - ix86->flags &= ~CF; - break; - - default: - DBG ( "COMBOOT unknown int22 function %04x\n", ix86->regs.ax ); - break; - } -} - -/** - * Hook BIOS interrupts related to COMBOOT API (INT 20h, 21h, 22h) - */ -void hook_comboot_interrupts ( ) { - - __asm__ __volatile__ ( - TEXT16_CODE ( "\nint20_wrapper:\n\t" - "pushl %0\n\t" - "pushw %%cs\n\t" - "call prot_call\n\t" - "addw $4, %%sp\n\t" - "call patch_cf\n\t" - "iret\n\t" ) - : : "i" ( int20 ) ); - - hook_bios_interrupt ( 0x20, ( unsigned int ) int20_wrapper, - &int20_vector ); - - __asm__ __volatile__ ( - TEXT16_CODE ( "\nint21_wrapper:\n\t" - "pushl %0\n\t" - "pushw %%cs\n\t" - "call prot_call\n\t" - "addw $4, %%sp\n\t" - "call patch_cf\n\t" - "iret\n\t" ) - : : "i" ( int21 ) ); - - hook_bios_interrupt ( 0x21, ( unsigned int ) int21_wrapper, - &int21_vector ); - - __asm__ __volatile__ ( - TEXT16_CODE ( "\nint22_wrapper:\n\t" - "pushl %0\n\t" - "pushw %%cs\n\t" - "call prot_call\n\t" - "addw $4, %%sp\n\t" - "call patch_cf\n\t" - "iret\n\t" ) - : : "i" ( int22) ); - - hook_bios_interrupt ( 0x22, ( unsigned int ) int22_wrapper, - &int22_vector ); -} - -/** - * Unhook BIOS interrupts related to COMBOOT API (INT 20h, 21h, 22h) - */ -void unhook_comboot_interrupts ( ) { - - unhook_bios_interrupt ( 0x20, ( unsigned int ) int20_wrapper, - &int20_vector ); - - unhook_bios_interrupt ( 0x21, ( unsigned int ) int21_wrapper, - &int21_vector ); - - unhook_bios_interrupt ( 0x22, ( unsigned int ) int22_wrapper, - &int22_vector ); -} - -/* Avoid dragging in serial console support unconditionally */ -struct uart serial_console __attribute__ (( weak )); diff --git a/qemu/roms/ipxe/src/arch/i386/interface/syslinux/comboot_resolv.c b/qemu/roms/ipxe/src/arch/i386/interface/syslinux/comboot_resolv.c deleted file mode 100644 index 03bbfd04a..000000000 --- a/qemu/roms/ipxe/src/arch/i386/interface/syslinux/comboot_resolv.c +++ /dev/null @@ -1,61 +0,0 @@ -#include <errno.h> -#include <comboot.h> -#include <ipxe/in.h> -#include <ipxe/list.h> -#include <ipxe/process.h> -#include <ipxe/resolv.h> - -FILE_LICENCE ( GPL2_OR_LATER ); - -struct comboot_resolver { - struct interface intf; - int rc; - struct in_addr addr; -}; - -static void comboot_resolv_close ( struct comboot_resolver *comboot_resolver, - int rc ) { - comboot_resolver->rc = rc; - intf_shutdown ( &comboot_resolver->intf, rc ); -} - -static void comboot_resolv_done ( struct comboot_resolver *comboot_resolver, - struct sockaddr *sa ) { - struct sockaddr_in *sin; - - if ( sa->sa_family == AF_INET ) { - sin = ( ( struct sockaddr_in * ) sa ); - comboot_resolver->addr = sin->sin_addr; - } -} - -static struct interface_operation comboot_resolv_op[] = { - INTF_OP ( intf_close, struct comboot_resolver *, comboot_resolv_close ), - INTF_OP ( resolv_done, struct comboot_resolver *, comboot_resolv_done ), -}; - -static struct interface_descriptor comboot_resolv_desc = - INTF_DESC ( struct comboot_resolver, intf, comboot_resolv_op ); - -static struct comboot_resolver comboot_resolver = { - .intf = INTF_INIT ( comboot_resolv_desc ), -}; - -int comboot_resolv ( const char *name, struct in_addr *address ) { - int rc; - - comboot_resolver.rc = -EINPROGRESS; - comboot_resolver.addr.s_addr = 0; - - if ( ( rc = resolv ( &comboot_resolver.intf, name, NULL ) ) != 0 ) - return rc; - - while ( comboot_resolver.rc == -EINPROGRESS ) - step(); - - if ( ! comboot_resolver.addr.s_addr ) - return -EAFNOSUPPORT; - - *address = comboot_resolver.addr; - return comboot_resolver.rc; -} diff --git a/qemu/roms/ipxe/src/arch/i386/interface/vmware/guestinfo.c b/qemu/roms/ipxe/src/arch/i386/interface/vmware/guestinfo.c deleted file mode 100644 index a0530c8d1..000000000 --- a/qemu/roms/ipxe/src/arch/i386/interface/vmware/guestinfo.c +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright (C) 2012 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. - */ - -FILE_LICENCE ( GPL2_OR_LATER ); - -/** @file - * - * VMware GuestInfo settings - * - */ - -#include <stdint.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <ipxe/init.h> -#include <ipxe/settings.h> -#include <ipxe/netdevice.h> -#include <ipxe/guestrpc.h> - -/** GuestInfo GuestRPC channel */ -static int guestinfo_channel; - -/** - * Fetch value of typed GuestInfo setting - * - * @v settings Settings block - * @v setting Setting to fetch - * @v type Setting type to attempt (or NULL for default) - * @v data Buffer to fill with setting data - * @v len Length of buffer - * @ret found Setting found in GuestInfo - * @ret len Length of setting data, or negative error - */ -static int guestinfo_fetch_type ( struct settings *settings, - struct setting *setting, - const struct setting_type *type, - void *data, size_t len, int *found ) { - const char *parent_name = settings->parent->name; - char command[ 24 /* "info-get guestinfo.ipxe." */ + - strlen ( parent_name ) + 1 /* "." */ + - strlen ( setting->name ) + 1 /* "." */ + - ( type ? strlen ( type->name ) : 0 ) + 1 /* NUL */ ]; - struct setting *predefined; - char *info; - int info_len; - int check_len; - int ret; - - /* Construct info-get command */ - snprintf ( command, sizeof ( command ), - "info-get guestinfo.ipxe.%s%s%s%s%s", - parent_name, ( parent_name[0] ? "." : "" ), setting->name, - ( type ? "." : "" ), ( type ? type->name : "" ) ); - - /* Check for existence and obtain length of GuestInfo value */ - info_len = guestrpc_command ( guestinfo_channel, command, NULL, 0 ); - if ( info_len < 0 ) { - ret = info_len; - goto err_get_info_len; - } - - /* Mark as found */ - *found = 1; - - /* Determine default type if necessary */ - if ( ! type ) { - predefined = find_setting ( setting->name ); - type = ( predefined ? predefined->type : &setting_type_string ); - } - assert ( type != NULL ); - - /* Allocate temporary block to hold GuestInfo value */ - info = zalloc ( info_len + 1 /* NUL */ ); - if ( ! info ) { - DBGC ( settings, "GuestInfo %p could not allocate %d bytes\n", - settings, info_len ); - ret = -ENOMEM; - goto err_alloc; - } - info[info_len] = '\0'; - - /* Fetch GuestInfo value */ - check_len = guestrpc_command ( guestinfo_channel, command, - info, info_len ); - if ( check_len < 0 ) { - ret = check_len; - goto err_get_info; - } - if ( check_len != info_len ) { - DBGC ( settings, "GuestInfo %p length mismatch (expected %d, " - "got %d)\n", settings, info_len, check_len ); - ret = -EIO; - goto err_get_info; - } - DBGC2 ( settings, "GuestInfo %p found %s = \"%s\"\n", - settings, &command[9] /* Skip "info-get " */, info ); - - /* Parse GuestInfo value according to type */ - ret = setting_parse ( type, info, data, len ); - if ( ret < 0 ) { - DBGC ( settings, "GuestInfo %p could not parse \"%s\" as %s: " - "%s\n", settings, info, type->name, strerror ( ret ) ); - goto err_parse; - } - - err_parse: - err_get_info: - free ( info ); - err_alloc: - err_get_info_len: - return ret; -} - -/** - * Fetch value of GuestInfo setting - * - * @v settings Settings block - * @v setting Setting to fetch - * @v data Buffer to fill with setting data - * @v len Length of buffer - * @ret len Length of setting data, or negative error - */ -static int guestinfo_fetch ( struct settings *settings, - struct setting *setting, - void *data, size_t len ) { - struct setting_type *type; - int found = 0; - int ret; - - /* Try default type first */ - ret = guestinfo_fetch_type ( settings, setting, NULL, - data, len, &found ); - if ( found ) - return ret; - - /* Otherwise, try all possible types */ - for_each_table_entry ( type, SETTING_TYPES ) { - ret = guestinfo_fetch_type ( settings, setting, type, - data, len, &found ); - if ( found ) - return ret; - } - - /* Not found */ - return -ENOENT; -} - -/** GuestInfo settings operations */ -static struct settings_operations guestinfo_settings_operations = { - .fetch = guestinfo_fetch, -}; - -/** GuestInfo settings */ -static struct settings guestinfo_settings = { - .refcnt = NULL, - .siblings = LIST_HEAD_INIT ( guestinfo_settings.siblings ), - .children = LIST_HEAD_INIT ( guestinfo_settings.children ), - .op = &guestinfo_settings_operations, -}; - -/** Initialise GuestInfo settings */ -static void guestinfo_init ( void ) { - int rc; - - /* Open GuestRPC channel */ - guestinfo_channel = guestrpc_open(); - if ( guestinfo_channel < 0 ) { - rc = guestinfo_channel; - DBG ( "GuestInfo could not open channel: %s\n", - strerror ( rc ) ); - return; - } - - /* Register root GuestInfo settings */ - if ( ( rc = register_settings ( &guestinfo_settings, NULL, - "vmware" ) ) != 0 ) { - DBG ( "GuestInfo could not register settings: %s\n", - strerror ( rc ) ); - return; - } -} - -/** GuestInfo settings initialiser */ -struct init_fn guestinfo_init_fn __init_fn ( INIT_NORMAL ) = { - .initialise = guestinfo_init, -}; - -/** - * Create per-netdevice GuestInfo settings - * - * @v netdev Network device - * @ret rc Return status code - */ -static int guestinfo_net_probe ( struct net_device *netdev ) { - struct settings *settings; - int rc; - - /* Do nothing unless we have a GuestInfo channel available */ - if ( guestinfo_channel < 0 ) - return 0; - - /* Allocate and initialise settings block */ - settings = zalloc ( sizeof ( *settings ) ); - if ( ! settings ) { - rc = -ENOMEM; - goto err_alloc; - } - settings_init ( settings, &guestinfo_settings_operations, NULL, NULL ); - - /* Register settings */ - if ( ( rc = register_settings ( settings, netdev_settings ( netdev ), - "vmware" ) ) != 0 ) { - DBGC ( settings, "GuestInfo %p could not register for %s: %s\n", - settings, netdev->name, strerror ( rc ) ); - goto err_register; - } - DBGC ( settings, "GuestInfo %p registered for %s\n", - settings, netdev->name ); - - return 0; - - err_register: - free ( settings ); - err_alloc: - return rc; -} - -/** - * Remove per-netdevice GuestInfo settings - * - * @v netdev Network device - */ -static void guestinfo_net_remove ( struct net_device *netdev ) { - struct settings *parent = netdev_settings ( netdev ); - struct settings *settings; - - list_for_each_entry ( settings, &parent->children, siblings ) { - if ( settings->op == &guestinfo_settings_operations ) { - DBGC ( settings, "GuestInfo %p unregistered for %s\n", - settings, netdev->name ); - unregister_settings ( settings ); - free ( settings ); - return; - } - } -} - -/** GuestInfo per-netdevice driver */ -struct net_driver guestinfo_net_driver __net_driver = { - .name = "GuestInfo", - .probe = guestinfo_net_probe, - .remove = guestinfo_net_remove, -}; diff --git a/qemu/roms/ipxe/src/arch/i386/interface/vmware/guestrpc.c b/qemu/roms/ipxe/src/arch/i386/interface/vmware/guestrpc.c deleted file mode 100644 index ef7ee8151..000000000 --- a/qemu/roms/ipxe/src/arch/i386/interface/vmware/guestrpc.c +++ /dev/null @@ -1,332 +0,0 @@ -/* - * Copyright (C) 2012 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 ); - -/** @file - * - * VMware GuestRPC mechanism - * - */ - -#include <stdint.h> -#include <string.h> -#include <errno.h> -#include <assert.h> -#include <ipxe/vmware.h> -#include <ipxe/guestrpc.h> - -/* Disambiguate the various error causes */ -#define EPROTO_OPEN __einfo_error ( EINFO_EPROTO_OPEN ) -#define EINFO_EPROTO_OPEN \ - __einfo_uniqify ( EINFO_EPROTO, 0x00, "GuestRPC open failed" ) -#define EPROTO_COMMAND_LEN __einfo_error ( EINFO_EPROTO_COMMAND_LEN ) -#define EINFO_EPROTO_COMMAND_LEN \ - __einfo_uniqify ( EINFO_EPROTO, 0x01, "GuestRPC command length failed" ) -#define EPROTO_COMMAND_DATA __einfo_error ( EINFO_EPROTO_COMMAND_DATA ) -#define EINFO_EPROTO_COMMAND_DATA \ - __einfo_uniqify ( EINFO_EPROTO, 0x02, "GuestRPC command data failed" ) -#define EPROTO_REPLY_LEN __einfo_error ( EINFO_EPROTO_REPLY_LEN ) -#define EINFO_EPROTO_REPLY_LEN \ - __einfo_uniqify ( EINFO_EPROTO, 0x03, "GuestRPC reply length failed" ) -#define EPROTO_REPLY_DATA __einfo_error ( EINFO_EPROTO_REPLY_DATA ) -#define EINFO_EPROTO_REPLY_DATA \ - __einfo_uniqify ( EINFO_EPROTO, 0x04, "GuestRPC reply data failed" ) -#define EPROTO_REPLY_FINISH __einfo_error ( EINFO_EPROTO_REPLY_FINISH ) -#define EINFO_EPROTO_REPLY_FINISH \ - __einfo_uniqify ( EINFO_EPROTO, 0x05, "GuestRPC reply finish failed" ) -#define EPROTO_CLOSE __einfo_error ( EINFO_EPROTO_CLOSE ) -#define EINFO_EPROTO_CLOSE \ - __einfo_uniqify ( EINFO_EPROTO, 0x06, "GuestRPC close failed" ) - -/** - * Open GuestRPC channel - * - * @ret channel Channel number, or negative error - */ -int guestrpc_open ( void ) { - uint16_t channel; - uint32_t discard_b; - uint32_t status; - - /* Issue GuestRPC command */ - status = vmware_cmd_guestrpc ( 0, GUESTRPC_OPEN, GUESTRPC_MAGIC, - &channel, &discard_b ); - if ( status != GUESTRPC_OPEN_SUCCESS ) { - DBGC ( GUESTRPC_MAGIC, "GuestRPC open failed: status %08x\n", - status ); - return -EPROTO_OPEN; - } - - DBGC ( GUESTRPC_MAGIC, "GuestRPC channel %d opened\n", channel ); - return channel; -} - -/** - * Send GuestRPC command length - * - * @v channel Channel number - * @v len Command length - * @ret rc Return status code - */ -static int guestrpc_command_len ( int channel, size_t len ) { - uint16_t discard_d; - uint32_t discard_b; - uint32_t status; - - /* Issue GuestRPC command */ - status = vmware_cmd_guestrpc ( channel, GUESTRPC_COMMAND_LEN, len, - &discard_d, &discard_b ); - if ( status != GUESTRPC_COMMAND_LEN_SUCCESS ) { - DBGC ( GUESTRPC_MAGIC, "GuestRPC channel %d send command " - "length %zd failed: status %08x\n", - channel, len, status ); - return -EPROTO_COMMAND_LEN; - } - - return 0; -} - -/** - * Send GuestRPC command data - * - * @v channel Channel number - * @v data Command data - * @ret rc Return status code - */ -static int guestrpc_command_data ( int channel, uint32_t data ) { - uint16_t discard_d; - uint32_t discard_b; - uint32_t status; - - /* Issue GuestRPC command */ - status = vmware_cmd_guestrpc ( channel, GUESTRPC_COMMAND_DATA, data, - &discard_d, &discard_b ); - if ( status != GUESTRPC_COMMAND_DATA_SUCCESS ) { - DBGC ( GUESTRPC_MAGIC, "GuestRPC channel %d send command " - "data %08x failed: status %08x\n", - channel, data, status ); - return -EPROTO_COMMAND_DATA; - } - - return 0; -} - -/** - * Receive GuestRPC reply length - * - * @v channel Channel number - * @ret reply_id Reply ID - * @ret len Reply length, or negative error - */ -static int guestrpc_reply_len ( int channel, uint16_t *reply_id ) { - uint32_t len; - uint32_t status; - - /* Issue GuestRPC command */ - status = vmware_cmd_guestrpc ( channel, GUESTRPC_REPLY_LEN, 0, - reply_id, &len ); - if ( status != GUESTRPC_REPLY_LEN_SUCCESS ) { - DBGC ( GUESTRPC_MAGIC, "GuestRPC channel %d receive reply " - "length failed: status %08x\n", channel, status ); - return -EPROTO_REPLY_LEN; - } - - return len; -} - -/** - * Receive GuestRPC reply data - * - * @v channel Channel number - * @v reply_id Reply ID - * @ret data Reply data - * @ret rc Return status code - */ -static int guestrpc_reply_data ( int channel, uint16_t reply_id, - uint32_t *data ) { - uint16_t discard_d; - uint32_t status; - - /* Issue GuestRPC command */ - status = vmware_cmd_guestrpc ( channel, GUESTRPC_REPLY_DATA, reply_id, - &discard_d, data ); - if ( status != GUESTRPC_REPLY_DATA_SUCCESS ) { - DBGC ( GUESTRPC_MAGIC, "GuestRPC channel %d receive reply " - "%d data failed: status %08x\n", - channel, reply_id, status ); - return -EPROTO_REPLY_DATA; - } - - return 0; -} - -/** - * Finish receiving GuestRPC reply - * - * @v channel Channel number - * @v reply_id Reply ID - * @ret rc Return status code - */ -static int guestrpc_reply_finish ( int channel, uint16_t reply_id ) { - uint16_t discard_d; - uint32_t discard_b; - uint32_t status; - - /* Issue GuestRPC command */ - status = vmware_cmd_guestrpc ( channel, GUESTRPC_REPLY_FINISH, reply_id, - &discard_d, &discard_b ); - if ( status != GUESTRPC_REPLY_FINISH_SUCCESS ) { - DBGC ( GUESTRPC_MAGIC, "GuestRPC channel %d finish reply %d " - "failed: status %08x\n", channel, reply_id, status ); - return -EPROTO_REPLY_FINISH; - } - - return 0; -} - -/** - * Close GuestRPC channel - * - * @v channel Channel number - */ -void guestrpc_close ( int channel ) { - uint16_t discard_d; - uint32_t discard_b; - uint32_t status; - - /* Issue GuestRPC command */ - status = vmware_cmd_guestrpc ( channel, GUESTRPC_CLOSE, 0, - &discard_d, &discard_b ); - if ( status != GUESTRPC_CLOSE_SUCCESS ) { - DBGC ( GUESTRPC_MAGIC, "GuestRPC channel %d close failed: " - "status %08x\n", channel, status ); - return; - } - - DBGC ( GUESTRPC_MAGIC, "GuestRPC channel %d closed\n", channel ); -} - -/** - * Issue GuestRPC command - * - * @v channel Channel number - * @v command Command - * @v reply Reply buffer - * @v reply_len Length of reply buffer - * @ret len Length of reply, or negative error - * - * The actual length of the reply will be returned even if the buffer - * was too small. - */ -int guestrpc_command ( int channel, const char *command, char *reply, - size_t reply_len ) { - const uint8_t *command_bytes = ( ( const void * ) command ); - uint8_t *reply_bytes = ( ( void * ) reply ); - size_t command_len = strlen ( command ); - int orig_reply_len = reply_len; - uint16_t status; - uint8_t *status_bytes = ( ( void * ) &status ); - size_t status_len = sizeof ( status ); - uint32_t data; - uint16_t reply_id; - int len; - int remaining; - unsigned int i; - int rc; - - DBGC2 ( GUESTRPC_MAGIC, "GuestRPC channel %d issuing command:\n", - channel ); - DBGC2_HDA ( GUESTRPC_MAGIC, 0, command, command_len ); - - /* Sanity check */ - assert ( ( reply != NULL ) || ( reply_len == 0 ) ); - - /* Send command length */ - if ( ( rc = guestrpc_command_len ( channel, command_len ) ) < 0 ) - return rc; - - /* Send command data */ - while ( command_len ) { - data = 0; - for ( i = sizeof ( data ) ; i ; i-- ) { - if ( command_len ) { - data = ( ( data & ~0xff ) | - *(command_bytes++) ); - command_len--; - } - data = ( ( data << 24 ) | ( data >> 8 ) ); - } - if ( ( rc = guestrpc_command_data ( channel, data ) ) < 0 ) - return rc; - } - - /* Receive reply length */ - if ( ( len = guestrpc_reply_len ( channel, &reply_id ) ) < 0 ) { - rc = len; - return rc; - } - - /* Receive reply */ - for ( remaining = len ; remaining > 0 ; remaining -= sizeof ( data ) ) { - if ( ( rc = guestrpc_reply_data ( channel, reply_id, - &data ) ) < 0 ) { - return rc; - } - for ( i = sizeof ( data ) ; i ; i-- ) { - if ( status_len ) { - *(status_bytes++) = ( data & 0xff ); - status_len--; - len--; - } else if ( reply_len ) { - *(reply_bytes++) = ( data & 0xff ); - reply_len--; - } - data = ( ( data << 24 ) | ( data >> 8 ) ); - } - } - - /* Finish receiving RPC reply */ - if ( ( rc = guestrpc_reply_finish ( channel, reply_id ) ) < 0 ) - return rc; - - DBGC2 ( GUESTRPC_MAGIC, "GuestRPC channel %d received reply (id %d, " - "length %d):\n", channel, reply_id, len ); - DBGC2_HDA ( GUESTRPC_MAGIC, 0, &status, sizeof ( status ) ); - DBGC2_HDA ( GUESTRPC_MAGIC, sizeof ( status ), reply, - ( ( len < orig_reply_len ) ? len : orig_reply_len ) ); - - /* Check reply status */ - if ( status != GUESTRPC_SUCCESS ) { - DBGC ( GUESTRPC_MAGIC, "GuestRPC channel %d command failed " - "(status %04x, reply id %d, reply length %d):\n", - channel, status, reply_id, len ); - DBGC_HDA ( GUESTRPC_MAGIC, 0, command, command_len ); - DBGC_HDA ( GUESTRPC_MAGIC, 0, &status, sizeof ( status ) ); - DBGC_HDA ( GUESTRPC_MAGIC, sizeof ( status ), reply, - ( ( len < orig_reply_len ) ? len : orig_reply_len )); - return -EIO; - } - - return len; -} diff --git a/qemu/roms/ipxe/src/arch/i386/interface/vmware/vmconsole.c b/qemu/roms/ipxe/src/arch/i386/interface/vmware/vmconsole.c deleted file mode 100644 index f7df4f75b..000000000 --- a/qemu/roms/ipxe/src/arch/i386/interface/vmware/vmconsole.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (C) 2012 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 ); - -/** @file - * - * VMware logfile console - * - */ - -#include <string.h> -#include <ipxe/console.h> -#include <ipxe/lineconsole.h> -#include <ipxe/init.h> -#include <ipxe/guestrpc.h> -#include <config/console.h> - -/** VMware logfile console buffer size */ -#define VMCONSOLE_BUFSIZE 128 - -/* Set default console usage if applicable */ -#if ! ( defined ( CONSOLE_VMWARE ) && CONSOLE_EXPLICIT ( CONSOLE_VMWARE ) ) -#undef CONSOLE_VMWARE -#define CONSOLE_VMWARE ( CONSOLE_USAGE_ALL & ~CONSOLE_USAGE_TUI ) -#endif - -/** VMware logfile console GuestRPC channel */ -static int vmconsole_channel; - -/** VMware logfile console line buffer */ -static struct { - char prefix[4]; - char message[VMCONSOLE_BUFSIZE]; -} vmconsole_buffer = { - .prefix = "log ", -}; - -/** VMware logfile console ANSI escape sequence handlers */ -static struct ansiesc_handler vmconsole_handlers[] = { - { 0, NULL } -}; - -/** VMware logfile line console */ -static struct line_console vmconsole_line = { - .buffer = vmconsole_buffer.message, - .len = sizeof ( vmconsole_buffer.message ), - .ctx = { - .handlers = vmconsole_handlers, - }, -}; - -/** VMware logfile console recursion marker */ -static int vmconsole_entered; - -/** - * Print a character to VMware logfile console - * - * @v character Character to be printed - */ -static void vmconsole_putchar ( int character ) { - int rc; - - /* Ignore if we are already mid-logging */ - if ( vmconsole_entered ) - return; - - /* Fill line buffer */ - if ( line_putchar ( &vmconsole_line, character ) == 0 ) - return; - - /* Guard against re-entry */ - vmconsole_entered = 1; - - /* Send log message */ - if ( ( rc = guestrpc_command ( vmconsole_channel, - vmconsole_buffer.prefix, NULL, 0 ) ) <0){ - DBG ( "VMware console could not send log message: %s\n", - strerror ( rc ) ); - } - - /* Clear re-entry flag */ - vmconsole_entered = 0; -} - -/** VMware logfile console driver */ -struct console_driver vmconsole __console_driver = { - .putchar = vmconsole_putchar, - .disabled = CONSOLE_DISABLED, - .usage = CONSOLE_VMWARE, -}; - -/** - * Initialise VMware logfile console - * - */ -static void vmconsole_init ( void ) { - int rc; - - /* Attempt to open console */ - vmconsole_channel = guestrpc_open(); - if ( vmconsole_channel < 0 ) { - rc = vmconsole_channel; - DBG ( "VMware console could not be initialised: %s\n", - strerror ( rc ) ); - return; - } - - /* Mark console as available */ - vmconsole.disabled = 0; -} - -/** - * VMware logfile console initialisation function - */ -struct init_fn vmconsole_init_fn __init_fn ( INIT_CONSOLE ) = { - .initialise = vmconsole_init, -}; diff --git a/qemu/roms/ipxe/src/arch/i386/interface/vmware/vmware.c b/qemu/roms/ipxe/src/arch/i386/interface/vmware/vmware.c deleted file mode 100644 index a415465fb..000000000 --- a/qemu/roms/ipxe/src/arch/i386/interface/vmware/vmware.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2012 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 ); - -/** @file - * - * VMware backdoor mechanism - * - * Based on the unofficial documentation at - * - * http://sites.google.com/site/chitchatvmback/backdoor - * - */ - -#include <stdint.h> -#include <errno.h> -#include <ipxe/vmware.h> - -/** - * Detect VMware presence - * - * @ret rc Return status code - */ -int vmware_present ( void ) { - uint32_t version; - uint32_t magic; - uint32_t product_type; - - /* Perform backdoor call */ - vmware_cmd_get_version ( &version, &magic, &product_type ); - - /* Check for VMware presence */ - if ( magic != VMW_MAGIC ) { - DBGC ( VMW_MAGIC, "VMware not present\n" ); - return -ENOENT; - } - - DBGC ( VMW_MAGIC, "VMware product type %04x version %08x detected\n", - product_type, version ); - return 0; -} diff --git a/qemu/roms/ipxe/src/arch/i386/kir-Makefile b/qemu/roms/ipxe/src/arch/i386/kir-Makefile deleted file mode 100644 index bbfc1a3a6..000000000 --- a/qemu/roms/ipxe/src/arch/i386/kir-Makefile +++ /dev/null @@ -1,26 +0,0 @@ -# Makefile to build a KEEP_IT_REAL flavour -# -# KEEP_IT_REAL, by its nature, requires a different build of every -# single object file, since the inclusion of ".code16gcc" will -# generate different machine code from the assembly. Unlike the other -# config options, there is no way that this global dependency can ever -# be reduced, so it makes sense to be able to build both the normal -# and the KIR versions without having to force a full rebuild each -# time. - -# Add this Makefile to MAKEDEPS -# -MAKEDEPS += arch/i386/kir-Makefile - -# Place binaries in bin-kir -# -BIN = bin-kir - -# Compile with -DKEEP_IT_REAL, forcibly include kir.h at the start of -# each file to drag in ".code16gcc" -# -CFLAGS += -DKEEP_IT_REAL -include kir.h - -include Makefile - -LDSCRIPT = arch/i386/scripts/i386-kir.lds diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/bootpart.S b/qemu/roms/ipxe/src/arch/i386/prefix/bootpart.S deleted file mode 100644 index 6d0c6034a..000000000 --- a/qemu/roms/ipxe/src/arch/i386/prefix/bootpart.S +++ /dev/null @@ -1,218 +0,0 @@ -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) - -#define BOOT_SEG 0x07c0 -#define EXEC_SEG 0x0100 -#define STACK_SEG 0x0200 -#define STACK_SIZE 0x2000 - - .text - .arch i386 - .section ".prefix", "awx", @progbits - .code16 - -/* - * Find active partition - * - * Parameters: - * %dl : BIOS drive number - * %bp : Active partition handler routine - */ -find_active_partition: - /* Set up stack at STACK_SEG:STACK_SIZE */ - movw $STACK_SEG, %ax - movw %ax, %ss - movw $STACK_SIZE, %sp - - /* Relocate self to EXEC_SEG */ - pushw $BOOT_SEG - popw %ds - pushw $EXEC_SEG - popw %es - xorw %si, %si - xorw %di, %di - movw $0x200, %cx - rep movsb - ljmp $EXEC_SEG, $1f -1: pushw %ds - popw %es - pushw %cs - popw %ds - - /* Check for LBA extensions */ - movb $0x41, %ah - movw $0x55aa, %bx - stc - int $0x13 - jc 1f - cmpw $0xaa55, %bx - jne 1f - movw $read_lba, read_sectors -1: - /* Read and process root partition table */ - xorb %dh, %dh - movw $0x0001, %cx - xorl %esi, %esi - xorl %edi, %edi - call process_table - - /* Print failure message */ - movw $10f, %si - jmp boot_error -10: .asciz "Could not locate active partition\r\n" - -/* - * Print failure message and boot next device - * - * Parameters: - * %si : Failure string - */ -boot_error: - cld - movw $0x0007, %bx - movb $0x0e, %ah -1: lodsb - testb %al, %al - je 99f - int $0x10 - jmp 1b -99: /* Boot next device */ - int $0x18 - -/* - * Process partition table - * - * Parameters: - * %dl : BIOS drive number - * %dh : Head - * %cl : Sector (bits 0-5), high two bits of cylinder (bits 6-7) - * %ch : Low eight bits of cylinder - * %esi:%edi : LBA address - * %bp : Active partition handler routine - * - * Returns: - * CF set on error - */ -process_table: - pushal - call read_boot_sector - jc 99f - movw $446, %bx -1: call process_partition - addw $16, %bx - cmpw $510, %bx - jne 1b -99: popal - ret - -/* - * Process partition - * - * Parameters: - * %dl : BIOS drive number - * %dh : Head - * %cl : Sector (bits 0-5), high two bits of cylinder (bits 6-7) - * %ch : Low eight bits of cylinder - * %esi:%edi : LBA address - * %bx : Offset within partition table - * %bp : Active partition handler routine - */ -process_partition: - pushal - /* Load C/H/S values from partition entry */ - movb %es:1(%bx), %dh - movw %es:2(%bx), %cx - /* Update LBA address from partition entry */ - addl %es:8(%bx), %edi - adcl $0, %esi - /* Check active flag */ - testb $0x80, %es:(%bx) - jz 1f - call read_boot_sector - jc 99f - jmp *%bp -1: /* Check for extended partition */ - movb %es:4(%bx), %al - cmpb $0x05, %al - je 2f - cmpb $0x0f, %al - je 2f - cmpb $0x85, %al - jne 99f -2: call process_table -99: popal - /* Reload original partition table */ - call read_boot_sector - ret - -/* - * Read single sector to %es:0000 and verify 0x55aa signature - * - * Parameters: - * %dl : BIOS drive number - * %dh : Head - * %cl : Sector (bits 0-5), high two bits of cylinder (bits 6-7) - * %ch : Low eight bits of cylinder - * %esi:%edi : LBA address - * - * Returns: - * CF set on error - */ -read_boot_sector: - pushw %ax - movw $1, %ax - call *read_sectors - jc 99f - cmpw $0xaa55, %es:(510) - je 99f - stc -99: popw %ax - ret - -/* - * Read sectors to %es:0000 - * - * Parameters: - * %dl : BIOS drive number - * %dh : Head - * %cl : Sector (bits 0-5), high two bits of cylinder (bits 6-7) - * %ch : Low eight bits of cylinder - * %esi:%edi : LBA address - * %ax : Number of sectors (max 127) - * - * Returns: - * CF set on error - */ -read_sectors: .word read_chs - -read_chs: - /* Read sectors using C/H/S address */ - pushal - xorw %bx, %bx - movb $0x02, %ah - stc - int $0x13 - sti - popal - ret - -read_lba: - /* Read sectors using LBA address */ - pushal - movw %ax, (lba_desc + 2) - pushw %es - popw (lba_desc + 6) - movl %edi, (lba_desc + 8) - movl %esi, (lba_desc + 12) - movw $lba_desc, %si - movb $0x42, %ah - int $0x13 - popal - ret - -lba_desc: - .byte 0x10 - .byte 0 - .word 1 - .word 0x0000 - .word 0x0000 - .long 0, 0 diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/dskprefix.S b/qemu/roms/ipxe/src/arch/i386/prefix/dskprefix.S deleted file mode 100644 index 7aa017ccd..000000000 --- a/qemu/roms/ipxe/src/arch/i386/prefix/dskprefix.S +++ /dev/null @@ -1,383 +0,0 @@ -/* NOTE: this boot sector contains instructions that need at least an 80186. - * Yes, as86 has a bug somewhere in the valid instruction set checks. - * - */ - -/* floppyload.S Copyright (C) 1991, 1992 Linus Torvalds - * modified by Drew Eckhardt - * modified by Bruce Evans (bde) - * - * floppyprefix.S is loaded at 0x0000:0x7c00 by the bios-startup routines. - * - * It then loads the system at SYSSEG<<4, using BIOS interrupts. - * - * The loader has been made as simple as possible, and continuous read errors - * will result in a unbreakable loop. Reboot by hand. It loads pretty fast by - * getting whole tracks at a time whenever possible. - */ - -FILE_LICENCE ( GPL2_ONLY ) - -.equ BOOTSEG, 0x07C0 /* original address of boot-sector */ - -.equ SYSSEG, 0x1000 /* system loaded at SYSSEG<<4 */ - - .org 0 - .arch i386 - .text - .section ".prefix", "ax", @progbits - .code16 - .globl _dsk_start -_dsk_start: - - jmp $BOOTSEG, $go /* reload cs:ip to match relocation addr */ -go: - movw $0x2000-12, %di /* 0x2000 is arbitrary value >= length */ - /* of bootsect + room for stack + 12 for */ - /* saved disk parm block */ - - movw $BOOTSEG, %ax - movw %ax,%ds - movw %ax,%es - movw %ax,%ss /* put stack at BOOTSEG:0x4000-12. */ - movw %di,%sp - -/* Many BIOS's default disk parameter tables will not recognize multi-sector - * reads beyond the maximum sector number specified in the default diskette - * parameter tables - this may mean 7 sectors in some cases. - * - * Since single sector reads are slow and out of the question, we must take care - * of this by creating new parameter tables (for the first disk) in RAM. We - * will set the maximum sector count to 36 - the most we will encounter on an - * ED 2.88. High doesn't hurt. Low does. - * - * Segments are as follows: ds=es=ss=cs - BOOTSEG - */ - - xorw %cx,%cx - movw %cx,%es /* access segment 0 */ - movw $0x78, %bx /* 0:bx is parameter table address */ - pushw %ds /* save ds */ -/* 0:bx is parameter table address */ - ldsw %es:(%bx),%si /* loads ds and si */ - - movw %ax,%es /* ax is BOOTSECT (loaded above) */ - movb $6, %cl /* copy 12 bytes */ - cld - pushw %di /* keep a copy for later */ - rep - movsw /* ds:si is source, es:di is dest */ - popw %di - - movb $36,%es:4(%di) - - movw %cx,%ds /* access segment 0 */ - xchgw %di,(%bx) - movw %es,%si - xchgw %si,2(%bx) - popw %ds /* restore ds */ - movw %di, dpoff /* save old parameters */ - movw %si, dpseg /* to restore just before finishing */ - pushw %ds - popw %es /* reload es */ - -/* Note that es is already set up. Also cx is 0 from rep movsw above. */ - - xorb %ah,%ah /* reset FDC */ - xorb %dl,%dl - int $0x13 - -/* Get disk drive parameters, specifically number of sectors/track. - * - * It seems that there is no BIOS call to get the number of sectors. Guess - * 36 sectors if sector 36 can be read, 18 sectors if sector 18 can be read, - * 15 if sector 15 can be read. Otherwise guess 9. - */ - - movw $disksizes, %si /* table of sizes to try */ - -probe_loop: - lodsb - cbtw /* extend to word */ - movw %ax, sectors - cmpw $disksizes+4, %si - jae got_sectors /* if all else fails, try 9 */ - xchgw %cx,%ax /* cx = track and sector */ - xorw %dx,%dx /* drive 0, head 0 */ - movw $0x0200, %bx /* address after boot sector */ - /* (512 bytes from origin, es = cs) */ - movw $0x0201, %ax /* service 2, 1 sector */ - int $0x13 - jc probe_loop /* try next value */ - -got_sectors: - movw $msg1end-msg1, %cx - movw $msg1, %si - call print_str - -/* ok, we've written the Loading... message, now we want to load the system */ - - movw $SYSSEG, %ax - movw %ax,%es /* segment of SYSSEG<<4 */ - pushw %es - call read_it - -/* This turns off the floppy drive motor, so that we enter the kernel in a - * known state, and don't have to worry about it later. - */ - movw $0x3f2, %dx - xorb %al,%al - outb %al,%dx - - call print_nl - pop %es /* = SYSSEG */ - -/* Restore original disk parameters */ - movw $0x78, %bx - movw dpoff, %di - movw dpseg, %si - xorw %ax,%ax - movw %ax,%ds - movw %di,(%bx) - movw %si,2(%bx) - - /* Everything now loaded. %es = SYSSEG, so %es:0000 points to - * start of loaded image. - */ - - /* Jump to loaded copy */ - ljmp $SYSSEG, $start_runtime - -endseg: .word SYSSEG - .section ".zinfo.fixup", "a", @progbits /* Compressor fixups */ - .ascii "ADDW" - .long endseg - .long 16 - .long 0 - .previous - -/* This routine loads the system at address SYSSEG<<4, making sure no 64kB - * boundaries are crossed. We try to load it as fast as possible, loading whole - * tracks whenever we can. - * - * in: es - starting address segment (normally SYSSEG) - */ -read_it: - movw $0,sread /* load whole image including prefix */ - movw %es,%ax - testw $0x0fff, %ax -die: jne die /* es must be at 64kB boundary */ - xorw %bx,%bx /* bx is starting address within segment */ -rp_read: - movw %es,%ax - movw %bx,%dx - movb $4, %cl - shrw %cl,%dx /* bx is always divisible by 16 */ - addw %dx,%ax - cmpw endseg, %ax /* have we loaded all yet? */ - jb ok1_read - ret -ok1_read: - movw sectors, %ax - subw sread, %ax - movw %ax,%cx - shlw $9, %cx - addw %bx,%cx - jnc ok2_read - je ok2_read - xorw %ax,%ax - subw %bx,%ax - shrw $9, %ax -ok2_read: - call read_track - movw %ax,%cx - addw sread, %ax - cmpw sectors, %ax - jne ok3_read - movw $1, %ax - subw head, %ax - jne ok4_read - incw track -ok4_read: - movw %ax, head - xorw %ax,%ax -ok3_read: - movw %ax, sread - shlw $9, %cx - addw %cx,%bx - jnc rp_read - movw %es,%ax - addb $0x10, %ah - movw %ax,%es - xorw %bx,%bx - jmp rp_read - -read_track: - pusha - pushw %ax - pushw %bx - pushw %bp /* just in case the BIOS is buggy */ - movw $0x0e2e, %ax /* 0x2e = . */ - movw $0x0007, %bx - int $0x10 - popw %bp - popw %bx - popw %ax - - movw track, %dx - movw sread, %cx - incw %cx - movb %dl,%ch - movw head, %dx - movb %dl,%dh - andw $0x0100, %dx - movb $2, %ah - - pushw %dx /* save for error dump */ - pushw %cx - pushw %bx - pushw %ax - - int $0x13 - jc bad_rt - addw $8, %sp - popa - ret - -bad_rt: pushw %ax /* save error code */ - call print_all /* ah = error, al = read */ - - xorb %ah,%ah - xorb %dl,%dl - int $0x13 - - addw $10, %sp - popa - jmp read_track - -/* print_all is for debugging purposes. It will print out all of the registers. - * The assumption is that this is called from a routine, with a stack frame like - * dx - * cx - * bx - * ax - * error - * ret <- sp - */ - -print_all: - call print_nl /* nl for readability */ - movw $5, %cx /* error code + 4 registers */ - movw %sp,%bp - -print_loop: - pushw %cx /* save count left */ - - cmpb $5, %cl - jae no_reg /* see if register name is needed */ - - movw $0x0007, %bx /* page 0, attribute 7 (normal) */ - movw $0xe05+0x41-1, %ax - subb %cl,%al - int $0x10 - - movb $0x58, %al /* 'X' */ - int $0x10 - - movb $0x3A, %al /* ':' */ - int $0x10 - -no_reg: - addw $2, %bp /* next register */ - call print_hex /* print it */ - movb $0x20, %al /* print a space */ - int $0x10 - popw %cx - loop print_loop - call print_nl /* nl for readability */ - ret - -print_str: - movw $0x0007, %bx /* page 0, attribute 7 (normal) */ - movb $0x0e, %ah /* write char, tty mode */ -prloop: - lodsb - int $0x10 - loop prloop - ret - -print_nl: - movw $0x0007, %bx /* page 0, attribute 7 (normal) */ - movw $0xe0d, %ax /* CR */ - int $0x10 - movb $0xa, %al /* LF */ - int $0x10 - ret - -/* print_hex prints the word pointed to by ss:bp in hexadecimal. */ - -print_hex: - movw (%bp),%dx /* load word into dx */ - movb $4, %cl - movb $0x0e, %ah /* write char, tty mode */ - movw $0x0007, %bx /* page 0, attribute 7 (normal) */ - call print_digit - call print_digit - call print_digit -/* fall through */ -print_digit: - rol %cl,%dx /* rotate so that lowest 4 bits are used */ - movb $0x0f, %al /* mask for nybble */ - andb %dl,%al - addb $0x90, %al /* convert al to ascii hex (four instructions) */ - daa - adcb $0x40, %al - daa - int $0x10 - ret - -sread: .word 0 /* sectors read of current track */ -head: .word 0 /* current head */ -track: .word 0 /* current track */ - -sectors: - .word 0 - -dpseg: .word 0 -dpoff: .word 0 - -disksizes: - .byte 36,18,15,9 - -msg1: - .ascii "Loading ROM image" -msg1end: - - .org 510, 0 - .word 0xAA55 - -start_runtime: - /* 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: - pushl $main - pushw %cs - call prot_call - popl %ecx /* discard */ - - /* Uninstall iPXE */ - call uninstall - - /* Boot next device */ - int $0x18 - diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/exeprefix.S b/qemu/roms/ipxe/src/arch/i386/prefix/exeprefix.S deleted file mode 100644 index 5c648d51d..000000000 --- a/qemu/roms/ipxe/src/arch/i386/prefix/exeprefix.S +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (C) 2011 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 ) - -/* Initial temporary stack size */ -#define EXE_STACK_SIZE 0x400 - -/* Temporary decompression area (avoid DOS high memory area) */ -#define EXE_DECOMPRESS_ADDRESS 0x110000 - -/* Fields within the Program Segment Prefix */ -#define PSP_CMDLINE_LEN 0x80 -#define PSP_CMDLINE_START 0x81 - - .text - .arch i386 - .org 0 - .code16 - .section ".prefix", "awx", @progbits - -signature: - /* "MZ" signature */ - .ascii "MZ" - -last_block: - /* Number of bytes in last block that are really used */ - .word 0 - -blocks: - /* Number of 512-byte blocks */ - .word 0 - .section ".zinfo.fixup", "a", @progbits /* Compressor fixups */ - .ascii "ADDW" - .long blocks - .long 512 - .long 0 - .previous - -num_reloc: - /* Number of relocation entries stored after the header */ - .word 0 - -header_pgh: - /* Number of paragraphs in the header */ - .word ( ( _exe_start - signature ) / 16 ) - -min_bss_pgh: - /* Minimum number of paragraphs of additional (BSS) memory */ - .word ( EXE_STACK_SIZE / 16 ) - -max_bss_pgh: - /* Maximum number of paragraphs of additional (BSS) memory */ - .word ( EXE_STACK_SIZE / 16 ) - -init_ss: - /* Initial stack segment (relative to start of executable) */ - .word -( ( _exe_start - signature ) / 16 ) - .section ".zinfo.fixup", "a", @progbits /* Compressor fixups */ - .ascii "ADDW" - .long init_ss - .long 16 - .long 0 - .previous - -init_sp: - /* Initial stack pointer */ - .word EXE_STACK_SIZE - -checksum: - /* Checksum (ignored) */ - .word 0 - -init_ip: - /* Initial instruction pointer */ - .word _exe_start - -init_cs: - /* Initial code segment (relative to start of executable) */ - .word -( ( _exe_start - signature ) / 16 ) - -reloc_table: - /* Relocation table offset */ - .word 0 - -overlay: - /* Overlay number */ - .word 0 - - .align 16, 0 - - .globl _exe_start -_exe_start: - /* Install iPXE. Use a fixed temporary decompression area to - * avoid trashing the DOS high memory area. - */ - call alloc_basemem - xorl %esi, %esi - movl $EXE_DECOMPRESS_ADDRESS, %edi - orl $0xffffffff, %ebp /* Allow arbitrary relocation */ - call install_prealloc - - /* 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: - /* Terminate command line with a NUL */ - movzbw PSP_CMDLINE_LEN, %si - movb $0, PSP_CMDLINE_START(%si) - - /* Calculate command line physical address */ - xorl %esi, %esi - movw %ds, %si - shll $4, %esi - addl $PSP_CMDLINE_START, %esi - - /* Set up %ds for access to .data16 */ - movw %bx, %ds - - /* Record command line address */ - movl %esi, cmdline_phys - - /* Run iPXE */ - pushl $main - pushw %cs - call prot_call - popl %ecx /* discard */ - - /* Uninstall iPXE */ - call uninstall - - /* Exit back to DOS. This is very unlikely to work */ - movw $0x4c00, %ax - int $0x21 diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/hdprefix.S b/qemu/roms/ipxe/src/arch/i386/prefix/hdprefix.S deleted file mode 100644 index 1d012d80b..000000000 --- a/qemu/roms/ipxe/src/arch/i386/prefix/hdprefix.S +++ /dev/null @@ -1,111 +0,0 @@ -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) - - .text - .arch i386 - .section ".prefix", "awx", @progbits - .code16 - .org 0 - .globl _hd_start -_hd_start: - - movw $load_image, %bp - jmp find_active_partition - -#include "bootpart.S" - -load_image: - /* Get disk geometry */ - pushal - pushw %es - movb $0x08, %ah - int $0x13 - jc load_failed - movb %cl, max_sector - movb %dh, max_head - popw %es - popal - -1: /* Read to end of current track */ - movb %cl, %al - negb %al - addb max_sector, %al - incb %al - andb $0x3f, %al - movzbl %al, %eax - call *read_sectors - jc load_failed - - /* Update %es */ - movw %es, %bx - shll $5, %eax - addw %ax, %bx - movw %bx, %es - shrl $5, %eax - - /* Update LBA address */ - addl %eax, %edi - adcl $0, %esi - - /* Update CHS address */ - andb $0xc0, %cl - orb $0x01, %cl - incb %dh - cmpb max_head, %dh - jbe 2f - xorb %dh, %dh - incb %ch - jnc 2f - addb $0xc0, %cl -2: - /* Loop until whole image is read */ - subl %eax, load_length - ja 1b - ljmp $BOOT_SEG, $start_image - -max_sector: - .byte 0 -max_head: - .byte 0 -load_length: - .long 0 - - .section ".zinfo.fixup", "a", @progbits /* Compressor fixups */ - .ascii "ADDL" - .long load_length - .long 512 - .long 0 - .previous - - -load_failed: - movw $10f, %si - jmp boot_error -10: .asciz "Could not load iPXE\r\n" - - .org 510 - .byte 0x55, 0xaa - -start_image: - /* 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: - pushl $main - pushw %cs - call prot_call - popl %ecx /* discard */ - - /* Uninstall iPXE */ - call uninstall - - /* Boot next device */ - int $0x18 diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/isaromprefix.S b/qemu/roms/ipxe/src/arch/i386/prefix/isaromprefix.S deleted file mode 100644 index fb49819ee..000000000 --- a/qemu/roms/ipxe/src/arch/i386/prefix/isaromprefix.S +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2014 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 ) - -#define BUSTYPE "ISAR" -#define _rom_start _isarom_start -#include "romprefix.S" diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/kkkpxeprefix.S b/qemu/roms/ipxe/src/arch/i386/prefix/kkkpxeprefix.S deleted file mode 100644 index 6e43cd26a..000000000 --- a/qemu/roms/ipxe/src/arch/i386/prefix/kkkpxeprefix.S +++ /dev/null @@ -1,17 +0,0 @@ -/***************************************************************************** - * PXE prefix that keeps the whole PXE stack present and provides an exit hook - * - * This prefix is essentially intended solely for the case of ipxelinux.0 - ***************************************************************************** - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) - -/* Provide the PXENV_FILE_EXIT_HOOK API call */ -REQUIRING_SYMBOL ( _kkkpxe_start ) -REQUIRE_OBJECT ( pxe_exit_hook ) - -#define PXELOADER_KEEP_UNDI -#define PXELOADER_KEEP_PXE -#define _pxe_start _kkkpxe_start -#include "pxeprefix.S" diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/kkpxeprefix.S b/qemu/roms/ipxe/src/arch/i386/prefix/kkpxeprefix.S deleted file mode 100644 index 3c17dbdb1..000000000 --- a/qemu/roms/ipxe/src/arch/i386/prefix/kkpxeprefix.S +++ /dev/null @@ -1,11 +0,0 @@ -/***************************************************************************** - * PXE prefix that keeps the whole PXE stack present - ***************************************************************************** - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) - -#define PXELOADER_KEEP_UNDI -#define PXELOADER_KEEP_PXE -#define _pxe_start _kkpxe_start -#include "pxeprefix.S" diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/kpxeprefix.S b/qemu/roms/ipxe/src/arch/i386/prefix/kpxeprefix.S deleted file mode 100644 index 200006d83..000000000 --- a/qemu/roms/ipxe/src/arch/i386/prefix/kpxeprefix.S +++ /dev/null @@ -1,10 +0,0 @@ -/***************************************************************************** - * PXE prefix that keep the UNDI portion of the PXE stack present - ***************************************************************************** - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) - -#define PXELOADER_KEEP_UNDI -#define _pxe_start _kpxe_start -#include "pxeprefix.S" diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/libprefix.S b/qemu/roms/ipxe/src/arch/i386/prefix/libprefix.S deleted file mode 100644 index 7d5c1ed53..000000000 --- a/qemu/roms/ipxe/src/arch/i386/prefix/libprefix.S +++ /dev/null @@ -1,1016 +0,0 @@ -/* - * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 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 ) - - .arch i386 - -/* Image compression enabled */ -#define COMPRESS 1 - -/* Protected mode flag */ -#define CR0_PE 1 - -/* Allow for DBG()-style messages within libprefix */ -#ifdef NDEBUG - .macro progress message - .endm -#else - .macro progress message - pushfl - pushw %ds - pushw %si - pushw %di - pushw %cs - popw %ds - xorw %di, %di - movw $progress_\@, %si - call print_message - popw %di - popw %si - popw %ds - popfl - .section ".prefix.data", "aw", @progbits -progress_\@: - .asciz "\message" - .size progress_\@, . - progress_\@ - .previous - .endm -#endif - -/***************************************************************************** - * Utility function: print character (with LF -> LF,CR translation) - * - * Parameters: - * %al : character to print - * %ds:di : output buffer (or %di=0 to print to console) - * Returns: - * %ds:di : next character in output buffer (if applicable) - ***************************************************************************** - */ - .section ".prefix.lib", "awx", @progbits - .code16 - .globl print_character -print_character: - /* Preserve registers */ - pushw %ax - pushw %bx - pushw %bp - /* If %di is non-zero, write character to buffer and exit */ - testw %di, %di - jz 1f - movb %al, %ds:(%di) - incw %di - jmp 3f -1: /* Print character */ - movw $0x0007, %bx /* page 0, attribute 7 (normal) */ - movb $0x0e, %ah /* write char, tty mode */ - cmpb $0x0a, %al /* '\n'? */ - jne 2f - int $0x10 - movb $0x0d, %al -2: int $0x10 - /* Restore registers and return */ -3: popw %bp - popw %bx - popw %ax - ret - .size print_character, . - print_character - -/***************************************************************************** - * Utility function: print space - * - * Parameters: - * %ds:di : output buffer (or %di=0 to print to console) - * Returns: - * %ds:di : next character in output buffer (if applicable) - ***************************************************************************** - */ - .section ".prefix.lib", "awx", @progbits - .code16 - .globl print_space -print_space: - /* Preserve registers */ - pushw %ax - /* Print space */ - movb $( ' ' ), %al - call print_character - /* Restore registers and return */ - popw %ax - ret - .size print_space, . - print_space - -/***************************************************************************** - * Utility function: print a NUL-terminated string - * - * Parameters: - * %ds:si : string to print - * %ds:di : output buffer (or %di=0 to print to console) - * Returns: - * %ds:si : character after terminating NUL - * %ds:di : next character in output buffer (if applicable) - ***************************************************************************** - */ - .section ".prefix.lib", "awx", @progbits - .code16 - .globl print_message -print_message: - /* Preserve registers */ - pushw %ax - /* Print string */ -1: lodsb - testb %al, %al - je 2f - call print_character - jmp 1b -2: /* Restore registers and return */ - popw %ax - ret - .size print_message, . - print_message - -/***************************************************************************** - * Utility functions: print hex digit/byte/word/dword - * - * Parameters: - * %al (low nibble) : digit to print - * %al : byte to print - * %ax : word to print - * %eax : dword to print - * %ds:di : output buffer (or %di=0 to print to console) - * Returns: - * %ds:di : next character in output buffer (if applicable) - ***************************************************************************** - */ - .section ".prefix.lib", "awx", @progbits - .code16 - .globl print_hex_dword -print_hex_dword: - rorl $16, %eax - call print_hex_word - rorl $16, %eax - /* Fall through */ - .size print_hex_dword, . - print_hex_dword - .globl print_hex_word -print_hex_word: - xchgb %al, %ah - call print_hex_byte - xchgb %al, %ah - /* Fall through */ - .size print_hex_word, . - print_hex_word - .globl print_hex_byte -print_hex_byte: - rorb $4, %al - call print_hex_nibble - rorb $4, %al - /* Fall through */ - .size print_hex_byte, . - print_hex_byte - .globl print_hex_nibble -print_hex_nibble: - /* Preserve registers */ - pushw %ax - /* Print digit (technique by Norbert Juffa <norbert.juffa@amd.com> */ - andb $0x0f, %al - cmpb $10, %al - sbbb $0x69, %al - das - call print_character - /* Restore registers and return */ - popw %ax - ret - .size print_hex_nibble, . - print_hex_nibble - -/***************************************************************************** - * Utility function: print PCI bus:dev.fn - * - * Parameters: - * %ax : PCI bus:dev.fn to print - * %ds:di : output buffer (or %di=0 to print to console) - * Returns: - * %ds:di : next character in output buffer (if applicable) - ***************************************************************************** - */ - .section ".prefix.lib", "awx", @progbits - .code16 - .globl print_pci_busdevfn -print_pci_busdevfn: - /* Preserve registers */ - pushw %ax - /* Print bus */ - xchgb %al, %ah - call print_hex_byte - /* Print ":" */ - movb $( ':' ), %al - call print_character - /* Print device */ - movb %ah, %al - shrb $3, %al - call print_hex_byte - /* Print "." */ - movb $( '.' ), %al - call print_character - /* Print function */ - movb %ah, %al - andb $0x07, %al - call print_hex_nibble - /* Restore registers and return */ - popw %ax - ret - .size print_pci_busdevfn, . - print_pci_busdevfn - -/***************************************************************************** - * Utility function: clear current line - * - * Parameters: - * %ds:di : output buffer (or %di=0 to print to console) - * Returns: - * %ds:di : next character in output buffer (if applicable) - ***************************************************************************** - */ - .section ".prefix.lib", "awx", @progbits - .code16 - .globl print_kill_line -print_kill_line: - /* Preserve registers */ - pushw %ax - pushw %cx - /* Print CR */ - movb $( '\r' ), %al - call print_character - /* Print 79 spaces */ - movw $79, %cx -1: call print_space - loop 1b - /* Print CR */ - call print_character - /* Restore registers and return */ - popw %cx - popw %ax - ret - .size print_kill_line, . - print_kill_line - -/**************************************************************************** - * copy_bytes - * - * Copy bytes - * - * Parameters: - * %ds:esi : source address - * %es:edi : destination address - * %ecx : length - * Returns: - * %ds:esi : next source address - * %es:edi : next destination address - * Corrupts: - * None - **************************************************************************** - */ - .section ".prefix.lib", "awx", @progbits - .code16 -copy_bytes: - pushl %ecx - rep addr32 movsb - popl %ecx - ret - .size copy_bytes, . - copy_bytes - -/**************************************************************************** - * zero_bytes - * - * Zero bytes - * - * Parameters: - * %es:edi : destination address - * %ecx : length - * Returns: - * %es:edi : next destination address - * Corrupts: - * None - **************************************************************************** - */ - .section ".prefix.lib", "awx", @progbits - .code16 -zero_bytes: - pushl %ecx - pushw %ax - xorw %ax, %ax - rep addr32 stosb - popw %ax - popl %ecx - ret - .size zero_bytes, . - zero_bytes - -/**************************************************************************** - * process_bytes - * - * Call memcpy()-like function - * - * Parameters: - * %esi : source physical address - * %edi : destination physical address - * %ecx : length - * %bx : memcpy()-like function to call, passing parameters: - * %ds:esi : source address - * %es:edi : destination address - * %ecx : length - * and returning: - * %ds:esi : next source address - * %es:edi : next destination address - * Returns: - * %esi : next source physical address - * %edi : next destination physical address - * Corrupts: - * None - **************************************************************************** - */ - .section ".prefix.lib", "awx", @progbits - .code16 -process_bytes: - -#ifndef KEEP_IT_REAL - - /* Preserve registers */ - pushl %eax - pushl %ebp - - /* Construct GDT on stack (since .prefix may not be writable) */ - .equ PM_DS, 0x18 /* Flat data segment */ - pushl $0x00cf9300 - pushl $0x0000ffff - .equ PM_SS, 0x10 /* Stack segment based at %ss:0000 */ - pushl $0x008f0930 - pushw %ss - pushw $0xffff - .equ PM_CS, 0x08 /* Code segment based at %cs:0000 */ - pushl $0x008f09b0 - pushw %cs - pushw $0xffff - pushl $0 /* Base and length */ - pushw %ss - pushw $0x1f - movzwl %sp, %ebp - shll $4, 0x02(%bp) - addl %ebp, 0x02(%bp) - shll $4, 0x0a(%bp) - shll $4, 0x12(%bp) - subw $8, %sp - sgdt -8(%bp) - - /* Switch to protected mode */ - pushw %gs - pushw %fs - pushw %es - pushw %ds - pushw %ss - pushw %cs - pushw $2f - cli - data32 lgdt (%bp) - movl %cr0, %eax - orb $CR0_PE, %al - movl %eax, %cr0 - ljmp $PM_CS, $1f -1: movw $PM_SS, %ax - movw %ax, %ss - movw $PM_DS, %ax - movw %ax, %ds - movw %ax, %es - movw %ax, %fs - movw %ax, %gs - -#ifdef NDEBUG - /* Call memcpy()-like function */ - call *%bx -#endif - - /* Return to (flat) real mode */ - movl %cr0, %eax - andb $0!CR0_PE, %al - movl %eax, %cr0 - lret -2: /* lret will ljmp to here */ - popw %ss - popw %ds - popw %es - popw %fs - popw %gs - -#ifndef NDEBUG - /* Call memcpy()-like function in flat real mode (to allow for - * debug output via INT 10). - */ - pushw %ds - pushw %es - xorw %ax, %ax - movw %ax, %ds - movw %ax, %es - call *%bx - popw %es - popw %ds -#endif - - /* Restore GDT */ - data32 lgdt -8(%bp) - addw $( 8 /* saved GDT */ + ( PM_DS + 8 ) /* GDT on stack */ ), %sp - - /* Restore registers and return */ - popl %ebp - popl %eax - ret - -#else /* KEEP_IT_REAL */ - - /* Preserve registers */ - pushl %eax - pushw %ds - pushw %es - - /* Convert %esi and %edi to %ds:esi and %es:edi */ - shrl $4, %esi - movw %si, %ds - xorw %si, %si - shll $4, %esi - shrl $4, %edi - movw %di, %es - xorw %di, %di - shll $4, %edi - - /* Call memcpy()-like function */ - call *%bx - - /* Convert %ds:esi and %es:edi back to physical addresses */ - xorl %eax, %eax - movw %ds, %ax - shll $4, %eax - addl %eax, %esi - xorl %eax, %eax - movw %es, %ax - shll $4, %eax - addl %eax, %edi - - /* Restore registers and return */ - popw %es - popw %ds - popl %eax - ret - -#endif /* KEEP_IT_REAL */ - - .size process_bytes, . - process_bytes - -/**************************************************************************** - * install_block - * - * Install block to specified address - * - * Parameters: - * %esi : source physical address (must be a multiple of 16) - * %edi : destination physical address (must be a multiple of 16) - * %ecx : length of (decompressed) data - * %edx : total length of block (including any uninitialised data portion) - * Returns: - * %esi : next source physical address (will be a multiple of 16) - * %edi : next destination physical address (will be a multiple of 16) - * Corrupts: - * none - **************************************************************************** - */ - .section ".prefix.lib", "awx", @progbits - .code16 -install_block: - /* Preserve registers */ - pushl %ecx - pushw %bx - - /* Decompress (or copy) source to destination */ -#if COMPRESS - movw $decompress16, %bx -#else - movw $copy_bytes, %bx -#endif - call process_bytes - - /* Zero .bss portion */ - negl %ecx - addl %edx, %ecx - movw $zero_bytes, %bx - call process_bytes - - /* Round up %esi and %edi to start of next blocks */ - addl $0xf, %esi - andl $~0xf, %esi - addl $0xf, %edi - andl $~0xf, %edi - - /* Restore registers and return */ - popw %bx - popl %ecx - ret - .size install_block, . - install_block - -/**************************************************************************** - * alloc_basemem - * - * Allocate space for .text16 and .data16 from top of base memory. - * Memory is allocated using the BIOS free base memory counter at - * 0x40:13. - * - * Parameters: - * none - * Returns: - * %ax : .text16 segment address - * %bx : .data16 segment address - * Corrupts: - * none - **************************************************************************** - */ - .section ".prefix.lib", "awx", @progbits - .code16 - .globl alloc_basemem -alloc_basemem: - /* Preserve registers */ - pushw %fs - - /* FBMS => %ax as segment address */ - pushw $0x40 - popw %fs - movw %fs:0x13, %ax - shlw $6, %ax - - /* Calculate .data16 segment address */ - subw $_data16_memsz_pgh, %ax - pushw %ax - - /* Calculate .text16 segment address. Round down to ensure - * low bits are zero, to speed up mode transitions under KVM. - */ - subw $_text16_memsz_pgh, %ax - andb $~0x03, %al - pushw %ax - - /* Update FBMS */ - shrw $6, %ax - movw %ax, %fs:0x13 - - /* Retrieve .text16 and .data16 segment addresses */ - popw %ax - popw %bx - - /* Restore registers and return */ - popw %fs - ret - .size alloc_basemem, . - alloc_basemem - -/**************************************************************************** - * free_basemem - * - * Free space allocated with alloc_basemem. - * - * Parameters: - * none (.text16 segment address is implicit in %cs) - * Returns: - * %ax : 0 if successfully freed - * Corrupts: - * none - **************************************************************************** - */ - .section ".text16", "ax", @progbits - .code16 - .globl free_basemem -free_basemem: - /* Preserve registers */ - pushw %fs - pushw %ax - - /* Check FBMS counter */ - movw %cs, %ax - shrw $6, %ax - pushw $0x40 - popw %fs - cmpw %ax, %fs:0x13 - jne 1f - - /* Check hooked interrupt count */ - cmpw $0, %cs:hooked_bios_interrupts - jne 1f - - /* OK to free memory */ - movw %cs, %ax - addw $_text16_memsz_pgh, %ax - addw $_data16_memsz_pgh, %ax - shrw $6, %ax - movw %ax, %fs:0x13 - xorw %ax, %ax - -1: /* Restore registers and return */ - popw %ax - popw %fs - ret - .size free_basemem, . - free_basemem - - .section ".text16.data", "aw", @progbits - .globl hooked_bios_interrupts -hooked_bios_interrupts: - .word 0 - .size hooked_bios_interrupts, . - hooked_bios_interrupts - -/**************************************************************************** - * install - * - * Install all text and data segments. - * - * Parameters: - * none - * Returns: - * %ax : .text16 segment address - * %bx : .data16 segment address - * Corrupts: - * none - **************************************************************************** - */ - .section ".prefix.lib", "awx", @progbits - .code16 - .globl install -install: - progress "install:\n" - /* Preserve registers */ - pushl %esi - pushl %edi - pushl %ebp - /* Allocate space for .text16 and .data16 */ - call alloc_basemem - /* Image source = %cs:0000 */ - xorl %esi, %esi - /* Image destination = default */ - xorl %edi, %edi - /* Allow arbitrary relocation */ - orl $0xffffffff, %ebp - /* Install text and data segments */ - call install_prealloc - /* Restore registers and return */ - popl %ebp - popl %edi - popl %esi - ret - .size install, . - install - -/**************************************************************************** - * install_prealloc - * - * Install all text and data segments. - * - * Parameters: - * %ax : .text16 segment address - * %bx : .data16 segment address - * %esi : Image source physical address (or zero for %cs:0000) - * %edi : Decompression temporary area physical address (or zero for default) - * %ebp : Maximum end address for relocation - * - 0xffffffff for no maximum - * - 0x00000000 to inhibit use of INT 15,e820 and INT 15,e801 - * Corrupts: - * none - **************************************************************************** - */ - .section ".prefix.lib", "awx", @progbits - .code16 - .globl install_prealloc -install_prealloc: - progress "install_prealloc:\n" - /* Save registers on external stack */ - pushal - pushw %ds - pushw %es - cld /* Sanity: clear the direction flag asap */ - - /* Switch to temporary stack in .bss16 */ - pushw %ss - popw %ds - movl %esp, %ecx - movw %bx, %ss - movl $_data16_memsz, %esp - pushw %ds - pushl %ecx - - /* Set up %ds for (read-only) access to .prefix */ - pushw %cs - popw %ds - - /* Save decompression temporary area physical address */ - pushl %edi - - /* Install .text16.early and calculate %ecx as offset to next block */ - progress " .text16.early\n" - pushl %esi - xorl %esi, %esi - movw %cs, %si - shll $4, %esi - pushl %esi /* Save original %cs:0000 */ - addl $_text16_early_lma, %esi - movzwl %ax, %edi - shll $4, %edi - movl $_text16_early_filesz, %ecx - movl $_text16_early_memsz, %edx - call install_block /* .text16.early */ - popl %ecx /* Calculate offset to next block */ - subl %esi, %ecx - negl %ecx - popl %esi - -#ifndef KEEP_IT_REAL - - /* Access high memory by enabling the A20 gate. (We will - * already have 4GB segment limits as a result of calling - * install_block.) - */ - progress " access_highmem\n" - pushw %cs - pushw $1f - pushw %ax - pushw $access_highmem - lret -1: /* Die if we could not access high memory */ - jnc 3f - movw $a20_death_message, %si - xorw %di, %di - call print_message -2: jmp 2b - .section ".prefix.data", "aw", @progbits -a20_death_message: - .asciz "\nHigh memory inaccessible - cannot continue\n" - .size a20_death_message, . - a20_death_message - .previous -3: -#endif - - /* Open payload (which may not yet be in memory) */ - progress " open_payload\n" - pushw %cs - pushw $1f - pushw %ax - pushw $open_payload - lret -1: /* Die if we could not access the payload */ - jnc 3f - xorw %di, %di - movl %esi, %eax - call print_hex_dword - call print_space - movl %ecx, %eax - call print_hex_dword - movw $payload_death_message, %si - call print_message -2: /* Halt system */ - cli - hlt - jmp 2b - .section ".prefix.data", "aw", @progbits -payload_death_message: - .asciz "\nPayload inaccessible - cannot continue\n" - .size payload_death_message, . - payload_death_message - .previous -3: - - /* Calculate physical address of payload (i.e. first source) */ - testl %esi, %esi - jnz 1f - movw %cs, %si - shll $4, %esi -1: addl %ecx, %esi - - /* Install .text16.late and .data16 */ - progress " .text16.late\n" - movl $_text16_late_filesz, %ecx - movl $_text16_late_memsz, %edx - call install_block /* .text16.late */ - progress " .data16\n" - movzwl %bx, %edi - shll $4, %edi - movl $_data16_filesz, %ecx - movl $_data16_filesz, %edx /* do not zero our temporary stack */ - call install_block /* .data16 */ - - /* Set up %ds for access to .data16 */ - movw %bx, %ds - - /* Restore decompression temporary area physical address */ - popl %edi - -#ifndef KEEP_IT_REAL - - /* Find a suitable decompression temporary area, if none specified */ - pushl %eax - testl %edi, %edi - jnz 1f - /* Use INT 15,88 to find the highest available address via INT - * 15,88. This limits us to around 64MB, which should avoid - * all of the POST-time memory map failure modes. - */ - movb $0x88, %ah - int $0x15 - movw %ax, %di - addl $0x400, %edi - subl $_textdata_memsz_kb, %edi - shll $10, %edi - /* Sanity check: if we have ended up below 1MB, use 1MB */ - cmpl $0x100000, %edi - jae 1f - movl $0x100000, %edi -1: popl %eax - - /* Install .text and .data to temporary area in high memory, - * prior to reading the E820 memory map and relocating - * properly. - */ - progress " .textdata\n" - pushl %edi - movl $_textdata_filesz, %ecx - movl $_textdata_memsz, %edx - call install_block - popl %edi - -#endif /* KEEP_IT_REAL */ - - /* Switch back to original stack and zero .bss16 */ - addr32 lss %ss:(%esp), %esp - pushl %edi - pushw %es - movw %bx, %es - movl $_data16_filesz, %edi - movl $_data16_memsz, %ecx - subl %edi, %ecx - call zero_bytes - popw %es - popl %edi - -#ifndef KEEP_IT_REAL - - /* Initialise librm at current location */ - progress " init_librm\n" - movw %ax, (init_librm_vector+2) - lcall *init_librm_vector - - /* Inhibit INT 15,e820 and INT 15,e801 if applicable */ - testl %ebp, %ebp - jnz 1f - incb memmap_post - decl %ebp -1: - /* Call relocate() to determine target address for relocation. - * relocate() will return with %esi, %edi and %ecx set up - * ready for the copy to the new location. - */ - progress " relocate\n" - movw %ax, (prot_call_vector+2) - pushl $relocate - lcall *prot_call_vector - popl %edx /* discard */ - - /* Copy code to new location */ - progress " copy\n" - pushl %edi - pushw %bx - movw $copy_bytes, %bx - call process_bytes - popw %bx - popl %edi - - /* Initialise librm at new location */ - progress " init_librm\n" - lcall *init_librm_vector - -#else /* KEEP_IT_REAL */ - - /* Initialise libkir */ - movw %ax, (init_libkir_vector+2) - lcall *init_libkir_vector - -#endif /* KEEP_IT_REAL */ - - /* Close access to payload */ - progress " close_payload\n" - movw %ax, (close_payload_vector+2) - lcall *close_payload_vector - - /* Restore registers */ - popw %es - popw %ds - popal - ret - .size install_prealloc, . - install_prealloc - - /* Vectors for far calls to .text16 functions. Must be in - * .data16, since .prefix may not be writable. - */ - .section ".data16", "aw", @progbits -#ifdef KEEP_IT_REAL -init_libkir_vector: - .word init_libkir - .word 0 - .size init_libkir_vector, . - init_libkir_vector -#else -init_librm_vector: - .word init_librm - .word 0 - .size init_librm_vector, . - init_librm_vector -prot_call_vector: - .word prot_call - .word 0 - .size prot_call_vector, . - prot_call_vector -#endif -close_payload_vector: - .word close_payload - .word 0 - .size close_payload_vector, . - close_payload_vector - - /* Dummy routines to open and close payload */ - .section ".text16.early.data", "aw", @progbits - .weak open_payload - .weak close_payload -open_payload: -close_payload: - clc - lret - .size open_payload, . - open_payload - .size close_payload, . - close_payload - -/**************************************************************************** - * uninstall - * - * Uninstall all text and data segments. - * - * Parameters: - * none (.text16 segment address is implicit in %cs) - * Returns: - * none - * Corrupts: - * none - **************************************************************************** - */ - .section ".text16", "ax", @progbits - .code16 - .globl uninstall -uninstall: - call free_basemem - ret - .size uninstall, . - uninstall - - - - /* File split information for the compressor */ -#if COMPRESS -#define PACK_OR_COPY "PACK" -#else -#define PACK_OR_COPY "COPY" -#endif - .section ".zinfo", "a", @progbits - .ascii "COPY" - .long _prefix_lma - .long _prefix_filesz - .long _max_align - .ascii PACK_OR_COPY - .long _text16_early_lma - .long _text16_early_filesz - .long _max_align - .ascii "PAYL" - .long 0 - .long 0 - .long _payload_align - .ascii "COPY" - .long _pprefix_lma - .long _pprefix_filesz - .long _max_align - .ascii PACK_OR_COPY - .long _text16_late_lma - .long _text16_late_filesz - .long _max_align - .ascii PACK_OR_COPY - .long _data16_lma - .long _data16_filesz - .long _max_align - .ascii PACK_OR_COPY - .long _textdata_lma - .long _textdata_filesz - .long _max_align - - .weak _payload_align - .equ _payload_align, 1 diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/lkrnprefix.S b/qemu/roms/ipxe/src/arch/i386/prefix/lkrnprefix.S deleted file mode 100644 index 64135e14b..000000000 --- a/qemu/roms/ipxe/src/arch/i386/prefix/lkrnprefix.S +++ /dev/null @@ -1,236 +0,0 @@ -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) - -#define BZI_LOAD_HIGH_ADDR 0x100000 - - .text - .arch i386 - .code16 - .section ".prefix", "ax", @progbits - .globl _lkrn_start -_lkrn_start: - -/***************************************************************************** - * - * Kernel header - * - * We place our prefix (i.e. our .prefix and .text16.early sections) - * within the bzImage real-mode portion which gets loaded at - * 1000:0000, and our payload (i.e. everything else) within the - * bzImage protected-mode portion which gets loaded at 0x100000 - * upwards. - * - */ - - .org 0x1f1 -setup_sects: - .byte -1 /* Allow for initial "boot sector" */ - .section ".zinfo.fixup", "a", @progbits /* Compressor fixups */ - .ascii "ADHL" - .long setup_sects - .long 512 - .long 0 - .previous -root_flags: - .word 0 -syssize: - .long 0 - .section ".zinfo.fixup", "a", @progbits /* Compressor fixups */ - .ascii "ADPL" - .long syssize - .long 16 - .long 0 - .previous -ram_size: - .word 0 -vid_mode: - .word 0 -root_dev: - .word 0 -boot_flag: - .word 0xaa55 -jump: - /* Manually specify a two-byte jmp instruction here rather - * than leaving it up to the assembler. - */ - .byte 0xeb, ( setup - header ) -header: - .byte 'H', 'd', 'r', 'S' -version: - .word 0x0207 /* 2.07 */ -realmode_swtch: - .long 0 -start_sys: - .word 0 -kernel_version: - .word version_string - 0x200 -type_of_loader: - .byte 0 -loadflags: - .byte 0x01 /* LOADED_HIGH */ -setup_move_size: - .word 0 -code32_start: - .long 0 -ramdisk_image: - .long 0 -ramdisk_size: - .long 0 -bootsect_kludge: - .long 0 -heap_end_ptr: - .word 0 -ext_loader_ver: - .byte 0 -ext_loader_type: - .byte 0 -cmd_line_ptr: - .long 0 -initrd_addr_max: - .long 0xffffffff -kernel_alignment: - .long 0 -relocatable_kernel: - .byte 0 -min_alignment: - .byte 0 -xloadflags: - .word 0 -cmdline_size: - .long 0x7ff -hardware_subarch: - .long 0 -hardware_subarch_data: - .byte 0, 0, 0, 0, 0, 0, 0, 0 - -version_string: - .asciz VERSION - -/***************************************************************************** - * - * Setup code - * - */ - -setup: - /* Fix up code segment */ - pushw %ds - pushw $1f - lret -1: - /* Set up stack just below 0x7c00 and clear direction flag */ - xorw %ax, %ax - movw %ax, %ss - movw $0x7c00, %sp - cld - - /* Retrieve command-line pointer */ - movl cmd_line_ptr, %edx - testl %edx, %edx - jz no_cmd_line - - /* Set up %es:%di to point to command line */ - movl %edx, %edi - andl $0xf, %edi - rorl $4, %edx - movw %dx, %es - - /* Find length of command line */ - pushw %di - movw $0xffff, %cx - repnz scasb - notw %cx - popw %si - - /* Make space for command line on stack */ - movw %sp, %di - subw %cx, %di - andw $~0xf, %di - movw %di, %sp - - /* Copy command line to stack */ - pushw %ds - pushw %es - popw %ds - pushw %ss - popw %es - rep movsb - popw %ds - - /* Store new command-line pointer */ - movzwl %sp, %edx -no_cmd_line: - - /* Calculate maximum relocation address */ - movl ramdisk_image, %ebp - testl %ebp, %ebp - jnz 1f - orl $0xffffffff, %ebp /* Allow arbitrary relocation if no initrd */ -1: - /* Install iPXE */ - call alloc_basemem - xorl %esi, %esi - xorl %edi, %edi - call install_prealloc - - /* 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: - /* Retrieve initrd pointer and size */ - movl ramdisk_image, %ebp - movl ramdisk_size, %ecx - - /* Set up %ds for access to .data16 */ - movw %bx, %ds - - /* Store command-line pointer */ - movl %edx, cmdline_phys - - /* Store initrd pointer and size */ - movl %ebp, initrd_phys - movl %ecx, initrd_len - - /* Run iPXE */ - pushl $main - pushw %cs - call prot_call - popl %ecx /* discard */ - - /* Uninstall iPXE */ - call uninstall - - /* Boot next device */ - int $0x18 - -/***************************************************************************** - * - * Open payload (called by libprefix) - * - * Parameters: - * %ds:0000 : Prefix - * %esi : Buffer for copy of image source (or zero if no buffer available) - * %ecx : Expected offset within buffer of first payload block - * Returns: - * %esi : Valid image source address (buffered or unbuffered) - * %ecx : Actual offset within buffer of first payload block - * CF set on error - */ - - .section ".text16.early", "awx", @progbits - .globl open_payload -open_payload: - - /* Our payload will always end up at BZI_LOAD_HIGH_ADDR */ - movl $BZI_LOAD_HIGH_ADDR, %esi - xorl %ecx, %ecx - lret - - /* Payload must be aligned to a whole number of setup sectors */ - .globl _payload_align - .equ _payload_align, 512 diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/mbr.S b/qemu/roms/ipxe/src/arch/i386/prefix/mbr.S deleted file mode 100644 index a1e237de8..000000000 --- a/qemu/roms/ipxe/src/arch/i386/prefix/mbr.S +++ /dev/null @@ -1,15 +0,0 @@ -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) - - .text - .arch i386 - .section ".prefix", "awx", @progbits - .code16 - .org 0 - -mbr: - movw $exec_sector, %bp - jmp find_active_partition -exec_sector: - ljmp $0x0000, $0x7c00 - -#include "bootpart.S" diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/mromprefix.S b/qemu/roms/ipxe/src/arch/i386/prefix/mromprefix.S deleted file mode 100644 index b636b92af..000000000 --- a/qemu/roms/ipxe/src/arch/i386/prefix/mromprefix.S +++ /dev/null @@ -1,516 +0,0 @@ -/* - * Copyright (C) 2010 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 ) - -#define PCIBIOS_READ_CONFIG_WORD 0xb109 -#define PCIBIOS_READ_CONFIG_DWORD 0xb10a -#define PCIBIOS_WRITE_CONFIG_WORD 0xb10c -#define PCIBIOS_WRITE_CONFIG_DWORD 0xb10d -#define PCI_COMMAND 0x04 -#define PCI_COMMAND_MEM 0x02 -#define PCI_BAR_0 0x10 -#define PCI_BAR_5 0x24 -#define PCI_BAR_EXPROM 0x30 - -#define PCIR_SIGNATURE ( 'P' + ( 'C' << 8 ) + ( 'I' << 16 ) + ( 'R' << 24 ) ) - -#define ROMPREFIX_EXCLUDE_PAYLOAD 1 -#define ROMPREFIX_MORE_IMAGES 1 -#define _pcirom_start _mrom_start -#include "pciromprefix.S" - - .text - .arch i386 - .code16 - -/* Obtain access to payload by exposing the expansion ROM BAR at the - * address currently used by a suitably large memory BAR on the same - * device. The memory BAR is temporarily disabled. Using a memory - * BAR on the same device means that we don't have to worry about the - * configuration of any intermediate PCI bridges. - * - * Parameters: - * %ds:0000 : Prefix - * %esi : Buffer for copy of image source (or zero if no buffer available) - * %ecx : Expected offset within buffer of first payload block - * Returns: - * %esi : Valid image source address (buffered or unbuffered) - * %ecx : Actual offset within buffer of first payload block - * CF set on error - */ - .section ".text16.early", "awx", @progbits - .globl open_payload -open_payload: - /* Preserve registers */ - pushl %eax - pushw %bx - pushl %edx - pushl %edi - pushw %bp - pushw %es - pushw %ds - - /* Retrieve bus:dev.fn from .prefix */ - movw init_pci_busdevfn, %bx - - /* Set up %ds for access to .text16.early */ - pushw %cs - popw %ds - - /* Set up %es for access to flat address space */ - xorw %ax, %ax - movw %ax, %es - - /* Store bus:dev.fn to .text16.early */ - movw %bx, payload_pci_busdevfn - - /* Get expansion ROM BAR current value */ - movw $PCI_BAR_EXPROM, %di - call pci_read_bar - movl %eax, rom_bar_orig_value - - /* Get expansion ROM BAR size */ - call pci_size_mem_bar_low - movl %ecx, rom_bar_size - - /* Find a suitable memory BAR to use */ - movw $PCI_BAR_0, %di /* %di is PCI BAR register */ - xorw %bp, %bp /* %bp is increment */ -find_mem_bar: - /* Move to next BAR */ - addw %bp, %di - cmpw $PCI_BAR_5, %di - jle 1f - stc - movl $0xbabababa, %esi /* Report "No suitable BAR" */ - movl rom_bar_size, %ecx - jmp 99f -1: movw $4, %bp - - /* Get BAR current value */ - call pci_read_bar - - /* Skip non-existent BARs */ - notl %eax - testl %eax, %eax - notl %eax - jz find_mem_bar - - /* Skip I/O BARs */ - testb $0x01, %al - jnz find_mem_bar - - /* Set increment to 8 for 64-bit BARs */ - testb $0x04, %al - jz 1f - movw $8, %bp -1: - /* Skip 64-bit BARs with high dword set; we couldn't use this - * address for the (32-bit) expansion ROM BAR anyway - */ - testl %edx, %edx - jnz find_mem_bar - - /* Get low dword of BAR size */ - call pci_size_mem_bar_low - - /* Skip BARs smaller than the expansion ROM BAR */ - cmpl %ecx, rom_bar_size - ja find_mem_bar - - /* We have a memory BAR with a 32-bit address that is large - * enough to use. Store BAR number and original value. - */ - movw %di, stolen_bar_register - movl %eax, stolen_bar_orig_value - - /* Remove flags from BAR address */ - xorb %al, %al - - /* Write zero to our stolen BAR. This doesn't technically - * disable it, but it's a pretty safe bet that the PCI bridge - * won't pass through accesses to this region anyway. Note - * that the high dword (if any) must already be zero. - */ - xorl %ecx, %ecx - call pci_write_config_dword - - /* Enable expansion ROM BAR at stolen BAR's address */ - movl %eax, %ecx - orb $0x1, %cl - movw $PCI_BAR_EXPROM, %di - call pci_write_config_dword - - /* Locate our ROM image */ -1: movl $0xaa55, %ecx /* 55aa signature */ - addr32 es cmpw %cx, (%eax) - jne 2f - movl $PCIR_SIGNATURE, %ecx /* PCIR signature */ - addr32 es movzwl 0x18(%eax), %edx - addr32 es cmpl %ecx, (%eax,%edx) - jne 2f - addr32 es cmpl $_build_id, build_id(%eax) /* iPXE build ID */ - je 3f - movl $0x80, %ecx /* Last image */ - addr32 es testb %cl, 0x15(%eax,%edx) - jnz 2f - addr32 es movzwl 0x10(%eax,%edx), %ecx /* PCIR image length */ - shll $9, %ecx - addl %ecx, %eax - jmp 1b -2: /* Failure */ - stc - movl %eax, %esi /* Report failure address */ - jmp 99f -3: - - /* Copy payload to buffer, or set buffer address to BAR address */ - testl %esi, %esi - jz 1f - /* We have a buffer; copy payload to it. Since .mrom is - * designed specifically for real hardware, we assume that - * flat real mode is working properly. (In the unlikely event - * that this code is run inside a hypervisor that doesn't - * properly support flat real mode, it will die horribly.) - */ - pushl %esi - movl %esi, %edi - movl %eax, %esi - addr32 es movzbl 2(%esi), %ecx - shll $7, %ecx - addr32 es movzwl mpciheader_image_length(%esi,%ecx,4), %edx - shll $7, %edx - addl %edx, %ecx - addr32 es rep movsl - popl %esi - jmp 2f -1: /* We have no buffer; set %esi to the BAR address */ - movl %eax, %esi -2: - - /* Locate first payload block (after the dummy ROM header) */ - addr32 es movzbl 2(%esi), %ecx - shll $9, %ecx - addl $_pprefix_skip, %ecx - - clc - /* Restore registers and return */ -99: popw %ds - popw %es - popw %bp - popl %edi - popl %edx - popw %bx - popl %eax - lret - .size open_payload, . - open_payload - - .section ".text16.early.data", "aw", @progbits -payload_pci_busdevfn: - .word 0 - .size payload_pci_busdevfn, . - payload_pci_busdevfn - - .section ".text16.early.data", "aw", @progbits -rom_bar_orig_value: - .long 0 - .size rom_bar_orig_value, . - rom_bar_orig_value - - .section ".text16.early.data", "aw", @progbits -rom_bar_size: - .long 0 - .size rom_bar_size, . - rom_bar_size - - .section ".text16.early.data", "aw", @progbits -stolen_bar_register: - .word 0 - .size stolen_bar_register, . - stolen_bar_register - - .section ".text16.early.data", "aw", @progbits -stolen_bar_orig_value: - .long 0 - .size stolen_bar_orig_value, . - stolen_bar_orig_value - -/* Restore original BAR values - * - * Parameters: - * none - * Returns: - * none - */ - .section ".text16.early", "awx", @progbits - .globl close_payload -close_payload: - /* Preserve registers */ - pushw %bx - pushw %di - pushl %ecx - pushw %ds - - /* Set up %ds for access to .text16.early */ - pushw %cs - popw %ds - - /* Retrieve stored bus:dev.fn */ - movw payload_pci_busdevfn, %bx - - /* Restore expansion ROM BAR original value */ - movw $PCI_BAR_EXPROM, %di - movl rom_bar_orig_value, %ecx - call pci_write_config_dword - - /* Restore stolen BAR original value */ - movw stolen_bar_register, %di - movl stolen_bar_orig_value, %ecx - call pci_write_config_dword - - /* Restore registers and return */ - popw %ds - popl %ecx - popw %di - popw %bx - lret - .size close_payload, . - close_payload - -/* Get PCI BAR value - * - * Parameters: - * %bx : PCI bus:dev.fn - * %di : PCI BAR register number - * Returns: - * %edx:%eax : PCI BAR value - */ - .section ".text16.early", "awx", @progbits -pci_read_bar: - /* Preserve registers */ - pushl %ecx - pushw %di - - /* Read low dword value */ - call pci_read_config_dword - movl %ecx, %eax - - /* Read high dword value, if applicable */ - xorl %edx, %edx - andb $0x07, %cl - cmpb $0x04, %cl - jne 1f - addw $4, %di - call pci_read_config_dword - movl %ecx, %edx -1: - /* Restore registers and return */ - popw %di - popl %ecx - ret - .size pci_read_bar, . - pci_read_bar - -/* Get low dword of PCI memory BAR size - * - * Parameters: - * %bx : PCI bus:dev.fn - * %di : PCI BAR register number - * %eax : Low dword of current PCI BAR value - * Returns: - * %ecx : PCI BAR size - */ - .section ".text16.early", "awx", @progbits -pci_size_mem_bar_low: - /* Preserve registers */ - pushw %dx - - /* Disable memory accesses */ - xorw %dx, %dx - call pci_set_mem_access - - /* Write all ones to BAR */ - xorl %ecx, %ecx - decl %ecx - call pci_write_config_dword - - /* Read back BAR */ - call pci_read_config_dword - - /* Calculate size */ - notl %ecx - orb $0x0f, %cl - incl %ecx - - /* Restore original value */ - pushl %ecx - movl %eax, %ecx - call pci_write_config_dword - popl %ecx - - /* Enable memory accesses */ - movw $PCI_COMMAND_MEM, %dx - call pci_set_mem_access - - /* Restore registers and return */ - popw %dx - ret - .size pci_size_mem_bar_low, . - pci_size_mem_bar_low - -/* Read PCI config dword - * - * Parameters: - * %bx : PCI bus:dev.fn - * %di : PCI register number - * Returns: - * %ecx : Dword value - */ - .section ".text16.early", "awx", @progbits -pci_read_config_dword: - /* Preserve registers */ - pushl %eax - pushl %ebx - pushl %edx - - /* Issue INT 0x1a,b10a */ - movw $PCIBIOS_READ_CONFIG_DWORD, %ax - int $0x1a - - /* Restore registers and return */ - popl %edx - popl %ebx - popl %eax - ret - .size pci_read_config_dword, . - pci_read_config_dword - -/* Write PCI config dword - * - * Parameters: - * %bx : PCI bus:dev.fn - * %di : PCI register number - * %ecx : PCI BAR value - * Returns: - * none - */ - .section ".text16.early", "awx", @progbits -pci_write_config_dword: - /* Preserve registers */ - pushal - - /* Issue INT 0x1a,b10d */ - movw $PCIBIOS_WRITE_CONFIG_DWORD, %ax - int $0x1a - - /* Restore registers and return */ - popal - ret - .size pci_write_config_dword, . - pci_write_config_dword - -/* Enable/disable memory access response in PCI command word - * - * Parameters: - * %bx : PCI bus:dev.fn - * %dx : PCI_COMMAND_MEM, or zero - * Returns: - * none - */ - .section ".text16.early", "awx", @progbits -pci_set_mem_access: - /* Preserve registers */ - pushal - - /* Read current value of command register */ - pushw %bx - pushw %dx - movw $PCI_COMMAND, %di - movw $PCIBIOS_READ_CONFIG_WORD, %ax - int $0x1a - popw %dx - popw %bx - - /* Set memory access enable as appropriate */ - andw $~PCI_COMMAND_MEM, %cx - orw %dx, %cx - - /* Write new value of command register */ - movw $PCIBIOS_WRITE_CONFIG_WORD, %ax - int $0x1a - - /* Restore registers and return */ - popal - ret - .size pci_set_mem_access, . - pci_set_mem_access - -/* Payload prefix - * - * We include a dummy ROM header to cover the "hidden" portion of the - * overall ROM image. - */ - .globl _payload_align - .equ _payload_align, 512 - .section ".pprefix", "ax", @progbits - .org 0x00 -mromheader: - .word 0xaa55 /* BIOS extension signature */ - .byte 0x01 /* Dummy size (BIOS bug workaround) */ - .org 0x18 - .word mpciheader - .org 0x1a - .word 0 - .size mromheader, . - mromheader - -mpciheader: - .ascii "PCIR" /* Signature */ - .word pci_vendor_id /* Vendor identification */ - .word pci_device_id /* Device identification */ - .word 0x0000 /* Device list pointer */ - .word mpciheader_len /* PCI data structure length */ - .byte 0x03 /* PCI data structure revision */ - .byte 0x02, 0x00, 0x00 /* Class code */ -mpciheader_image_length: - .word 0 /* Image length */ - .word 0x0001 /* Revision level */ - .byte 0xff /* Code type */ - .byte 0x80 /* Last image indicator */ -mpciheader_runtime_length: - .word 0 /* Maximum run-time image length */ - .word 0x0000 /* Configuration utility code header */ - .word 0x0000 /* DMTF CLP entry point */ - .equ mpciheader_len, . - mpciheader - .size mpciheader, . - mpciheader - - .section ".zinfo.fixup", "a", @progbits /* Compressor fixups */ - .ascii "APPW" - .long mpciheader_image_length - .long 512 - .long 0 - .ascii "APPW" - .long mpciheader_runtime_length - .long 512 - .long 0 - .previous - -/* Fix up additional image source size - * - */ - .section ".zinfo.fixup", "a", @progbits /* Compressor fixups */ - .ascii "ADPW" - .long extra_size - .long 512 - .long 0 - .previous diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/nbiprefix.S b/qemu/roms/ipxe/src/arch/i386/prefix/nbiprefix.S deleted file mode 100644 index 16c79566c..000000000 --- a/qemu/roms/ipxe/src/arch/i386/prefix/nbiprefix.S +++ /dev/null @@ -1,84 +0,0 @@ -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) - - .text - .arch i386 - .code16 - .section ".prefix", "ax", @progbits - .org 0 - -nbi_header: - -/***************************************************************************** - * NBI file header - ***************************************************************************** - */ -file_header: - .long 0x1b031336 /* Signature */ - .byte 0x04 /* 16 bytes header, no vendor info */ - .byte 0 - .byte 0 - .byte 0 /* No flags */ - .word 0x0000, 0x07c0 /* Load header to 0x07c0:0x0000 */ - .word _nbi_start, 0x07c0 /* Start execution at 0x07c0:entry */ - .size file_header, . - file_header - -/***************************************************************************** - * NBI segment header - ***************************************************************************** - */ -segment_header: - .byte 0x04 /* 16 bytes header, no vendor info */ - .byte 0 - .byte 0 - .byte 0x04 /* Last segment */ - .long 0x00007e00 -imglen: .long -512 -memlen: .long -512 - .size segment_header, . - segment_header - - .section ".zinfo.fixup", "a", @progbits /* Compressor fixups */ - .ascii "ADDL" - .long imglen - .long 1 - .long 0 - .ascii "ADDL" - .long memlen - .long 1 - .long 0 - .previous - -/***************************************************************************** - * NBI entry point - ***************************************************************************** - */ - .globl _nbi_start -_nbi_start: - /* 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: - pushl $main - pushw %cs - call prot_call - popl %ecx /* discard */ - - /* Uninstall iPXE */ - call uninstall - - /* Reboot system */ - int $0x19 - - .previous - .size _nbi_start, . - _nbi_start - -nbi_header_end: - .org 512 diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/nullprefix.S b/qemu/roms/ipxe/src/arch/i386/prefix/nullprefix.S deleted file mode 100644 index bd0ff339e..000000000 --- a/qemu/roms/ipxe/src/arch/i386/prefix/nullprefix.S +++ /dev/null @@ -1,15 +0,0 @@ -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) - - .org 0 - .text - .arch i386 - - .section ".prefix", "ax", @progbits - .code16 -_prefix: - - .section ".text16", "ax", @progbits -prefix_exit: - -prefix_exit_end: - .previous diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/pciromprefix.S b/qemu/roms/ipxe/src/arch/i386/prefix/pciromprefix.S deleted file mode 100644 index 5a5a49647..000000000 --- a/qemu/roms/ipxe/src/arch/i386/prefix/pciromprefix.S +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2014 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 ) - -#define BUSTYPE "PCIR" -#define _rom_start _pcirom_start -#include "romprefix.S" diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/pxeprefix.S b/qemu/roms/ipxe/src/arch/i386/prefix/pxeprefix.S deleted file mode 100644 index 465ce4345..000000000 --- a/qemu/roms/ipxe/src/arch/i386/prefix/pxeprefix.S +++ /dev/null @@ -1,862 +0,0 @@ -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) - -#define PXENV_UNDI_SHUTDOWN 0x0005 -#define PXENV_UNDI_GET_NIC_TYPE 0x0012 -#define PXENV_UNDI_GET_IFACE_INFO 0x0013 -#define PXENV_STOP_UNDI 0x0015 -#define PXENV_UNLOAD_STACK 0x0070 -#define PXENV_GET_CACHED_INFO 0x0071 -#define PXENV_PACKET_TYPE_DHCP_ACK 0x0002 -#define PXENV_FILE_CMDLINE 0x00e8 - -#define PXE_HACK_EB54 0x0001 - - .text - .arch i386 - .org 0 - .code16 - -#include <undi.h> - -#define STACK_MAGIC ( 'L' + ( 'R' << 8 ) + ( 'E' << 16 ) + ( 'T' << 24 ) ) -#define EB_MAGIC_1 ( 'E' + ( 't' << 8 ) + ( 'h' << 16 ) + ( 'e' << 24 ) ) -#define EB_MAGIC_2 ( 'r' + ( 'b' << 8 ) + ( 'o' << 16 ) + ( 'o' << 24 ) ) - -/* Prefix memory layout: - * - * iPXE binary image - * Temporary stack - * Temporary copy of DHCPACK packet - * Temporary copy of command line - */ -#define PREFIX_STACK_SIZE 2048 -#define PREFIX_TEMP_DHCPACK PREFIX_STACK_SIZE -#define PREFIX_TEMP_DHCPACK_SIZE ( 1260 /* sizeof ( BOOTPLAYER_t ) */ ) -#define PREFIX_TEMP_CMDLINE ( PREFIX_TEMP_DHCPACK + PREFIX_TEMP_DHCPACK_SIZE ) -#define PREFIX_TEMP_CMDLINE_SIZE 4096 - -/***************************************************************************** - * Entry point: set operating context, print welcome message - ***************************************************************************** - */ - .section ".prefix", "ax", @progbits - .globl _pxe_start -_pxe_start: - jmp $0x7c0, $1f -1: - /* Preserve registers for possible return to PXE */ - pushfl - pushal - pushw %gs - pushw %fs - pushw %es - pushw %ds - - /* Store magic word on PXE stack and remember PXE %ss:esp */ - pushl $STACK_MAGIC - movw %ss, %cs:pxe_ss - movl %esp, %cs:pxe_esp - - /* Set up segments */ - movw %cs, %ax - movw %ax, %ds - movw $0x40, %ax /* BIOS data segment access */ - movw %ax, %fs - /* Set up temporary stack immediately after the iPXE image */ - movw %cs, %ax - addw image_size_pgh, %ax - movw %ax, %ss - movl $PREFIX_STACK_SIZE, %esp - /* Clear direction flag, for the sake of sanity */ - cld - /* Print welcome message */ - movw $10f, %si - xorw %di, %di - call print_message - .section ".prefix.data", "aw", @progbits -10: .asciz "PXE->EB:" - .previous - - /* Image size (for stack placement calculation) */ - .section ".prefix.data", "aw", @progbits -image_size_pgh: - .word 0 - .previous - .section ".zinfo.fixup", "a", @progbits /* Compressor fixups */ - .ascii "ADDW" - .long image_size_pgh - .long 16 - .long 0 - .previous - -/***************************************************************************** - * Find us a usable !PXE or PXENV+ entry point - ***************************************************************************** - */ -detect_pxe: - /* Plan A: !PXE pointer from the stack */ - lgsl pxe_esp, %ebp /* %gs:%bp -> original stack */ - lesw %gs:52(%bp), %bx - call is_valid_ppxe - je have_ppxe - - /* Plan B: PXENV+ pointer from initial ES:BX */ - movw %gs:32(%bp),%bx - movw %gs:8(%bp),%es - call is_valid_pxenv - je have_pxenv - - /* Plan C: PXENV+ structure via INT 1Ah */ - movw $0x5650, %ax - int $0x1a - jc 1f - cmpw $0x564e, %ax - jne 1f - call is_valid_pxenv - je have_pxenv -1: - /* Plan D: scan base memory for !PXE */ - call memory_scan_ppxe - je have_ppxe - - /* Plan E: scan base memory for PXENV+ */ - call memory_scan_pxenv - jne stack_not_found - -have_pxenv: - movw %bx, pxenv_offset - movw %es, pxenv_segment - - cmpw $0x201, %es:6(%bx) /* API version >= 2.01 */ - jb 1f - cmpb $0x2c, %es:8(%bx) /* ... and structure long enough */ - jb 2f - - lesw %es:0x28(%bx), %bx /* Find !PXE from PXENV+ */ - call is_valid_ppxe - je have_ppxe -2: - call memory_scan_ppxe /* We are *supposed* to have !PXE... */ - je have_ppxe -1: - lesw pxenv_segoff, %bx /* Nope, we're stuck with PXENV+ */ - - /* Record entry point and UNDI segments */ - pushl %es:0x0a(%bx) /* Entry point */ - pushw %es:0x24(%bx) /* UNDI code segment */ - pushw %es:0x26(%bx) /* UNDI code size */ - pushw %es:0x20(%bx) /* UNDI data segment */ - pushw %es:0x22(%bx) /* UNDI data size */ - - /* Print "PXENV+ at <address>" */ - movw $10f, %si - jmp check_have_stack - .section ".prefix.data", "aw", @progbits -10: .asciz " PXENV+ at " - .previous - -have_ppxe: - movw %bx, ppxe_offset - movw %es, ppxe_segment - - pushl %es:0x10(%bx) /* Entry point */ - pushw %es:0x30(%bx) /* UNDI code segment */ - pushw %es:0x36(%bx) /* UNDI code size */ - pushw %es:0x28(%bx) /* UNDI data segment */ - pushw %es:0x2e(%bx) /* UNDI data size */ - - /* Print "!PXE at <address>" */ - movw $10f, %si - jmp check_have_stack - .section ".prefix.data", "aw", @progbits -10: .asciz " !PXE at " - .previous - -is_valid_ppxe: - cmpl $0x45585021, %es:(%bx) - jne 1f - movzbw %es:4(%bx), %cx - cmpw $0x58, %cx - jae is_valid_checksum -1: - ret - -is_valid_pxenv: - cmpl $0x4e455850, %es:(%bx) - jne 1b - cmpw $0x2b56, %es:4(%bx) - jne 1b - movzbw %es:8(%bx), %cx - cmpw $0x28, %cx - jb 1b - -is_valid_checksum: - pushw %ax - movw %bx, %si - xorw %ax, %ax -2: - es lodsb - addb %al, %ah - loopw 2b - popw %ax - ret - -memory_scan_ppxe: - movw $is_valid_ppxe, %dx - jmp memory_scan_common - -memory_scan_pxenv: - movw $is_valid_pxenv, %dx - -memory_scan_common: - movw %fs:(0x13), %ax - shlw $6, %ax - decw %ax -1: incw %ax - cmpw $( 0xa000 - 1 ), %ax - ja 2f - movw %ax, %es - xorw %bx, %bx - call *%dx - jne 1b -2: ret - -/***************************************************************************** - * Sanity check: we must have an entry point - ***************************************************************************** - */ -check_have_stack: - /* Save common values pushed onto the stack */ - popl undi_data_segoff - popl undi_code_segoff - popl entry_segoff - - /* Print have !PXE/PXENV+ message; structure pointer in %es:%bx */ - call print_message - call print_segoff - movb $( ',' ), %al - call print_character - - /* Check for entry point */ - movl entry_segoff, %eax - testl %eax, %eax - jnz 99f - /* No entry point: print message and skip everything else */ -stack_not_found: - movw $10f, %si - call print_message - jmp finished - .section ".prefix.data", "aw", @progbits -10: .asciz " No PXE stack found!\n" - .previous -99: - -/***************************************************************************** - * Calculate base memory usage by UNDI - ***************************************************************************** - */ -find_undi_basemem_usage: - movw undi_code_segment, %ax - movw undi_code_size, %bx - movw undi_data_segment, %cx - movw undi_data_size, %dx - cmpw %ax, %cx - ja 1f - xchgw %ax, %cx - xchgw %bx, %dx -1: /* %ax:%bx now describes the lower region, %cx:%dx the higher */ - shrw $6, %ax /* Round down to nearest kB */ - movw %ax, undi_fbms_start - addw $0x0f, %dx /* Round up to next segment */ - shrw $4, %dx - addw %dx, %cx - addw $((1024 / 16) - 1), %cx /* Round up to next kB */ - shrw $6, %cx - movw %cx, undi_fbms_end - -/***************************************************************************** - * Print information about detected PXE stack - ***************************************************************************** - */ -print_structure_information: - /* Print entry point */ - movw $10f, %si - call print_message - les entry_segoff, %bx - call print_segoff - .section ".prefix.data", "aw", @progbits -10: .asciz " entry point at " - .previous - /* Print UNDI code segment */ - movw $10f, %si - call print_message - les undi_code_segoff, %bx - call print_segoff - .section ".prefix.data", "aw", @progbits -10: .asciz "\n UNDI code segment " - .previous - /* Print UNDI data segment */ - movw $10f, %si - call print_message - les undi_data_segoff, %bx - call print_segoff - .section ".prefix.data", "aw", @progbits -10: .asciz ", data segment " - .previous - /* Print UNDI memory usage */ - movw $10f, %si - call print_message - movw undi_fbms_start, %ax - call print_word - movb $( '-' ), %al - call print_character - movw undi_fbms_end, %ax - call print_word - movw $20f, %si - call print_message - .section ".prefix.data", "aw", @progbits -10: .asciz " (" -20: .asciz "kB)\n" - .previous - -/***************************************************************************** - * Determine physical device - ***************************************************************************** - */ -get_physical_device: - /* Issue PXENV_UNDI_GET_NIC_TYPE */ - movw $PXENV_UNDI_GET_NIC_TYPE, %bx - call pxe_call - jnc 1f - call print_pxe_error - jmp no_physical_device -1: /* Determine physical device type */ - movb ( pxe_parameter_structure + 0x02 ), %al - cmpb $2, %al - je pci_physical_device - jmp no_physical_device - -pci_physical_device: - /* Record PCI bus:dev.fn and vendor/device IDs */ - movl ( pxe_parameter_structure + 0x03 ), %eax - movl %eax, pci_vendor - movw ( pxe_parameter_structure + 0x0b ), %ax - movw %ax, pci_busdevfn - movw $10f, %si - call print_message - call print_pci_busdevfn - jmp 99f - .section ".prefix.data", "aw", @progbits -10: .asciz " UNDI device is PCI " - .previous - -no_physical_device: - /* No device found, or device type not understood */ - movw $10f, %si - call print_message - .section ".prefix.data", "aw", @progbits -10: .asciz " Unable to determine UNDI physical device" - .previous - -99: - -/***************************************************************************** - * Determine interface type - ***************************************************************************** - */ -get_iface_type: - /* Issue PXENV_UNDI_GET_IFACE_INFO */ - movw $PXENV_UNDI_GET_IFACE_INFO, %bx - call pxe_call - jnc 1f - call print_pxe_error - jmp 99f -1: /* Print interface type */ - movw $10f, %si - call print_message - leaw ( pxe_parameter_structure + 0x02 ), %si - call print_message - .section ".prefix.data", "aw", @progbits -10: .asciz ", type " - .previous - /* Check for "Etherboot" interface type */ - cmpl $EB_MAGIC_1, ( pxe_parameter_structure + 0x02 ) - jne 99f - cmpl $EB_MAGIC_2, ( pxe_parameter_structure + 0x06 ) - jne 99f - movw $10f, %si - call print_message - .section ".prefix.data", "aw", @progbits -10: .asciz " (workaround enabled)" - .previous - /* Flag Etherboot workarounds as required */ - orw $PXE_HACK_EB54, pxe_hacks - -99: movb $0x0a, %al - call print_character - -/***************************************************************************** - * Get cached DHCP_ACK packet - ***************************************************************************** - */ -get_dhcpack: - /* Issue PXENV_GET_CACHED_INFO */ - xorl %esi, %esi - movw %ss, %si - movw %si, ( pxe_parameter_structure + 0x08 ) - movw $PREFIX_TEMP_DHCPACK, ( pxe_parameter_structure + 0x06 ) - movw $PREFIX_TEMP_DHCPACK_SIZE, ( pxe_parameter_structure +0x04 ) - movw $PXENV_PACKET_TYPE_DHCP_ACK, ( pxe_parameter_structure + 0x02 ) - movw $PXENV_GET_CACHED_INFO, %bx - call pxe_call - jnc 1f - call print_pxe_error - jmp 99f -1: /* Store physical address of packet */ - shll $4, %esi - addl $PREFIX_TEMP_DHCPACK, %esi - movl %esi, pxe_cached_dhcpack -99: - .section ".prefix.data", "aw", @progbits -pxe_cached_dhcpack: - .long 0 - .previous - -/***************************************************************************** - * Check for a command line - ***************************************************************************** - */ -get_cmdline: - /* Issue PXENV_FILE_CMDLINE */ - xorl %esi, %esi - movw %ss, %si - movw %si, ( pxe_parameter_structure + 0x06 ) - movw $PREFIX_TEMP_CMDLINE, ( pxe_parameter_structure + 0x04 ) - movw $PREFIX_TEMP_CMDLINE_SIZE, ( pxe_parameter_structure + 0x02 ) - movw $PXENV_FILE_CMDLINE, %bx - call pxe_call - jc 99f /* Suppress errors; this is an iPXE extension API call */ - /* Check for non-NULL command line */ - movw ( pxe_parameter_structure + 0x02 ), %ax - testw %ax, %ax - jz 99f - /* Record command line */ - shll $4, %esi - addl $PREFIX_TEMP_CMDLINE, %esi - movl %esi, pxe_cmdline -99: - .section ".prefix.data", "aw", @progbits -pxe_cmdline: - .long 0 - .previous - -/***************************************************************************** - * Leave NIC in a safe state - ***************************************************************************** - */ -#ifndef PXELOADER_KEEP_PXE -shutdown_nic: - /* Issue PXENV_UNDI_SHUTDOWN */ - movw $PXENV_UNDI_SHUTDOWN, %bx - call pxe_call - jnc 1f - call print_pxe_error -1: -unload_base_code: - /* Etherboot treats PXENV_UNLOAD_STACK as PXENV_STOP_UNDI, so - * we must not issue this call if the underlying stack is - * Etherboot and we were not intending to issue a PXENV_STOP_UNDI. - */ -#ifdef PXELOADER_KEEP_UNDI - testw $PXE_HACK_EB54, pxe_hacks - jnz 99f -#endif /* PXELOADER_KEEP_UNDI */ - /* Issue PXENV_UNLOAD_STACK */ - movw $PXENV_UNLOAD_STACK, %bx - call pxe_call - jnc 1f - call print_pxe_error - jmp 99f -1: /* Free base memory used by PXE base code */ - movw undi_fbms_start, %ax - movw %fs:(0x13), %bx - call free_basemem -99: - andw $~( UNDI_FL_INITIALIZED | UNDI_FL_KEEP_ALL ), flags -#endif /* PXELOADER_KEEP_PXE */ - -/***************************************************************************** - * Unload UNDI driver - ***************************************************************************** - */ -#ifndef PXELOADER_KEEP_UNDI -unload_undi: - /* Issue PXENV_STOP_UNDI */ - movw $PXENV_STOP_UNDI, %bx - call pxe_call - jnc 1f - call print_pxe_error - jmp 99f -1: /* Free base memory used by UNDI */ - movw undi_fbms_end, %ax - movw undi_fbms_start, %bx - call free_basemem - /* Clear UNDI_FL_STARTED */ - andw $~UNDI_FL_STARTED, flags -99: -#endif /* PXELOADER_KEEP_UNDI */ - -/***************************************************************************** - * Print remaining free base memory - ***************************************************************************** - */ -print_free_basemem: - movw $10f, %si - call print_message - movw %fs:(0x13), %ax - call print_word - movw $20f, %si - call print_message - .section ".prefix.data", "aw", @progbits -10: .asciz " " -20: .asciz "kB free base memory after PXE unload\n" - .previous - -/***************************************************************************** - * Exit point - ***************************************************************************** - */ -finished: - jmp run_ipxe - -/***************************************************************************** - * Subroutine: print segment:offset address - * - * Parameters: - * %es:%bx : segment:offset address to print - * %ds:di : output buffer (or %di=0 to print to console) - * Returns: - * %ds:di : next character in output buffer (if applicable) - ***************************************************************************** - */ -print_segoff: - /* Preserve registers */ - pushw %ax - /* Print "<segment>:offset" */ - movw %es, %ax - call print_hex_word - movb $( ':' ), %al - call print_character - movw %bx, %ax - call print_hex_word - /* Restore registers and return */ - popw %ax - ret - -/***************************************************************************** - * Subroutine: print decimal word - * - * Parameters: - * %ax : word to print - * %ds:di : output buffer (or %di=0 to print to console) - * Returns: - * %ds:di : next character in output buffer (if applicable) - ***************************************************************************** - */ -print_word: - /* Preserve registers */ - pushw %ax - pushw %bx - pushw %cx - pushw %dx - /* Build up digit sequence on stack */ - movw $10, %bx - xorw %cx, %cx -1: xorw %dx, %dx - divw %bx, %ax - pushw %dx - incw %cx - testw %ax, %ax - jnz 1b - /* Print digit sequence */ -1: popw %ax - call print_hex_nibble - loop 1b - /* Restore registers and return */ - popw %dx - popw %cx - popw %bx - popw %ax - ret - -/***************************************************************************** - * Subroutine: zero 1kB block of base memory - * - * Parameters: - * %bx : block to zero (in kB) - * Returns: - * Nothing - ***************************************************************************** - */ -zero_kb: - /* Preserve registers */ - pushw %ax - pushw %cx - pushw %di - pushw %es - /* Zero block */ - movw %bx, %ax - shlw $6, %ax - movw %ax, %es - movw $0x400, %cx - xorw %di, %di - xorw %ax, %ax - rep stosb - /* Restore registers and return */ - popw %es - popw %di - popw %cx - popw %ax - ret - -/***************************************************************************** - * Subroutine: free and zero base memory - * - * Parameters: - * %ax : Desired new free base memory counter (in kB) - * %bx : Expected current free base memory counter (in kB) - * %fs : BIOS data segment (0x40) - * Returns: - * None - * - * The base memory from %bx kB to %ax kB is unconditionally zeroed. - * It will be freed if and only if the expected current free base - * memory counter (%bx) matches the actual current free base memory - * counter in 0x40:0x13; if this does not match then the memory will - * be leaked. - ***************************************************************************** - */ -free_basemem: - /* Zero base memory */ - pushw %bx -1: cmpw %bx, %ax - je 2f - call zero_kb - incw %bx - jmp 1b -2: popw %bx - /* Free base memory */ - cmpw %fs:(0x13), %bx /* Update FBMS only if "old" value */ - jne 1f /* is correct */ -1: movw %ax, %fs:(0x13) - ret - -/***************************************************************************** - * Subroutine: make a PXE API call. Works with either !PXE or PXENV+ API. - * - * Parameters: - * %bx : PXE API call number - * %ds:pxe_parameter_structure : Parameters for PXE API call - * Returns: - * %ax : PXE status code (not exit code) - * CF set if %ax is non-zero - ***************************************************************************** - */ -pxe_call: - /* Preserve registers */ - pushw %di - pushw %es - /* Set up registers for PXENV+ API. %bx already set up */ - pushw %ds - popw %es - movw $pxe_parameter_structure, %di - /* Set up stack for !PXE API */ - pushw %es - pushw %di - pushw %bx - /* Make the API call */ - lcall *entry_segoff - /* Reset the stack */ - addw $6, %sp - movw pxe_parameter_structure, %ax - clc - testw %ax, %ax - jz 1f - stc -1: /* Clear direction flag, for the sake of sanity */ - cld - /* Restore registers and return */ - popw %es - popw %di - ret - -/***************************************************************************** - * Subroutine: print PXE API call error message - * - * Parameters: - * %ax : PXE status code - * %bx : PXE API call number - * Returns: - * Nothing - ***************************************************************************** - */ -print_pxe_error: - pushw %si - movw $10f, %si - call print_message - xchgw %ax, %bx - call print_hex_word - movw $20f, %si - call print_message - xchgw %ax, %bx - call print_hex_word - movw $30f, %si - call print_message - popw %si - ret - .section ".prefix.data", "aw", @progbits -10: .asciz " UNDI API call " -20: .asciz " failed: status code " -30: .asciz "\n" - .previous - -/***************************************************************************** - * PXE data structures - ***************************************************************************** - */ - .section ".prefix.data" - -pxe_esp: .long 0 -pxe_ss: .word 0 - -pxe_parameter_structure: .fill 64 - -undi_code_segoff: -undi_code_size: .word 0 -undi_code_segment: .word 0 - -undi_data_segoff: -undi_data_size: .word 0 -undi_data_segment: .word 0 - -pxe_hacks: .word 0 - -/* The following fields are part of a struct undi_device */ - -undi_device: - -pxenv_segoff: -pxenv_offset: .word 0 -pxenv_segment: .word 0 - -ppxe_segoff: -ppxe_offset: .word 0 -ppxe_segment: .word 0 - -entry_segoff: -entry_offset: .word 0 -entry_segment: .word 0 - -undi_fbms_start: .word 0 -undi_fbms_end: .word 0 - -pci_busdevfn: .word UNDI_NO_PCI_BUSDEVFN -isapnp_csn: .word UNDI_NO_ISAPNP_CSN -isapnp_read_port: .word UNDI_NO_ISAPNP_READ_PORT - -pci_vendor: .word 0 -pci_device: .word 0 -flags: - .word ( UNDI_FL_INITIALIZED | UNDI_FL_STARTED | UNDI_FL_KEEP_ALL ) - - .equ undi_device_size, ( . - undi_device ) - -/***************************************************************************** - * Run iPXE main code - ***************************************************************************** - */ - .section ".prefix" -run_ipxe: - /* Install iPXE */ - call install - - /* Set up real-mode stack */ - movw %bx, %ss - movw $_estack16, %sp - -#ifdef PXELOADER_KEEP_UNDI - /* Copy our undi_device structure to the preloaded_undi variable */ - movw %bx, %es - movw $preloaded_undi, %di - movw $undi_device, %si - movw $undi_device_size, %cx - rep movsb -#endif - - /* Retrieve PXE %ss:esp */ - movw pxe_ss, %di - movl pxe_esp, %ebp - - /* Retrieve PXE command line, if any */ - movl pxe_cmdline, %esi - - /* Retrieve cached DHCPACK, if any */ - movl pxe_cached_dhcpack, %ecx - - /* Jump to .text16 segment with %ds pointing to .data16 */ - movw %bx, %ds - pushw %ax - pushw $1f - lret - .section ".text16", "ax", @progbits -1: - /* Update the exit hook */ - movw %cs, ( pxe_exit_hook + 2 ) - - /* Store command-line pointer */ - movl %esi, cmdline_phys - - /* Store cached DHCPACK pointer */ - movl %ecx, cached_dhcpack_phys - - /* Run main program */ - pushl $main - pushw %cs - call prot_call - popl %ecx /* discard */ - - /* Uninstall iPXE */ - call uninstall - - /* Restore PXE stack */ - movw %di, %ss - movl %ebp, %esp - - /* Jump to hook if applicable */ - ljmpw *pxe_exit_hook - - .section ".data16", "aw", @progbits - .globl pxe_exit_hook -pxe_exit_hook: - .word exit_ipxe, 0 - .previous - -exit_ipxe: - /* Check PXE stack magic */ - popl %eax - cmpl $STACK_MAGIC, %eax - jne 1f - - /* PXE stack OK: return to caller */ - popw %ds - popw %es - popw %fs - popw %gs - popal - popfl - xorw %ax, %ax /* Return success */ - lret - -1: /* PXE stack corrupt or removed: use INT 18 */ - int $0x18 - .previous diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/romprefix.S b/qemu/roms/ipxe/src/arch/i386/prefix/romprefix.S deleted file mode 100644 index 18dda2b37..000000000 --- a/qemu/roms/ipxe/src/arch/i386/prefix/romprefix.S +++ /dev/null @@ -1,895 +0,0 @@ -/* At entry, the processor is in 16 bit real mode and the code is being - * executed from an address it was not linked to. Code must be pic and - * 32 bit sensitive until things are fixed up. - * - * Also be very careful as the stack is at the rear end of the interrupt - * table so using a noticeable amount of stack space is a no-no. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) - -#include <config/general.h> -#include <config/branding.h> - -#define PNP_SIGNATURE ( '$' + ( 'P' << 8 ) + ( 'n' << 16 ) + ( 'P' << 24 ) ) -#define PMM_SIGNATURE ( '$' + ( 'P' << 8 ) + ( 'M' << 16 ) + ( 'M' << 24 ) ) -#define PCI_SIGNATURE ( 'P' + ( 'C' << 8 ) + ( 'I' << 16 ) + ( ' ' << 24 ) ) -#define STACK_MAGIC ( 'L' + ( 'R' << 8 ) + ( 'E' << 16 ) + ( 'T' << 24 ) ) -#define PMM_ALLOCATE 0x0000 -#define PMM_FIND 0x0001 -#define PMM_HANDLE_BASE ( ( ( 'F' - 'A' + 1 ) << 26 ) + \ - ( ( 'E' - 'A' + 1 ) << 21 ) + \ - ( ( 'N' - 'A' + 1 ) << 16 ) ) -#define PMM_HANDLE_BASE_IMAGE_SOURCE \ - ( PMM_HANDLE_BASE | 0x00001000 ) -#define PMM_HANDLE_BASE_DECOMPRESS_TO \ - ( PMM_HANDLE_BASE | 0x00002000 ) -#define PCI_FUNC_MASK 0x07 - -/* ROM banner timeout, converted to a number of (18Hz) timer ticks. */ -#define ROM_BANNER_TIMEOUT_TICKS ( ( 18 * ROM_BANNER_TIMEOUT ) / 10 ) - -/* Allow payload to be excluded from ROM size - */ -#if ROMPREFIX_EXCLUDE_PAYLOAD -#define ZINFO_TYPE_ADxB "ADHB" -#define ZINFO_TYPE_ADxW "ADHW" -#else -#define ZINFO_TYPE_ADxB "ADDB" -#define ZINFO_TYPE_ADxW "ADDW" -#endif - -/* Allow ROM to be marked as containing multiple images - */ -#if ROMPREFIX_MORE_IMAGES -#define INDICATOR 0x00 -#else -#define INDICATOR 0x80 -#endif - -/* Default to building a PCI ROM if no bus type is specified - */ -#ifndef BUSTYPE -#define BUSTYPE "PCIR" -#endif - - .text - .code16 - .arch i386 - .section ".prefix", "ax", @progbits - .globl _rom_start -_rom_start: - - .org 0x00 -romheader: - .word 0xAA55 /* BIOS extension signature */ -romheader_size: .byte 0 /* Size in 512-byte blocks */ - jmp init /* Initialisation vector */ -checksum: - .byte 0 - .org 0x10 - .word ipxeheader - .org 0x16 - .word undiheader -.ifeqs BUSTYPE, "PCIR" - .org 0x18 - .word pciheader -.endif - .org 0x1a - .word pnpheader - .size romheader, . - romheader - - .section ".zinfo.fixup", "a", @progbits /* Compressor fixups */ - .ascii ZINFO_TYPE_ADxB - .long romheader_size - .long 512 - .long 0 - .previous - -.ifeqs BUSTYPE, "PCIR" -pciheader: - .ascii "PCIR" /* Signature */ - .word pci_vendor_id /* Vendor identification */ - .word pci_device_id /* Device identification */ - .word ( pci_devlist - pciheader ) /* Device list pointer */ - .word pciheader_len /* PCI data structure length */ - .byte 0x03 /* PCI data structure revision */ - .byte 0x02, 0x00, 0x00 /* Class code */ -pciheader_image_length: - .word 0 /* Image length */ - .word 0x0001 /* Revision level */ - .byte 0x00 /* Code type */ - .byte INDICATOR /* Last image indicator */ -pciheader_runtime_length: - .word 0 /* Maximum run-time image length */ - .word 0x0000 /* Configuration utility code header */ - .word 0x0000 /* DMTF CLP entry point */ - .equ pciheader_len, . - pciheader - .size pciheader, . - pciheader - - /* PCI additional device list (filled in by linker) */ - .section ".pci_devlist.00000000", "a", @progbits -pci_devlist: - .previous - .section ".pci_devlist.ffffffff", "a", @progbits -pci_devlist_end: - .short 0x0000 /* List terminator */ - .previous - /* Ensure that terminator is always present */ - .reloc pciheader, RELOC_TYPE_NONE, pci_devlist_end - - .section ".zinfo.fixup", "a", @progbits /* Compressor fixups */ - .ascii ZINFO_TYPE_ADxW - .long pciheader_image_length - .long 512 - .long 0 - .ascii ZINFO_TYPE_ADxW - .long pciheader_runtime_length - .long 512 - .long 0 - .previous -.endif /* PCIR */ - - /* PnP doesn't require any particular alignment, but IBM - * BIOSes will scan on 16-byte boundaries rather than using - * the offset stored at 0x1a - */ - .align 16 -pnpheader: - .ascii "$PnP" /* Signature */ - .byte 0x01 /* Structure revision */ - .byte ( pnpheader_len / 16 ) /* Length (in 16 byte increments) */ - .word 0x0000 /* Offset of next header */ - .byte 0x00 /* Reserved */ - .byte 0x00 /* Checksum */ - .long 0x00000000 /* Device identifier */ - .word mfgstr /* Manufacturer string */ - .word prodstr /* Product name */ - .byte 0x02 /* Device base type code */ - .byte 0x00 /* Device sub-type code */ - .byte 0x00 /* Device interface type code */ - .byte 0xf4 /* Device indicator */ - .word 0x0000 /* Boot connection vector */ - .word 0x0000 /* Disconnect vector */ - .word bev_entry /* Boot execution vector */ - .word 0x0000 /* Reserved */ - .word 0x0000 /* Static resource information vector*/ - .equ pnpheader_len, . - pnpheader - .size pnpheader, . - pnpheader - -/* Manufacturer string */ -mfgstr: - .asciz "http://ipxe.org" - .size mfgstr, . - mfgstr - -/* Product string - * - * Defaults to PRODUCT_SHORT_NAME. If the ROM image is writable at - * initialisation time, it will be filled in to include the PCI - * bus:dev.fn number of the card as well. - */ -prodstr: - .ascii PRODUCT_SHORT_NAME -.ifeqs BUSTYPE, "PCIR" -prodstr_separator: - .byte 0 - .ascii "(PCI " -prodstr_pci_id: - .ascii "xx:xx.x)" /* Filled in by init code */ -.endif /* PCIR */ - .byte 0 - .size prodstr, . - prodstr - - .globl undiheader - .weak undiloader -undiheader: - .ascii "UNDI" /* Signature */ - .byte undiheader_len /* Length of structure */ - .byte 0 /* Checksum */ - .byte 0 /* Structure revision */ - .byte 0,1,2 /* PXE version: 2.1.0 */ - .word undiloader /* Offset to loader routine */ - .word _data16_memsz /* Stack segment size */ - .word _data16_memsz /* Data segment size */ - .word _text16_memsz /* Code segment size */ - .ascii BUSTYPE /* Bus type */ - .equ undiheader_len, . - undiheader - .size undiheader, . - undiheader - -ipxeheader: - .ascii "iPXE" /* Signature */ - .byte ipxeheader_len /* Length of structure */ - .byte 0 /* Checksum */ -shrunk_rom_size: - .byte 0 /* Shrunk size (in 512-byte blocks) */ - .byte 0 /* Reserved */ -build_id: - .long _build_id /* Randomly-generated build ID */ - .equ ipxeheader_len, . - ipxeheader - .size ipxeheader, . - ipxeheader - - .section ".zinfo.fixup", "a", @progbits /* Compressor fixups */ - .ascii "ADHB" - .long shrunk_rom_size - .long 512 - .long 0 - .previous - -/* Initialisation (called once during POST) - * - * Determine whether or not this is a PnP system via a signature - * check. If it is PnP, return to the PnP BIOS indicating that we are - * a boot-capable device; the BIOS will call our boot execution vector - * if it wants to boot us. If it is not PnP, hook INT 19. - */ -init: - /* Preserve registers, clear direction flag, set %ds=%cs */ - pushaw - pushw %ds - pushw %es - pushw %fs - pushw %gs - cld - pushw %cs - popw %ds - - /* Print message as early as possible */ - movw $init_message, %si - xorw %di, %di - call print_message - - /* Store PCI 3.0 runtime segment address for later use, if - * applicable. - */ -.ifeqs BUSTYPE, "PCIR" - movw %bx, %gs -.endif - - /* Store PCI bus:dev.fn address, print PCI bus:dev.fn, and add - * PCI bus:dev.fn to product name string, if applicable. - */ -.ifeqs BUSTYPE, "PCIR" - xorw %di, %di - call print_space - movw %ax, init_pci_busdevfn - call print_pci_busdevfn - movw $prodstr_pci_id, %di - call print_pci_busdevfn - movb $( ' ' ), prodstr_separator -.endif - - /* Print segment address */ - xorw %di, %di - call print_space - movw %cs, %ax - call print_hex_word - - /* Check for PCI BIOS version, if applicable */ -.ifeqs BUSTYPE, "PCIR" - pushl %ebx - pushl %edx - pushl %edi - stc - movw $0xb101, %ax - int $0x1a - jc no_pci3 - cmpl $PCI_SIGNATURE, %edx - jne no_pci3 - testb %ah, %ah - jnz no_pci3 - movw $init_message_pci, %si - xorw %di, %di - call print_message - movb %bh, %al - call print_hex_nibble - movb $( '.' ), %al - call print_character - movb %bl, %al - call print_hex_byte - cmpb $3, %bh - jb no_pci3 - /* PCI >=3.0: leave %gs as-is if sane */ - movw %gs, %ax - cmpw $0xa000, %ax /* Insane if %gs < 0xa000 */ - jb pci3_insane - movw %cs, %bx /* Sane if %cs == %gs */ - cmpw %bx, %ax - je 1f - movzbw romheader_size, %cx /* Sane if %cs+len <= %gs */ - shlw $5, %cx - addw %cx, %bx - cmpw %bx, %ax - jae 1f - movw %cs, %bx /* Sane if %gs+len <= %cs */ - addw %cx, %ax - cmpw %bx, %ax - jbe 1f -pci3_insane: /* PCI 3.0 with insane %gs value: print error and ignore %gs */ - movb $( '!' ), %al - call print_character - movw %gs, %ax - call print_hex_word -no_pci3: - /* PCI <3.0: set %gs (runtime segment) = %cs (init-time segment) */ - pushw %cs - popw %gs -1: popl %edi - popl %edx - popl %ebx -.endif /* PCIR */ - - /* Check for PnP BIOS. Although %es:di should point to the - * PnP BIOS signature on entry, some BIOSes fail to do this. - */ - movw $( 0xf000 - 1 ), %bx -pnp_scan: - incw %bx - jz no_pnp - movw %bx, %es - cmpl $PNP_SIGNATURE, %es:0 - jne pnp_scan - xorw %dx, %dx - xorw %si, %si - movzbw %es:5, %cx -1: es lodsb - addb %al, %dl - loop 1b - jnz pnp_scan - /* Is PnP: print PnP message */ - movw $init_message_pnp, %si - xorw %di, %di - call print_message - jmp pnp_done -no_pnp: /* Not PnP-compliant - hook INT 19 */ -#ifdef NONPNP_HOOK_INT19 - movw $init_message_int19, %si - xorw %di, %di - call print_message - xorw %ax, %ax - movw %ax, %es - pushl %es:( 0x19 * 4 ) - popl orig_int19 - pushw %gs /* %gs contains runtime %cs */ - pushw $int19_entry - popl %es:( 0x19 * 4 ) -#endif /* NONPNP_HOOK_INT19 */ -pnp_done: - - /* Check for PMM */ - movw $( 0xe000 - 1 ), %bx -pmm_scan: - incw %bx - jz no_pmm - movw %bx, %es - cmpl $PMM_SIGNATURE, %es:0 - jne pmm_scan - xorw %dx, %dx - xorw %si, %si - movzbw %es:5, %cx -1: es lodsb - addb %al, %dl - loop 1b - jnz pmm_scan - /* PMM found: print PMM message */ - movw $init_message_pmm, %si - xorw %di, %di - call print_message - /* We have PMM and so a 1kB stack: preserve whole registers */ - pushal - /* Allocate image source PMM block. Round up the size to the - * nearest 4kB (8 512-byte sectors) to work around AMI BIOS bugs. - */ - movzbl romheader_size, %ecx - addw extra_size, %cx - addw $0x0007, %cx /* Round up to multiple of 8 512-byte sectors */ - andw $0xfff8, %cx - shll $5, %ecx - movl $PMM_HANDLE_BASE_IMAGE_SOURCE, %ebx - movw $get_pmm_image_source, %bp - call get_pmm - movl %esi, image_source - jz 1f - /* Copy ROM to image source PMM block */ - pushw %es - xorw %ax, %ax - movw %ax, %es - movl %esi, %edi - xorl %esi, %esi - movzbl romheader_size, %ecx - shll $7, %ecx - addr32 rep movsl /* PMM presence implies flat real mode */ - popw %es - /* Shrink ROM */ - movb shrunk_rom_size, %al - movb %al, romheader_size -1: /* Allocate decompression PMM block. Round up the size to the - * nearest 128kB and use the size within the PMM handle; this - * allows the same decompression area to be shared between - * multiple iPXE ROMs even with differing build IDs - */ - movl $_textdata_memsz_pgh, %ecx - addl $0x00001fff, %ecx - andl $0xffffe000, %ecx - movl %ecx, %ebx - shrw $12, %bx - orl $PMM_HANDLE_BASE_DECOMPRESS_TO, %ebx - movw $get_pmm_decompress_to, %bp - call get_pmm - movl %esi, decompress_to - /* Restore registers */ - popal -no_pmm: - - /* Update checksum */ - xorw %bx, %bx - xorw %si, %si - movzbw romheader_size, %cx - shlw $9, %cx -1: lodsb - addb %al, %bl - loop 1b - subb %bl, checksum - - /* Copy self to option ROM space, if applicable. Required for - * PCI3.0, which loads us to a temporary location in low - * memory. Will be a no-op for lower PCI versions. - */ -.ifeqs BUSTYPE, "PCIR" - xorw %di, %di - call print_space - movw %gs, %ax - call print_hex_word - movzbw romheader_size, %cx - shlw $9, %cx - movw %ax, %es - xorw %si, %si - xorw %di, %di - cs rep movsb -.endif - - /* Skip prompt if this is not the first PCI function, if applicable */ -.ifeqs BUSTYPE, "PCIR" - testb $PCI_FUNC_MASK, init_pci_busdevfn - jnz no_shell -.endif - /* Prompt for POST-time shell */ - movw $init_message_prompt, %si - xorw %di, %di - call print_message - movw $prodstr, %si - call print_message - movw $init_message_dots, %si - call print_message - /* Wait for Ctrl-B */ - movw $0xff02, %bx - call wait_for_key - /* Clear prompt */ - pushf - xorw %di, %di - call print_kill_line - movw $init_message_done, %si - call print_message - popf - jnz no_shell - /* Ctrl-B was pressed: invoke iPXE. The keypress will be - * picked up by the initial shell prompt, and we will drop - * into a shell. - */ - xorl %ebp, %ebp /* Inhibit use of INT 15,e820 and INT 15,e801 */ - pushw %cs - call exec -no_shell: - movb $( '\n' ), %al - xorw %di, %di - call print_character - - /* Restore registers */ - popw %gs - popw %fs - popw %es - popw %ds - popaw - - /* Indicate boot capability to PnP BIOS, if present */ - movw $0x20, %ax - lret - .size init, . - init - -/* Attempt to find or allocate PMM block - * - * Parameters: - * %ecx : size of block to allocate, in paragraphs - * %ebx : PMM handle base - * %bp : routine to check acceptability of found blocks - * %es:0000 : PMM structure - * Returns: - * %ebx : PMM handle - * %esi : allocated block address, or zero (with ZF set) if allocation failed - */ -get_pmm: - /* Preserve registers */ - pushl %eax - pushw %di - movw $( ' ' ), %di -get_pmm_find: - /* Try to find existing block */ - pushl %ebx /* PMM handle */ - pushw $PMM_FIND - lcall *%es:7 - addw $6, %sp - pushw %dx - pushw %ax - popl %esi - /* Treat 0xffffffff (not supported) as 0x00000000 (not found) */ - incl %esi - jz get_pmm_allocate - decl %esi - jz get_pmm_allocate - /* Block found - check acceptability */ - call *%bp - jnc get_pmm_done - /* Block not acceptable - increment handle and retry */ - incl %ebx - jmp get_pmm_find -get_pmm_allocate: - /* Block not found - try to allocate new block */ - pushw $0x0002 /* Extended memory */ - pushl %ebx /* PMM handle */ - pushl %ecx /* Length */ - pushw $PMM_ALLOCATE - lcall *%es:7 - addw $12, %sp - pushw %dx - pushw %ax - popl %esi - movw $( '+' ), %di /* Indicate allocation attempt */ -get_pmm_done: - /* Print block address */ - movw %di, %ax - xorw %di, %di - call print_character - movl %esi, %eax - call print_hex_dword - /* Treat 0xffffffff (not supported) as 0x00000000 (allocation - * failed), and set ZF to indicate a zero result. - */ - incl %esi - jz 1f - decl %esi -1: /* Restore registers and return */ - popw %di - popl %eax - ret - .size get_pmm, . - get_pmm - - /* Check acceptability of image source block */ -get_pmm_image_source: - pushw %es - xorw %ax, %ax - movw %ax, %es - movl build_id, %eax - addr32 cmpl %es:build_id(%esi), %eax - je 1f - stc -1: popw %es - ret - .size get_pmm_image_source, . - get_pmm_image_source - - /* Check acceptability of decompression block */ -get_pmm_decompress_to: - clc - ret - .size get_pmm_decompress_to, . - get_pmm_decompress_to - -/* - * Note to hardware vendors: - * - * If you wish to brand this boot ROM, please do so by defining the - * strings PRODUCT_NAME and PRODUCT_SHORT_NAME in config/branding.h. - * - * While nothing in the GPL prevents you from removing all references - * to iPXE or http://ipxe.org, we prefer you not to do so. - * - * If you have an OEM-mandated branding requirement that cannot be - * satisfied simply by defining PRODUCT_NAME and PRODUCT_SHORT_NAME, - * please contact us. - * - * [ Including an ASCII NUL in PRODUCT_NAME is considered to be - * bypassing the spirit of this request! ] - */ -init_message: - .ascii "\n" - .ascii PRODUCT_NAME - .ascii "\n" - .ascii PRODUCT_SHORT_NAME - .ascii " (" - .ascii PRODUCT_URI - .asciz ")" - .size init_message, . - init_message -.ifeqs BUSTYPE, "PCIR" -init_message_pci: - .asciz " PCI" - .size init_message_pci, . - init_message_pci -.endif /* PCIR */ -init_message_pnp: - .asciz " PnP" - .size init_message_pnp, . - init_message_pnp -init_message_pmm: - .asciz " PMM" - .size init_message_pmm, . - init_message_pmm -init_message_int19: - .asciz " INT19" - .size init_message_int19, . - init_message_int19 -init_message_prompt: - .asciz "\nPress Ctrl-B to configure " - .size init_message_prompt, . - init_message_prompt -init_message_dots: - .asciz "..." - .size init_message_dots, . - init_message_dots -init_message_done: - .asciz "\n\n" - .size init_message_done, . - init_message_done - -/* PCI bus:dev.fn - * - */ -.ifeqs BUSTYPE, "PCIR" -init_pci_busdevfn: - .word 0 - .size init_pci_busdevfn, . - init_pci_busdevfn -.endif /* PCIR */ - -/* Image source area - * - * May be either zero (indicating to use option ROM space as source), - * or within a PMM-allocated block. - */ - .globl image_source -image_source: - .long 0 - .size image_source, . - image_source - -/* Additional image source size (in 512-byte sectors) - * - */ -extra_size: - .word 0 - .size extra_size, . - extra_size - -/* Temporary decompression area - * - * May be either zero (indicating to use default decompression area in - * high memory), or within a PMM-allocated block. - */ - .globl decompress_to -decompress_to: - .long 0 - .size decompress_to, . - decompress_to - -/* Boot Execution Vector entry point - * - * Called by the PnP BIOS when it wants to boot us. - */ -bev_entry: - orl $0xffffffff, %ebp /* Allow arbitrary relocation */ - pushw %cs - call exec - lret - .size bev_entry, . - bev_entry - -/* INT19 entry point - * - * Called via the hooked INT 19 if we detected a non-PnP BIOS. We - * attempt to return via the original INT 19 vector (if we were able - * to store it). - */ -int19_entry: - pushw %cs - popw %ds - /* Prompt user to press B to boot */ - movw $int19_message_prompt, %si - xorw %di, %di - call print_message - movw $prodstr, %si - call print_message - movw $int19_message_dots, %si - call print_message - movw $0xdf4e, %bx - call wait_for_key - pushf - xorw %di, %di - call print_kill_line - movw $int19_message_done, %si - call print_message - popf - jz 1f - /* Leave keypress in buffer and start iPXE. The keypress will - * cause the usual initial Ctrl-B prompt to be skipped. - */ - orl $0xffffffff, %ebp /* Allow arbitrary relocation */ - pushw %cs - call exec -1: /* Try to call original INT 19 vector */ - movl %cs:orig_int19, %eax - testl %eax, %eax - je 2f - ljmp *%cs:orig_int19 -2: /* No chained vector: issue INT 18 as a last resort */ - int $0x18 - .size int19_entry, . - int19_entry -orig_int19: - .long 0 - .size orig_int19, . - orig_int19 - -int19_message_prompt: - .asciz "Press N to skip booting from " - .size int19_message_prompt, . - int19_message_prompt -int19_message_dots: - .asciz "..." - .size int19_message_dots, . - int19_message_dots -int19_message_done: - .asciz "\n\n" - .size int19_message_done, . - int19_message_done - -/* Execute as a boot device - * - */ -exec: /* Set %ds = %cs */ - pushw %cs - popw %ds - - /* Print message as soon as possible */ - movw $prodstr, %si - xorw %di, %di - call print_message - movw $exec_message_pre_install, %si - call print_message - - /* Store magic word on BIOS stack and remember BIOS %ss:sp */ - pushl $STACK_MAGIC - movw %ss, %cx - movw %sp, %dx - - /* Obtain a reasonably-sized temporary stack */ - xorw %bx, %bx - movw %bx, %ss - movw $0x7c00, %sp - - /* Install iPXE */ - call alloc_basemem - movl image_source, %esi - movl decompress_to, %edi - call install_prealloc - - /* Print message indicating successful installation */ - movw $exec_message_post_install, %si - xorw %di, %di - call print_message - - /* 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: - /* Retrieve PCI bus:dev.fn, if applicable */ -.ifeqs BUSTYPE, "PCIR" - movw init_pci_busdevfn, %ax -.endif - - /* Set up %ds for access to .data16 */ - movw %bx, %ds - - /* Store PCI bus:dev.fn, if applicable */ -.ifeqs BUSTYPE, "PCIR" -#ifdef AUTOBOOT_ROM_FILTER - movw %ax, autoboot_busdevfn -#endif /* AUTOBOOT_ROM_FILTER */ -.endif - - /* Call main() */ - pushl $main - pushw %cs - call prot_call - popl %eax /* discard */ - - /* Set up flat real mode for return to BIOS */ - call flatten_real_mode - - /* Uninstall iPXE */ - call uninstall - - /* Restore BIOS stack */ - movw %cx, %ss - movw %dx, %sp - - /* Check magic word on BIOS stack */ - popl %eax - cmpl $STACK_MAGIC, %eax - jne 1f - /* BIOS stack OK: return to caller */ - lret -1: /* BIOS stack corrupt: use INT 18 */ - int $0x18 - .previous - -exec_message_pre_install: - .asciz " starting execution..." - .size exec_message_pre_install, . - exec_message_pre_install -exec_message_post_install: - .asciz "ok\n" - .size exec_message_post_install, . - exec_message_post_install - -/* Wait for key press specified by %bl (masked by %bh) - * - * Used by init and INT19 code when prompting user. If the specified - * key is pressed, it is left in the keyboard buffer. - * - * Returns with ZF set iff specified key is pressed. - */ -wait_for_key: - /* Preserve registers */ - pushw %cx - pushw %ax -1: /* Empty the keyboard buffer before waiting for input */ - movb $0x01, %ah - int $0x16 - jz 2f - xorw %ax, %ax - int $0x16 - jmp 1b -2: /* Wait for a key press */ - movw $ROM_BANNER_TIMEOUT_TICKS, %cx -3: decw %cx - js 99f /* Exit with ZF clear */ - /* Wait for timer tick to be updated */ - call wait_for_tick - /* Check to see if a key was pressed */ - movb $0x01, %ah - int $0x16 - jz 3b - /* Check to see if key was the specified key */ - andb %bh, %al - cmpb %al, %bl - je 99f /* Exit with ZF set */ - /* Not the specified key: remove from buffer and stop waiting */ - pushfw - xorw %ax, %ax - int $0x16 - popfw /* Exit with ZF clear */ -99: /* Restore registers and return */ - popw %ax - popw %cx - ret - .size wait_for_key, . - wait_for_key - -/* Wait for timer tick - * - * Used by wait_for_key - */ -wait_for_tick: - pushl %eax - pushw %fs - movw $0x40, %ax - movw %ax, %fs - movl %fs:(0x6c), %eax -1: pushf - sti - hlt - popf - cmpl %fs:(0x6c), %eax - je 1b - popw %fs - popl %eax - ret - .size wait_for_tick, . - wait_for_tick - -/* Drag in objects via _rom_start */ -REQUIRING_SYMBOL ( _rom_start ) - -/* Drag in ROM configuration */ -REQUIRE_OBJECT ( config_romprefix ) diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/undiloader.S b/qemu/roms/ipxe/src/arch/i386/prefix/undiloader.S deleted file mode 100644 index 5cace44b7..000000000 --- a/qemu/roms/ipxe/src/arch/i386/prefix/undiloader.S +++ /dev/null @@ -1,54 +0,0 @@ -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) - - .text - .code16 - .arch i386 - .section ".prefix", "ax", @progbits - -/* UNDI loader - * - * Called by an external program to load our PXE stack. - */ - .globl undiloader -undiloader: - /* Save registers */ - pushl %esi - pushl %edi - pushl %ebp - pushw %ds - pushw %es - pushw %bx - /* ROM segment address to %ds */ - pushw %cs - popw %ds - /* UNDI loader parameter structure address into %es:%di */ - movw %sp, %bx - movw %ss:22(%bx), %di - movw %ss:24(%bx), %es - /* Install to specified real-mode addresses */ - pushw %di - movw %es:12(%di), %bx - movw %es:14(%di), %ax - movl image_source, %esi - movl decompress_to, %edi - orl $0xffffffff, %ebp /* Allow arbitrary relocation */ - call install_prealloc - popw %di - /* Call UNDI loader C code */ - pushl $pxe_loader_call - pushw %cs - pushw $1f - pushw %ax - pushw $prot_call - lret -1: popw %bx /* discard */ - popw %bx /* discard */ - /* Restore registers and return */ - popw %bx - popw %es - popw %ds - popl %ebp - popl %edi - popl %esi - lret - .size undiloader, . - undiloader diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/unlzma.S b/qemu/roms/ipxe/src/arch/i386/prefix/unlzma.S deleted file mode 100644 index 8d4b3c1a8..000000000 --- a/qemu/roms/ipxe/src/arch/i386/prefix/unlzma.S +++ /dev/null @@ -1,942 +0,0 @@ -/* - * Copyright (C) 2015 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 (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 ); - -/**************************************************************************** - * - * This file provides the decompress() and decompress16() functions - * which can be called in order to decompress an LZMA-compressed - * image. The code is modelled on the public-domain "XZ Embedded" - * implementation as used by the Linux kernel. Symbol names are - * chosen to match the XZ Embedded implementation where possible, for - * ease of reference. - * - * This code is optimised for size rather than speed, since the amount - * of data to be decompressed is trivially small by modern standards. - * - * The same basic assembly code is used to compile both decompress() - * and decompress16(). - * - * Note that these functions require large amounts of stack space. - * - **************************************************************************** - */ - - .text - .arch i586 - .section ".prefix.lib", "ax", @progbits - -#ifdef CODE16 -#define ADDR16 -#define ADDR32 addr32 -#define decompress decompress16 - .code16 -#else /* CODE16 */ -#define ADDR16 addr16 -#define ADDR32 - .code32 -#endif /* CODE16 */ - -/**************************************************************************** - * Debugging - **************************************************************************** - * - * This code will usually run in 16-bit protected mode, in which case - * only the 0xe9 debug port (present on some virtual machines) can be - * used. - * - * To debug on real hardware, build with DEBUG=libprefix. This will - * cause this code to be called in flat real mode, and so DEBUG_INT10 - * may be used. - */ - -/* Enable debugging via 0xe9 debug port */ -#define DEBUG_E9 0 - -/* Enable debugging via BIOS INT 10 (works only when in flat real mode) */ -#define DEBUG_INT10 0 - -#if ( DEBUG_E9 || DEBUG_INT10 ) - .macro print_character, reg - pushfl - pushw %ax - pushw %bx - pushw %bp - movb \reg, %al - movw $0x0007, %bx - movb $0x0e, %ah -#if DEBUG_E9 - outb %al, $0xe9 -#endif -#if DEBUG_INT10 - cmpb $('\n'), %al - jne L\@ - int $0x10 - movb $('\r'), %al -L\@: int $0x10 -#endif - popw %bp - popw %bx - popw %ax - popfl - .endm - - .macro print_hex_nibble - pushfl - pushw %ax - cmpb $10, %al - sbb $0x69, %al - das - print_character %al - popw %ax - popfl - .endm - - .macro print_hex_byte, reg - pushfl - pushw %ax - movb \reg, %al - pushw %ax - shrb $4, %al - print_hex_nibble - popw %ax - andb $0x0f, %al - print_hex_nibble - popw %ax - popfl - .endm - - .macro print_hex_word, reg - pushw %ax - movw \reg, %ax - print_hex_byte %ah - print_hex_byte %al - popw %ax - .endm - - .macro print_hex_dword, reg - pushl %eax - movl \reg, %eax - rorl $16, %eax - print_hex_word %ax - rorl $16, %eax - print_hex_word %ax - popl %eax - .endm -#else - .macro print_character, char - .endm - .macro print_hex_byte, reg - .endm - .macro print_hex_word, reg - .endm - .macro print_hex_dword, reg - .endm -#endif - -/**************************************************************************** - * LZMA parameters and data structures - **************************************************************************** - */ - -/* LZMA decompressor states (as used in XZ Embedded) */ -#define STATE_LIT_LIT 0x00 -#define STATE_MATCH_LIT_LIT 0x01 -#define STATE_REP_LIT_LIT 0x02 -#define STATE_SHORTREP_LIT_LIT 0x03 -#define STATE_MATCH_LIT 0x04 -#define STATE_REP_LIT 0x05 -#define STATE_SHORTREP_LIT 0x06 -#define STATE_LIT_MATCH 0x07 -#define STATE_LIT_LONGREP 0x08 -#define STATE_LIT_SHORTREP 0x09 -#define STATE_NONLIT_MATCH 0x0a -#define STATE_NONLIT_REP 0x0b - -/* LZMA maximum decompressor state in which most recent symbol was a literal */ -#define STATE_LIT_MAX 0x06 - -/* LZMA number of literal context bits ("lc=" parameter) */ -#define LZMA_LC 2 - - .struct 0 -lzma_len_dec: -choice: .word 0 -choice2: .word 0 -low: .rept ( 1 << 3 ) - .word 0 - .endr -mid: .rept ( 1 << 3 ) - .word 0 - .endr -high: .rept ( 1 << 8 ) - .word 0 - .endr - .equ sizeof__lzma_len_dec, . - lzma_len_dec - .previous - - .struct 0 -lzma_dec: -out_start: .long 0 -rc_code: .long 0 -rc_range: .long 0 -len: .word 0 -reps: -rep0: .long 0 -rep1: .long 0 -rep2: .long 0 -rep3: .long 0 -probs: -is_match: .word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -is_rep: .word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -is_rep0: .word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -is_rep1: .word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -is_rep2: .word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -is_rep0_long: .word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -dist_slot: .rept ( 4 * ( 1 << 6 ) ) - .word 0 - .endr -dist_special: .rept ( ( 1 << ( 14 / 2 ) ) - 14 ) - .word 0 - .endr -dist_align: .rept ( 1 << 4 ) - .word 0 - .endr -match_len_dec: .space sizeof__lzma_len_dec -rep_len_dec: .space sizeof__lzma_len_dec -literal: .rept ( ( 1 << LZMA_LC ) * 0x300 ) - .word 0 - .endr - .align 4 - .equ sizeof__lzma_dec, . - lzma_dec - .previous - - /* Some binutils versions seem not to handle .struct/.previous */ - .section ".prefix.lib", "ax", @progbits - -/***************************************************************************** - * Normalise range encoder - * - * Parameters: - * %ss:%ebp : LZMA parameter block - * %ds:%esi : compressed input data pointer - * Returns: - * %ds:%esi : compressed input data pointer (possibly updated) - * %eax : current range - ***************************************************************************** - */ -rc_normalise: - /* Check if rc_range is less than 1<<24 */ - testb $0xff, (rc_range+3)(%ebp) - jnz 1f - /* If it is, shift in a new byte from the compressed input data */ - shll $8, rc_range(%ebp) - shll $8, rc_code(%ebp) - ADDR32 lodsb - movb %al, (rc_code+0)(%ebp) -1: /* Return current range */ - movl rc_range(%ebp), %eax - ret - .size rc_normalise, . - rc_normalise - -/***************************************************************************** - * Decode single range-encoded bit using a probability estimate - * - * Parameters: - * %ss:%ebp : LZMA parameter block - * %ds:%esi : compressed input data pointer - * %ebx : probability estimate pointer (offset from %ebp) - * Returns: - * %ds:%esi : compressed input data pointer (possibly updated) - * CF : decoded bit - * ZF : inverse of decoded bit - * Corrupts: - * none - ***************************************************************************** - */ -rc_bit: - /* Preserve registers */ - pushl %eax - pushl %edx - /* Perform normalisation */ - call rc_normalise - /* Calculate bound in %eax and probability estimate in %dx */ - shrl $11, %eax - movzwl (%ebp,%ebx), %edx - mul %edx /* will zero %edx */ - movw (%ebp,%ebx), %dx - /* Compare code against bound */ - cmpl %eax, rc_code(%ebp) - jae 2f -1: /* Code is less than bound */ - movl %eax, rc_range(%ebp) - negw %dx - addw $(1<<11), %dx - shrw $5, %dx - addw %dx, (%ebp,%ebx) - xorw %ax, %ax /* Clear CF, set ZF */ - jmp 99f -2: /* Code is greater than or equal to bound */ - subl %eax, rc_range(%ebp) - subl %eax, rc_code(%ebp) - shrw $5, %dx - subw %dx, (%ebp,%ebx) - incw %dx /* Clear ZF (%dx is 11-bit; can never wrap) */ - stc /* Set CF */ -99: /* Restore registers and return */ - popl %edx - popl %eax - ret - .size rc_bit, . - rc_bit - -/***************************************************************************** - * Decode MSB-first bittree - * - * Parameters: - * %ss:%ebp : LZMA parameter block - * %ds:%esi : compressed input data pointer - * %ebx : probability estimate set pointer (offset from %ebp) - * %cx : number of bits to decode - * Returns: - * %ds:%esi : compressed input data pointer (possibly updated) - * %eax : decoded bittree - * Corrupts: - * none - ***************************************************************************** - */ -rc_bittree: - /* Preserve registers */ - pushl %edi - pushw %cx - movl %ebx, %edi - /* Initialise registers */ - movl $1, %eax -1: /* Decode bit */ - leaw (%edi,%eax,2), %bx /* high word always zero anyway */ - call rc_bit - rclw %ax - ADDR16 loop 1b - /* Restore registers, clear unwanted high bit of result, and return */ - movl %edi, %ebx - popw %cx - popl %edi - btrw %cx, %ax - ret - .size rc_bittree, . - rc_bittree - -/***************************************************************************** - * Decode LSB-first bittree - * - * Parameters: - * %ss:%ebp : LZMA parameter block - * %ds:%esi : compressed input data pointer - * %ebx : probability estimate set pointer (offset from %ebp) - * %cx : number of bits to decode - * Returns: - * %ds:%esi : compressed input data pointer (possibly updated) - * %eax : decoded bittree - * Corrupts: - * none - ***************************************************************************** - */ -rc_bittree_reverse: - /* Preserve registers */ - pushw %cx - /* Decode bittree */ - call rc_bittree -1: /* Reverse result */ - rcrb %al - rclb %ah - ADDR16 loop 1b - shrw $8, %ax - /* Restore registers and return */ - popw %cx - ret - .size rc_bittree_reverse, . - rc_bittree_reverse - -/***************************************************************************** - * Decode MSB-first bittree with optional match byte - * - * Parameters: - * %ss:%ebp : LZMA parameter block - * %ds:%esi : compressed input data pointer - * %ebx : probability estimate set pointer (offset from %ebp) - * %cl : match byte - * %ch : 1 to use match byte, 0 to ignore match byte - * Returns: - * %ds:%esi : compressed input data pointer (possibly updated) - * %eax : decoded bittree - * Corrupts: - * none - ***************************************************************************** - */ -rc_bittree_match: - /* Preserve registers */ - pushl %edi - pushw %cx - pushw %dx - movl %ebx, %edi - /* Initialise registers */ - movl $1, %eax -1: /* Decode bit */ - rolb $1, %cl - movw %cx, %dx - andb %dh, %dl /* match_bit in %dl */ - movw %dx, %bx - addb %bl, %bh - xorb %bl, %bl - addw %ax, %bx /* offset + match_bit + symbol */ - leaw (%edi,%ebx,2), %bx /* high word always zero anyway */ - call rc_bit - rclw %ax - movb %al, %dh - notb %dh - xorb %dh, %dl - andb %dl, %ch /* offset &= ( match_bit ^ bit ) */ - testb %ah, %ah - jz 1b - /* Restore registers, clear unwanted high bit of result, and return */ - movl %edi, %ebx - popw %dx - popw %cx - popl %edi - xorb %ah, %ah - ret - .size rc_bittree_match, . - rc_bittree_match - -/***************************************************************************** - * Decode direct bits (no probability estimates) - * - * Parameters: - * %ss:%ebp : LZMA parameter block - * %ds:%esi : compressed input data pointer - * %cx : number of bits to decode - * Returns: - * %ds:%esi : compressed input data pointer (possibly updated) - * %eax : decoded bits - * Corrupts: - * none - ***************************************************************************** - */ -rc_direct: - /* Preserve registers */ - pushl %ebx - pushw %cx - pushl %edx - /* Initialise registers */ - xorl %edx, %edx -1: /* Perform normalisation */ - call rc_normalise - /* Decode bit */ - shrl $1, %eax - movl %eax, rc_range(%ebp) - movl rc_code(%ebp), %ebx - subl %eax, %ebx - js 2f - movl %ebx, rc_code(%ebp) -2: rcll %ebx - rcll %edx - xorb $1, %dl - ADDR16 loop 1b - /* Restore registers and return */ - movl %edx, %eax - popl %edx - popw %cx - popl %ebx - ret - .size rc_direct, . - rc_direct - -/***************************************************************************** - * Decode an LZMA literal - * - * Parameters: - * %ss:%ebp : LZMA parameter block - * %ds:%esi : compressed input data pointer - * %es:%edi : uncompressed output data pointer - * %edx : LZMA state - * Returns: - * %ds:%esi : compressed input data pointer (possibly updated) - * %es:%edi : uncompressed output data pointer (updated) - * %edx : LZMA state - * CF : end of payload marker found (always zero) - * Corrupts: - * %eax - * %ebx - * %ecx - ***************************************************************************** - * - * Literals are coded as an eight-bit tree, using a match byte if the - * previous symbol was not a literal. - * - */ -lzma_literal: - /* Get most recent output byte, if available */ - xorl %ebx, %ebx - cmpl %edi, out_start(%ebp) - je 1f - movb %es:-1(%edi), %bh -1: /* Locate probability estimate set */ - shrb $( 8 - LZMA_LC ), %bh - shlb $1, %bh - leaw literal(%ebx,%ebx,2), %bx - /* Get match byte, if applicable */ - xorw %cx, %cx - cmpb $STATE_LIT_MAX, %dl - jbe 1f - movl rep0(%ebp), %eax - notl %eax - movb %es:(%edi,%eax), %cl - movb $1, %ch -1: /* Decode bittree */ - call rc_bittree_match - /* Store output byte */ - ADDR32 stosb - print_hex_byte %al - print_character $(' ') - /* Update LZMA state */ - subb $3, %dl - jns 1f - xorb %dl, %dl -1: cmpb $7, %dl - jb 1f - subb $3, %dl -1: /* Clear CF and return */ - clc - ret - .size lzma_literal, . - lzma_literal - -/***************************************************************************** - * Decode an LZMA length - * - * Parameters: - * %ss:%ebp : LZMA parameter block - * %ds:%esi : compressed input data pointer - * %ebx : length parameter pointer (offset from %ebp) - * Returns: - * %ds:%esi : compressed input data pointer (possibly updated) - * Corrupts: - * %ebx - ***************************************************************************** - * - * Lengths are encoded as: - * - * "0" + 3 bits : lengths 2-9 ("low") - * "10" + 3 bits : lengths 10-17 ("mid") - * "11" + 8 bits : lengths 18-273 ("high") - */ -lzma_len: - /* Preserve registers */ - pushl %eax - pushl %ecx - pushl %edi - movl %ebx, %edi - /* Start by assuming three bits and a base length of 2 */ - movw $3, %cx - movw $2, len(%ebp) - /* Check low-length choice bit */ - leal choice(%edi), %ebx - call rc_bit - leal low(%edi), %ebx - jz 1f - /* Check high-length choice bit */ - leal choice2(%edi), %ebx - call rc_bit - leal mid(%edi), %ebx - movb $10, len(%ebp) - jz 1f - leal high(%edi), %ebx - movb $8, %cl - movb $18, len(%ebp) -1: /* Get encoded length */ - call rc_bittree - addw %ax, len(%ebp) - /* Restore registers and return */ - movl %edi, %ebx - popl %edi - popl %ecx - popl %eax - ret - .size lzma_len, . - lzma_len - -/***************************************************************************** - * Copy (possibly repeated) matched data - * - * Parameters: - * %ss:%ebp : LZMA parameter block - * %ds:%esi : compressed input data pointer - * %es:%edi : uncompressed output data pointer - * %cl : repeated match distance index (for repeated matches) - * %eax : match distance (for non-repeated matches) - * Returns: - * %ds:%esi : compressed input data pointer (possibly updated) - * %es:%edi : uncompressed output data pointer - * CF : match distance is out of range - * Corrupts: - * %eax - * %ebx - * %ecx - ***************************************************************************** - */ -match: /* Update repeated match list */ - print_character $('[') - movl $3, %ecx - jmp 1f -match_rep: - print_character $('[') - print_character $('R') - print_hex_byte %cl - print_character $('=') - movzbl %cl, %ecx - movl reps(%ebp,%ecx,4), %eax - jcxz 2f -1: movl (reps-4)(%ebp,%ecx,4), %ebx - movl %ebx, reps(%ebp,%ecx,4) - loop 1b - movl %eax, rep0(%ebp) -2: /* Preserve registers */ - pushl %esi - /* Get stored match length */ - movzwl len(%ebp), %ecx - print_hex_dword %eax - print_character $('+') - print_hex_word %cx - print_character $(']') - print_character $(' ') - /* Abort with CF set if match distance is out of range */ - movl out_start(%ebp), %esi - negl %esi - leal -1(%edi,%esi), %esi - cmpl %eax, %esi - jc 99f - /* Perform copy */ - notl %eax - leal (%edi,%eax), %esi - ADDR32 es rep movsb -99: /* Restore registers and return */ - popl %esi - ret - .size match, . - match - -/***************************************************************************** - * Decode an LZMA match - * - * Parameters: - * %ss:%ebp : LZMA parameter block - * %ds:%esi : compressed input data pointer - * %es:%edi : uncompressed output data pointer - * %edx : LZMA state - * Returns: - * %ds:%esi : compressed input data pointer (possibly updated) - * %es:%edi : uncompressed output data pointer - * %edx : LZMA state - * CF : end of payload marker found - * Corrupts: - * %eax - * %ebx - * %ecx - ***************************************************************************** - * - * Matches are encoded as an LZMA length followed by a 6-bit "distance - * slot" code, 0-26 fixed-probability bits, and 0-5 context encoded - * bits. - */ -lzma_match: - /* Preserve registers */ - pushl %edi - /* Update LZMA state */ - cmpb $STATE_LIT_MAX, %dl - movb $STATE_LIT_MATCH, %dl - jbe 1f - movb $STATE_NONLIT_MATCH, %dl -1: /* Decode length */ - movl $match_len_dec, %ebx - call lzma_len - /* Decode distance slot */ - movw len(%ebp), %bx - subw $2, %bx - cmpw $4, %bx - jb 1f - movw $3, %bx -1: shlw $7, %bx - addw $dist_slot, %bx - movw $6, %cx - call rc_bittree - /* Distance slots 0-3 are literal distances */ - cmpb $4, %al - jb 99f - /* Determine initial bits: 10/11 for even/odd distance codes */ - movl %eax, %edi - andw $1, %di - orw $2, %di - /* Determine number of context-encoded bits */ - movw %ax, %cx - shrb $1, %cl - decb %cl - /* Select context to be used in absence of fixed-probability bits */ - movl %edi, %ebx - shlw %cl, %bx - subw %ax, %bx - leaw (dist_special-2)(%ebx,%ebx), %bx - /* Decode fixed-probability bits, if any */ - cmpb $6, %cl - jb 1f - subb $4, %cl - shll %cl, %edi - call rc_direct - orl %eax, %edi - /* Select context to be used in presence of fixed-probability bits */ - movb $4, %cl - movl $dist_align, %ebx -1: /* Decode context-encoded bits */ - shll %cl, %edi - call rc_bittree_reverse - orl %edi, %eax -99: /* Restore registers and tail-call */ - popl %edi - jmp match - .size lzma_match, . - lzma_match - -/***************************************************************************** - * Decode an LZMA repeated match - * - * Parameters: - * %ss:%ebp : LZMA parameter block - * %ds:%esi : compressed input data pointer - * %es:%edi : uncompressed output data pointer - * %edx : LZMA state - * Returns: - * %ds:%esi : compressed input data pointer (possibly updated) - * %es:%edi : uncompressed output data pointer - * %edx : LZMA state - * CF : end of payload marker found - * Corrupts: - * %eax - * %ebx - * %ecx - ***************************************************************************** - * - * Repeated matches are encoded as: - * - * "00" : shortrep0 (implicit length 1) - * "01" + len : longrep0 - * "10" + len : longrep1 - * "110" + len : longrep2 - * "111" + len : longrep3 - */ -lzma_rep_match: - /* Initially assume longrep0 */ - movw $(STATE_LIT_LONGREP << 8), %cx - /* Get is_rep0 bit */ - leal is_rep0(,%edx,2), %ebx - call rc_bit - jnz 1f - /* Get is_rep0_long bit */ - leal is_rep0_long(,%edx,2), %ebx - call rc_bit - jnz 98f - movw $1, len(%ebp) - movb $STATE_LIT_SHORTREP, %ch - jmp 99f -1: /* Get is_rep1 bit */ - incb %cl - leal is_rep1(,%edx,2), %ebx - call rc_bit - jz 98f - /* Get is_rep2 bit */ - incb %cl - leal is_rep2(,%edx,2), %ebx - call rc_bit - adcb $0, %cl -98: /* Decode length */ - movl $rep_len_dec, %ebx - call lzma_len -99: /* Update LZMA state */ - cmpb $STATE_LIT_MAX, %dl - movb %ch, %dl - jbe 1f - movb $STATE_NONLIT_REP, %dl -1: /* Tail call */ - jmp match_rep - .size lzma_match, . - lzma_match - -/***************************************************************************** - * Decode one LZMA symbol - * - * Parameters: - * %ss:%ebp : LZMA parameter block - * %ds:%esi : compressed input data pointer - * %es:%edi : uncompressed output data pointer - * %edx : LZMA state - * Returns: - * %ds:%esi : compressed input data pointer (possibly updated) - * %es:%edi : uncompressed output data pointer (updated) - * %edx : LZMA state - * CF : end of payload marker found - * Corrupts: - * %eax - * %ebx - * %ecx - ***************************************************************************** - */ -lzma_decode: - /* Get is_match bit */ - leal is_match(,%edx,2), %ebx - call rc_bit - jz lzma_literal - /* Get is_rep bit */ - leal is_rep(,%edx,2), %ebx - call rc_bit - jz lzma_match - jmp lzma_rep_match - .size lzma_decode, . - lzma_decode - -/**************************************************************************** - * Undo effect of branch-call-jump (BCJ) filter - * - * Parameters: - * %es:%esi : start of uncompressed output data (note %es) - * %es:%edi : end of uncompressed output data - * Returns: - * Corrupts: - * %eax - * %ebx - * %ecx - * %edx - * %esi - ***************************************************************************** - */ -bcj_filter: - /* Store (negative) start of data in %edx */ - movl %esi, %edx - negl %edx - /* Calculate limit in %ecx */ - leal -5(%edi,%edx), %ecx -1: /* Calculate offset in %ebx */ - leal (%esi,%edx), %ebx - /* Check for end of data */ - cmpl %ecx, %ebx - ja 99f - /* Check for an opcode which would be followed by a rel32 address */ - ADDR32 es lodsb - andb $0xfe, %al - cmpb $0xe8, %al - jne 1b - /* Get current jump target value in %eax */ - ADDR32 es lodsl - /* Convert absolute addresses in the range [0,limit) back to - * relative addresses in the range [-offset,limit-offset). - */ - cmpl %ecx, %eax - jae 2f - subl %ebx,%es:-4(%esi) -2: /* Convert negative numbers in the range [-offset,0) back to - * positive numbers in the range [limit-offset,limit). - */ - notl %eax /* Range is now [0,offset) */ - cmpl %ebx, %eax - jae 1b - addl %ecx,%es:-4(%esi) - jmp 1b -99: /* Return */ - ret - .size bcj_filter, . - bcj_filter - -/**************************************************************************** - * decompress (real-mode or 16/32-bit protected-mode near call) - * - * Decompress data - * - * Parameters (passed via registers): - * %ds:%esi : Start of compressed input data - * %es:%edi : Start of output buffer - * Returns: - * %ds:%esi - End of compressed input data - * %es:%edi - End of decompressed output data - * All other registers are preserved - * - * NOTE: It would be possible to build a smaller version of the - * decompression code for -DKEEP_IT_REAL by using 16-bit registers - * where possible. - **************************************************************************** - */ - .globl decompress -decompress: - /* Preserve registers */ - pushl %eax - pushl %ebx - pushl %ecx - pushl %edx - pushl %ebp - /* Allocate parameter block */ - subl $sizeof__lzma_dec, %esp - movl %esp, %ebp - /* Zero parameter block and set all probabilities to 0.5 */ - pushl %edi - pushw %es - pushw %ss - popw %es - movl %ebp, %edi - xorl %eax, %eax - movl $( sizeof__lzma_dec / 4 ), %ecx - ADDR32 rep stosl - leal probs(%ebp), %edi - movw $( ( 1 << 11 ) / 2 ), %ax - movl $( ( sizeof__lzma_dec - probs ) / 2 ), %ecx - ADDR32 rep stosw - popw %es - popl %edi - /* Initialise remaining parameters */ - movl %edi, out_start(%ebp) - print_character $('\n') - ADDR32 lodsb /* discard initial byte */ - print_hex_byte %al - ADDR32 lodsl - bswapl %eax - print_hex_dword %eax - print_character $('\n') - movl %eax, rc_code(%ebp) - decl rc_range(%ebp) - movl $STATE_LIT_LIT, %edx -1: /* Decompress until we reach end of buffer */ - call lzma_decode - jnc 1b - call rc_normalise - print_character $('\n') - /* Undo BCJ filter */ - pushl %esi - movl out_start(%ebp), %esi - call bcj_filter - popl %esi - /* Restore registers and return */ - addl $sizeof__lzma_dec, %esp - popl %ebp - popl %edx - popl %ecx - popl %ebx - popl %eax - ret - - /* Specify minimum amount of stack space required */ - .globl _min_decompress_stack - .equ _min_decompress_stack, ( sizeof__lzma_dec + 512 /* margin */ ) diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/unlzma16.S b/qemu/roms/ipxe/src/arch/i386/prefix/unlzma16.S deleted file mode 100644 index 32b43f0dc..000000000 --- a/qemu/roms/ipxe/src/arch/i386/prefix/unlzma16.S +++ /dev/null @@ -1,9 +0,0 @@ -/* - * 16-bit version of the decompressor - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) - -#define CODE16 -#include "unlzma.S" diff --git a/qemu/roms/ipxe/src/arch/i386/prefix/usbdisk.S b/qemu/roms/ipxe/src/arch/i386/prefix/usbdisk.S deleted file mode 100644 index 9676406e2..000000000 --- a/qemu/roms/ipxe/src/arch/i386/prefix/usbdisk.S +++ /dev/null @@ -1,34 +0,0 @@ -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) - - .text - .arch i386 - .section ".prefix", "awx", @progbits - .code16 - .org 0 - -#include "mbr.S" - -/* Partition table: 64 heads, 32 sectors/track (ZIP-drive compatible) */ - .org 446 - .space 16 - .space 16 - /* Partition 3: log partition (for CONSOLE_INT13) */ - .byte 0x00, 0x01, 0x01, 0x00 - .byte 0xe0, 0x3f, 0x20, 0x00 - .long 0x00000020 - .long 0x000007e0 - /* Partition 4: boot partition */ - .byte 0x80, 0x00, 0x01, 0x01 - .byte 0xeb, 0x3f, 0x20, 0x02 - .long 0x00000800 - .long 0x00001000 - - .org 510 - .byte 0x55, 0xaa - -/* Skip to start of log partition */ - .org 32 * 512 - .ascii "iPXE LOG\n\n" - -/* Skip to start of boot partition */ - .org 2048 * 512 diff --git a/qemu/roms/ipxe/src/arch/i386/scripts/i386-kir.lds b/qemu/roms/ipxe/src/arch/i386/scripts/i386-kir.lds deleted file mode 100644 index 66bf804e6..000000000 --- a/qemu/roms/ipxe/src/arch/i386/scripts/i386-kir.lds +++ /dev/null @@ -1,202 +0,0 @@ -/* -*- sh -*- */ - -/* - * Linker script for i386 images - * - */ - -OUTPUT_FORMAT ( "elf32-i386", "elf32-i386", "elf32-i386" ) -OUTPUT_ARCH ( i386 ) - -SECTIONS { - - /* All sections in the resulting file have consecutive load - * addresses, but may have individual link addresses depending on - * the memory model being used. - * - * The linker symbols _prefix_link_addr, load_addr, and - * _max_align may be specified explicitly. If not specified, they - * will default to: - * - * _prefix_link_addr = 0 - * _load_addr = 0 - * _max_align = 16 - * - * We guarantee alignment of virtual addresses to any alignment - * specified by the constituent object files (e.g. via - * __attribute__((aligned(x)))). Load addresses are guaranteed - * only up to _max_align. Provided that all loader and relocation - * code honours _max_align, this means that physical addresses are - * also guaranteed up to _max_align. - * - * Note that when using -DKEEP_IT_REAL, the UNDI segments are only - * guaranteed to be loaded on a paragraph boundary (i.e. 16-byte - * alignment). Using _max_align>16 will therefore not guarantee - * >16-byte alignment of physical addresses when -DKEEP_IT_REAL is - * used (though virtual addresses will still be fully aligned). - * - */ - - /* - * The prefix - */ - - _prefix_link_addr = DEFINED ( _prefix_link_addr ) ? _prefix_link_addr : 0; - . = _prefix_link_addr; - _prefix = .; - - .prefix : AT ( _prefix_load_offset + __prefix ) { - __prefix = .; - _entry = .; - *(.prefix) - *(.prefix.*) - _eprefix_progbits = .; - } - - _eprefix = .; - - /* - * The 16-bit sections - */ - - _text16_link_addr = 0; - . = _text16_link_addr; - _text16 = .; - - . += 1; /* Prevent NULL being valid */ - - .text16 : AT ( _text16_load_offset + __text16 ) { - __text16 = .; - KEEP(*(.text.null_trap)) - KEEP(*(.text.null_trap.*)) - *(.text16) - *(.text16.*) - *(.text) - *(.text.*) - _etext16_progbits = .; - } = 0x9090 - - _etext16 = .; - - _data16_link_addr = 0; - . = _data16_link_addr; - _data16 = .; - - . += 1; /* Prevent NULL being valid */ - - .rodata16 : AT ( _data16_load_offset + __rodata16 ) { - __rodata16 = .; - *(.rodata16) - *(.rodata16.*) - *(.rodata) - *(.rodata.*) - } - .data16 : AT ( _data16_load_offset + __data16 ) { - __data16 = .; - *(.data16) - *(.data16.*) - *(.data) - *(.data.*) - KEEP(*(SORT(.tbl.*))) /* Various tables. See include/tables.h */ - KEEP(*(.provided)) - KEEP(*(.provided.*)) - _edata16_progbits = .; - } - .bss16 : AT ( _data16_load_offset + __bss16 ) { - __bss16 = .; - _bss16 = .; - *(.bss16) - *(.bss16.*) - *(.bss) - *(.bss.*) - *(COMMON) - _ebss16 = .; - } - .stack16 : AT ( _data16_load_offset + __stack16 ) { - __stack16 = .; - *(.stack16) - *(.stack16.*) - *(.stack) - *(.stack.*) - } - - _edata16 = .; - - _end = .; - - /* - * Dispose of the comment and note sections to make the link map - * easier to read - */ - - /DISCARD/ : { - *(.comment) - *(.comment.*) - *(.note) - *(.note.*) - *(.discard) - *(.discard.*) - } - - /* - * Load address calculations. The slightly obscure nature of the - * calculations is because ALIGN(x) can only operate on the - * location counter. - */ - - _max_align = DEFINED ( _max_align ) ? _max_align : 16; - _load_addr = DEFINED ( _load_addr ) ? _load_addr : 0; - - . = _load_addr; - - . -= _prefix_link_addr; - _prefix_load_offset = ALIGN ( _max_align ); - _prefix_load_addr = _prefix_link_addr + _prefix_load_offset; - _prefix_size = _eprefix - _prefix; - _prefix_progbits_size = _eprefix_progbits - _prefix; - . = _prefix_load_addr + _prefix_progbits_size; - - . -= _text16_link_addr; - _text16_load_offset = ALIGN ( _max_align ); - _text16_load_addr = _text16_link_addr + _text16_load_offset; - _text16_size = _etext16 - _text16; - _text16_progbits_size = _etext16_progbits - _text16; - . = _text16_load_addr + _text16_progbits_size; - - . -= _data16_link_addr; - _data16_load_offset = ALIGN ( _max_align ); - _data16_load_addr = _data16_link_addr + _data16_load_offset; - _data16_size = _edata16 - _data16; - _data16_progbits_size = _edata16_progbits - _data16; - . = _data16_load_addr + _data16_progbits_size; - - . = ALIGN ( _max_align ); - - _load_size = . - _load_addr; - - /* - * Alignment checks. ALIGN() can only operate on the location - * counter, so we set the location counter to each value we want - * to check. - */ - - . = _prefix_load_addr - _prefix_link_addr; - _assert = ASSERT ( ( . == ALIGN ( _max_align ) ), - "_prefix is badly aligned" ); - - . = _text16_load_addr - _text16_link_addr; - _assert = ASSERT ( ( . == ALIGN ( _max_align ) ), - "_text16 is badly aligned" ); - - . = _data16_load_addr - _data16_link_addr; - _assert = ASSERT ( ( . == ALIGN ( _max_align ) ), - "_data16 is badly aligned" ); - - /* - * Values calculated to save code from doing it - */ - _text16_size_pgh = ( ( _text16_size + 15 ) / 16 ); - _data16_size_pgh = ( ( _data16_size + 15 ) / 16 ); - _load_size_pgh = ( ( _load_size + 15 ) / 16 ); - _load_size_sect = ( ( _load_size + 511 ) / 512 ); -} diff --git a/qemu/roms/ipxe/src/arch/i386/scripts/i386.lds b/qemu/roms/ipxe/src/arch/i386/scripts/i386.lds deleted file mode 100644 index 38c89e14b..000000000 --- a/qemu/roms/ipxe/src/arch/i386/scripts/i386.lds +++ /dev/null @@ -1,254 +0,0 @@ -/* -*- ld-script -*- */ - -/* - * Linker script for i386 images - * - */ - -SECTIONS { - - /* Each section starts at a virtual address of zero. - * - * We guarantee alignment of virtual addresses to any alignment - * specified by the constituent object files (e.g. via - * __attribute__((aligned(x)))). Load addresses are guaranteed - * only up to _max_align. Provided that all loader and relocation - * code honours _max_align, this means that physical addresses are - * also guaranteed up to _max_align. - * - * Note that when using -DKEEP_IT_REAL, the UNDI segments are only - * guaranteed to be loaded on a paragraph boundary (i.e. 16-byte - * alignment). Using _max_align>16 will therefore not guarantee - * >16-byte alignment of physical addresses when -DKEEP_IT_REAL is - * used (though virtual addresses will still be fully aligned). - * - */ - - PROVIDE ( _max_align = 16 ); - - /* - * Allow decompressor to require a minimum amount of temporary stack - * space. - * - */ - PROVIDE ( _min_decompress_stack = 0 ); - - /* - * The prefix - * - */ - - .prefix 0x0 : AT ( _prefix_lma ) { - _prefix = .; - *(.prefix) - *(SORT(.pci_devlist.*)) - *(.prefix.*) - _mprefix = .; - } .bss.prefix (NOLOAD) : AT ( _end_lma ) { - _eprefix = .; - } - _prefix_filesz = ABSOLUTE ( _mprefix ) - ABSOLUTE ( _prefix ); - _prefix_memsz = ABSOLUTE ( _eprefix ) - ABSOLUTE ( _prefix ); - - /* - * The 16-bit (real-mode) code section - * - */ - - .text16.early 0x0 : AT ( _text16_early_lma ) { - _text16 = .; - KEEP(*(.text16.null)) - KEEP(*(.text16.null.*)) - . += 1; /* Prevent NULL being valid */ - *(.text16.early) - *(.text16.early.*) - _etext16_early = .; - } .text16.late ALIGN ( _max_align ) : AT ( _text16_late_lma ) { - _text16_late = .; - *(.text16) - *(.text16.*) - _mtext16 = .; - } .bss.text16 (NOLOAD) : AT ( _end_lma ) { - _etext16 = .; - } - _text16_early_filesz = ABSOLUTE ( _etext16_early ) - ABSOLUTE ( _text16 ); - _text16_early_memsz = ABSOLUTE ( _etext16_early ) - ABSOLUTE ( _text16 ); - _text16_late_filesz = ABSOLUTE ( _mtext16 ) - ABSOLUTE ( _text16_late ); - _text16_late_memsz = ABSOLUTE ( _etext16 ) - ABSOLUTE ( _text16_late ); - _text16_memsz = ABSOLUTE ( _etext16 ) - ABSOLUTE ( _text16 ); - - /* - * The 16-bit (real-mode) data section - * - */ - - .data16 0x0 : AT ( _data16_lma ) { - _data16 = .; - . += 1; /* Prevent NULL being valid */ - *(.rodata16) - *(.rodata16.*) - *(.data16) - *(.data16.*) - _mdata16 = .; - } .bss.data16 (NOLOAD) : AT ( _end_lma ) { - *(.bss16) - *(.bss16.*) - *(.stack16) - *(.stack16.*) - . = MAX ( ., _mdata16 + _min_decompress_stack ); - _edata16 = .; - } - _data16_filesz = ABSOLUTE ( _mdata16 ) - ABSOLUTE ( _data16 ); - _data16_memsz = ABSOLUTE ( _edata16 ) - ABSOLUTE ( _data16 ); - - /* - * The 32-bit sections - * - */ - - .textdata 0x0 : AT ( _textdata_lma ) { - _textdata = .; - KEEP(*(.text.null_trap)) - KEEP(*(.text.null_trap.*)) - . += 1; /* Prevent NULL being valid */ - *(.text) - *(.text.*) - *(.rodata) - *(.rodata.*) - *(.data) - *(.data.*) - KEEP(*(SORT(.tbl.*))) /* Various tables. See include/tables.h */ - KEEP(*(.provided)) - KEEP(*(.provided.*)) - _mtextdata = .; - } .bss.textdata (NOLOAD) : AT ( _end_lma ) { - *(.bss) - *(.bss.*) - *(COMMON) - *(.stack) - *(.stack.*) - _etextdata = .; - } - _textdata_filesz = ABSOLUTE ( _mtextdata ) - ABSOLUTE ( _textdata ); - _textdata_memsz = ABSOLUTE ( _etextdata ) - ABSOLUTE ( _textdata ); - - /* - * Payload prefix - * - * If present, this will be placed between .text16.early and .text16.late. - * - */ - .pprefix 0x0 : AT ( _pprefix_lma ) { - _pprefix = .; - KEEP(*(.pprefix)) - KEEP(*(.pprefix.*)) - _mpprefix = .; - } .bss.pprefix (NOLOAD) : AT ( _end_lma ) { - _epprefix = .; - } - _pprefix_filesz = ABSOLUTE ( _mpprefix ) - ABSOLUTE ( _pprefix ); - _pprefix_memsz = ABSOLUTE ( _epprefix ) - ABSOLUTE ( _pprefix ); - - /* - * Compressor information block - * - */ - - .zinfo 0x0 : AT ( _zinfo_lma ) { - _zinfo = .; - KEEP(*(.zinfo)) - KEEP(*(.zinfo.*)) - _mzinfo = .; - } .bss.zinfo (NOLOAD) : AT ( _end_lma ) { - _ezinfo = .; - } - _zinfo_filesz = ABSOLUTE ( _mzinfo ) - ABSOLUTE ( _zinfo ); - _zinfo_memsz = ABSOLUTE ( _ezinfo ) - ABSOLUTE ( _zinfo ); - - /* - * Weak symbols that need zero values if not otherwise defined - * - */ - - .weak 0x0 : AT ( _end_lma ) { - _weak = .; - *(.weak) - *(.weak.*) - _eweak = .; - } - _assert = ASSERT ( ( _weak == _eweak ), ".weak is non-zero length" ); - - /* - * Dispose of the comment and note sections to make the link map - * easier to read - * - */ - - /DISCARD/ : { - *(.comment) - *(.comment.*) - *(.note) - *(.note.*) - *(.eh_frame) - *(.eh_frame.*) - *(.rel) - *(.rel.*) - *(.einfo) - *(.einfo.*) - *(.discard) - *(.discard.*) - } - - /* - * Load address calculations. In older versions of ld, ALIGN() - * can operate only on the location counter, so we use that. - * - */ - - . = 0; - - . = ALIGN ( _max_align ); - _prefix_lma = .; - . += _prefix_filesz; - - . = ALIGN ( _max_align ); - _text16_early_lma = .; - . += _text16_early_filesz; - - . = ALIGN ( _max_align ); - . = ALIGN ( _payload_align ); - _pprefix_lma = .; - . += _pprefix_filesz; - - . = ALIGN ( _max_align ); - _payload_lma = .; - _pprefix_skip = ABSOLUTE ( _payload_lma ) - ABSOLUTE ( _pprefix_lma ); - _text16_late_lma = .; - . += _text16_late_filesz; - - . = ALIGN ( _max_align ); - _data16_lma = .; - . += _data16_filesz; - - . = ALIGN ( _max_align ); - _textdata_lma = .; - . += _textdata_filesz; - - _filesz = .; /* Do not include zinfo block in file size */ - - . = ALIGN ( _max_align ); - _zinfo_lma = .; - . += _zinfo_filesz; - - . = ALIGN ( _max_align ); - _end_lma = .; - - /* - * Values calculated to save code from doing it - * - */ - _text16_memsz_pgh = ( ( _text16_memsz + 15 ) / 16 ); - _data16_memsz_pgh = ( ( _data16_memsz + 15 ) / 16 ); - _textdata_memsz_pgh = ( ( _textdata_memsz + 15 ) / 16 ); - _textdata_memsz_kb = ( ( _textdata_memsz + 1023 ) / 1024 ); -} diff --git a/qemu/roms/ipxe/src/arch/i386/scripts/linux.lds b/qemu/roms/ipxe/src/arch/i386/scripts/linux.lds deleted file mode 100644 index 9f2eeaf3c..000000000 --- a/qemu/roms/ipxe/src/arch/i386/scripts/linux.lds +++ /dev/null @@ -1,104 +0,0 @@ -/* -*- sh -*- */ - -/* - * Linker script for i386 Linux images - * - */ - -OUTPUT_FORMAT ( "elf32-i386", "elf32-i386", "elf32-i386" ) -OUTPUT_ARCH ( i386 ) - -SECTIONS { - _max_align = 32; - - . = 0x08048000; - - /* - * The text section - * - */ - - . = ALIGN ( _max_align ); - .text : { - _text = .; - *(.text) - *(.text.*) - _etext = .; - } - - /* - * The rodata section - * - */ - - . = ALIGN ( _max_align ); - .rodata : { - _rodata = .; - *(.rodata) - *(.rodata.*) - _erodata = .; - } - - /* - * The data section - * - * Adjust the address for the data segment. We want to adjust up to - * the same address within the page on the next page up. - */ - - . = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); - . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); - .data : { - _data = .; - *(.data) - *(.data.*) - KEEP(*(SORT(.tbl.*))) - KEEP(*(.provided)) - KEEP(*(.provided.*)) - _edata = .; - } - - /* - * The bss section - * - */ - - . = ALIGN ( _max_align ); - .bss : { - _bss = .; - *(.bss) - *(.bss.*) - *(COMMON) - _ebss = .; - } - - /* - * Weak symbols that need zero values if not otherwise defined - * - */ - - .weak 0x0 : { - _weak = .; - *(.weak) - *(.weak.*) - _eweak = .; - } - _assert = ASSERT ( ( _weak == _eweak ), ".weak is non-zero length" ); - - /* - * Dispose of the comment and note sections to make the link map - * easier to read - * - */ - - /DISCARD/ : { - *(.comment) - *(.comment.*) - *(.note) - *(.note.*) - *(.rel) - *(.rel.*) - *(.discard) - *(.discard.*) - } -} diff --git a/qemu/roms/ipxe/src/arch/i386/transitions/liba20.S b/qemu/roms/ipxe/src/arch/i386/transitions/liba20.S deleted file mode 100644 index 6c1e1f62f..000000000 --- a/qemu/roms/ipxe/src/arch/i386/transitions/liba20.S +++ /dev/null @@ -1,313 +0,0 @@ -/* - * Copyright (C) 2010 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 ) - - .arch i386 - -/**************************************************************************** - * test_a20_short, test_a20_long - * - * Check to see if A20 line is enabled - * - * Parameters: - * none - * Returns: - * CF set if A20 line is not enabled - * Corrupts: - * none - **************************************************************************** - */ -#define TEST_A20_SHORT_MAX_RETRIES 0x20 -#define TEST_A20_LONG_MAX_RETRIES 0x200000 - .section ".text16.early", "awx", @progbits - .code16 -test_a20_short: - pushl %ecx - movl $TEST_A20_SHORT_MAX_RETRIES, %ecx - jmp 1f - .size test_a20_short, . - test_a20_short -test_a20_long: - pushl %ecx - movl $TEST_A20_LONG_MAX_RETRIES, %ecx -1: pushw %ax - pushw %ds - pushw %es - - /* Set up segment registers for access across the 1MB boundary */ - xorw %ax, %ax - movw %ax, %ds - decw %ax - movw %ax, %es - -2: /* Modify and check test pattern; succeed if we see a difference */ - pushfw - cli - xchgw %ds:0, %cx - movw %es:0x10, %ax - xchgw %ds:0, %cx - popfw - cmpw %ax, %cx - clc - jnz 99f - - /* Delay and retry */ - outb %al, $0x80 - addr32 loop 2b - stc - -99: /* Restore registers and return */ - popw %es - popw %ds - popw %ax - popl %ecx - ret - .size test_a20_long, . - test_a20_long - -/**************************************************************************** - * enable_a20_bios - * - * Try enabling A20 line via BIOS - * - * Parameters: - * none - * Returns: - * CF set if A20 line is not enabled - * Corrupts: - * none - **************************************************************************** - */ - .section ".text16.early", "awx", @progbits - .code16 -enable_a20_bios: - - /* Preserve registers. Be very paranoid, since some BIOSes - * are reported to clobber %ebx - */ - pushal - - /* Attempt INT 15,2401 */ - movw $0x2401, %ax - int $0x15 - jc 99f - - /* Check that success was really successful */ - call test_a20_short - -99: /* Restore registers and return */ - popal - ret - .size enable_a20_bios, . - enable_a20_bios - -/**************************************************************************** - * enable_a20_kbc - * - * Try enabling A20 line via keyboard controller - * - * Parameters: - * none - * Returns: - * CF set if A20 line is not enabled - * Corrupts: - * none - **************************************************************************** - */ -#define KC_RDWR 0x60 -#define KC_RDWR_SET_A20 0xdf -#define KC_CMD 0x64 -#define KC_CMD_WOUT 0xd1 -#define KC_CMD_NULL 0xff -#define KC_STATUS 0x64 -#define KC_STATUS_OBUF_FULL 0x01 -#define KC_STATUS_IBUF_FULL 0x02 -#define KC_MAX_RETRIES 100000 - .section ".text16.early", "awx", @progbits - .code16 -enable_a20_kbc: - /* Preserve registers */ - pushw %ax - - /* Try keyboard controller */ - call empty_kbc - movb $KC_CMD_WOUT, %al - outb %al, $KC_CMD - call empty_kbc - movb $KC_RDWR_SET_A20, %al - outb %al, $KC_RDWR - call empty_kbc - movb $KC_CMD_NULL, %al - outb %al, $KC_CMD - call empty_kbc - - /* Check to see if it worked */ - call test_a20_long - - /* Restore registers and return */ - popw %ax - ret - .size enable_a20_kbc, . - enable_a20_kbc - - .section ".text16.early", "awx", @progbits - .code16 -empty_kbc: - /* Preserve registers */ - pushl %ecx - pushw %ax - - /* Wait for KBC to become empty */ - movl $KC_MAX_RETRIES, %ecx -1: outb %al, $0x80 - inb $KC_STATUS, %al - testb $( KC_STATUS_OBUF_FULL | KC_STATUS_IBUF_FULL ), %al - jz 99f - testb $KC_STATUS_OBUF_FULL, %al - jz 2f - outb %al, $0x80 - inb $KC_RDWR, %al -2: addr32 loop 1b - -99: /* Restore registers and return */ - popw %ax - popl %ecx - ret - .size empty_kbc, . - empty_kbc - -/**************************************************************************** - * enable_a20_fast - * - * Try enabling A20 line via "Fast Gate A20" - * - * Parameters: - * none - * Returns: - * CF set if A20 line is not enabled - * Corrupts: - * none - **************************************************************************** - */ -#define SCP_A 0x92 - .section ".text16.early", "awx", @progbits - .code16 -enable_a20_fast: - /* Preserve registers */ - pushw %ax - - /* Try "Fast Gate A20" */ - inb $SCP_A, %al - orb $0x02, %al - andb $~0x01, %al - outb %al, $SCP_A - - /* Check to see if it worked */ - call test_a20_long - - /* Restore registers and return */ - popw %ax - ret - .size enable_a20_fast, . - enable_a20_fast - -/**************************************************************************** - * enable_a20 - * - * Try enabling A20 line via any available method - * - * Parameters: - * none - * Returns: - * CF set if A20 line is not enabled - * Corrupts: - * none - **************************************************************************** - */ -#define ENABLE_A20_RETRIES 255 - .section ".text16.early", "awx", @progbits - .code16 - .globl enable_a20 -enable_a20: - /* Preserve registers */ - pushl %ecx - pushw %ax - - /* Check to see if A20 is already enabled */ - call test_a20_short - jnc 99f - - /* Use known working method, if we have one */ - movw %cs:enable_a20_method, %ax - testw %ax, %ax - jz 1f - call *%ax - jmp 99f -1: - /* Try all methods in turn until one works */ - movl $ENABLE_A20_RETRIES, %ecx -2: movw $enable_a20_bios, %ax - movw %ax, %cs:enable_a20_method - call *%ax - jnc 99f - movw $enable_a20_kbc, %ax - movw %ax, %cs:enable_a20_method - call *%ax - jnc 99f - movw $enable_a20_fast, %ax - movw %ax, %cs:enable_a20_method - call *%ax - jnc 99f - addr32 loop 2b - /* Failure; exit with carry set */ - movw $0, %cs:enable_a20_method - stc - -99: /* Restore registers and return */ - popw %ax - popl %ecx - ret - - .section ".text16.early.data", "aw", @progbits - .align 2 -enable_a20_method: - .word 0 - .size enable_a20_method, . - enable_a20_method - -/**************************************************************************** - * access_highmem (real mode far call) - * - * Open up access to high memory with A20 enabled - * - * Parameters: - * none - * Returns: - * CF set if high memory could not be accessed - * Corrupts: - * none - **************************************************************************** - */ - .section ".text16.early", "awx", @progbits - .code16 - .globl access_highmem -access_highmem: - /* Enable A20 line */ - call enable_a20 - lret - .size access_highmem, . - access_highmem diff --git a/qemu/roms/ipxe/src/arch/i386/transitions/libkir.S b/qemu/roms/ipxe/src/arch/i386/transitions/libkir.S deleted file mode 100644 index fa9459d52..000000000 --- a/qemu/roms/ipxe/src/arch/i386/transitions/libkir.S +++ /dev/null @@ -1,256 +0,0 @@ -/* - * libkir: a transition library for -DKEEP_IT_REAL - * - * Michael Brown <mbrown@fensystems.co.uk> - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) - -/**************************************************************************** - * This file defines libkir: an interface between external and - * internal environments when -DKEEP_IT_REAL is used, so that both - * internal and external environments are in real mode. It deals with - * switching data segments and the stack. It provides the following - * functions: - * - * ext_to_kir & switch between external and internal (kir) - * kir_to_ext environments, preserving all non-segment - * registers - * - * kir_call issue a call to an internal routine from external - * code - * - * libkir is written to avoid assuming that segments are anything - * other than opaque data types, and also avoids assuming that the - * stack pointer is 16-bit. This should enable it to run just as well - * in 16:16 or 16:32 protected mode as in real mode. - **************************************************************************** - */ - -/* Breakpoint for when debugging under bochs */ -#define BOCHSBP xchgw %bx, %bx - - .text - .arch i386 - .section ".text16", "awx", @progbits - .code16 - -/**************************************************************************** - * init_libkir (real-mode or 16:xx protected-mode far call) - * - * Initialise libkir ready for transitions to the kir environment - * - * Parameters: - * %cs : .text16 segment - * %ds : .data16 segment - **************************************************************************** - */ - .globl init_libkir -init_libkir: - /* Record segment registers */ - pushw %ds - popw %cs:kir_ds - lret - -/**************************************************************************** - * ext_to_kir (real-mode or 16:xx protected-mode near call) - * - * Switch from external stack and segment registers to internal stack - * and segment registers. %ss:sp is restored from the saved kir_ds - * and kir_sp. %ds, %es, %fs and %gs are all restored from the saved - * kir_ds. All other registers are preserved. - * - * %cs:0000 must point to the start of the runtime image code segment - * on entry. - * - * Parameters: none - **************************************************************************** - */ - - .globl ext_to_kir -ext_to_kir: - /* Record external segment registers */ - movw %ds, %cs:ext_ds - pushw %cs - popw %ds /* Set %ds = %cs for easier access to variables */ - movw %es, %ds:ext_es - movw %fs, %ds:ext_fs - movw %gs, %ds:ext_fs - - /* Preserve registers */ - movw %ax, %ds:save_ax - - /* Extract near return address from stack */ - popw %ds:save_retaddr - - /* Record external %ss:esp */ - movw %ss, %ds:ext_ss - movl %esp, %ds:ext_esp - - /* Load internal segment registers and stack pointer */ - movw %ds:kir_ds, %ax - movw %ax, %ss - movzwl %ds:kir_sp, %esp - movw %ax, %ds - movw %ax, %es - movw %ax, %fs - movw %ax, %gs -1: - - /* Place return address on new stack */ - pushw %cs:save_retaddr - - /* Restore registers and return */ - movw %cs:save_ax, %ax - ret - -/**************************************************************************** - * kir_to_ext (real-mode or 16:xx protected-mode near call) - * - * Switch from internal stack and segment registers to external stack - * and segment registers. %ss:%esp is restored from the saved ext_ss - * and ext_esp. Other segment registers are restored from the - * corresponding locations. All other registers are preserved. - * - * Note that it is actually %ss that is recorded as kir_ds, on the - * assumption that %ss == %ds when kir_to_ext is called. - * - * Parameters: none - **************************************************************************** - */ - - .globl kir_to_ext -kir_to_ext: - /* Record near return address */ - pushw %cs - popw %ds /* Set %ds = %cs for easier access to variables */ - popw %ds:save_retaddr - - /* Record internal segment registers and %sp */ - movw %ss, %ds:kir_ds - movw %sp, %ds:kir_sp - - /* Load external segment registers and stack pointer */ - movw %ds:ext_ss, %ss - movl %ds:ext_esp, %esp - movw %ds:ext_gs, %gs - movw %ds:ext_fs, %fs - movw %ds:ext_es, %es - movw %ds:ext_ds, %ds - - /* Return */ - pushw %cs:save_retaddr - ret - -/**************************************************************************** - * kir_call (real-mode or 16:xx protected-mode far call) - * - * Call a specific C function in the internal code. The prototype of - * the C function must be - * void function ( struct i386_all_resg *ix86 ); - * ix86 will point to a struct containing the real-mode registers - * at entry to kir_call. - * - * All registers will be preserved across kir_call(), unless the C - * function explicitly overwrites values in ix86. Interrupt status - * will also be preserved. - * - * Parameters: - * function : (32-bit) virtual address of C function to call - * - * Example usage: - * pushl $pxe_api_call - * lcall $UNDI_CS, $kir_call - * addw $4, %sp - * to call in to the C function - * void pxe_api_call ( struct i386_all_regs *ix86 ); - **************************************************************************** - */ - - .globl kir_call -kir_call: - /* Preserve flags. Must do this before any operation that may - * affect flags. - */ - pushfl - popl %cs:save_flags - - /* Disable interrupts. We do funny things with the stack, and - * we're not re-entrant. - */ - cli - - /* Extract address of internal routine from stack. We must do - * this without using (%bp), because we may be called with - * either a 16-bit or a 32-bit stack segment. - */ - popl %cs:save_retaddr /* Scratch location */ - popl %cs:save_function - subl $8, %esp /* Restore %esp */ - - /* Switch to internal stack. Note that the external stack is - * inaccessible once we're running internally (since we have - * no concept of 48-bit far pointers) - */ - call ext_to_kir - - /* Store external registers on internal stack */ - pushl %cs:save_flags - pushal - pushl %cs:ext_fs_and_gs - pushl %cs:ext_ds_and_es - pushl %cs:ext_cs_and_ss - - /* Push &ix86 on stack and call function */ - sti - pushl %esp - data32 call *%cs:save_function - popl %eax /* discard */ - - /* Restore external registers from internal stack */ - popl %cs:ext_cs_and_ss - popl %cs:ext_ds_and_es - popl %cs:ext_fs_and_gs - popal - popl %cs:save_flags - - /* Switch to external stack */ - call kir_to_ext - - /* Restore flags */ - pushl %cs:save_flags - popfl - - /* Return */ - lret - -/**************************************************************************** - * Stored internal and external stack and segment registers - **************************************************************************** - */ - -ext_cs_and_ss: -ext_cs: .word 0 -ext_ss: .word 0 -ext_ds_and_es: -ext_ds: .word 0 -ext_es: .word 0 -ext_fs_and_gs: -ext_fs: .word 0 -ext_gs: .word 0 -ext_esp: .long 0 - - .globl kir_ds -kir_ds: .word 0 - .globl kir_sp -kir_sp: .word _estack - -/**************************************************************************** - * Temporary variables - **************************************************************************** - */ -save_ax: .word 0 -save_retaddr: .long 0 -save_flags: .long 0 -save_function: .long 0 diff --git a/qemu/roms/ipxe/src/arch/i386/transitions/libpm.S b/qemu/roms/ipxe/src/arch/i386/transitions/libpm.S deleted file mode 100644 index e69de29bb..000000000 --- a/qemu/roms/ipxe/src/arch/i386/transitions/libpm.S +++ /dev/null diff --git a/qemu/roms/ipxe/src/arch/i386/transitions/librm.S b/qemu/roms/ipxe/src/arch/i386/transitions/librm.S deleted file mode 100644 index 863e22415..000000000 --- a/qemu/roms/ipxe/src/arch/i386/transitions/librm.S +++ /dev/null @@ -1,671 +0,0 @@ -/* - * librm: a library for interfacing to real-mode code - * - * Michael Brown <mbrown@fensystems.co.uk> - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) - -/* Drag in local definitions */ -#include "librm.h" - -/* For switches to/from protected mode */ -#define CR0_PE 1 - -/* Size of various C data structures */ -#define SIZEOF_I386_SEG_REGS 12 -#define SIZEOF_I386_REGS 32 -#define SIZEOF_REAL_MODE_REGS ( SIZEOF_I386_SEG_REGS + SIZEOF_I386_REGS ) -#define SIZEOF_I386_FLAGS 4 -#define SIZEOF_I386_ALL_REGS ( SIZEOF_REAL_MODE_REGS + SIZEOF_I386_FLAGS ) - - .arch i386 - -/**************************************************************************** - * Global descriptor table - * - * Call init_librm to set up the GDT before attempting to use any - * protected-mode code. - * - * NOTE: This must be located before prot_to_real, otherwise gas - * throws a "can't handle non absolute segment in `ljmp'" error due to - * not knowing the value of REAL_CS when the ljmp is encountered. - * - * Note also that putting ".word gdt_end - gdt - 1" directly into - * gdt_limit, rather than going via gdt_length, will also produce the - * "non absolute segment" error. This is most probably a bug in gas. - **************************************************************************** - */ - .section ".data16", "aw", @progbits - .align 16 -gdt: -gdtr: /* The first GDT entry is unused, the GDTR can fit here. */ -gdt_limit: .word gdt_length - 1 -gdt_base: .long 0 - .word 0 /* padding */ - - .org gdt + VIRTUAL_CS, 0 -virtual_cs: /* 32 bit protected mode code segment, virtual addresses */ - .word 0xffff, 0 - .byte 0, 0x9f, 0xcf, 0 - - .org gdt + VIRTUAL_DS, 0 -virtual_ds: /* 32 bit protected mode data segment, virtual addresses */ - .word 0xffff, 0 - .byte 0, 0x93, 0xcf, 0 - - .org gdt + PHYSICAL_CS, 0 -physical_cs: /* 32 bit protected mode code segment, physical addresses */ - .word 0xffff, 0 - .byte 0, 0x9f, 0xcf, 0 - - .org gdt + PHYSICAL_DS, 0 -physical_ds: /* 32 bit protected mode data segment, physical addresses */ - .word 0xffff, 0 - .byte 0, 0x93, 0xcf, 0 - - .org gdt + REAL_CS, 0 -real_cs: /* 16 bit real mode code segment */ - .word 0xffff, 0 - .byte 0, 0x9b, 0x00, 0 - - .org gdt + REAL_DS -real_ds: /* 16 bit real mode data segment */ - .word 0xffff, ( REAL_DS << 4 ) - .byte 0, 0x93, 0x00, 0 - -gdt_end: - .equ gdt_length, gdt_end - gdt - -/**************************************************************************** - * init_librm (real-mode far call, 16-bit real-mode far return address) - * - * Initialise the GDT ready for transitions to protected mode. - * - * Parameters: - * %cs : .text16 segment - * %ds : .data16 segment - * %edi : Physical base of protected-mode code (virt_offset) - **************************************************************************** - */ - .section ".text16", "ax", @progbits - .code16 - .globl init_librm -init_librm: - /* Preserve registers */ - pushl %eax - pushl %ebx - - /* Store virt_offset and set up virtual_cs and virtual_ds segments */ - movl %edi, %eax - movw $virtual_cs, %bx - call set_seg_base - movw $virtual_ds, %bx - call set_seg_base - movl %edi, rm_virt_offset - - /* Negate virt_offset */ - negl %edi - - /* Store rm_cs and text16, set up real_cs segment */ - xorl %eax, %eax - movw %cs, %ax - movw %ax, %cs:rm_cs - shll $4, %eax - movw $real_cs, %bx - call set_seg_base - addr32 leal (%eax, %edi), %ebx - movl %ebx, rm_text16 - - /* Store rm_ds and data16 */ - xorl %eax, %eax - movw %ds, %ax - movw %ax, %cs:rm_ds - shll $4, %eax - addr32 leal (%eax, %edi), %ebx - movl %ebx, rm_data16 - - /* Set GDT base */ - movl %eax, gdt_base - addl $gdt, gdt_base - - /* Initialise IDT */ - pushl $init_idt - pushw %cs - call prot_call - popl %eax /* discard */ - - /* Restore registers */ - negl %edi - popl %ebx - popl %eax - lret - - .section ".text16", "ax", @progbits - .code16 -set_seg_base: -1: movw %ax, 2(%bx) - rorl $16, %eax - movb %al, 4(%bx) - movb %ah, 7(%bx) - roll $16, %eax - ret - -/**************************************************************************** - * real_to_prot (real-mode near call, 32-bit virtual return address) - * - * Switch from 16-bit real-mode to 32-bit protected mode with virtual - * addresses. The real-mode %ss:sp is stored in rm_ss and rm_sp, and - * the protected-mode %esp is restored from the saved pm_esp. - * Interrupts are disabled. All other registers may be destroyed. - * - * The return address for this function should be a 32-bit virtual - * address. - * - * Parameters: - * %ecx : number of bytes to move from RM stack to PM stack - * - **************************************************************************** - */ - .section ".text16", "ax", @progbits - .code16 -real_to_prot: - /* Enable A20 line */ - call enable_a20 - /* A failure at this point is fatal, and there's nothing we - * can do about it other than lock the machine to make the - * problem immediately visible. - */ -1: jc 1b - - /* Make sure we have our data segment available */ - movw %cs:rm_ds, %ax - movw %ax, %ds - - /* Add virt_offset, text16 and data16 to stack to be - * copied, and also copy the return address. - */ - pushl rm_virt_offset - pushl rm_text16 - pushl rm_data16 - addw $16, %cx /* %ecx must be less than 64kB anyway */ - - /* Real-mode %ss:%sp => %ebp:%edx and virtual address => %esi */ - xorl %ebp, %ebp - movw %ss, %bp - movzwl %sp, %edx - movl %ebp, %eax - shll $4, %eax - addr32 leal (%eax,%edx), %esi - subl rm_virt_offset, %esi - - /* Load protected-mode global descriptor table */ - data32 lgdt gdtr - - /* Zero segment registers. This wastes around 12 cycles on - * real hardware, but saves a substantial number of emulated - * instructions under KVM. - */ - xorw %ax, %ax - movw %ax, %ds - movw %ax, %es - movw %ax, %fs - movw %ax, %gs - movw %ax, %ss - - /* Switch to protected mode */ - cli - movl %cr0, %eax - orb $CR0_PE, %al - movl %eax, %cr0 - data32 ljmp $VIRTUAL_CS, $r2p_pmode - .section ".text", "ax", @progbits - .code32 -r2p_pmode: - /* Set up protected-mode data segments and stack pointer */ - movw $VIRTUAL_DS, %ax - movw %ax, %ds - movw %ax, %es - movw %ax, %fs - movw %ax, %gs - movw %ax, %ss - movl pm_esp, %esp - - /* Load protected-mode interrupt descriptor table */ - lidt idtr - - /* Record real-mode %ss:sp (after removal of data) */ - movw %bp, rm_ss - addl %ecx, %edx - movw %dx, rm_sp - - /* Move data from RM stack to PM stack */ - subl %ecx, %esp - movl %esp, %edi - rep movsb - - /* Publish virt_offset, text16 and data16 for PM code to use */ - popl data16 - popl text16 - popl virt_offset - - /* Return to virtual address */ - ret - -/**************************************************************************** - * prot_to_real (protected-mode near call, 32-bit real-mode return address) - * - * Switch from 32-bit protected mode with virtual addresses to 16-bit - * real mode. The protected-mode %esp is stored in pm_esp and the - * real-mode %ss:sp is restored from the saved rm_ss and rm_sp. The - * high word of the real-mode %esp is set to zero. All real-mode data - * segment registers are loaded from the saved rm_ds. Interrupts are - * *not* enabled, since we want to be able to use prot_to_real in an - * ISR. All other registers may be destroyed. - * - * The return address for this function should be a 32-bit (sic) - * real-mode offset within .code16. - * - * Parameters: - * %ecx : number of bytes to move from PM stack to RM stack - * %esi : real-mode global and interrupt descriptor table registers - * - **************************************************************************** - */ - .section ".text", "ax", @progbits - .code32 -prot_to_real: - /* Copy real-mode global descriptor table register to RM code segment */ - movl text16, %edi - leal rm_gdtr(%edi), %edi - movsw - movsl - - /* Load real-mode interrupt descriptor table register */ - lidt (%esi) - - /* Add return address to data to be moved to RM stack */ - addl $4, %ecx - - /* Real-mode %ss:sp => %ebp:edx and virtual address => %edi */ - movzwl rm_ss, %ebp - movzwl rm_sp, %edx - subl %ecx, %edx - movl %ebp, %eax - shll $4, %eax - leal (%eax,%edx), %edi - subl virt_offset, %edi - - /* Move data from PM stack to RM stack */ - movl %esp, %esi - rep movsb - - /* Record protected-mode %esp (after removal of data) */ - movl %esi, pm_esp - - /* Load real-mode segment limits */ - movw $REAL_DS, %ax - movw %ax, %ds - movw %ax, %es - movw %ax, %fs - movw %ax, %gs - movw %ax, %ss - ljmp $REAL_CS, $p2r_rmode - .section ".text16", "ax", @progbits - .code16 -p2r_rmode: - /* Load real-mode GDT */ - data32 lgdt %cs:rm_gdtr - /* Switch to real mode */ - movl %cr0, %eax - andb $0!CR0_PE, %al - movl %eax, %cr0 -p2r_ljmp_rm_cs: - ljmp $0, $1f -1: - /* Set up real-mode data segments and stack pointer */ - movw %cs:rm_ds, %ax - movw %ax, %ds - movw %ax, %es - movw %ax, %fs - movw %ax, %gs - movw %bp, %ss - movl %edx, %esp - - /* Return to real-mode address */ - data32 ret - - - /* Real-mode code and data segments. Assigned by the call to - * init_librm. rm_cs doubles as the segment part of the jump - * instruction used by prot_to_real. Both are located in - * .text16 rather than .data16: rm_cs since it forms part of - * the jump instruction within the code segment, and rm_ds - * since real-mode code needs to be able to locate the data - * segment with no other reference available. - */ - .globl rm_cs - .equ rm_cs, ( p2r_ljmp_rm_cs + 3 ) - - .section ".text16.data", "aw", @progbits - .globl rm_ds -rm_ds: .word 0 - - /* Real-mode global and interrupt descriptor table registers */ - .section ".text16.data", "aw", @progbits -rm_gdtr: - .word 0 /* Limit */ - .long 0 /* Base */ - -/**************************************************************************** - * prot_call (real-mode far call, 16-bit real-mode far return address) - * - * Call a specific C function in the protected-mode code. The - * prototype of the C function must be - * void function ( struct i386_all_regs *ix86 ); - * ix86 will point to a struct containing the real-mode registers - * at entry to prot_call. - * - * All registers will be preserved across prot_call(), unless the C - * function explicitly overwrites values in ix86. Interrupt status - * and GDT will also be preserved. Gate A20 will be enabled. - * - * Note that prot_call() does not rely on the real-mode stack - * remaining intact in order to return, since everything relevant is - * copied to the protected-mode stack for the duration of the call. - * In particular, this means that a real-mode prefix can make a call - * to main() which will return correctly even if the prefix's stack - * gets vapourised during the Etherboot run. (The prefix cannot rely - * on anything else on the stack being preserved, so should move any - * critical data to registers before calling main()). - * - * Parameters: - * function : virtual address of protected-mode function to call - * - * Example usage: - * pushl $pxe_api_call - * call prot_call - * addw $4, %sp - * to call in to the C function - * void pxe_api_call ( struct i386_all_regs *ix86 ); - **************************************************************************** - */ - -#define PC_OFFSET_GDT ( 0 ) -#define PC_OFFSET_IDT ( PC_OFFSET_GDT + 6 ) -#define PC_OFFSET_IX86 ( PC_OFFSET_IDT + 6 ) -#define PC_OFFSET_RETADDR ( PC_OFFSET_IX86 + SIZEOF_I386_ALL_REGS ) -#define PC_OFFSET_FUNCTION ( PC_OFFSET_RETADDR + 4 ) -#define PC_OFFSET_END ( PC_OFFSET_FUNCTION + 4 ) - - .section ".text16", "ax", @progbits - .code16 - .globl prot_call -prot_call: - /* Preserve registers, flags and GDT on external RM stack */ - pushfl - pushal - pushw %gs - pushw %fs - pushw %es - pushw %ds - pushw %ss - pushw %cs - subw $PC_OFFSET_IX86, %sp - movw %sp, %bp - sidt PC_OFFSET_IDT(%bp) - sgdt PC_OFFSET_GDT(%bp) - - /* For sanity's sake, clear the direction flag as soon as possible */ - cld - - /* Switch to protected mode and move register dump to PM stack */ - movl $PC_OFFSET_END, %ecx - pushl $pc_pmode - jmp real_to_prot - .section ".text", "ax", @progbits - .code32 -pc_pmode: - /* Call function */ - leal PC_OFFSET_IX86(%esp), %eax - pushl %eax - call *(PC_OFFSET_FUNCTION+4)(%esp) - popl %eax /* discard */ - - /* Switch to real mode and move register dump back to RM stack */ - movl $PC_OFFSET_END, %ecx - movl %esp, %esi - pushl $pc_rmode - jmp prot_to_real - .section ".text16", "ax", @progbits - .code16 -pc_rmode: - /* Restore registers and flags and return */ - addw $( PC_OFFSET_IX86 + 4 /* also skip %cs and %ss */ ), %sp - popw %ds - popw %es - popw %fs - popw %gs - popal - /* popal skips %esp. We therefore want to do "movl -20(%sp), - * %esp", but -20(%sp) is not a valid 80386 expression. - * Fortunately, prot_to_real() zeroes the high word of %esp, so - * we can just use -20(%esp) instead. - */ - addr32 movl -20(%esp), %esp - popfl - lret - -/**************************************************************************** - * real_call (protected-mode near call, 32-bit virtual return address) - * - * Call a real-mode function from protected-mode code. - * - * The non-segment register values will be passed directly to the - * real-mode code. The segment registers will be set as per - * prot_to_real. The non-segment register values set by the real-mode - * function will be passed back to the protected-mode caller. A - * result of this is that this routine cannot be called directly from - * C code, since it clobbers registers that the C ABI expects the - * callee to preserve. - * - * librm.h defines a convenient macro REAL_CODE() for using real_call. - * See librm.h and realmode.h for details and examples. - * - * Parameters: - * (32-bit) near pointer to real-mode function to call - * - * Returns: none - **************************************************************************** - */ - -#define RC_OFFSET_PRESERVE_REGS ( 0 ) -#define RC_OFFSET_RETADDR ( RC_OFFSET_PRESERVE_REGS + SIZEOF_I386_REGS ) -#define RC_OFFSET_FUNCTION ( RC_OFFSET_RETADDR + 4 ) -#define RC_OFFSET_END ( RC_OFFSET_FUNCTION + 4 ) - - .section ".text", "ax", @progbits - .code32 - .globl real_call -real_call: - /* Create register dump and function pointer copy on PM stack */ - pushal - pushl RC_OFFSET_FUNCTION(%esp) - - /* Switch to real mode and move register dump to RM stack */ - movl $( RC_OFFSET_RETADDR + 4 /* function pointer copy */ ), %ecx - pushl $rc_rmode - movl $rm_default_gdtr_idtr, %esi - jmp prot_to_real - .section ".text16", "ax", @progbits - .code16 -rc_rmode: - /* Call real-mode function */ - popl rc_function - popal - call *rc_function - pushal - - /* For sanity's sake, clear the direction flag as soon as possible */ - cld - - /* Switch to protected mode and move register dump back to PM stack */ - movl $RC_OFFSET_RETADDR, %ecx - pushl $rc_pmode - jmp real_to_prot - .section ".text", "ax", @progbits - .code32 -rc_pmode: - /* Restore registers and return */ - popal - ret - - - /* Function vector, used because "call xx(%sp)" is not a valid - * 16-bit expression. - */ - .section ".data16", "aw", @progbits -rc_function: .word 0, 0 - - /* Default real-mode global and interrupt descriptor table registers */ - .section ".data", "aw", @progbits -rm_default_gdtr_idtr: - .word 0 /* Global descriptor table limit */ - .long 0 /* Global descriptor table base */ - .word 0x03ff /* Interrupt descriptor table limit */ - .long 0 /* Interrupt descriptor table base */ - -/**************************************************************************** - * flatten_real_mode (real-mode near call) - * - * Switch to flat real mode - * - **************************************************************************** - */ - .section ".text16", "ax", @progbits - .code16 - .globl flatten_real_mode -flatten_real_mode: - /* Modify GDT to use flat real mode */ - movb $0x8f, real_cs + 6 - movb $0x8f, real_ds + 6 - /* Call dummy protected-mode function */ - pushl $flatten_dummy - pushw %cs - call prot_call - addw $4, %sp - /* Restore GDT */ - movb $0x00, real_cs + 6 - movb $0x00, real_ds + 6 - /* Return */ - ret - - .section ".text", "ax", @progbits - .code32 -flatten_dummy: - ret - -/**************************************************************************** - * Interrupt wrapper - * - * Used by the protected-mode interrupt vectors to call the - * interrupt() function. - * - * May be entered with either physical or virtual stack segment. - **************************************************************************** - */ - .globl interrupt_wrapper -interrupt_wrapper: - /* Preserve segment registers and original %esp */ - pushl %ds - pushl %es - pushl %fs - pushl %gs - pushl %ss - pushl %esp - - /* Switch to virtual addressing */ - call _intr_to_virt - - /* Expand IRQ number to whole %eax register */ - movzbl %al, %eax - - /* Call interrupt handler */ - call interrupt - - /* Restore original stack and segment registers */ - lss (%esp), %esp - popl %ss - popl %gs - popl %fs - popl %es - popl %ds - - /* Restore registers and return */ - popal - iret - -/**************************************************************************** - * Stored real-mode and protected-mode stack pointers - * - * The real-mode stack pointer is stored here whenever real_to_prot - * is called and restored whenever prot_to_real is called. The - * converse happens for the protected-mode stack pointer. - * - * Despite initial appearances this scheme is, in fact re-entrant, - * because program flow dictates that we always return via the point - * we left by. For example: - * PXE API call entry - * 1 real => prot - * ... - * Print a text string - * ... - * 2 prot => real - * INT 10 - * 3 real => prot - * ... - * ... - * 4 prot => real - * PXE API call exit - * - * At point 1, the RM mode stack value, say RPXE, is stored in - * rm_ss,sp. We want this value to still be present in rm_ss,sp when - * we reach point 4. - * - * At point 2, the RM stack value is restored from RPXE. At point 3, - * the RM stack value is again stored in rm_ss,sp. This *does* - * overwrite the RPXE that we have stored there, but it's the same - * value, since the code between points 2 and 3 has managed to return - * to us. - **************************************************************************** - */ - .section ".data", "aw", @progbits - .globl rm_sp -rm_sp: .word 0 - .globl rm_ss -rm_ss: .word 0 -pm_esp: .long _estack - -/**************************************************************************** - * Virtual address offsets - * - * These are used by the protected-mode code to map between virtual - * and physical addresses, and to access variables in the .text16 or - * .data16 segments. - **************************************************************************** - */ - /* Internal copies, created by init_librm (which runs in real mode) */ - .section ".data16", "aw", @progbits -rm_virt_offset: .long 0 -rm_text16: .long 0 -rm_data16: .long 0 - - /* Externally-visible copies, created by real_to_prot */ - .section ".data", "aw", @progbits - .globl virt_offset -virt_offset: .long 0 - .globl text16 -text16: .long 0 - .globl data16 -data16: .long 0 diff --git a/qemu/roms/ipxe/src/arch/i386/transitions/librm_mgmt.c b/qemu/roms/ipxe/src/arch/i386/transitions/librm_mgmt.c deleted file mode 100644 index becb02677..000000000 --- a/qemu/roms/ipxe/src/arch/i386/transitions/librm_mgmt.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * librm: a library for interfacing to real-mode code - * - * Michael Brown <mbrown@fensystems.co.uk> - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdint.h> -#include <ipxe/profile.h> -#include <realmode.h> -#include <pic8259.h> - -/* - * This file provides functions for managing librm. - * - */ - -/** The interrupt wrapper */ -extern char interrupt_wrapper[]; - -/** The interrupt vectors */ -static struct interrupt_vector intr_vec[NUM_INT]; - -/** The interrupt descriptor table */ -struct interrupt_descriptor idt[NUM_INT] __attribute__ (( aligned ( 16 ) )); - -/** The interrupt descriptor table register */ -struct idtr idtr = { - .limit = ( sizeof ( idt ) - 1 ), -}; - -/** Timer interrupt profiler */ -static struct profiler timer_irq_profiler __profiler = { .name = "irq.timer" }; - -/** Other interrupt profiler */ -static struct profiler other_irq_profiler __profiler = { .name = "irq.other" }; - -/** - * Allocate space on the real-mode stack and copy data there from a - * user buffer - * - * @v data User buffer - * @v size Size of stack data - * @ret sp New value of real-mode stack pointer - */ -uint16_t copy_user_to_rm_stack ( userptr_t data, size_t size ) { - userptr_t rm_stack; - rm_sp -= size; - rm_stack = real_to_user ( rm_ss, rm_sp ); - memcpy_user ( rm_stack, 0, data, 0, size ); - return rm_sp; -}; - -/** - * Deallocate space on the real-mode stack, optionally copying back - * data to a user buffer. - * - * @v data User buffer - * @v size Size of stack data - */ -void remove_user_from_rm_stack ( userptr_t data, size_t size ) { - if ( data ) { - userptr_t rm_stack = real_to_user ( rm_ss, rm_sp ); - memcpy_user ( rm_stack, 0, data, 0, size ); - } - rm_sp += size; -}; - -/** - * Set interrupt vector - * - * @v intr Interrupt number - * @v vector Interrupt vector, or NULL to disable - */ -void set_interrupt_vector ( unsigned int intr, void *vector ) { - struct interrupt_descriptor *idte; - - idte = &idt[intr]; - idte->segment = VIRTUAL_CS; - idte->attr = ( vector ? ( IDTE_PRESENT | IDTE_TYPE_IRQ32 ) : 0 ); - idte->low = ( ( ( uint32_t ) vector ) & 0xffff ); - idte->high = ( ( ( uint32_t ) vector ) >> 16 ); -} - -/** - * Initialise interrupt descriptor table - * - */ -void init_idt ( void ) { - struct interrupt_vector *vec; - unsigned int intr; - - /* Initialise the interrupt descriptor table and interrupt vectors */ - for ( intr = 0 ; intr < NUM_INT ; intr++ ) { - vec = &intr_vec[intr]; - vec->pushal = PUSHAL_INSN; - vec->movb = MOVB_INSN; - vec->intr = intr; - vec->jmp = JMP_INSN; - vec->offset = ( ( uint32_t ) interrupt_wrapper - - ( uint32_t ) vec->next ); - set_interrupt_vector ( intr, vec ); - } - DBGC ( &intr_vec[0], "INTn vector at %p+%zxn (phys %#lx+%zxn)\n", - intr_vec, sizeof ( intr_vec[0] ), - virt_to_phys ( intr_vec ), sizeof ( intr_vec[0] ) ); - - /* Initialise the interrupt descriptor table register */ - idtr.base = virt_to_phys ( idt ); -} - -/** - * Determine interrupt profiler (for debugging) - * - * @v intr Interrupt number - * @ret profiler Profiler - */ -static struct profiler * interrupt_profiler ( int intr ) { - - switch ( intr ) { - case IRQ_INT ( 0 ) : - return &timer_irq_profiler; - default: - return &other_irq_profiler; - } -} - -/** - * Interrupt handler - * - * @v intr Interrupt number - */ -void __attribute__ (( cdecl, regparm ( 1 ) )) interrupt ( int intr ) { - struct profiler *profiler = interrupt_profiler ( intr ); - uint32_t discard_eax; - - /* Reissue interrupt in real mode */ - profile_start ( profiler ); - __asm__ __volatile__ ( REAL_CODE ( "movb %%al, %%cs:(1f + 1)\n\t" - "\n1:\n\t" - "int $0x00\n\t" ) - : "=a" ( discard_eax ) : "0" ( intr ) ); - profile_stop ( profiler ); - profile_exclude ( profiler ); -} - -PROVIDE_UACCESS_INLINE ( librm, phys_to_user ); -PROVIDE_UACCESS_INLINE ( librm, user_to_phys ); -PROVIDE_UACCESS_INLINE ( librm, virt_to_user ); -PROVIDE_UACCESS_INLINE ( librm, user_to_virt ); -PROVIDE_UACCESS_INLINE ( librm, userptr_add ); -PROVIDE_UACCESS_INLINE ( librm, memcpy_user ); -PROVIDE_UACCESS_INLINE ( librm, memmove_user ); -PROVIDE_UACCESS_INLINE ( librm, memset_user ); -PROVIDE_UACCESS_INLINE ( librm, strlen_user ); -PROVIDE_UACCESS_INLINE ( librm, memchr_user ); diff --git a/qemu/roms/ipxe/src/arch/i386/transitions/librm_test.c b/qemu/roms/ipxe/src/arch/i386/transitions/librm_test.c deleted file mode 100644 index f1a517eda..000000000 --- a/qemu/roms/ipxe/src/arch/i386/transitions/librm_test.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 2014 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 ); - -/** @file - * - * Real mode transition self-tests - * - * This file allows for easy measurement of the time taken to perform - * real mode transitions, which may have a substantial overhead when - * running under a hypervisor. - * - */ - -/* Forcibly enable assertions */ -#undef NDEBUG - -#include <ipxe/test.h> -#include <ipxe/profile.h> -#include <realmode.h> - -/** Number of sample iterations for profiling */ -#define PROFILE_COUNT 4096 - -/** Protected-to-real mode transition profiler */ -static struct profiler p2r_profiler __profiler = { .name = "p2r" }; - -/** Real-to-protected mode transition profiler */ -static struct profiler r2p_profiler __profiler = { .name = "r2p" }; - -/** Real-mode call profiler */ -static struct profiler real_call_profiler __profiler = { .name = "real_call" }; - -/** Protected-mode call profiler */ -static struct profiler prot_call_profiler __profiler = { .name = "prot_call" }; - -/** - * Dummy protected-mode function - */ -static void librm_test_prot_call ( void ) { - /* Do nothing */ -} - -/** - * Perform real mode transition self-tests - * - */ -static void librm_test_exec ( void ) { - unsigned int i; - unsigned long timestamp; - unsigned long started; - unsigned long stopped; - unsigned int discard_d; - - /* Profile mode transitions. We want to profile each - * direction of the transition separately, so perform an RDTSC - * while in real mode and tweak the profilers' start/stop - * times appropriately. - */ - for ( i = 0 ; i < PROFILE_COUNT ; i++ ) { - profile_start ( &p2r_profiler ); - __asm__ __volatile__ ( REAL_CODE ( "rdtsc\n\t" ) - : "=a" ( timestamp ), "=d" ( discard_d ) - : ); - profile_start_at ( &r2p_profiler, timestamp ); - profile_stop ( &r2p_profiler ); - profile_stop_at ( &p2r_profiler, timestamp ); - } - - /* Profile complete real-mode call cycle */ - for ( i = 0 ; i < PROFILE_COUNT ; i++ ) { - profile_start ( &real_call_profiler ); - __asm__ __volatile__ ( REAL_CODE ( "" ) : : ); - profile_stop ( &real_call_profiler ); - } - - /* Profile complete protected-mode call cycle */ - for ( i = 0 ; i < PROFILE_COUNT ; i++ ) { - __asm__ __volatile__ ( REAL_CODE ( "rdtsc\n\t" - "movl %0, %2\n\t" - "pushl %3\n\t" - "pushw %%cs\n\t" - "call prot_call\n\t" - "addw $4, %%sp\n\t" - "rdtsc\n\t" ) - : "=a" ( stopped ), "=d" ( discard_d ), - "=r" ( started ) - : "i" ( librm_test_prot_call ) ); - profile_start_at ( &prot_call_profiler, started ); - profile_stop_at ( &prot_call_profiler, stopped ); - } -} - -/** Real mode transition self-test */ -struct self_test librm_test __self_test = { - .name = "librm", - .exec = librm_test_exec, -}; - -REQUIRING_SYMBOL ( librm_test ); -REQUIRE_OBJECT ( test ); |