summaryrefslogtreecommitdiffstats
path: root/qemu/roms/ipxe/src/interface
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/roms/ipxe/src/interface')
-rw-r--r--qemu/roms/ipxe/src/interface/bofm/bofm.c345
-rw-r--r--qemu/roms/ipxe/src/interface/efi/efi_autoboot.c71
-rw-r--r--qemu/roms/ipxe/src/interface/efi/efi_bofm.c338
-rw-r--r--qemu/roms/ipxe/src/interface/efi/efi_console.c360
-rw-r--r--qemu/roms/ipxe/src/interface/efi/efi_debug.c665
-rw-r--r--qemu/roms/ipxe/src/interface/efi/efi_download.c240
-rw-r--r--qemu/roms/ipxe/src/interface/efi/efi_driver.c517
-rw-r--r--qemu/roms/ipxe/src/interface/efi/efi_file.c718
-rw-r--r--qemu/roms/ipxe/src/interface/efi/efi_guid.c209
-rw-r--r--qemu/roms/ipxe/src/interface/efi/efi_hii.c581
-rw-r--r--qemu/roms/ipxe/src/interface/efi/efi_init.c226
-rw-r--r--qemu/roms/ipxe/src/interface/efi/efi_pci.c361
-rw-r--r--qemu/roms/ipxe/src/interface/efi/efi_reboot.c65
-rw-r--r--qemu/roms/ipxe/src/interface/efi/efi_smbios.c67
-rw-r--r--qemu/roms/ipxe/src/interface/efi/efi_snp.c1248
-rw-r--r--qemu/roms/ipxe/src/interface/efi/efi_snp_hii.c727
-rw-r--r--qemu/roms/ipxe/src/interface/efi/efi_strings.c152
-rw-r--r--qemu/roms/ipxe/src/interface/efi/efi_time.c75
-rw-r--r--qemu/roms/ipxe/src/interface/efi/efi_timer.c128
-rw-r--r--qemu/roms/ipxe/src/interface/efi/efi_uaccess.c44
-rw-r--r--qemu/roms/ipxe/src/interface/efi/efi_umalloc.c108
-rw-r--r--qemu/roms/ipxe/src/interface/efi/efi_utils.c218
-rw-r--r--qemu/roms/ipxe/src/interface/efi/efi_watchdog.c82
-rw-r--r--qemu/roms/ipxe/src/interface/efi/efi_wrap.c319
-rw-r--r--qemu/roms/ipxe/src/interface/hyperv/vmbus.c1333
-rw-r--r--qemu/roms/ipxe/src/interface/linux/linux_console.c155
-rw-r--r--qemu/roms/ipxe/src/interface/linux/linux_entropy.c101
-rw-r--r--qemu/roms/ipxe/src/interface/linux/linux_nap.c41
-rw-r--r--qemu/roms/ipxe/src/interface/linux/linux_pci.c189
-rw-r--r--qemu/roms/ipxe/src/interface/linux/linux_smbios.c115
-rw-r--r--qemu/roms/ipxe/src/interface/linux/linux_time.c50
-rw-r--r--qemu/roms/ipxe/src/interface/linux/linux_timer.c87
-rw-r--r--qemu/roms/ipxe/src/interface/linux/linux_uaccess.c38
-rw-r--r--qemu/roms/ipxe/src/interface/linux/linux_umalloc.c154
-rw-r--r--qemu/roms/ipxe/src/interface/smbios/smbios.c252
-rw-r--r--qemu/roms/ipxe/src/interface/smbios/smbios_settings.c259
-rw-r--r--qemu/roms/ipxe/src/interface/xen/xenbus.c397
-rw-r--r--qemu/roms/ipxe/src/interface/xen/xengrant.c232
-rw-r--r--qemu/roms/ipxe/src/interface/xen/xenstore.c555
39 files changed, 0 insertions, 11822 deletions
diff --git a/qemu/roms/ipxe/src/interface/bofm/bofm.c b/qemu/roms/ipxe/src/interface/bofm/bofm.c
deleted file mode 100644
index 545088dc6..000000000
--- a/qemu/roms/ipxe/src/interface/bofm/bofm.c
+++ /dev/null
@@ -1,345 +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 );
-
-#include <stdint.h>
-#include <string.h>
-#include <errno.h>
-#include <ipxe/uaccess.h>
-#include <ipxe/list.h>
-#include <ipxe/ethernet.h>
-#include <ipxe/bofm.h>
-
-/** @file
- *
- * IBM BladeCenter Open Fabric Manager (BOFM)
- *
- */
-
-/** List of BOFM devices */
-static LIST_HEAD ( bofmdevs );
-
-/**
- * Register BOFM device
- *
- * @v bofm BOFM device
- * @ret rc Return status code
- */
-int bofm_register ( struct bofm_device *bofm ) {
-
- list_add ( &bofm->list, &bofmdevs );
- DBG ( "BOFM: " PCI_FMT " registered using driver \"%s\"\n",
- PCI_ARGS ( bofm->pci ), bofm->pci->id->name );
- return 0;
-}
-
-/**
- * Unregister BOFM device
- *
- * @v bofm BOFM device
- */
-void bofm_unregister ( struct bofm_device *bofm ) {
-
- list_del ( &bofm->list );
- DBG ( "BOFM: " PCI_FMT " unregistered\n", PCI_ARGS ( bofm->pci ) );
-}
-
-/**
- * Find BOFM device matching PCI bus:dev.fn address
- *
- * @v busdevfn PCI bus:dev.fn address
- * @ret bofm BOFM device, or NULL
- */
-static struct bofm_device * bofm_find_busdevfn ( unsigned int busdevfn ) {
- struct bofm_device *bofm;
-
- list_for_each_entry ( bofm, &bofmdevs, list ) {
- if ( bofm->pci->busdevfn == busdevfn )
- return bofm;
- }
- return NULL;
-}
-
-/**
- * Find BOFM driver for PCI device
- *
- * @v pci PCI device
- * @ret rc Return status code
- */
-int bofm_find_driver ( struct pci_device *pci ) {
- struct pci_driver *driver;
- struct pci_device_id *id;
- unsigned int i;
-
- for_each_table_entry ( driver, BOFM_DRIVERS ) {
- for ( i = 0 ; i < driver->id_count ; i++ ) {
- id = &driver->ids[i];
- if ( ( id->vendor == pci->vendor ) &&
- ( id->device == pci->device ) ) {
- pci_set_driver ( pci, driver, id );
- return 0;
- }
- }
- }
- return -ENOENT;
-}
-
-/**
- * Probe PCI device for BOFM driver
- *
- * @v pci PCI device
- * @ret rc Return status code
- */
-static int bofm_probe ( struct pci_device *pci ) {
- int rc;
-
- /* Probe device */
- if ( ( rc = pci_probe ( pci ) ) != 0 ) {
- DBG ( "BOFM: " PCI_FMT " could not load driver: %s\n",
- PCI_ARGS ( pci ), strerror ( rc ) );
- return rc;
- }
-
- return 0;
-}
-
-/**
- * Remove PCI device
- *
- * @v pci PCI device
- */
-static void bofm_remove ( struct pci_device *pci ) {
-
- /* Note that the IBM BIOS may re-read the expansion ROM after
- * the BOFM initialisation call. The BOFM driver must ensure
- * that the card is left in a state in which expansion ROM
- * reads will succeed. (For example, if a card contains an
- * embedded CPU that may issue reads to the same underlying
- * flash device, and these reads are not locked against reads
- * via the expansion ROM BAR, then the CPU must be stopped.)
- *
- * If this is not done, then occasional corrupted reads from
- * the expansion ROM will be seen, and the BIOS may complain
- * about a ROM checksum error.
- */
- pci_remove ( pci );
- DBG ( "BOFM: " PCI_FMT " removed\n", PCI_ARGS ( pci ) );
-}
-
-/**
- * Locate BOFM table section
- *
- * @v bofmtab BOFM table
- * @v len Length of BOFM table
- * @v magic Section magic
- * @v bofmsec BOFM section header to fill in
- * @ret offset Offset to section, or 0 if not found
- */
-static size_t bofm_locate_section ( userptr_t bofmtab, size_t len,
- uint32_t magic,
- struct bofm_section_header *bofmsec ) {
- size_t offset = sizeof ( struct bofm_global_header );
-
- while ( offset < len ) {
- copy_from_user ( bofmsec, bofmtab, offset,
- sizeof ( *bofmsec ) );
- if ( bofmsec->magic == magic )
- return offset;
- if ( bofmsec->magic == BOFM_DONE_MAGIC )
- break;
- offset += ( sizeof ( *bofmsec ) + bofmsec->length );
- }
- return 0;
-}
-
-/**
- * Process BOFM Ethernet parameter entry
- *
- * @v bofm BOFM device
- * @v en EN parameter entry
- * @ret rc Return status code
- */
-static int bofm_en ( struct bofm_device *bofm, struct bofm_en *en ) {
- uint8_t mac[6];
- int rc;
-
- /* Retrieve current MAC address */
- if ( ( rc = bofm->op->harvest ( bofm, en->mport, mac ) ) != 0 ) {
- DBG ( "BOFM: " PCI_FMT " mport %d could not harvest: %s\n",
- PCI_ARGS ( bofm->pci ), en->mport, strerror ( rc ) );
- return rc;
- }
-
- /* Harvest MAC address if necessary */
- if ( en->options & BOFM_EN_RQ_HVST_MASK ) {
- DBG ( "BOFM: " PCI_FMT " mport %d harvested MAC %s\n",
- PCI_ARGS ( bofm->pci ), en->mport, eth_ntoa ( mac ) );
- memcpy ( en->mac_a, mac, sizeof ( en->mac_a ) );
- en->options |= ( BOFM_EN_EN_A | BOFM_EN_HVST );
- }
-
- /* Mark as changed if necessary */
- if ( ( en->options & BOFM_EN_EN_A ) &&
- ( memcmp ( en->mac_a, mac, sizeof ( en->mac_a ) ) != 0 ) ) {
- DBG ( "BOFM: " PCI_FMT " mport %d MAC %s",
- PCI_ARGS ( bofm->pci ), en->mport, eth_ntoa ( mac ) );
- DBG ( " changed to %s\n", eth_ntoa ( en->mac_a ) );
- en->options |= BOFM_EN_CHG_CHANGED;
- }
-
- /* Apply MAC address if necessary */
- if ( ( en->options & BOFM_EN_EN_A ) &&
- ( en->options & BOFM_EN_USAGE_ENTRY ) &&
- ( ! ( en->options & BOFM_EN_USAGE_HARVEST ) ) ) {
- DBG ( "BOFM: " PCI_FMT " mport %d applied MAC %s\n",
- PCI_ARGS ( bofm->pci ), en->mport,
- eth_ntoa ( en->mac_a ) );
- memcpy ( mac, en->mac_a, sizeof ( mac ) );
- }
-
- /* Store MAC address */
- if ( ( rc = bofm->op->update ( bofm, en->mport, mac ) ) != 0 ) {
- DBG ( "BOFM: " PCI_FMT " mport %d could not update: %s\n",
- PCI_ARGS ( bofm->pci ), en->mport, strerror ( rc ) );
- return rc;
- }
-
- return 0;
-}
-
-/**
- * Process BOFM table
- *
- * @v bofmtab BOFM table
- * @v pci PCI device
- * @ret bofmrc BOFM return status
- */
-int bofm ( userptr_t bofmtab, struct pci_device *pci ) {
- struct bofm_global_header bofmhdr;
- struct bofm_section_header bofmsec;
- struct bofm_en en;
- struct bofm_device *bofm;
- size_t en_region_offset;
- size_t en_offset;
- int skip;
- int rc;
- int bofmrc;
-
- /* Read BOFM structure */
- copy_from_user ( &bofmhdr, bofmtab, 0, sizeof ( bofmhdr ) );
- if ( bofmhdr.magic != BOFM_IOAA_MAGIC ) {
- DBG ( "BOFM: invalid table signature " BOFM_MAGIC_FMT "\n",
- BOFM_MAGIC_ARGS ( bofmhdr.magic ) );
- bofmrc = BOFM_ERR_INVALID_ACTION;
- goto err_bad_signature;
- }
- DBG ( "BOFM: " BOFM_MAGIC_FMT " (profile \"%s\")\n",
- BOFM_MAGIC_ARGS ( bofmhdr.action ), bofmhdr.profile );
-
- /* Determine whether or not we should skip normal POST
- * initialisation.
- */
- switch ( bofmhdr.action ) {
- case BOFM_ACTION_UPDT:
- case BOFM_ACTION_DFLT:
- case BOFM_ACTION_HVST:
- skip = BOFM_SKIP_INIT;
- break;
- case BOFM_ACTION_PARM:
- case BOFM_ACTION_NONE:
- skip = 0;
- break;
- default:
- DBG ( "BOFM: invalid action " BOFM_MAGIC_FMT "\n",
- BOFM_MAGIC_ARGS ( bofmhdr.action ) );
- bofmrc = BOFM_ERR_INVALID_ACTION;
- goto err_bad_action;
- }
-
- /* Find BOFM driver */
- if ( ( rc = bofm_find_driver ( pci ) ) != 0 ) {
- DBG ( "BOFM: " PCI_FMT " has no driver\n", PCI_ARGS ( pci ) );
- bofmrc = BOFM_ERR_DEVICE_ERROR;
- goto err_find_driver;
- }
-
- /* Probe driver for PCI device */
- if ( ( rc = bofm_probe ( pci ) ) != 0 ) {
- bofmrc = BOFM_ERR_DEVICE_ERROR;
- goto err_probe;
- }
-
- /* Locate EN section, if present */
- en_region_offset = bofm_locate_section ( bofmtab, bofmhdr.length,
- BOFM_EN_MAGIC, &bofmsec );
- if ( ! en_region_offset ) {
- DBG ( "BOFM: No EN section found\n" );
- bofmrc = ( BOFM_SUCCESS | skip );
- goto err_no_en_section;
- }
-
- /* Iterate through EN entries */
- for ( en_offset = ( en_region_offset + sizeof ( bofmsec ) ) ;
- en_offset < ( en_region_offset + sizeof ( bofmsec ) +
- bofmsec.length ) ; en_offset += sizeof ( en ) ) {
- copy_from_user ( &en, bofmtab, en_offset, sizeof ( en ) );
- DBG2 ( "BOFM: EN entry found:\n" );
- DBG2_HDA ( en_offset, &en, sizeof ( en ) );
- if ( ( en.options & BOFM_EN_MAP_MASK ) != BOFM_EN_MAP_PFA ) {
- DBG ( "BOFM: slot %d port %d has no PCI mapping\n",
- en.slot, ( en.port + 1 ) );
- continue;
- }
- DBG ( "BOFM: slot %d port %d%s is " PCI_FMT " mport %d\n",
- en.slot, ( en.port + 1 ),
- ( ( en.slot || en.port ) ? "" : "(?)" ),
- PCI_BUS ( en.busdevfn ), PCI_SLOT ( en.busdevfn ),
- PCI_FUNC ( en.busdevfn ), en.mport );
- bofm = bofm_find_busdevfn ( en.busdevfn );
- if ( ! bofm ) {
- DBG ( "BOFM: " PCI_FMT " mport %d ignored\n",
- PCI_BUS ( en.busdevfn ), PCI_SLOT ( en.busdevfn ),
- PCI_FUNC ( en.busdevfn ), en.mport );
- continue;
- }
- if ( ( rc = bofm_en ( bofm, &en ) ) == 0 ) {
- en.options |= BOFM_EN_CSM_SUCCESS;
- } else {
- en.options |= BOFM_EN_CSM_FAILED;
- }
- DBG2 ( "BOFM: EN entry after processing:\n" );
- DBG2_HDA ( en_offset, &en, sizeof ( en ) );
- copy_to_user ( bofmtab, en_offset, &en, sizeof ( en ) );
- }
-
- bofmrc = ( BOFM_SUCCESS | skip );
-
- err_no_en_section:
- bofm_remove ( pci );
- err_probe:
- err_find_driver:
- err_bad_action:
- err_bad_signature:
- return bofmrc;
-}
diff --git a/qemu/roms/ipxe/src/interface/efi/efi_autoboot.c b/qemu/roms/ipxe/src/interface/efi/efi_autoboot.c
deleted file mode 100644
index a9e807e23..000000000
--- a/qemu/roms/ipxe/src/interface/efi/efi_autoboot.c
+++ /dev/null
@@ -1,71 +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 );
-
-#include <ipxe/efi/efi.h>
-#include <ipxe/efi/efi_autoboot.h>
-#include <ipxe/efi/Protocol/SimpleNetwork.h>
-#include <usr/autoboot.h>
-
-/** @file
- *
- * EFI autoboot device
- *
- */
-
-/**
- * Identify autoboot device
- *
- */
-void efi_set_autoboot ( void ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- union {
- EFI_SIMPLE_NETWORK_PROTOCOL *snp;
- void *interface;
- } snp;
- EFI_SIMPLE_NETWORK_MODE *mode;
- EFI_STATUS efirc;
-
- /* Look for an SNP instance on the image's device handle */
- if ( ( efirc = bs->OpenProtocol ( efi_loaded_image->DeviceHandle,
- &efi_simple_network_protocol_guid,
- &snp.interface, efi_image_handle,
- NULL,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
- DBGC ( efi_loaded_image, "EFI found no autoboot device\n" );
- return;
- }
-
- /* Record autoboot device */
- mode = snp.snp->Mode;
- set_autoboot_ll_addr ( &mode->CurrentAddress, mode->HwAddressSize );
- DBGC ( efi_loaded_image, "EFI found autoboot link-layer address:\n" );
- DBGC_HDA ( efi_loaded_image, 0, &mode->CurrentAddress,
- mode->HwAddressSize );
-
- /* Close protocol */
- bs->CloseProtocol ( efi_loaded_image->DeviceHandle,
- &efi_simple_network_protocol_guid,
- efi_image_handle, NULL );
-}
diff --git a/qemu/roms/ipxe/src/interface/efi/efi_bofm.c b/qemu/roms/ipxe/src/interface/efi/efi_bofm.c
deleted file mode 100644
index ea0e15f7f..000000000
--- a/qemu/roms/ipxe/src/interface/efi/efi_bofm.c
+++ /dev/null
@@ -1,338 +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 );
-
-#include <errno.h>
-#include <ipxe/bofm.h>
-#include <ipxe/efi/efi.h>
-#include <ipxe/efi/efi_pci.h>
-#include <ipxe/efi/efi_driver.h>
-
-/** @file
- *
- * IBM BladeCenter Open Fabric Manager (BOFM) EFI interface
- *
- */
-
-/***************************************************************************
- *
- * EFI BOFM definitions
- *
- ***************************************************************************
- *
- * Taken from the BOFM UEFI Vendor Specification document
- *
- */
-
-#define IBM_BOFM_DRIVER_CONFIGURATION_PROTOCOL_GUID \
- { 0x03207ce2, 0xd9c7, 0x11dc, \
- { 0xa9, 0x4d, 0x00, 0x19, 0x7d, 0x89, 0x02, 0x38 } }
-
-#define IBM_BOFM_DRIVER_CONFIGURATION2_PROTOCOL_GUID \
- { 0xe82a9763, 0x0584, 0x4e41, \
- { 0xbb, 0x39, 0xe0, 0xcd, 0xb8, 0xc1, 0xf0, 0xfc } }
-
-typedef struct {
- UINT8 Id;
- UINT8 ResultByte;
-} __attribute__ (( packed )) BOFM_EPID_Results_t;
-
-typedef struct {
- UINT8 Version;
- UINT8 Level;
- UINT16 Length;
- UINT8 Checksum;
- UINT8 Profile[32];
- UINT8 GlobalOption0;
- UINT8 GlobalOption1;
- UINT8 GlobalOption2;
- UINT8 GlobalOption3;
- UINT32 SequenceStamp;
- UINT8 Regions[911]; // For use by BOFM Driver
- UINT32 Reserved1;
-} __attribute__ (( packed )) BOFM_Parameters_t;
-
-typedef struct {
- UINT32 Reserved1;
- UINT8 Version;
- UINT8 Level;
- UINT8 Checksum;
- UINT32 SequenceStamp;
- UINT8 SUIDResults;
- UINT8 EntryResults[32];
- UINT8 Reserved2;
- UINT8 Reserved3;
- UINT8 FCTgtResults[2];
- UINT8 SASTgtResults[2];
- BOFM_EPID_Results_t EPIDResults[2];
- UINT8 Results4[10];
-} __attribute__ (( packed )) BOFM_Results_t;
-
-typedef struct {
- UINT32 Signature;
- UINT32 SubSignature;
- BOFM_Parameters_t Parameters;
- BOFM_Results_t Results;
-} __attribute__ (( packed )) BOFM_DataStructure_t;
-
-#define IBM_BOFM_TABLE BOFM_DataStructure_t
-
-typedef struct _IBM_BOFM_DRIVER_CONFIGURATION_PROTOCOL
- IBM_BOFM_DRIVER_CONFIGURATION_PROTOCOL;
-
-typedef struct _IBM_BOFM_DRIVER_CONFIGURATION_PROTOCOL2
- IBM_BOFM_DRIVER_CONFIGURATION_PROTOCOL2;
-
-typedef EFI_STATUS ( EFIAPI *IBM_BOFM_DRIVER_CONFIGURATION_SUPPORT ) (
- IN IBM_BOFM_DRIVER_CONFIGURATION_PROTOCOL *This,
- EFI_HANDLE ControllerHandle,
- UINT8 SupporttedOptions,
- UINT8 iSCSI_Parameter_Version,
- UINT8 BOFM_Parameter_Version
-);
-
-typedef EFI_STATUS ( EFIAPI *IBM_BOFM_DRIVER_CONFIGURATION_STATUS ) (
- IN IBM_BOFM_DRIVER_CONFIGURATION_PROTOCOL *This,
- EFI_HANDLE ControllerHandle,
- BOOLEAN ResetRequired,
- UINT8 BOFMReturnCode
-);
-
-typedef EFI_STATUS ( EFIAPI *IBM_BOFM_DRIVER_CONFIGURATION_STATUS2 ) (
- IN IBM_BOFM_DRIVER_CONFIGURATION_PROTOCOL2 *This,
- EFI_HANDLE ControllerHandle,
- BOOLEAN ResetRequired,
- UINT8 BOFMReturnCode
-);
-
-struct _IBM_BOFM_DRIVER_CONFIGURATION_PROTOCOL {
- IBM_BOFM_TABLE BofmTable;
- IBM_BOFM_DRIVER_CONFIGURATION_STATUS SetStatus;
- IBM_BOFM_DRIVER_CONFIGURATION_SUPPORT RegisterSupport;
-};
-
-struct _IBM_BOFM_DRIVER_CONFIGURATION_PROTOCOL2 {
- UINT32 Signature;
- UINT32 Reserved1;
- UINT64 Reserved2;
- IBM_BOFM_DRIVER_CONFIGURATION_STATUS2 SetStatus;
- IBM_BOFM_DRIVER_CONFIGURATION_SUPPORT RegisterSupport;
- IBM_BOFM_TABLE BofmTable;
-};
-
-/***************************************************************************
- *
- * EFI BOFM interface
- *
- ***************************************************************************
- */
-
-/** BOFM1 protocol GUID */
-static EFI_GUID bofm1_protocol_guid =
- IBM_BOFM_DRIVER_CONFIGURATION_PROTOCOL_GUID;
-
-/** BOFM2 protocol GUID */
-static EFI_GUID bofm2_protocol_guid =
- IBM_BOFM_DRIVER_CONFIGURATION2_PROTOCOL_GUID;
-
-/**
- * Check if device is supported
- *
- * @v device EFI device handle
- * @ret rc Return status code
- */
-static int efi_bofm_supported ( EFI_HANDLE device ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- struct pci_device pci;
- union {
- IBM_BOFM_DRIVER_CONFIGURATION_PROTOCOL *bofm1;
- void *interface;
- } bofm1;
- EFI_STATUS efirc;
- int rc;
-
- /* Get PCI device information */
- if ( ( rc = efipci_info ( device, &pci ) ) != 0 )
- return rc;
-
- /* Look for a BOFM driver */
- if ( ( rc = bofm_find_driver ( &pci ) ) != 0 ) {
- DBGCP ( device, "EFIBOFM %p %s has no driver\n",
- device, efi_handle_name ( device ) );
- return rc;
- }
-
- /* Locate BOFM protocol */
- if ( ( efirc = bs->LocateProtocol ( &bofm1_protocol_guid, NULL,
- &bofm1.interface ) ) != 0 ) {
- rc = -EEFI ( efirc );
- DBGC ( device, "EFIBOFM %p %s cannot find BOFM protocol\n",
- device, efi_handle_name ( device ) );
- return rc;
- }
-
- /* Register support for this device */
- if ( ( efirc = bofm1.bofm1->RegisterSupport ( bofm1.bofm1, device,
- 0x04 /* Can change MAC */,
- 0x00 /* No iSCSI */,
- 0x02 /* Version */ ))!=0){
- rc = -EEFI ( efirc );
- DBGC ( device, "EFIBOFM %p %s could not register support: %s\n",
- device, efi_handle_name ( device ), strerror ( rc ) );
- return rc;
- }
-
- DBGC ( device, "EFIBOFM %p %s has driver \"%s\"\n",
- device, efi_handle_name ( device ), pci.id->name );
- return 0;
-}
-
-/**
- * Attach driver to device
- *
- * @v efidev EFI device
- * @ret rc Return status code
- */
-static int efi_bofm_start ( struct efi_device *efidev ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- EFI_HANDLE device = efidev->device;
- union {
- IBM_BOFM_DRIVER_CONFIGURATION_PROTOCOL *bofm1;
- void *interface;
- } bofm1;
- union {
- IBM_BOFM_DRIVER_CONFIGURATION_PROTOCOL2 *bofm2;
- void *interface;
- } bofm2;
- struct pci_device pci;
- IBM_BOFM_TABLE *bofmtab;
- IBM_BOFM_TABLE *bofmtab2;
- int bofmrc;
- EFI_STATUS efirc;
- int rc;
-
- /* Open PCI device, if possible */
- if ( ( rc = efipci_open ( device, EFI_OPEN_PROTOCOL_GET_PROTOCOL,
- &pci ) ) != 0 )
- goto err_open;
-
- /* Locate BOFM protocol */
- if ( ( efirc = bs->LocateProtocol ( &bofm1_protocol_guid, NULL,
- &bofm1.interface ) ) != 0 ) {
- rc = -EEFI ( efirc );
- DBGC ( device, "EFIBOFM %p %s cannot find BOFM protocol\n",
- device, efi_handle_name ( device ) );
- goto err_locate_bofm;
- }
- bofmtab = &bofm1.bofm1->BofmTable;
- DBGC ( device, "EFIBOFM %p %s found version 1 BOFM table at %p+%04x\n",
- device, efi_handle_name ( device ), bofmtab,
- bofmtab->Parameters.Length );
-
- /* Locate BOFM2 protocol, if available */
- if ( ( efirc = bs->LocateProtocol ( &bofm2_protocol_guid, NULL,
- &bofm2.interface ) ) == 0 ) {
- bofmtab2 = &bofm2.bofm2->BofmTable;
- DBGC ( device, "EFIBOFM %p %s found version 2 BOFM table at "
- "%p+%04x\n", device, efi_handle_name ( device ),
- bofmtab2, bofmtab2->Parameters.Length );
- assert ( bofm2.bofm2->RegisterSupport ==
- bofm1.bofm1->RegisterSupport );
- } else {
- DBGC ( device, "EFIBOFM %p %s cannot find BOFM2 protocol\n",
- device, efi_handle_name ( device ) );
- /* Not a fatal error; may be a BOFM1-only system */
- bofmtab2 = NULL;
- }
-
- /* Process BOFM table */
- DBGC2 ( device, "EFIBOFM %p %s version 1 before processing:\n",
- device, efi_handle_name ( device ) );
- DBGC2_HD ( device, bofmtab, bofmtab->Parameters.Length );
- if ( bofmtab2 ) {
- DBGC2 ( device, "EFIBOFM %p %s version 2 before processing:\n",
- device, efi_handle_name ( device ) );
- DBGC2_HD ( device, bofmtab2, bofmtab2->Parameters.Length );
- }
- bofmrc = bofm ( virt_to_user ( bofmtab2 ? bofmtab2 : bofmtab ), &pci );
- DBGC ( device, "EFIBOFM %p %s status %08x\n",
- device, efi_handle_name ( device ), bofmrc );
- DBGC2 ( device, "EFIBOFM %p %s version 1 after processing:\n",
- device, efi_handle_name ( device ) );
- DBGC2_HD ( device, bofmtab, bofmtab->Parameters.Length );
- if ( bofmtab2 ) {
- DBGC2 ( device, "EFIBOFM %p %s version 2 after processing:\n",
- device, efi_handle_name ( device ) );
- DBGC2_HD ( device, bofmtab2, bofmtab2->Parameters.Length );
- }
-
- /* Return BOFM status */
- if ( bofmtab2 ) {
- if ( ( efirc = bofm2.bofm2->SetStatus ( bofm2.bofm2, device,
- FALSE, bofmrc ) ) != 0){
- rc = -EEFI ( efirc );
- DBGC ( device, "EFIBOFM %p %s could not set BOFM2 "
- "status: %s\n", device,
- efi_handle_name ( device ), strerror ( rc ) );
- goto err_set_status;
- }
- } else {
- if ( ( efirc = bofm1.bofm1->SetStatus ( bofm1.bofm1, device,
- FALSE, bofmrc ) ) != 0){
- rc = -EEFI ( efirc );
- DBGC ( device, "EFIBOFM %p %s could not set BOFM "
- "status: %s\n", device,
- efi_handle_name ( device ), strerror ( rc ) );
- goto err_set_status;
- }
- }
-
- /* BOFM (ab)uses the "start" method to mean "process and exit" */
- rc = -EAGAIN;
-
- err_set_status:
- err_locate_bofm:
- efipci_close ( device );
- err_open:
- return rc;
-}
-
-/**
- * Detach driver from device
- *
- * @v device EFI device
- */
-static void efi_bofm_stop ( struct efi_device *efidev __unused ) {
-
- /* Should never happen */
- assert ( 0 );
-}
-
-/** EFI BOFM driver */
-struct efi_driver efi_bofm_driver __efi_driver ( EFI_DRIVER_EARLY ) = {
- .name = "BOFM",
- .supported = efi_bofm_supported,
- .start = efi_bofm_start,
- .stop = efi_bofm_stop,
-};
diff --git a/qemu/roms/ipxe/src/interface/efi/efi_console.c b/qemu/roms/ipxe/src/interface/efi/efi_console.c
deleted file mode 100644
index 3b30f3097..000000000
--- a/qemu/roms/ipxe/src/interface/efi/efi_console.c
+++ /dev/null
@@ -1,360 +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.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include <stddef.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <ipxe/efi/efi.h>
-#include <ipxe/efi/Protocol/ConsoleControl/ConsoleControl.h>
-#include <ipxe/ansiesc.h>
-#include <ipxe/console.h>
-#include <ipxe/init.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_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_EFI ) && CONSOLE_EXPLICIT ( CONSOLE_EFI ) )
-#undef CONSOLE_EFI
-#define CONSOLE_EFI ( CONSOLE_USAGE_ALL & ~CONSOLE_USAGE_LOG )
-#endif
-
-/** Current character attribute */
-static unsigned int efi_attr = ATTR_DEFAULT;
-
-/** Console control protocol */
-static EFI_CONSOLE_CONTROL_PROTOCOL *conctrl;
-EFI_REQUEST_PROTOCOL ( EFI_CONSOLE_CONTROL_PROTOCOL, &conctrl );
-
-/**
- * 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 efi_handle_cup ( struct ansiesc_context *ctx __unused,
- unsigned int count __unused, int params[] ) {
- EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *conout = efi_systab->ConOut;
- int cx = ( params[1] - 1 );
- int cy = ( params[0] - 1 );
-
- if ( cx < 0 )
- cx = 0;
- if ( cy < 0 )
- cy = 0;
-
- conout->SetCursorPosition ( conout, cx, cy );
-}
-
-/**
- * Handle ANSI ED (erase in page)
- *
- * @v ctx ANSI escape sequence context
- * @v count Parameter count
- * @v params[0] Region to erase
- */
-static void efi_handle_ed ( struct ansiesc_context *ctx __unused,
- unsigned int count __unused,
- int params[] __unused ) {
- EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *conout = efi_systab->ConOut;
-
- /* We assume that we always clear the whole screen */
- assert ( params[0] == ANSIESC_ED_ALL );
-
- conout->ClearScreen ( conout );
-}
-
-/**
- * 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 efi_handle_sgr ( struct ansiesc_context *ctx __unused,
- unsigned int count, int params[] ) {
- EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *conout = efi_systab->ConOut;
- static const uint8_t efi_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 efi_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 ) {
- efi_attr = ATTR_DEFAULT;
- } else if ( aspect == 1 ) {
- efi_attr |= ATTR_BOLD;
- } else if ( aspect == 22 ) {
- efi_attr &= ~ATTR_BOLD;
- } else if ( ( aspect >= 30 ) && ( aspect <= 39 ) ) {
- efi_attr &= ~ATTR_FCOL_MASK;
- efi_attr |= efi_attr_fcols[ aspect - 30 ];
- } else if ( ( aspect >= 40 ) && ( aspect <= 49 ) ) {
- efi_attr &= ~ATTR_BCOL_MASK;
- efi_attr |= efi_attr_bcols[ aspect - 40 ];
- }
- }
-
- conout->SetAttribute ( conout, efi_attr );
-}
-
-/**
- * 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 efi_handle_dectcem_set ( struct ansiesc_context *ctx __unused,
- unsigned int count __unused,
- int params[] __unused ) {
- EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *conout = efi_systab->ConOut;
-
- conout->EnableCursor ( conout, TRUE );
-}
-
-/**
- * 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 efi_handle_dectcem_reset ( struct ansiesc_context *ctx __unused,
- unsigned int count __unused,
- int params[] __unused ) {
- EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *conout = efi_systab->ConOut;
-
- conout->EnableCursor ( conout, FALSE );
-}
-
-/** EFI console ANSI escape sequence handlers */
-static struct ansiesc_handler efi_ansiesc_handlers[] = {
- { ANSIESC_CUP, efi_handle_cup },
- { ANSIESC_ED, efi_handle_ed },
- { ANSIESC_SGR, efi_handle_sgr },
- { ANSIESC_DECTCEM_SET, efi_handle_dectcem_set },
- { ANSIESC_DECTCEM_RESET, efi_handle_dectcem_reset },
- { 0, NULL }
-};
-
-/** EFI console ANSI escape sequence context */
-static struct ansiesc_context efi_ansiesc_ctx = {
- .handlers = efi_ansiesc_handlers,
-};
-
-/**
- * Print a character to EFI console
- *
- * @v character Character to be printed
- */
-static void efi_putchar ( int character ) {
- EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *conout = efi_systab->ConOut;
- wchar_t wstr[] = { character, 0 };
-
- /* Intercept ANSI escape sequences */
- character = ansiesc_process ( &efi_ansiesc_ctx, character );
- if ( character < 0 )
- return;
-
- conout->OutputString ( conout, wstr );
-}
-
-/**
- * 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 = "";
-
-/** Mapping from EFI scan codes to ANSI escape sequences */
-static const char *ansi_sequences[] = {
- [SCAN_UP] = "[A",
- [SCAN_DOWN] = "[B",
- [SCAN_RIGHT] = "[C",
- [SCAN_LEFT] = "[D",
- [SCAN_HOME] = "[H",
- [SCAN_END] = "[F",
- [SCAN_INSERT] = "[2~",
- /* EFI translates an incoming backspace via the serial console
- * into a SCAN_DELETE. There's not much we can do about this.
- */
- [SCAN_DELETE] = "[3~",
- [SCAN_PAGE_UP] = "[5~",
- [SCAN_PAGE_DOWN] = "[6~",
- /* EFI translates some (but not all) incoming escape sequences
- * via the serial console into equivalent scancodes. When it
- * doesn't recognise a sequence, it helpfully(!) translates
- * the initial ESC and passes the remainder through verbatim.
- * Treating SCAN_ESC as equivalent to an empty escape sequence
- * works around this bug.
- */
- [SCAN_ESC] = "",
-};
-
-/**
- * Get ANSI escape sequence corresponding to EFI scancode
- *
- * @v scancode EFI scancode
- * @ret ansi_seq ANSI escape sequence, if any, otherwise NULL
- */
-static const char * scancode_to_ansi_seq ( unsigned int scancode ) {
- if ( scancode < ( sizeof ( ansi_sequences ) /
- sizeof ( ansi_sequences[0] ) ) ) {
- return ansi_sequences[scancode];
- }
- return NULL;
-}
-
-/**
- * Get character from EFI console
- *
- * @ret character Character read from console
- */
-static int efi_getchar ( void ) {
- EFI_SIMPLE_TEXT_INPUT_PROTOCOL *conin = efi_systab->ConIn;
- const char *ansi_seq;
- EFI_INPUT_KEY key;
- EFI_STATUS efirc;
- int rc;
-
- /* If we are mid-sequence, pass out the next byte */
- if ( *ansi_input )
- return *(ansi_input++);
-
- /* Read key from real EFI console */
- if ( ( efirc = conin->ReadKeyStroke ( conin, &key ) ) != 0 ) {
- rc = -EEFI ( efirc );
- DBG ( "EFI could not read keystroke: %s\n", strerror ( rc ) );
- return 0;
- }
- DBG2 ( "EFI read key stroke with unicode %04x scancode %04x\n",
- key.UnicodeChar, key.ScanCode );
-
- /* If key has a Unicode representation, return it */
- if ( key.UnicodeChar )
- return key.UnicodeChar;
-
- /* Otherwise, check for a special key that we know about */
- if ( ( ansi_seq = scancode_to_ansi_seq ( key.ScanCode ) ) ) {
- /* Start of escape sequence: return ESC (0x1b) */
- ansi_input = ansi_seq;
- return 0x1b;
- }
-
- return 0;
-}
-
-/**
- * Check for character ready to read from EFI console
- *
- * @ret True Character available to read
- * @ret False No character available to read
- */
-static int efi_iskey ( void ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- EFI_SIMPLE_TEXT_INPUT_PROTOCOL *conin = efi_systab->ConIn;
- EFI_STATUS efirc;
-
- /* If we are mid-sequence, we are always ready */
- if ( *ansi_input )
- return 1;
-
- /* Check to see if the WaitForKey event has fired */
- if ( ( efirc = bs->CheckEvent ( conin->WaitForKey ) ) == 0 )
- return 1;
-
- return 0;
-}
-
-/** EFI console driver */
-struct console_driver efi_console __console_driver = {
- .putchar = efi_putchar,
- .getchar = efi_getchar,
- .iskey = efi_iskey,
- .usage = CONSOLE_EFI,
-};
-
-/**
- * Initialise EFI console
- *
- */
-static void efi_console_init ( void ) {
- EFI_CONSOLE_CONTROL_SCREEN_MODE mode;
-
- /* On some older EFI 1.10 implementations, we must use the
- * (now obsolete) EFI_CONSOLE_CONTROL_PROTOCOL to switch the
- * console into text mode.
- */
- if ( conctrl ) {
- conctrl->GetMode ( conctrl, &mode, NULL, NULL );
- if ( mode != EfiConsoleControlScreenText ) {
- conctrl->SetMode ( conctrl,
- EfiConsoleControlScreenText );
- }
- }
-}
-
-/**
- * EFI console initialisation function
- */
-struct init_fn efi_console_init_fn __init_fn ( INIT_EARLY ) = {
- .initialise = efi_console_init,
-};
diff --git a/qemu/roms/ipxe/src/interface/efi/efi_debug.c b/qemu/roms/ipxe/src/interface/efi/efi_debug.c
deleted file mode 100644
index 473803951..000000000
--- a/qemu/roms/ipxe/src/interface/efi/efi_debug.c
+++ /dev/null
@@ -1,665 +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
- *
- * EFI debugging utilities
- *
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <ipxe/uuid.h>
-#include <ipxe/base16.h>
-#include <ipxe/efi/efi.h>
-#include <ipxe/efi/efi_utils.h>
-#include <ipxe/efi/Protocol/ComponentName.h>
-#include <ipxe/efi/Protocol/ComponentName2.h>
-#include <ipxe/efi/Protocol/DevicePathToText.h>
-#include <ipxe/efi/IndustryStandard/PeImage.h>
-
-/** Device path to text protocol */
-static EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *efidpt;
-EFI_REQUEST_PROTOCOL ( EFI_DEVICE_PATH_TO_TEXT_PROTOCOL, &efidpt );
-
-/** Iscsi4Dxe module GUID */
-static EFI_GUID efi_iscsi4_dxe_guid = {
- 0x4579b72d, 0x7ec4, 0x4dd4,
- { 0x84, 0x86, 0x08, 0x3c, 0x86, 0xb1, 0x82, 0xa7 }
-};
-
-/** VlanConfigDxe module GUID */
-static EFI_GUID efi_vlan_config_dxe_guid = {
- 0xe4f61863, 0xfe2c, 0x4b56,
- { 0xa8, 0xf4, 0x08, 0x51, 0x9b, 0xc4, 0x39, 0xdf }
-};
-
-/** A well-known GUID */
-struct efi_well_known_guid {
- /** GUID */
- EFI_GUID *guid;
- /** Name */
- const char *name;
-};
-
-/** Well-known GUIDs */
-static struct efi_well_known_guid efi_well_known_guids[] = {
- { &efi_arp_protocol_guid,
- "Arp" },
- { &efi_arp_service_binding_protocol_guid,
- "ArpSb" },
- { &efi_block_io_protocol_guid,
- "BlockIo" },
- { &efi_bus_specific_driver_override_protocol_guid,
- "BusSpecificDriverOverride" },
- { &efi_component_name_protocol_guid,
- "ComponentName" },
- { &efi_component_name2_protocol_guid,
- "ComponentName2" },
- { &efi_device_path_protocol_guid,
- "DevicePath" },
- { &efi_driver_binding_protocol_guid,
- "DriverBinding" },
- { &efi_dhcp4_protocol_guid,
- "Dhcp4" },
- { &efi_dhcp4_service_binding_protocol_guid,
- "Dhcp4Sb" },
- { &efi_disk_io_protocol_guid,
- "DiskIo" },
- { &efi_graphics_output_protocol_guid,
- "GraphicsOutput" },
- { &efi_hii_config_access_protocol_guid,
- "HiiConfigAccess" },
- { &efi_ip4_protocol_guid,
- "Ip4" },
- { &efi_ip4_config_protocol_guid,
- "Ip4Config" },
- { &efi_ip4_service_binding_protocol_guid,
- "Ip4Sb" },
- { &efi_iscsi4_dxe_guid,
- "IScsi4Dxe" },
- { &efi_load_file_protocol_guid,
- "LoadFile" },
- { &efi_load_file2_protocol_guid,
- "LoadFile2" },
- { &efi_loaded_image_protocol_guid,
- "LoadedImage" },
- { &efi_loaded_image_device_path_protocol_guid,
- "LoadedImageDevicePath"},
- { &efi_managed_network_protocol_guid,
- "ManagedNetwork" },
- { &efi_managed_network_service_binding_protocol_guid,
- "ManagedNetworkSb" },
- { &efi_mtftp4_protocol_guid,
- "Mtftp4" },
- { &efi_mtftp4_service_binding_protocol_guid,
- "Mtftp4Sb" },
- { &efi_nii_protocol_guid,
- "Nii" },
- { &efi_nii31_protocol_guid,
- "Nii31" },
- { &efi_pci_io_protocol_guid,
- "PciIo" },
- { &efi_pci_root_bridge_io_protocol_guid,
- "PciRootBridgeIo" },
- { &efi_pxe_base_code_protocol_guid,
- "PxeBaseCode" },
- { &efi_simple_file_system_protocol_guid,
- "SimpleFileSystem" },
- { &efi_simple_network_protocol_guid,
- "SimpleNetwork" },
- { &efi_tcg_protocol_guid,
- "Tcg" },
- { &efi_tcp4_protocol_guid,
- "Tcp4" },
- { &efi_tcp4_service_binding_protocol_guid,
- "Tcp4Sb" },
- { &efi_udp4_protocol_guid,
- "Udp4" },
- { &efi_udp4_service_binding_protocol_guid,
- "Udp4Sb" },
- { &efi_vlan_config_protocol_guid,
- "VlanConfig" },
- { &efi_vlan_config_dxe_guid,
- "VlanConfigDxe" },
-};
-
-/**
- * Convert GUID to a printable string
- *
- * @v guid GUID
- * @ret string Printable string
- */
-const char * efi_guid_ntoa ( EFI_GUID *guid ) {
- union {
- union uuid uuid;
- EFI_GUID guid;
- } u;
- unsigned int i;
-
- /* Sanity check */
- if ( ! guid )
- return NULL;
-
- /* Check for a match against well-known GUIDs */
- for ( i = 0 ; i < ( sizeof ( efi_well_known_guids ) /
- sizeof ( efi_well_known_guids[0] ) ) ; i++ ) {
- if ( memcmp ( guid, efi_well_known_guids[i].guid,
- sizeof ( *guid ) ) == 0 ) {
- return efi_well_known_guids[i].name;
- }
- }
-
- /* Convert GUID to standard endianness */
- memcpy ( &u.guid, guid, sizeof ( u.guid ) );
- uuid_mangle ( &u.uuid );
- return uuid_ntoa ( &u.uuid );
-}
-
-/**
- * Name protocol open attributes
- *
- * @v attributes Protocol open attributes
- * @ret name Protocol open attributes name
- *
- * Returns a (static) string with characters for each set bit
- * corresponding to BY_(H)ANDLE_PROTOCOL, (G)ET_PROTOCOL,
- * (T)EST_PROTOCOL, BY_(C)HILD_CONTROLLER, BY_(D)RIVER, and
- * E(X)CLUSIVE.
- */
-static const char * efi_open_attributes_name ( unsigned int attributes ) {
- static char attribute_chars[] = "HGTCDX";
- static char name[ sizeof ( attribute_chars ) ];
- char *tmp = name;
- unsigned int i;
-
- for ( i = 0 ; i < ( sizeof ( attribute_chars ) - 1 ) ; i++ ) {
- if ( attributes & ( 1 << i ) )
- *(tmp++) = attribute_chars[i];
- }
- *tmp = '\0';
-
- return name;
-}
-
-/**
- * Print list of openers of a given protocol on a given handle
- *
- * @v handle EFI handle
- * @v protocol Protocol GUID
- */
-void dbg_efi_openers ( EFI_HANDLE handle, EFI_GUID *protocol ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *openers;
- EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *opener;
- UINTN count;
- unsigned int i;
- EFI_STATUS efirc;
- int rc;
-
- /* Sanity check */
- if ( ( ! handle ) || ( ! protocol ) ) {
- printf ( "EFI could not retrieve openers for %s on %p\n",
- efi_guid_ntoa ( protocol ), handle );
- return;
- }
-
- /* Retrieve list of openers */
- if ( ( efirc = bs->OpenProtocolInformation ( handle, protocol, &openers,
- &count ) ) != 0 ) {
- rc = -EEFI ( efirc );
- printf ( "EFI could not retrieve openers for %s on %p: %s\n",
- efi_guid_ntoa ( protocol ), handle, strerror ( rc ) );
- return;
- }
-
- /* Dump list of openers */
- for ( i = 0 ; i < count ; i++ ) {
- opener = &openers[i];
- printf ( "HANDLE %p %s %s opened %dx (%s)",
- handle, efi_handle_name ( handle ),
- efi_guid_ntoa ( protocol ), opener->OpenCount,
- efi_open_attributes_name ( opener->Attributes ) );
- printf ( " by %p %s", opener->AgentHandle,
- efi_handle_name ( opener->AgentHandle ) );
- if ( opener->ControllerHandle == handle ) {
- printf ( "\n" );
- } else {
- printf ( " for %p %s\n", opener->ControllerHandle,
- efi_handle_name ( opener->ControllerHandle ) );
- }
- }
-
- /* Free list */
- bs->FreePool ( openers );
-}
-
-/**
- * Print list of protocol handlers attached to a handle
- *
- * @v handle EFI handle
- */
-void dbg_efi_protocols ( EFI_HANDLE handle ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- EFI_GUID **protocols;
- EFI_GUID *protocol;
- UINTN count;
- unsigned int i;
- EFI_STATUS efirc;
- int rc;
-
- /* Sanity check */
- if ( ! handle ) {
- printf ( "EFI could not retrieve protocols for %p\n", handle );
- return;
- }
-
- /* Retrieve list of protocols */
- if ( ( efirc = bs->ProtocolsPerHandle ( handle, &protocols,
- &count ) ) != 0 ) {
- rc = -EEFI ( efirc );
- printf ( "EFI could not retrieve protocols for %p: %s\n",
- handle, strerror ( rc ) );
- return;
- }
-
- /* Dump list of protocols */
- for ( i = 0 ; i < count ; i++ ) {
- protocol = protocols[i];
- printf ( "HANDLE %p %s %s supported\n",
- handle, efi_handle_name ( handle ),
- efi_guid_ntoa ( protocol ) );
- dbg_efi_openers ( handle, protocol );
- }
-
- /* Free list */
- bs->FreePool ( protocols );
-}
-
-/**
- * Get textual representation of device path
- *
- * @v path Device path
- * @ret text Textual representation of device path, or NULL
- */
-const char * efi_devpath_text ( EFI_DEVICE_PATH_PROTOCOL *path ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- static char text[256];
- void *start;
- void *end;
- size_t max_len;
- size_t len;
- CHAR16 *wtext;
-
- /* Sanity checks */
- if ( ! path ) {
- DBG ( "[NULL DevicePath]" );
- return NULL;
- }
-
- /* If we have no DevicePathToText protocol then use a raw hex string */
- if ( ! efidpt ) {
- DBG ( "[No DevicePathToText]" );
- start = path;
- end = efi_devpath_end ( path );
- len = ( end - start );
- max_len = ( ( sizeof ( text ) - 1 /* NUL */ ) / 2 /* "xx" */ );
- if ( len > max_len )
- len = max_len;
- base16_encode ( start, len, text, sizeof ( text ) );
- return text;
- }
-
- /* Convert path to a textual representation */
- wtext = efidpt->ConvertDevicePathToText ( path, TRUE, FALSE );
- if ( ! wtext )
- return NULL;
-
- /* Store path in buffer */
- snprintf ( text, sizeof ( text ), "%ls", wtext );
-
- /* Free path */
- bs->FreePool ( wtext );
-
- return text;
-}
-
-/**
- * Get driver name
- *
- * @v wtf Component name protocol
- * @ret name Driver name, or NULL
- */
-static const char * efi_driver_name ( EFI_COMPONENT_NAME_PROTOCOL *wtf ) {
- static char name[64];
- CHAR16 *driver_name;
- EFI_STATUS efirc;
-
- /* Sanity check */
- if ( ! wtf ) {
- DBG ( "[NULL ComponentName]" );
- return NULL;
- }
-
- /* Try "eng" first; if that fails then try the first language */
- if ( ( ( efirc = wtf->GetDriverName ( wtf, "eng",
- &driver_name ) ) != 0 ) &&
- ( ( efirc = wtf->GetDriverName ( wtf, wtf->SupportedLanguages,
- &driver_name ) ) != 0 ) ) {
- return NULL;
- }
-
- /* Convert name from CHAR16 to char */
- snprintf ( name, sizeof ( name ), "%ls", driver_name );
- return name;
-}
-
-/**
- * Get driver name
- *
- * @v wtf Component name protocol
- * @ret name Driver name, or NULL
- */
-static const char * efi_driver_name2 ( EFI_COMPONENT_NAME2_PROTOCOL *wtf ) {
- static char name[64];
- CHAR16 *driver_name;
- EFI_STATUS efirc;
-
- /* Sanity check */
- if ( ! wtf ) {
- DBG ( "[NULL ComponentName2]" );
- return NULL;
- }
-
- /* Try "en" first; if that fails then try the first language */
- if ( ( ( efirc = wtf->GetDriverName ( wtf, "en",
- &driver_name ) ) != 0 ) &&
- ( ( efirc = wtf->GetDriverName ( wtf, wtf->SupportedLanguages,
- &driver_name ) ) != 0 ) ) {
- return NULL;
- }
-
- /* Convert name from CHAR16 to char */
- snprintf ( name, sizeof ( name ), "%ls", driver_name );
- return name;
-}
-
-/**
- * Get PE/COFF debug filename
- *
- * @v loaded Loaded image
- * @ret name PE/COFF debug filename, or NULL
- */
-static const char *
-efi_pecoff_debug_name ( EFI_LOADED_IMAGE_PROTOCOL *loaded ) {
- static char buf[32];
- EFI_IMAGE_DOS_HEADER *dos;
- EFI_IMAGE_OPTIONAL_HEADER_UNION *pe;
- EFI_IMAGE_OPTIONAL_HEADER32 *opt32;
- EFI_IMAGE_OPTIONAL_HEADER64 *opt64;
- EFI_IMAGE_DATA_DIRECTORY *datadir;
- EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *debug;
- EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY *codeview_nb10;
- EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY *codeview_rsds;
- EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY *codeview_mtoc;
- uint16_t dos_magic;
- uint32_t pe_magic;
- uint16_t opt_magic;
- uint32_t codeview_magic;
- size_t max_len;
- char *name;
- char *tmp;
-
- /* Sanity check */
- if ( ! loaded ) {
- DBG ( "[NULL LoadedImage]" );
- return NULL;
- }
-
- /* Parse DOS header */
- dos = loaded->ImageBase;
- if ( ! dos ) {
- DBG ( "[Missing DOS header]" );
- return NULL;
- }
- dos_magic = dos->e_magic;
- if ( dos_magic != EFI_IMAGE_DOS_SIGNATURE ) {
- DBG ( "[Bad DOS signature %#04x]", dos_magic );
- return NULL;
- }
- pe = ( loaded->ImageBase + dos->e_lfanew );
-
- /* Parse PE header */
- pe_magic = pe->Pe32.Signature;
- if ( pe_magic != EFI_IMAGE_NT_SIGNATURE ) {
- DBG ( "[Bad PE signature %#08x]", pe_magic );
- return NULL;
- }
- opt32 = &pe->Pe32.OptionalHeader;
- opt64 = &pe->Pe32Plus.OptionalHeader;
- opt_magic = opt32->Magic;
- if ( opt_magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC ) {
- datadir = opt32->DataDirectory;
- } else if ( opt_magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC ) {
- datadir = opt64->DataDirectory;
- } else {
- DBG ( "[Bad optional header signature %#04x]", opt_magic );
- return NULL;
- }
-
- /* Parse data directory entry */
- if ( ! datadir[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress ) {
- DBG ( "[Empty debug directory entry]" );
- return NULL;
- }
- debug = ( loaded->ImageBase +
- datadir[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress );
-
- /* Parse debug directory entry */
- if ( debug->Type != EFI_IMAGE_DEBUG_TYPE_CODEVIEW ) {
- DBG ( "[Not a CodeView debug directory entry (type %d)]",
- debug->Type );
- return NULL;
- }
- codeview_nb10 = ( loaded->ImageBase + debug->RVA );
- codeview_rsds = ( loaded->ImageBase + debug->RVA );
- codeview_mtoc = ( loaded->ImageBase + debug->RVA );
- codeview_magic = codeview_nb10->Signature;
-
- /* Parse CodeView entry */
- if ( codeview_magic == CODEVIEW_SIGNATURE_NB10 ) {
- name = ( ( void * ) ( codeview_nb10 + 1 ) );
- } else if ( codeview_magic == CODEVIEW_SIGNATURE_RSDS ) {
- name = ( ( void * ) ( codeview_rsds + 1 ) );
- } else if ( codeview_magic == CODEVIEW_SIGNATURE_MTOC ) {
- name = ( ( void * ) ( codeview_mtoc + 1 ) );
- } else {
- DBG ( "[Bad CodeView signature %#08x]", codeview_magic );
- return NULL;
- }
-
- /* Sanity check - avoid scanning endlessly through memory */
- max_len = EFI_PAGE_SIZE; /* Reasonably sane */
- if ( strnlen ( name, max_len ) == max_len ) {
- DBG ( "[Excessively long or invalid CodeView name]" );
- return NULL;
- }
-
- /* Skip any directory components. We cannot modify this data
- * or create a temporary buffer, so do not use basename().
- */
- while ( ( ( tmp = strchr ( name, '/' ) ) != NULL ) ||
- ( ( tmp = strchr ( name, '\\' ) ) != NULL ) ) {
- name = ( tmp + 1 );
- }
-
- /* Copy base name to buffer */
- snprintf ( buf, sizeof ( buf ), "%s", name );
-
- /* Strip file suffix, if present */
- if ( ( tmp = strrchr ( name, '.' ) ) != NULL )
- *tmp = '\0';
-
- return name;
-}
-
-/**
- * Get initial loaded image name
- *
- * @v loaded Loaded image
- * @ret name Initial loaded image name, or NULL
- */
-static const char *
-efi_first_loaded_image_name ( EFI_LOADED_IMAGE_PROTOCOL *loaded ) {
-
- /* Sanity check */
- if ( ! loaded ) {
- DBG ( "[NULL LoadedImage]" );
- return NULL;
- }
-
- return ( ( loaded->ParentHandle == NULL ) ? "DxeCore(?)" : NULL );
-}
-
-/**
- * Get loaded image name from file path
- *
- * @v loaded Loaded image
- * @ret name Loaded image name, or NULL
- */
-static const char *
-efi_loaded_image_filepath_name ( EFI_LOADED_IMAGE_PROTOCOL *loaded ) {
-
- /* Sanity check */
- if ( ! loaded ) {
- DBG ( "[NULL LoadedImage]" );
- return NULL;
- }
-
- return efi_devpath_text ( loaded->FilePath );
-}
-
-/** An EFI handle name type */
-struct efi_handle_name_type {
- /** Protocol */
- EFI_GUID *protocol;
- /**
- * Get name
- *
- * @v interface Protocol interface
- * @ret name Name of handle, or NULL on failure
- */
- const char * ( * name ) ( void *interface );
-};
-
-/**
- * Define an EFI handle name type
- *
- * @v protocol Protocol interface
- * @v name Method to get name
- * @ret type EFI handle name type
- */
-#define EFI_HANDLE_NAME_TYPE( protocol, name ) { \
- (protocol), \
- ( const char * ( * ) ( void * ) ) (name), \
- }
-
-/** EFI handle name types */
-static struct efi_handle_name_type efi_handle_name_types[] = {
- /* Device path */
- EFI_HANDLE_NAME_TYPE ( &efi_device_path_protocol_guid,
- efi_devpath_text ),
- /* Driver name (for driver image handles) */
- EFI_HANDLE_NAME_TYPE ( &efi_component_name2_protocol_guid,
- efi_driver_name2 ),
- /* Driver name (via obsolete original ComponentName protocol) */
- EFI_HANDLE_NAME_TYPE ( &efi_component_name_protocol_guid,
- efi_driver_name ),
- /* PE/COFF debug filename (for image handles) */
- EFI_HANDLE_NAME_TYPE ( &efi_loaded_image_protocol_guid,
- efi_pecoff_debug_name ),
- /* Loaded image device path (for image handles) */
- EFI_HANDLE_NAME_TYPE ( &efi_loaded_image_device_path_protocol_guid,
- efi_devpath_text ),
- /* First loaded image name (for the DxeCore image) */
- EFI_HANDLE_NAME_TYPE ( &efi_loaded_image_protocol_guid,
- efi_first_loaded_image_name ),
- /* Handle's loaded image file path (for image handles) */
- EFI_HANDLE_NAME_TYPE ( &efi_loaded_image_protocol_guid,
- efi_loaded_image_filepath_name ),
-};
-
-/**
- * Get name of an EFI handle
- *
- * @v handle EFI handle
- * @ret text Name of handle, or NULL
- */
-const char * efi_handle_name ( EFI_HANDLE handle ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- struct efi_handle_name_type *type;
- unsigned int i;
- void *interface;
- const char *name;
- EFI_STATUS efirc;
-
- /* Fail immediately for NULL handles */
- if ( ! handle )
- return NULL;
-
- /* Try each name type in turn */
- for ( i = 0 ; i < ( sizeof ( efi_handle_name_types ) /
- sizeof ( efi_handle_name_types[0] ) ) ; i++ ) {
- type = &efi_handle_name_types[i];
- DBG2 ( "<%d", i );
-
- /* Try to open the applicable protocol */
- efirc = bs->OpenProtocol ( handle, type->protocol, &interface,
- efi_image_handle, handle,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL );
- if ( efirc != 0 ) {
- DBG2 ( ">" );
- continue;
- }
-
- /* Try to get name from this protocol */
- DBG2 ( "-" );
- name = type->name ( interface );
- DBG2 ( "%c", ( name ? ( name[0] ? 'Y' : 'E' ) : 'N' ) );
-
- /* Close protocol */
- bs->CloseProtocol ( handle, type->protocol,
- efi_image_handle, handle );
- DBG2 ( ">" );
-
- /* Use this name, if possible */
- if ( name && name[0] )
- return name;
- }
-
- return "UNKNOWN";
-}
diff --git a/qemu/roms/ipxe/src/interface/efi/efi_download.c b/qemu/roms/ipxe/src/interface/efi/efi_download.c
deleted file mode 100644
index 1218852e2..000000000
--- a/qemu/roms/ipxe/src/interface/efi/efi_download.c
+++ /dev/null
@@ -1,240 +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 any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <ipxe/open.h>
-#include <ipxe/process.h>
-#include <ipxe/iobuf.h>
-#include <ipxe/xfer.h>
-#include <ipxe/efi/efi.h>
-#include <ipxe/efi/efi_snp.h>
-#include <ipxe/efi/efi_download.h>
-
-/** iPXE download protocol GUID */
-static EFI_GUID ipxe_download_protocol_guid
- = IPXE_DOWNLOAD_PROTOCOL_GUID;
-
-/** A single in-progress file */
-struct efi_download_file {
- /** Data transfer interface that provides downloaded data */
- struct interface xfer;
-
- /** Current file position */
- size_t pos;
-
- /** Data callback */
- IPXE_DOWNLOAD_DATA_CALLBACK data_callback;
-
- /** Finish callback */
- IPXE_DOWNLOAD_FINISH_CALLBACK finish_callback;
-
- /** Callback context */
- void *context;
-};
-
-/* xfer interface */
-
-/**
- * Transfer finished or was aborted
- *
- * @v file Data transfer file
- * @v rc Reason for close
- */
-static void efi_download_close ( struct efi_download_file *file, int rc ) {
-
- file->finish_callback ( file->context, EFIRC ( rc ) );
-
- intf_shutdown ( &file->xfer, rc );
-
- efi_snp_release();
-}
-
-/**
- * Process received data
- *
- * @v file Data transfer file
- * @v iobuf I/O buffer
- * @v meta Data transfer metadata
- * @ret rc Return status code
- */
-static int efi_download_deliver_iob ( struct efi_download_file *file,
- struct io_buffer *iobuf,
- struct xfer_metadata *meta ) {
- EFI_STATUS efirc;
- size_t len = iob_len ( iobuf );
- int rc;
-
- /* Calculate new buffer position */
- if ( meta->flags & XFER_FL_ABS_OFFSET )
- file->pos = 0;
- file->pos += meta->offset;
-
- /* Call out to the data handler */
- if ( ( efirc = file->data_callback ( file->context, iobuf->data,
- len, file->pos ) ) != 0 ) {
- rc = -EEFI ( efirc );
- goto err_callback;
- }
-
- /* Update current buffer position */
- file->pos += len;
-
- /* Success */
- rc = 0;
-
- err_callback:
- free_iob ( iobuf );
- return rc;
-}
-
-/** Data transfer interface operations */
-static struct interface_operation efi_xfer_operations[] = {
- INTF_OP ( xfer_deliver, struct efi_download_file *, efi_download_deliver_iob ),
- INTF_OP ( intf_close, struct efi_download_file *, efi_download_close ),
-};
-
-/** EFI download data transfer interface descriptor */
-static struct interface_descriptor efi_download_file_xfer_desc =
- INTF_DESC ( struct efi_download_file, xfer, efi_xfer_operations );
-
-/**
- * Start downloading a file, and register callback functions to handle the
- * download.
- *
- * @v This iPXE Download Protocol instance
- * @v Url URL to download from
- * @v DataCallback Callback that will be invoked when data arrives
- * @v FinishCallback Callback that will be invoked when the download ends
- * @v Context Context passed to the Data and Finish callbacks
- * @v File Token that can be used to abort the download
- * @ret Status EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_download_start ( IPXE_DOWNLOAD_PROTOCOL *This __unused,
- CHAR8 *Url,
- IPXE_DOWNLOAD_DATA_CALLBACK DataCallback,
- IPXE_DOWNLOAD_FINISH_CALLBACK FinishCallback,
- VOID *Context,
- IPXE_DOWNLOAD_FILE *File ) {
- struct efi_download_file *file;
- int rc;
-
- file = malloc ( sizeof ( struct efi_download_file ) );
- if ( file == NULL ) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- intf_init ( &file->xfer, &efi_download_file_xfer_desc, NULL );
- rc = xfer_open ( &file->xfer, LOCATION_URI_STRING, Url );
- if ( rc ) {
- free ( file );
- return EFIRC ( rc );
- }
-
- efi_snp_claim();
- file->pos = 0;
- file->data_callback = DataCallback;
- file->finish_callback = FinishCallback;
- file->context = Context;
- *File = file;
- return EFI_SUCCESS;
-}
-
-/**
- * Forcibly abort downloading a file that is currently in progress.
- *
- * It is not safe to call this function after the Finish callback has executed.
- *
- * @v This iPXE Download Protocol instance
- * @v File Token obtained from Start
- * @v Status Reason for aborting the download
- * @ret Status EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_download_abort ( IPXE_DOWNLOAD_PROTOCOL *This __unused,
- IPXE_DOWNLOAD_FILE File,
- EFI_STATUS Status ) {
- struct efi_download_file *file = File;
-
- efi_download_close ( file, -EEFI ( Status ) );
- return EFI_SUCCESS;
-}
-
-/**
- * Poll for more data from iPXE. This function will invoke the registered
- * callbacks if data is available or if downloads complete.
- *
- * @v This iPXE Download Protocol instance
- * @ret Status EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_download_poll ( IPXE_DOWNLOAD_PROTOCOL *This __unused ) {
- step();
- return EFI_SUCCESS;
-}
-
-/** Publicly exposed iPXE download protocol */
-static IPXE_DOWNLOAD_PROTOCOL ipxe_download_protocol_interface = {
- .Start = efi_download_start,
- .Abort = efi_download_abort,
- .Poll = efi_download_poll
-};
-
-/**
- * Install iPXE download protocol
- *
- * @v handle EFI handle
- * @ret rc Return status code
- */
-int efi_download_install ( EFI_HANDLE handle ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- EFI_STATUS efirc;
- int rc;
-
- efirc = bs->InstallMultipleProtocolInterfaces (
- &handle,
- &ipxe_download_protocol_guid,
- &ipxe_download_protocol_interface,
- NULL );
- if ( efirc ) {
- rc = -EEFI ( efirc );
- DBG ( "Could not install download protocol: %s\n",
- strerror ( rc ) );
- return rc;
- }
-
- return 0;
-}
-
-/**
- * Uninstall iPXE download protocol
- *
- * @v handle EFI handle
- */
-void efi_download_uninstall ( EFI_HANDLE handle ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-
- bs->UninstallMultipleProtocolInterfaces (
- handle,
- &ipxe_download_protocol_guid,
- &ipxe_download_protocol_interface, NULL );
-}
diff --git a/qemu/roms/ipxe/src/interface/efi/efi_driver.c b/qemu/roms/ipxe/src/interface/efi/efi_driver.c
deleted file mode 100644
index ba7784cd7..000000000
--- a/qemu/roms/ipxe/src/interface/efi/efi_driver.c
+++ /dev/null
@@ -1,517 +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.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <ipxe/version.h>
-#include <ipxe/efi/efi.h>
-#include <ipxe/efi/Protocol/DriverBinding.h>
-#include <ipxe/efi/Protocol/ComponentName2.h>
-#include <ipxe/efi/Protocol/DevicePath.h>
-#include <ipxe/efi/efi_strings.h>
-#include <ipxe/efi/efi_driver.h>
-
-/** @file
- *
- * EFI driver interface
- *
- */
-
-static EFI_DRIVER_BINDING_PROTOCOL efi_driver_binding;
-
-/** List of controlled EFI devices */
-static LIST_HEAD ( efi_devices );
-
-/**
- * Find EFI device
- *
- * @v device EFI device handle
- * @ret efidev EFI device, or NULL if not found
- */
-static struct efi_device * efidev_find ( EFI_HANDLE device ) {
- struct efi_device *efidev;
-
- /* Look for an existing EFI device */
- list_for_each_entry ( efidev, &efi_devices, dev.siblings ) {
- if ( efidev->device == device )
- return efidev;
- }
-
- return NULL;
-}
-
-/**
- * Get parent EFI device
- *
- * @v dev Generic device
- * @ret efidev Parent EFI device, or NULL
- */
-struct efi_device * efidev_parent ( struct device *dev ) {
- struct device *parent = dev->parent;
- struct efi_device *efidev;
-
- /* Check that parent exists and is an EFI device */
- if ( ! parent )
- return NULL;
- if ( parent->desc.bus_type != BUS_TYPE_EFI )
- return NULL;
-
- /* Get containing EFI device */
- efidev = container_of ( parent, struct efi_device, dev );
- return efidev;
-}
-
-/**
- * Check to see if driver supports a device
- *
- * @v driver EFI driver
- * @v device EFI device
- * @v child Path to child device, if any
- * @ret efirc EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_driver_supported ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
- EFI_HANDLE device, EFI_DEVICE_PATH_PROTOCOL *child ) {
- struct efi_driver *efidrv;
- int rc;
-
- DBGCP ( device, "EFIDRV %p %s DRIVER_SUPPORTED",
- device, efi_handle_name ( device ) );
- if ( child )
- DBGCP ( device, " (child %s)", efi_devpath_text ( child ) );
- DBGCP ( device, "\n" );
-
- /* Do nothing if we are already driving this device */
- if ( efidev_find ( device ) != NULL ) {
- DBGCP ( device, "EFIDRV %p %s is already started\n",
- device, efi_handle_name ( device ) );
- return EFI_ALREADY_STARTED;
- }
-
- /* Look for a driver claiming to support this device */
- for_each_table_entry ( efidrv, EFI_DRIVERS ) {
- if ( ( rc = efidrv->supported ( device ) ) == 0 ) {
- DBGC ( device, "EFIDRV %p %s has driver \"%s\"\n",
- device, efi_handle_name ( device ),
- efidrv->name );
- return 0;
- }
- }
- DBGCP ( device, "EFIDRV %p %s has no driver\n",
- device, efi_handle_name ( device ) );
-
- return EFI_UNSUPPORTED;
-}
-
-/**
- * Attach driver to device
- *
- * @v driver EFI driver
- * @v device EFI device
- * @v child Path to child device, if any
- * @ret efirc EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_driver_start ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
- EFI_HANDLE device, EFI_DEVICE_PATH_PROTOCOL *child ) {
- struct efi_driver *efidrv;
- struct efi_device *efidev;
- EFI_STATUS efirc;
- int rc;
-
- DBGC ( device, "EFIDRV %p %s DRIVER_START",
- device, efi_handle_name ( device ) );
- if ( child )
- DBGC ( device, " (child %s)", efi_devpath_text ( child ) );
- DBGC ( device, "\n" );
-
- /* Do nothing if we are already driving this device */
- efidev = efidev_find ( device );
- if ( efidev ) {
- DBGCP ( device, "EFIDRV %p %s is already started\n",
- device, efi_handle_name ( device ) );
- efirc = EFI_ALREADY_STARTED;
- goto err_already_started;
- }
-
- /* Allocate and initialise structure */
- efidev = zalloc ( sizeof ( *efidev ) );
- if ( ! efidev ) {
- efirc = EFI_OUT_OF_RESOURCES;
- goto err_alloc;
- }
- efidev->device = device;
- efidev->dev.desc.bus_type = BUS_TYPE_EFI;
- INIT_LIST_HEAD ( &efidev->dev.children );
- list_add ( &efidev->dev.siblings, &efi_devices );
-
- /* Try to start this device */
- for_each_table_entry ( efidrv, EFI_DRIVERS ) {
- if ( ( rc = efidrv->supported ( device ) ) != 0 ) {
- DBGC ( device, "EFIDRV %p %s is not supported by "
- "driver \"%s\": %s\n", device,
- efi_handle_name ( device ), efidrv->name,
- strerror ( rc ) );
- continue;
- }
- if ( ( rc = efidrv->start ( efidev ) ) == 0 ) {
- efidev->driver = efidrv;
- DBGC ( device, "EFIDRV %p %s using driver \"%s\"\n",
- device, efi_handle_name ( device ),
- efidev->driver->name );
- return 0;
- }
- DBGC ( device, "EFIDRV %p %s could not start driver \"%s\": "
- "%s\n", device, efi_handle_name ( device ),
- efidrv->name, strerror ( rc ) );
- }
- efirc = EFI_UNSUPPORTED;
-
- list_del ( &efidev->dev.siblings );
- free ( efidev );
- err_alloc:
- err_already_started:
- return efirc;
-}
-
-/**
- * Detach driver from device
- *
- * @v driver EFI driver
- * @v device EFI device
- * @v pci PCI device
- * @v num_children Number of child devices
- * @v children List of child devices
- * @ret efirc EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_driver_stop ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
- EFI_HANDLE device, UINTN num_children,
- EFI_HANDLE *children ) {
- struct efi_driver *efidrv;
- struct efi_device *efidev;
- UINTN i;
-
- DBGC ( device, "EFIDRV %p %s DRIVER_STOP",
- device, efi_handle_name ( device ) );
- for ( i = 0 ; i < num_children ; i++ ) {
- DBGC ( device, "%s%p %s", ( i ? ", " : " child " ),
- children[i], efi_handle_name ( children[i] ) );
- }
- DBGC ( device, "\n" );
-
- /* Do nothing unless we are driving this device */
- efidev = efidev_find ( device );
- if ( ! efidev ) {
- DBGCP ( device, "EFIDRV %p %s is not started\n",
- device, efi_handle_name ( device ) );
- return 0;
- }
-
- /* Stop this device */
- efidrv = efidev->driver;
- assert ( efidrv != NULL );
- efidrv->stop ( efidev );
- list_del ( &efidev->dev.siblings );
- free ( efidev );
-
- return 0;
-}
-
-/** EFI driver binding protocol */
-static EFI_DRIVER_BINDING_PROTOCOL efi_driver_binding = {
- .Supported = efi_driver_supported,
- .Start = efi_driver_start,
- .Stop = efi_driver_stop,
-};
-
-/**
- * Look up driver name
- *
- * @v wtf Component name protocol
- * @v language Language to use
- * @v driver_name Driver name to fill in
- * @ret efirc EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_driver_name ( EFI_COMPONENT_NAME2_PROTOCOL *wtf __unused,
- CHAR8 *language __unused, CHAR16 **driver_name ) {
- const wchar_t *name;
-
- name = ( product_wname[0] ? product_wname : build_wname );
- *driver_name = ( ( wchar_t * ) name );
- return 0;
-}
-
-/**
- * Look up controller name
- *
- * @v wtf Component name protocol
- * @v device Device
- * @v child Child device, or NULL
- * @v language Language to use
- * @v driver_name Device name to fill in
- * @ret efirc EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_driver_controller_name ( EFI_COMPONENT_NAME2_PROTOCOL *wtf __unused,
- EFI_HANDLE device, EFI_HANDLE child,
- CHAR8 *language, CHAR16 **controller_name ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- union {
- EFI_COMPONENT_NAME2_PROTOCOL *name2;
- void *interface;
- } name2;
- EFI_STATUS efirc;
-
- /* Delegate to the EFI_COMPONENT_NAME2_PROTOCOL instance
- * installed on child handle, if present.
- */
- if ( ( child != NULL ) &&
- ( ( efirc = bs->OpenProtocol (
- child, &efi_component_name2_protocol_guid,
- &name2.interface, NULL, NULL,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL ) ) == 0 ) ) {
- return name2.name2->GetControllerName ( name2.name2, device,
- child, language,
- controller_name );
- }
-
- /* Otherwise, let EFI use the default Device Path Name */
- return EFI_UNSUPPORTED;
-}
-
-/** EFI component name protocol */
-static EFI_COMPONENT_NAME2_PROTOCOL efi_wtf = {
- .GetDriverName = efi_driver_name,
- .GetControllerName = efi_driver_controller_name,
- .SupportedLanguages = "en",
-};
-
-/**
- * Install EFI driver
- *
- * @ret rc Return status code
- */
-int efi_driver_install ( void ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- EFI_STATUS efirc;
- int rc;
-
- /* Calculate driver version number. We use the build
- * timestamp (in seconds since the Epoch) shifted right by six
- * bits: this gives us an approximately one-minute resolution
- * and a scheme which will last until the year 10680.
- */
- efi_driver_binding.Version = ( build_timestamp >> 6 );
-
- /* Install protocols on image handle */
- efi_driver_binding.ImageHandle = efi_image_handle;
- efi_driver_binding.DriverBindingHandle = efi_image_handle;
- if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
- &efi_image_handle,
- &efi_driver_binding_protocol_guid, &efi_driver_binding,
- &efi_component_name2_protocol_guid, &efi_wtf,
- NULL ) ) != 0 ) {
- rc = -EEFI ( efirc );
- DBGC ( &efi_driver_binding, "EFIDRV could not install "
- "protocols: %s\n", strerror ( rc ) );
- return rc;
- }
-
- return 0;
-}
-
-/**
- * Uninstall EFI driver
- *
- */
-void efi_driver_uninstall ( void ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-
- /* Uninstall protocols */
- bs->UninstallMultipleProtocolInterfaces (
- efi_image_handle,
- &efi_driver_binding_protocol_guid, &efi_driver_binding,
- &efi_component_name2_protocol_guid, &efi_wtf, NULL );
-}
-
-/**
- * Try to connect EFI driver
- *
- * @v device EFI device
- * @ret rc Return status code
- */
-static int efi_driver_connect ( EFI_HANDLE device ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- EFI_HANDLE drivers[2] =
- { efi_driver_binding.DriverBindingHandle, NULL };
- EFI_STATUS efirc;
- int rc;
-
- /* Check if we want to drive this device */
- if ( ( efirc = efi_driver_supported ( &efi_driver_binding, device,
- NULL ) ) != 0 ) {
- /* Not supported; not an error */
- return 0;
- }
-
- /* Disconnect any existing drivers */
- DBGC2 ( device, "EFIDRV %p %s before disconnecting:\n",
- device, efi_handle_name ( device ) );
- DBGC2_EFI_PROTOCOLS ( device, device );
- DBGC ( device, "EFIDRV %p %s disconnecting existing drivers\n",
- device, efi_handle_name ( device ) );
- if ( ( efirc = bs->DisconnectController ( device, NULL,
- NULL ) ) != 0 ) {
- rc = -EEFI ( efirc );
- DBGC ( device, "EFIDRV %p %s could not disconnect existing "
- "drivers: %s\n", device, efi_handle_name ( device ),
- strerror ( rc ) );
- /* Ignore the error and attempt to connect our drivers */
- }
- DBGC2 ( device, "EFIDRV %p %s after disconnecting:\n",
- device, efi_handle_name ( device ) );
- DBGC2_EFI_PROTOCOLS ( device, device );
-
- /* Connect our driver */
- DBGC ( device, "EFIDRV %p %s connecting new drivers\n",
- device, efi_handle_name ( device ) );
- if ( ( efirc = bs->ConnectController ( device, drivers, NULL,
- FALSE ) ) != 0 ) {
- rc = -EEFI ( efirc );
- DBGC ( device, "EFIDRV %p %s could not connect new drivers: "
- "%s\n", device, efi_handle_name ( device ),
- strerror ( rc ) );
- return rc;
- }
- DBGC2 ( device, "EFIDRV %p %s after connecting:\n",
- device, efi_handle_name ( device ) );
- DBGC2_EFI_PROTOCOLS ( device, device );
-
- return 0;
-}
-
-/**
- * Try to disconnect EFI driver
- *
- * @v device EFI device
- * @ret rc Return status code
- */
-static int efi_driver_disconnect ( EFI_HANDLE device ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-
- /* Disconnect our driver */
- bs->DisconnectController ( device,
- efi_driver_binding.DriverBindingHandle,
- NULL );
- return 0;
-}
-
-/**
- * Reconnect original EFI driver
- *
- * @v device EFI device
- * @ret rc Return status code
- */
-static int efi_driver_reconnect ( EFI_HANDLE device ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-
- /* Reconnect any available driver */
- bs->ConnectController ( device, NULL, NULL, FALSE );
-
- return 0;
-}
-
-/**
- * Connect/disconnect EFI driver from all handles
- *
- * @v method Connect/disconnect method
- * @ret rc Return status code
- */
-static int efi_driver_handles ( int ( * method ) ( EFI_HANDLE handle ) ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- EFI_HANDLE *handles;
- UINTN num_handles;
- EFI_STATUS efirc;
- UINTN i;
- int rc;
-
- /* Enumerate all handles */
- if ( ( efirc = bs->LocateHandleBuffer ( AllHandles, NULL, NULL,
- &num_handles,
- &handles ) ) != 0 ) {
- rc = -EEFI ( efirc );
- DBGC ( &efi_driver_binding, "EFIDRV could not list handles: "
- "%s\n", strerror ( rc ) );
- goto err_locate;
- }
-
- /* Connect/disconnect driver from all handles */
- for ( i = 0 ; i < num_handles ; i++ ) {
- if ( ( rc = method ( handles[i] ) ) != 0 )
- goto err_method;
- }
-
- /* Success */
- rc = 0;
-
- err_method:
- bs->FreePool ( handles );
- err_locate:
- return rc;
-}
-
-/**
- * Connect EFI driver to all possible devices
- *
- * @ret rc Return status code
- */
-int efi_driver_connect_all ( void ) {
-
- DBGC ( &efi_driver_binding, "EFIDRV connecting our drivers\n" );
- return efi_driver_handles ( efi_driver_connect );
-}
-
-/**
- * Disconnect EFI driver from all possible devices
- *
- * @ret rc Return status code
- */
-void efi_driver_disconnect_all ( void ) {
-
- DBGC ( &efi_driver_binding, "EFIDRV disconnecting our drivers\n" );
- efi_driver_handles ( efi_driver_disconnect );
-}
-
-/**
- * Reconnect original EFI drivers to all possible devices
- *
- * @ret rc Return status code
- */
-void efi_driver_reconnect_all ( void ) {
-
- DBGC ( &efi_driver_binding, "EFIDRV reconnecting old drivers\n" );
- efi_driver_handles ( efi_driver_reconnect );
-}
diff --git a/qemu/roms/ipxe/src/interface/efi/efi_file.c b/qemu/roms/ipxe/src/interface/efi/efi_file.c
deleted file mode 100644
index 3715b70bf..000000000
--- a/qemu/roms/ipxe/src/interface/efi/efi_file.c
+++ /dev/null
@@ -1,718 +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
- *
- * EFI file protocols
- *
- */
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <strings.h>
-#include <errno.h>
-#include <wchar.h>
-#include <ipxe/image.h>
-#include <ipxe/efi/efi.h>
-#include <ipxe/efi/Protocol/SimpleFileSystem.h>
-#include <ipxe/efi/Protocol/BlockIo.h>
-#include <ipxe/efi/Protocol/DiskIo.h>
-#include <ipxe/efi/Guid/FileInfo.h>
-#include <ipxe/efi/Guid/FileSystemInfo.h>
-#include <ipxe/efi/efi_strings.h>
-#include <ipxe/efi/efi_file.h>
-
-/** EFI file information GUID */
-static EFI_GUID efi_file_info_id = EFI_FILE_INFO_ID;
-
-/** EFI file system information GUID */
-static EFI_GUID efi_file_system_info_id = EFI_FILE_SYSTEM_INFO_ID;
-
-/** EFI media ID */
-#define EFI_MEDIA_ID_MAGIC 0x69505845
-
-/** An image exposed as an EFI file */
-struct efi_file {
- /** EFI file protocol */
- EFI_FILE_PROTOCOL file;
- /** Image */
- struct image *image;
- /** Current file position */
- size_t pos;
-};
-
-static struct efi_file efi_file_root;
-
-/**
- * Get EFI file name (for debugging)
- *
- * @v file EFI file
- * @ret name Name
- */
-static const char * efi_file_name ( struct efi_file *file ) {
-
- return ( file->image ? file->image->name : "<root>" );
-}
-
-/**
- * Find EFI file image
- *
- * @v wname Filename
- * @ret image Image, or NULL
- */
-static struct image * efi_file_find ( const CHAR16 *wname ) {
- char name[ wcslen ( wname ) + 1 /* NUL */ ];
- struct image *image;
-
- /* Find image */
- snprintf ( name, sizeof ( name ), "%ls", wname );
- list_for_each_entry ( image, &images, list ) {
- if ( strcasecmp ( image->name, name ) == 0 )
- return image;
- }
-
- return NULL;
-
-}
-
-/**
- * Open file
- *
- * @v this EFI file
- * @ret new New EFI file
- * @v wname Filename
- * @v mode File mode
- * @v attributes File attributes (for newly-created files)
- * @ret efirc EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_file_open ( EFI_FILE_PROTOCOL *this, EFI_FILE_PROTOCOL **new,
- CHAR16 *wname, UINT64 mode __unused,
- UINT64 attributes __unused ) {
- struct efi_file *file = container_of ( this, struct efi_file, file );
- struct efi_file *new_file;
- struct image *image;
-
- /* Initial '\' indicates opening from the root directory */
- while ( *wname == L'\\' ) {
- file = &efi_file_root;
- wname++;
- }
-
- /* Allow root directory itself to be opened */
- if ( ( wname[0] == L'\0' ) || ( wname[0] == L'.' ) ) {
- *new = &efi_file_root.file;
- return 0;
- }
-
- /* Fail unless opening from the root */
- if ( file->image ) {
- DBGC ( file, "EFIFILE %s is not a directory\n",
- efi_file_name ( file ) );
- return EFI_NOT_FOUND;
- }
-
- /* Identify image */
- image = efi_file_find ( wname );
- if ( ! image ) {
- DBGC ( file, "EFIFILE \"%ls\" does not exist\n", wname );
- return EFI_NOT_FOUND;
- }
-
- /* Fail unless opening read-only */
- if ( mode != EFI_FILE_MODE_READ ) {
- DBGC ( file, "EFIFILE %s cannot be opened in mode %#08llx\n",
- image->name, mode );
- return EFI_WRITE_PROTECTED;
- }
-
- /* Allocate and initialise file */
- new_file = zalloc ( sizeof ( *new_file ) );
- memcpy ( &new_file->file, &efi_file_root.file,
- sizeof ( new_file->file ) );
- new_file->image = image_get ( image );
- *new = &new_file->file;
- DBGC ( new_file, "EFIFILE %s opened\n", efi_file_name ( new_file ) );
-
- return 0;
-}
-
-/**
- * Close file
- *
- * @v this EFI file
- * @ret efirc EFI status code
- */
-static EFI_STATUS EFIAPI efi_file_close ( EFI_FILE_PROTOCOL *this ) {
- struct efi_file *file = container_of ( this, struct efi_file, file );
-
- /* Do nothing if this is the root */
- if ( ! file->image )
- return 0;
-
- /* Close file */
- DBGC ( file, "EFIFILE %s closed\n", efi_file_name ( file ) );
- image_put ( file->image );
- free ( file );
-
- return 0;
-}
-
-/**
- * Close and delete file
- *
- * @v this EFI file
- * @ret efirc EFI status code
- */
-static EFI_STATUS EFIAPI efi_file_delete ( EFI_FILE_PROTOCOL *this ) {
- struct efi_file *file = container_of ( this, struct efi_file, file );
-
- DBGC ( file, "EFIFILE %s cannot be deleted\n", efi_file_name ( file ) );
-
- /* Close file */
- efi_file_close ( this );
-
- /* Warn of failure to delete */
- return EFI_WARN_DELETE_FAILURE;
-}
-
-/**
- * Return variable-length data structure
- *
- * @v base Base data structure (starting with UINT64)
- * @v base_len Length of base data structure
- * @v name Name to append to base data structure
- * @v len Length of data buffer
- * @v data Data buffer
- * @ret efirc EFI status code
- */
-static EFI_STATUS efi_file_varlen ( UINT64 *base, size_t base_len,
- const char *name, UINTN *len, VOID *data ) {
- size_t name_len;
-
- /* Calculate structure length */
- name_len = strlen ( name );
- *base = ( base_len + ( name_len + 1 /* NUL */ ) * sizeof ( wchar_t ) );
- if ( *len < *base ) {
- *len = *base;
- return EFI_BUFFER_TOO_SMALL;
- }
-
- /* Copy data to buffer */
- *len = *base;
- memcpy ( data, base, base_len );
- efi_snprintf ( ( data + base_len ), ( name_len + 1 /* NUL */ ),
- "%s", name );
-
- return 0;
-}
-
-/**
- * Return file information structure
- *
- * @v image Image, or NULL for the root directory
- * @v len Length of data buffer
- * @v data Data buffer
- * @ret efirc EFI status code
- */
-static EFI_STATUS efi_file_info ( struct image *image, UINTN *len,
- VOID *data ) {
- EFI_FILE_INFO info;
- const char *name;
-
- /* Populate file information */
- memset ( &info, 0, sizeof ( info ) );
- if ( image ) {
- info.FileSize = image->len;
- info.PhysicalSize = image->len;
- info.Attribute = EFI_FILE_READ_ONLY;
- name = image->name;
- } else {
- info.Attribute = ( EFI_FILE_READ_ONLY | EFI_FILE_DIRECTORY );
- name = "";
- }
-
- return efi_file_varlen ( &info.Size, SIZE_OF_EFI_FILE_INFO, name,
- len, data );
-}
-
-/**
- * Read directory entry
- *
- * @v file EFI file
- * @v len Length to read
- * @v data Data buffer
- * @ret efirc EFI status code
- */
-static EFI_STATUS efi_file_read_dir ( struct efi_file *file, UINTN *len,
- VOID *data ) {
- EFI_STATUS efirc;
- struct image *image;
- unsigned int index;
-
- /* Construct directory entry at current position */
- index = file->pos;
- for_each_image ( image ) {
- if ( index-- == 0 ) {
- efirc = efi_file_info ( image, len, data );
- if ( efirc == 0 )
- file->pos++;
- return efirc;
- }
- }
-
- /* No more entries */
- *len = 0;
- return 0;
-}
-
-/**
- * Read from file
- *
- * @v this EFI file
- * @v len Length to read
- * @v data Data buffer
- * @ret efirc EFI status code
- */
-static EFI_STATUS EFIAPI efi_file_read ( EFI_FILE_PROTOCOL *this,
- UINTN *len, VOID *data ) {
- struct efi_file *file = container_of ( this, struct efi_file, file );
- size_t remaining;
-
- /* If this is the root directory, then construct a directory entry */
- if ( ! file->image )
- return efi_file_read_dir ( file, len, data );
-
- /* Read from the file */
- remaining = ( file->image->len - file->pos );
- if ( *len > remaining )
- *len = remaining;
- DBGC ( file, "EFIFILE %s read [%#08zx,%#08zx)\n",
- efi_file_name ( file ), file->pos,
- ( ( size_t ) ( file->pos + *len ) ) );
- copy_from_user ( data, file->image->data, file->pos, *len );
- file->pos += *len;
- return 0;
-}
-
-/**
- * Write to file
- *
- * @v this EFI file
- * @v len Length to write
- * @v data Data buffer
- * @ret efirc EFI status code
- */
-static EFI_STATUS EFIAPI efi_file_write ( EFI_FILE_PROTOCOL *this,
- UINTN *len, VOID *data __unused ) {
- struct efi_file *file = container_of ( this, struct efi_file, file );
-
- DBGC ( file, "EFIFILE %s cannot write [%#08zx, %#08zx)\n",
- efi_file_name ( file ), file->pos,
- ( ( size_t ) ( file->pos + *len ) ) );
- return EFI_WRITE_PROTECTED;
-}
-
-/**
- * Set file position
- *
- * @v this EFI file
- * @v position New file position
- * @ret efirc EFI status code
- */
-static EFI_STATUS EFIAPI efi_file_set_position ( EFI_FILE_PROTOCOL *this,
- UINT64 position ) {
- struct efi_file *file = container_of ( this, struct efi_file, file );
-
- /* If this is the root directory, reset to the start */
- if ( ! file->image ) {
- DBGC ( file, "EFIFILE root directory rewound\n" );
- file->pos = 0;
- return 0;
- }
-
- /* Check for the magic end-of-file value */
- if ( position == 0xffffffffffffffffULL )
- position = file->image->len;
-
- /* Fail if we attempt to seek past the end of the file (since
- * we do not support writes).
- */
- if ( position > file->image->len ) {
- DBGC ( file, "EFIFILE %s cannot seek to %#08llx of %#08zx\n",
- efi_file_name ( file ), position, file->image->len );
- return EFI_UNSUPPORTED;
- }
-
- /* Set position */
- file->pos = position;
- DBGC ( file, "EFIFILE %s position set to %#08zx\n",
- efi_file_name ( file ), file->pos );
-
- return 0;
-}
-
-/**
- * Get file position
- *
- * @v this EFI file
- * @ret position New file position
- * @ret efirc EFI status code
- */
-static EFI_STATUS EFIAPI efi_file_get_position ( EFI_FILE_PROTOCOL *this,
- UINT64 *position ) {
- struct efi_file *file = container_of ( this, struct efi_file, file );
-
- *position = file->pos;
- return 0;
-}
-
-/**
- * Get file information
- *
- * @v this EFI file
- * @v type Type of information
- * @v len Buffer size
- * @v data Buffer
- * @ret efirc EFI status code
- */
-static EFI_STATUS EFIAPI efi_file_get_info ( EFI_FILE_PROTOCOL *this,
- EFI_GUID *type,
- UINTN *len, VOID *data ) {
- struct efi_file *file = container_of ( this, struct efi_file, file );
- EFI_FILE_SYSTEM_INFO fsinfo;
- struct image *image;
-
- /* Determine information to return */
- if ( memcmp ( type, &efi_file_info_id, sizeof ( *type ) ) == 0 ) {
-
- /* Get file information */
- DBGC ( file, "EFIFILE %s get file information\n",
- efi_file_name ( file ) );
- return efi_file_info ( file->image, len, data );
-
- } else if ( memcmp ( type, &efi_file_system_info_id,
- sizeof ( *type ) ) == 0 ) {
-
- /* Get file system information */
- DBGC ( file, "EFIFILE %s get file system information\n",
- efi_file_name ( file ) );
- memset ( &fsinfo, 0, sizeof ( fsinfo ) );
- fsinfo.ReadOnly = 1;
- for_each_image ( image )
- fsinfo.VolumeSize += image->len;
- return efi_file_varlen ( &fsinfo.Size,
- SIZE_OF_EFI_FILE_SYSTEM_INFO, "iPXE",
- len, data );
- } else {
-
- DBGC ( file, "EFIFILE %s cannot get information of type %s\n",
- efi_file_name ( file ), efi_guid_ntoa ( type ) );
- return EFI_UNSUPPORTED;
- }
-}
-
-/**
- * Set file information
- *
- * @v this EFI file
- * @v type Type of information
- * @v len Buffer size
- * @v data Buffer
- * @ret efirc EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_file_set_info ( EFI_FILE_PROTOCOL *this, EFI_GUID *type,
- UINTN len __unused, VOID *data __unused ) {
- struct efi_file *file = container_of ( this, struct efi_file, file );
-
- DBGC ( file, "EFIFILE %s cannot set information of type %s\n",
- efi_file_name ( file ), efi_guid_ntoa ( type ) );
- return EFI_WRITE_PROTECTED;
-}
-
-/**
- * Flush file modified data
- *
- * @v this EFI file
- * @v type Type of information
- * @v len Buffer size
- * @v data Buffer
- * @ret efirc EFI status code
- */
-static EFI_STATUS EFIAPI efi_file_flush ( EFI_FILE_PROTOCOL *this ) {
- struct efi_file *file = container_of ( this, struct efi_file, file );
-
- DBGC ( file, "EFIFILE %s flushed\n", efi_file_name ( file ) );
- return 0;
-}
-
-/** Root directory */
-static struct efi_file efi_file_root = {
- .file = {
- .Revision = EFI_FILE_PROTOCOL_REVISION,
- .Open = efi_file_open,
- .Close = efi_file_close,
- .Delete = efi_file_delete,
- .Read = efi_file_read,
- .Write = efi_file_write,
- .GetPosition = efi_file_get_position,
- .SetPosition = efi_file_set_position,
- .GetInfo = efi_file_get_info,
- .SetInfo = efi_file_set_info,
- .Flush = efi_file_flush,
- },
- .image = NULL,
-};
-
-/**
- * Open root directory
- *
- * @v filesystem EFI simple file system
- * @ret file EFI file handle
- * @ret efirc EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_file_open_volume ( EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *filesystem __unused,
- EFI_FILE_PROTOCOL **file ) {
-
- DBGC ( &efi_file_root, "EFIFILE open volume\n" );
- *file = &efi_file_root.file;
- return 0;
-}
-
-/** EFI simple file system protocol */
-static EFI_SIMPLE_FILE_SYSTEM_PROTOCOL efi_simple_file_system_protocol = {
- .Revision = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION,
- .OpenVolume = efi_file_open_volume,
-};
-
-/** Dummy block I/O reset */
-static EFI_STATUS EFIAPI
-efi_block_io_reset ( EFI_BLOCK_IO_PROTOCOL *this __unused, BOOLEAN extended ) {
-
- DBGC ( &efi_file_root, "EFIFILE block %sreset\n",
- ( extended ? "extended " : "" ) );
- return 0;
-}
-
-/** Dummy block I/O read */
-static EFI_STATUS EFIAPI
-efi_block_io_read_blocks ( EFI_BLOCK_IO_PROTOCOL *this __unused, UINT32 MediaId,
- EFI_LBA lba, UINTN len, VOID *data ) {
-
- DBGC ( &efi_file_root, "EFIFILE block read ID %#08x LBA %#08llx -> "
- "%p+%zx\n", MediaId, ( ( unsigned long long ) lba ),
- data, ( ( size_t ) len ) );
- return EFI_NO_MEDIA;
-}
-
-/** Dummy block I/O write */
-static EFI_STATUS EFIAPI
-efi_block_io_write_blocks ( EFI_BLOCK_IO_PROTOCOL *this __unused,
- UINT32 MediaId, EFI_LBA lba, UINTN len,
- VOID *data ) {
-
- DBGC ( &efi_file_root, "EFIFILE block write ID %#08x LBA %#08llx <- "
- "%p+%zx\n", MediaId, ( ( unsigned long long ) lba ),
- data, ( ( size_t ) len ) );
- return EFI_NO_MEDIA;
-}
-
-/** Dummy block I/O flush */
-static EFI_STATUS EFIAPI
-efi_block_io_flush_blocks ( EFI_BLOCK_IO_PROTOCOL *this __unused ) {
-
- DBGC ( &efi_file_root, "EFIFILE block flush\n" );
- return 0;
-}
-
-/** Dummy block I/O media */
-static EFI_BLOCK_IO_MEDIA efi_block_io_media = {
- .MediaId = EFI_MEDIA_ID_MAGIC,
- .MediaPresent = TRUE,
- .ReadOnly = TRUE,
- .BlockSize = 1,
-};
-
-/** Dummy EFI block I/O protocol */
-static EFI_BLOCK_IO_PROTOCOL efi_block_io_protocol = {
- .Revision = EFI_BLOCK_IO_PROTOCOL_REVISION,
- .Media = &efi_block_io_media,
- .Reset = efi_block_io_reset,
- .ReadBlocks = efi_block_io_read_blocks,
- .WriteBlocks = efi_block_io_write_blocks,
- .FlushBlocks = efi_block_io_flush_blocks,
-};
-
-/** Dummy disk I/O read */
-static EFI_STATUS EFIAPI
-efi_disk_io_read_disk ( EFI_DISK_IO_PROTOCOL *this __unused, UINT32 MediaId,
- UINT64 offset, UINTN len, VOID *data ) {
-
- DBGC ( &efi_file_root, "EFIFILE disk read ID %#08x offset %#08llx -> "
- "%p+%zx\n", MediaId, ( ( unsigned long long ) offset ),
- data, ( ( size_t ) len ) );
- return EFI_NO_MEDIA;
-}
-
-/** Dummy disk I/O write */
-static EFI_STATUS EFIAPI
-efi_disk_io_write_disk ( EFI_DISK_IO_PROTOCOL *this __unused, UINT32 MediaId,
- UINT64 offset, UINTN len, VOID *data ) {
-
- DBGC ( &efi_file_root, "EFIFILE disk write ID %#08x offset %#08llx <- "
- "%p+%zx\n", MediaId, ( ( unsigned long long ) offset ),
- data, ( ( size_t ) len ) );
- return EFI_NO_MEDIA;
-}
-
-/** Dummy EFI disk I/O protocol */
-static EFI_DISK_IO_PROTOCOL efi_disk_io_protocol = {
- .Revision = EFI_DISK_IO_PROTOCOL_REVISION,
- .ReadDisk = efi_disk_io_read_disk,
- .WriteDisk = efi_disk_io_write_disk,
-};
-
-/**
- * Install EFI simple file system protocol
- *
- * @v handle EFI handle
- * @ret rc Return status code
- */
-int efi_file_install ( EFI_HANDLE handle ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- union {
- EFI_DISK_IO_PROTOCOL *diskio;
- void *interface;
- } diskio;
- EFI_STATUS efirc;
- int rc;
-
- /* Install the simple file system protocol, block I/O
- * protocol, and disk I/O protocol. We don't have a block
- * device, but large parts of the EDK2 codebase make the
- * assumption that file systems are normally attached to block
- * devices, and so we create a dummy block device on the same
- * handle just to keep things looking normal.
- */
- if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
- &handle,
- &efi_block_io_protocol_guid,
- &efi_block_io_protocol,
- &efi_disk_io_protocol_guid,
- &efi_disk_io_protocol,
- &efi_simple_file_system_protocol_guid,
- &efi_simple_file_system_protocol, NULL ) ) != 0 ) {
- rc = -EEFI ( efirc );
- DBGC ( handle, "Could not install simple file system "
- "protocols: %s\n", strerror ( rc ) );
- goto err_install;
- }
-
- /* The FAT filesystem driver has a bug: if a block device
- * contains no FAT filesystem but does have an
- * EFI_SIMPLE_FILE_SYSTEM_PROTOCOL instance, the FAT driver
- * will assume that it must have previously installed the
- * EFI_SIMPLE_FILE_SYSTEM_PROTOCOL. This causes the FAT
- * driver to claim control of our device, and to refuse to
- * stop driving it, which prevents us from later uninstalling
- * correctly.
- *
- * Work around this bug by opening the disk I/O protocol
- * ourselves, thereby preventing the FAT driver from opening
- * it.
- *
- * Note that the alternative approach of opening the block I/O
- * protocol (and thereby in theory preventing DiskIo from
- * attaching to the block I/O protocol) causes an endless loop
- * of calls to our DRIVER_STOP method when starting the EFI
- * shell. I have no idea why this is.
- */
- if ( ( efirc = bs->OpenProtocol ( handle, &efi_disk_io_protocol_guid,
- &diskio.interface, efi_image_handle,
- handle,
- EFI_OPEN_PROTOCOL_BY_DRIVER ) ) != 0){
- rc = -EEFI ( efirc );
- DBGC ( handle, "Could not open disk I/O protocol: %s\n",
- strerror ( rc ) );
- DBGC_EFI_OPENERS ( handle, handle, &efi_disk_io_protocol_guid );
- goto err_open;
- }
- assert ( diskio.diskio == &efi_disk_io_protocol );
-
- return 0;
-
- bs->CloseProtocol ( handle, &efi_disk_io_protocol_guid,
- efi_image_handle, handle );
- err_open:
- bs->UninstallMultipleProtocolInterfaces (
- handle,
- &efi_simple_file_system_protocol_guid,
- &efi_simple_file_system_protocol,
- &efi_disk_io_protocol_guid,
- &efi_disk_io_protocol,
- &efi_block_io_protocol_guid,
- &efi_block_io_protocol, NULL );
- err_install:
- return rc;
-}
-
-/**
- * Uninstall EFI simple file system protocol
- *
- * @v handle EFI handle
- */
-void efi_file_uninstall ( EFI_HANDLE handle ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- EFI_STATUS efirc;
- int rc;
-
- /* Close our own disk I/O protocol */
- bs->CloseProtocol ( handle, &efi_disk_io_protocol_guid,
- efi_image_handle, handle );
-
- /* We must install the file system protocol first, since
- * otherwise the EDK2 code will attempt to helpfully uninstall
- * it when the block I/O protocol is uninstalled, leading to a
- * system lock-up.
- */
- if ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
- handle,
- &efi_simple_file_system_protocol_guid,
- &efi_simple_file_system_protocol,
- &efi_disk_io_protocol_guid,
- &efi_disk_io_protocol,
- &efi_block_io_protocol_guid,
- &efi_block_io_protocol, NULL ) ) != 0 ) {
- rc = -EEFI ( efirc );
- DBGC ( handle, "Could not uninstall simple file system "
- "protocols: %s\n", strerror ( rc ) );
- /* Oh dear */
- }
-}
diff --git a/qemu/roms/ipxe/src/interface/efi/efi_guid.c b/qemu/roms/ipxe/src/interface/efi/efi_guid.c
deleted file mode 100644
index ab1c91e9f..000000000
--- a/qemu/roms/ipxe/src/interface/efi/efi_guid.c
+++ /dev/null
@@ -1,209 +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 );
-
-#include <ipxe/efi/efi.h>
-#include <ipxe/efi/Protocol/Arp.h>
-#include <ipxe/efi/Protocol/BlockIo.h>
-#include <ipxe/efi/Protocol/BusSpecificDriverOverride.h>
-#include <ipxe/efi/Protocol/ComponentName.h>
-#include <ipxe/efi/Protocol/ComponentName2.h>
-#include <ipxe/efi/Protocol/DevicePath.h>
-#include <ipxe/efi/Protocol/DevicePathToText.h>
-#include <ipxe/efi/Protocol/Dhcp4.h>
-#include <ipxe/efi/Protocol/DiskIo.h>
-#include <ipxe/efi/Protocol/DriverBinding.h>
-#include <ipxe/efi/Protocol/GraphicsOutput.h>
-#include <ipxe/efi/Protocol/HiiConfigAccess.h>
-#include <ipxe/efi/Protocol/Ip4.h>
-#include <ipxe/efi/Protocol/Ip4Config.h>
-#include <ipxe/efi/Protocol/LoadFile.h>
-#include <ipxe/efi/Protocol/LoadFile2.h>
-#include <ipxe/efi/Protocol/LoadedImage.h>
-#include <ipxe/efi/Protocol/ManagedNetwork.h>
-#include <ipxe/efi/Protocol/Mtftp4.h>
-#include <ipxe/efi/Protocol/NetworkInterfaceIdentifier.h>
-#include <ipxe/efi/Protocol/PciIo.h>
-#include <ipxe/efi/Protocol/PciRootBridgeIo.h>
-#include <ipxe/efi/Protocol/PxeBaseCode.h>
-#include <ipxe/efi/Protocol/SimpleFileSystem.h>
-#include <ipxe/efi/Protocol/SimpleNetwork.h>
-#include <ipxe/efi/Protocol/TcgService.h>
-#include <ipxe/efi/Protocol/Tcp4.h>
-#include <ipxe/efi/Protocol/Udp4.h>
-#include <ipxe/efi/Protocol/VlanConfig.h>
-
-/** @file
- *
- * EFI GUIDs
- *
- */
-
-/** ARP protocol GUID */
-EFI_GUID efi_arp_protocol_guid
- = EFI_ARP_PROTOCOL_GUID;
-
-/** ARP service binding protocol GUID */
-EFI_GUID efi_arp_service_binding_protocol_guid
- = EFI_ARP_SERVICE_BINDING_PROTOCOL_GUID;
-
-/** Block I/O protocol GUID */
-EFI_GUID efi_block_io_protocol_guid
- = EFI_BLOCK_IO_PROTOCOL_GUID;
-
-/** Bus specific driver override protocol GUID */
-EFI_GUID efi_bus_specific_driver_override_protocol_guid
- = EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL_GUID;
-
-/** Component name protocol GUID */
-EFI_GUID efi_component_name_protocol_guid
- = EFI_COMPONENT_NAME_PROTOCOL_GUID;
-
-/** Component name 2 protocol GUID */
-EFI_GUID efi_component_name2_protocol_guid
- = EFI_COMPONENT_NAME2_PROTOCOL_GUID;
-
-/** Device path protocol GUID */
-EFI_GUID efi_device_path_protocol_guid
- = EFI_DEVICE_PATH_PROTOCOL_GUID;
-
-/** DHCPv4 protocol GUID */
-EFI_GUID efi_dhcp4_protocol_guid
- = EFI_DHCP4_PROTOCOL_GUID;
-
-/** DHCPv4 service binding protocol GUID */
-EFI_GUID efi_dhcp4_service_binding_protocol_guid
- = EFI_DHCP4_SERVICE_BINDING_PROTOCOL_GUID;
-
-/** Disk I/O protocol GUID */
-EFI_GUID efi_disk_io_protocol_guid
- = EFI_DISK_IO_PROTOCOL_GUID;
-
-/** Driver binding protocol GUID */
-EFI_GUID efi_driver_binding_protocol_guid
- = EFI_DRIVER_BINDING_PROTOCOL_GUID;
-
-/** Graphics output protocol GUID */
-EFI_GUID efi_graphics_output_protocol_guid
- = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
-
-/** HII configuration access protocol GUID */
-EFI_GUID efi_hii_config_access_protocol_guid
- = EFI_HII_CONFIG_ACCESS_PROTOCOL_GUID;
-
-/** IPv4 protocol GUID */
-EFI_GUID efi_ip4_protocol_guid
- = EFI_IP4_PROTOCOL_GUID;
-
-/** IPv4 configuration protocol GUID */
-EFI_GUID efi_ip4_config_protocol_guid
- = EFI_IP4_CONFIG_PROTOCOL_GUID;
-
-/** IPv4 service binding protocol GUID */
-EFI_GUID efi_ip4_service_binding_protocol_guid
- = EFI_IP4_SERVICE_BINDING_PROTOCOL_GUID;
-
-/** Load file protocol GUID */
-EFI_GUID efi_load_file_protocol_guid
- = EFI_LOAD_FILE_PROTOCOL_GUID;
-
-/** Load file 2 protocol GUID */
-EFI_GUID efi_load_file2_protocol_guid
- = EFI_LOAD_FILE2_PROTOCOL_GUID;
-
-/** Loaded image protocol GUID */
-EFI_GUID efi_loaded_image_protocol_guid
- = EFI_LOADED_IMAGE_PROTOCOL_GUID;
-
-/** Loaded image device path protocol GUID */
-EFI_GUID efi_loaded_image_device_path_protocol_guid
- = EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID;
-
-/** Managed network protocol GUID */
-EFI_GUID efi_managed_network_protocol_guid
- = EFI_MANAGED_NETWORK_PROTOCOL_GUID;
-
-/** Managed network service binding protocol GUID */
-EFI_GUID efi_managed_network_service_binding_protocol_guid
- = EFI_MANAGED_NETWORK_SERVICE_BINDING_PROTOCOL_GUID;
-
-/** MTFTPv4 protocol GUID */
-EFI_GUID efi_mtftp4_protocol_guid
- = EFI_MTFTP4_PROTOCOL_GUID;
-
-/** MTFTPv4 service binding protocol GUID */
-EFI_GUID efi_mtftp4_service_binding_protocol_guid
- = EFI_MTFTP4_SERVICE_BINDING_PROTOCOL_GUID;
-
-/** Network interface identifier protocol GUID (old version) */
-EFI_GUID efi_nii_protocol_guid
- = EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_GUID;
-
-/** Network interface identifier protocol GUID (new version) */
-EFI_GUID efi_nii31_protocol_guid
- = EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_GUID_31;
-
-/** PCI I/O protocol GUID */
-EFI_GUID efi_pci_io_protocol_guid
- = EFI_PCI_IO_PROTOCOL_GUID;
-
-/** PCI root bridge I/O protocol GUID */
-EFI_GUID efi_pci_root_bridge_io_protocol_guid
- = EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID;
-
-/** PXE base code protocol GUID */
-EFI_GUID efi_pxe_base_code_protocol_guid
- = EFI_PXE_BASE_CODE_PROTOCOL_GUID;
-
-/** Simple file system protocol GUID */
-EFI_GUID efi_simple_file_system_protocol_guid
- = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
-
-/** Simple network protocol GUID */
-EFI_GUID efi_simple_network_protocol_guid
- = EFI_SIMPLE_NETWORK_PROTOCOL_GUID;
-
-/** TCG protocol GUID */
-EFI_GUID efi_tcg_protocol_guid
- = EFI_TCG_PROTOCOL_GUID;
-
-/** TCPv4 protocol GUID */
-EFI_GUID efi_tcp4_protocol_guid
- = EFI_TCP4_PROTOCOL_GUID;
-
-/** TCPv4 service binding protocol GUID */
-EFI_GUID efi_tcp4_service_binding_protocol_guid
- = EFI_TCP4_SERVICE_BINDING_PROTOCOL_GUID;
-
-/** UDPv4 protocol GUID */
-EFI_GUID efi_udp4_protocol_guid
- = EFI_UDP4_PROTOCOL_GUID;
-
-/** UDPv4 service binding protocol GUID */
-EFI_GUID efi_udp4_service_binding_protocol_guid
- = EFI_UDP4_SERVICE_BINDING_PROTOCOL_GUID;
-
-/** VLAN configuration protocol GUID */
-EFI_GUID efi_vlan_config_protocol_guid
- = EFI_VLAN_CONFIG_PROTOCOL_GUID;
diff --git a/qemu/roms/ipxe/src/interface/efi/efi_hii.c b/qemu/roms/ipxe/src/interface/efi/efi_hii.c
deleted file mode 100644
index 0ea970e67..000000000
--- a/qemu/roms/ipxe/src/interface/efi/efi_hii.c
+++ /dev/null
@@ -1,581 +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 );
-
-#include <stdlib.h>
-#include <stddef.h>
-#include <stdarg.h>
-#include <string.h>
-#include <ipxe/efi/efi.h>
-#include <ipxe/efi/efi_strings.h>
-#include <ipxe/efi/efi_hii.h>
-
-/** Tiano GUID */
-static const EFI_GUID tiano_guid = EFI_IFR_TIANO_GUID;
-
-/**
- * Add string to IFR builder
- *
- * @v ifr IFR builder
- * @v fmt Format string
- * @v ... Arguments
- * @ret string_id String identifier, or zero on failure
- */
-unsigned int efi_ifr_string ( struct efi_ifr_builder *ifr, const char *fmt,
- ... ) {
- EFI_HII_STRING_BLOCK *new_strings;
- EFI_HII_SIBT_STRING_UCS2_BLOCK *ucs2;
- size_t new_strings_len;
- va_list args;
- size_t len;
- unsigned int string_id;
-
- /* Do nothing if a previous allocation has failed */
- if ( ifr->failed )
- return 0;
-
- /* Calculate string length */
- va_start ( args, fmt );
- len = ( efi_vsnprintf ( NULL, 0, fmt, args ) + 1 /* wNUL */ );
- va_end ( args );
-
- /* Reallocate strings */
- new_strings_len = ( ifr->strings_len +
- offsetof ( typeof ( *ucs2 ), StringText ) +
- ( len * sizeof ( ucs2->StringText[0] ) ) );
- new_strings = realloc ( ifr->strings, new_strings_len );
- if ( ! new_strings ) {
- ifr->failed = 1;
- return 0;
- }
- ucs2 = ( ( ( void * ) new_strings ) + ifr->strings_len );
- ifr->strings = new_strings;
- ifr->strings_len = new_strings_len;
-
- /* Fill in string */
- ucs2->Header.BlockType = EFI_HII_SIBT_STRING_UCS2;
- va_start ( args, fmt );
- efi_vsnprintf ( ucs2->StringText, len, fmt, args );
- va_end ( args );
-
- /* Allocate string ID */
- string_id = ++(ifr->string_id);
-
- DBGC ( ifr, "IFR %p string %#04x is \"%ls\"\n",
- ifr, string_id, ucs2->StringText );
- return string_id;
-}
-
-/**
- * Add IFR opcode to IFR builder
- *
- * @v ifr IFR builder
- * @v opcode Opcode
- * @v len Opcode length
- * @ret op Opcode, or NULL
- */
-static void * efi_ifr_op ( struct efi_ifr_builder *ifr, unsigned int opcode,
- size_t len ) {
- EFI_IFR_OP_HEADER *new_ops;
- EFI_IFR_OP_HEADER *op;
- size_t new_ops_len;
-
- /* Do nothing if a previous allocation has failed */
- if ( ifr->failed )
- return NULL;
-
- /* Reallocate opcodes */
- new_ops_len = ( ifr->ops_len + len );
- new_ops = realloc ( ifr->ops, new_ops_len );
- if ( ! new_ops ) {
- ifr->failed = 1;
- return NULL;
- }
- op = ( ( ( void * ) new_ops ) + ifr->ops_len );
- ifr->ops = new_ops;
- ifr->ops_len = new_ops_len;
-
- /* Fill in opcode header */
- op->OpCode = opcode;
- op->Length = len;
-
- return op;
-}
-
-/**
- * Add end opcode to IFR builder
- *
- * @v ifr IFR builder
- */
-void efi_ifr_end_op ( struct efi_ifr_builder *ifr ) {
- size_t dispaddr = ifr->ops_len;
- EFI_IFR_END *end;
-
- /* Add opcode */
- end = efi_ifr_op ( ifr, EFI_IFR_END_OP, sizeof ( *end ) );
-
- DBGC ( ifr, "IFR %p end\n", ifr );
- DBGC2_HDA ( ifr, dispaddr, end, sizeof ( *end ) );
-}
-
-/**
- * Add false opcode to IFR builder
- *
- * @v ifr IFR builder
- */
-void efi_ifr_false_op ( struct efi_ifr_builder *ifr ) {
- size_t dispaddr = ifr->ops_len;
- EFI_IFR_FALSE *false;
-
- /* Add opcode */
- false = efi_ifr_op ( ifr, EFI_IFR_FALSE_OP, sizeof ( *false ) );
-
- DBGC ( ifr, "IFR %p false\n", ifr );
- DBGC2_HDA ( ifr, dispaddr, false, sizeof ( *false ) );
-}
-
-/**
- * Add form opcode to IFR builder
- *
- * @v ifr IFR builder
- * @v title_id Title string identifier
- * @ret form_id Form identifier
- */
-unsigned int efi_ifr_form_op ( struct efi_ifr_builder *ifr,
- unsigned int title_id ) {
- size_t dispaddr = ifr->ops_len;
- EFI_IFR_FORM *form;
-
- /* Add opcode */
- form = efi_ifr_op ( ifr, EFI_IFR_FORM_OP, sizeof ( *form ) );
- if ( ! form )
- return 0;
- form->Header.Scope = 1;
- form->FormId = ++(ifr->form_id);
- form->FormTitle = title_id;
-
- DBGC ( ifr, "IFR %p name/value store %#04x title %#04x\n",
- ifr, form->FormId, title_id );
- DBGC2_HDA ( ifr, dispaddr, form, sizeof ( *form ) );
- return form->FormId;
-}
-
-/**
- * Add formset opcode to IFR builder
- *
- * @v ifr IFR builder
- * @v guid GUID
- * @v title_id Title string identifier
- * @v help_id Help string identifier
- * @v ... Class GUIDs (terminated by NULL)
- */
-void efi_ifr_form_set_op ( struct efi_ifr_builder *ifr, const EFI_GUID *guid,
- unsigned int title_id, unsigned int help_id, ... ) {
- size_t dispaddr = ifr->ops_len;
- EFI_IFR_FORM_SET *formset;
- EFI_GUID *class_guid;
- unsigned int num_class_guids = 0;
- size_t len;
- va_list args;
-
- /* Count number of class GUIDs */
- va_start ( args, help_id );
- while ( va_arg ( args, const EFI_GUID * ) != NULL )
- num_class_guids++;
- va_end ( args );
-
- /* Add opcode */
- len = ( sizeof ( *formset ) +
- ( num_class_guids * sizeof ( *class_guid ) ) );
- formset = efi_ifr_op ( ifr, EFI_IFR_FORM_SET_OP, len );
- if ( ! formset )
- return;
- formset->Header.Scope = 1;
- memcpy ( &formset->Guid, guid, sizeof ( formset->Guid ) );
- formset->FormSetTitle = title_id;
- formset->Help = help_id;
- formset->Flags = num_class_guids;
-
- /* Add class GUIDs */
- class_guid = ( ( ( void * ) formset ) + sizeof ( *formset ) );
- va_start ( args, help_id );
- while ( num_class_guids-- ) {
- memcpy ( class_guid++, va_arg ( args, const EFI_GUID * ),
- sizeof ( *class_guid ) );
- }
- va_end ( args );
-
- DBGC ( ifr, "IFR %p formset title %#04x help %#04x\n",
- ifr, title_id, help_id );
- DBGC2_HDA ( ifr, dispaddr, formset, len );
-}
-
-/**
- * Add get opcode to IFR builder
- *
- * @v ifr IFR builder
- * @v varstore_id Variable store identifier
- * @v varstore_info Variable string identifier or offset
- * @v varstore_type Variable type
- */
-void efi_ifr_get_op ( struct efi_ifr_builder *ifr, unsigned int varstore_id,
- unsigned int varstore_info, unsigned int varstore_type ) {
- size_t dispaddr = ifr->ops_len;
- EFI_IFR_GET *get;
-
- /* Add opcode */
- get = efi_ifr_op ( ifr, EFI_IFR_GET_OP, sizeof ( *get ) );
- get->VarStoreId = varstore_id;
- get->VarStoreInfo.VarName = varstore_info;
- get->VarStoreType = varstore_type;
-
- DBGC ( ifr, "IFR %p get varstore %#04x:%#04x type %#02x\n",
- ifr, varstore_id, varstore_info, varstore_type );
- DBGC2_HDA ( ifr, dispaddr, get, sizeof ( *get ) );
-}
-
-/**
- * Add GUID class opcode to IFR builder
- *
- * @v ifr IFR builder
- * @v class Class
- */
-void efi_ifr_guid_class_op ( struct efi_ifr_builder *ifr, unsigned int class ) {
- size_t dispaddr = ifr->ops_len;
- EFI_IFR_GUID_CLASS *guid_class;
-
- /* Add opcode */
- guid_class = efi_ifr_op ( ifr, EFI_IFR_GUID_OP,
- sizeof ( *guid_class ) );
- if ( ! guid_class )
- return;
- memcpy ( &guid_class->Guid, &tiano_guid, sizeof ( guid_class->Guid ) );
- guid_class->ExtendOpCode = EFI_IFR_EXTEND_OP_CLASS;
- guid_class->Class = class;
-
- DBGC ( ifr, "IFR %p GUID class %#02x\n", ifr, class );
- DBGC2_HDA ( ifr, dispaddr, guid_class, sizeof ( *guid_class ) );
-}
-
-/**
- * Add GUID subclass opcode to IFR builder
- *
- * @v ifr IFR builder
- * @v subclass Subclass
- */
-void efi_ifr_guid_subclass_op ( struct efi_ifr_builder *ifr,
- unsigned int subclass ) {
- size_t dispaddr = ifr->ops_len;
- EFI_IFR_GUID_SUBCLASS *guid_subclass;
-
- /* Add opcode */
- guid_subclass = efi_ifr_op ( ifr, EFI_IFR_GUID_OP,
- sizeof ( *guid_subclass ) );
- if ( ! guid_subclass )
- return;
- memcpy ( &guid_subclass->Guid, &tiano_guid,
- sizeof ( guid_subclass->Guid ) );
- guid_subclass->ExtendOpCode = EFI_IFR_EXTEND_OP_SUBCLASS;
- guid_subclass->SubClass = subclass;
-
- DBGC ( ifr, "IFR %p GUID subclass %#02x\n", ifr, subclass );
- DBGC2_HDA ( ifr, dispaddr, guid_subclass, sizeof ( *guid_subclass ) );
-}
-
-/**
- * Add numeric opcode to IFR builder
- *
- * @v ifr IFR builder
- * @v prompt_id Prompt string identifier
- * @v help_id Help string identifier
- * @v question_id Question identifier
- * @v varstore_id Variable store identifier
- * @v varstore_info Variable string identifier or offset
- * @v vflags Variable flags
- * @v min_value Minimum value
- * @v max_value Maximum value
- * @v step Step
- * @v flags Flags
- */
-void efi_ifr_numeric_op ( struct efi_ifr_builder *ifr, unsigned int prompt_id,
- unsigned int help_id, unsigned int question_id,
- unsigned int varstore_id, unsigned int varstore_info,
- unsigned int vflags, unsigned long min_value,
- unsigned long max_value, unsigned int step,
- unsigned int flags ) {
- size_t dispaddr = ifr->ops_len;
- EFI_IFR_NUMERIC *numeric;
- unsigned int size;
-
- /* Add opcode */
- numeric = efi_ifr_op ( ifr, EFI_IFR_NUMERIC_OP, sizeof ( *numeric ) );
- if ( ! numeric )
- return;
- numeric->Question.Header.Prompt = prompt_id;
- numeric->Question.Header.Help = help_id;
- numeric->Question.QuestionId = question_id;
- numeric->Question.VarStoreId = varstore_id;
- numeric->Question.VarStoreInfo.VarName = varstore_info;
- numeric->Question.Flags = vflags;
- size = ( flags & EFI_IFR_NUMERIC_SIZE );
- switch ( size ) {
- case EFI_IFR_NUMERIC_SIZE_1 :
- numeric->data.u8.MinValue = min_value;
- numeric->data.u8.MaxValue = max_value;
- numeric->data.u8.Step = step;
- break;
- case EFI_IFR_NUMERIC_SIZE_2 :
- numeric->data.u16.MinValue = min_value;
- numeric->data.u16.MaxValue = max_value;
- numeric->data.u16.Step = step;
- break;
- case EFI_IFR_NUMERIC_SIZE_4 :
- numeric->data.u32.MinValue = min_value;
- numeric->data.u32.MaxValue = max_value;
- numeric->data.u32.Step = step;
- break;
- case EFI_IFR_NUMERIC_SIZE_8 :
- numeric->data.u64.MinValue = min_value;
- numeric->data.u64.MaxValue = max_value;
- numeric->data.u64.Step = step;
- break;
- }
-
- DBGC ( ifr, "IFR %p numeric prompt %#04x help %#04x question %#04x "
- "varstore %#04x:%#04x\n", ifr, prompt_id, help_id, question_id,
- varstore_id, varstore_info );
- DBGC2_HDA ( ifr, dispaddr, numeric, sizeof ( *numeric ) );
-}
-
-/**
- * Add string opcode to IFR builder
- *
- * @v ifr IFR builder
- * @v prompt_id Prompt string identifier
- * @v help_id Help string identifier
- * @v question_id Question identifier
- * @v varstore_id Variable store identifier
- * @v varstore_info Variable string identifier or offset
- * @v vflags Variable flags
- * @v min_size Minimum size
- * @v max_size Maximum size
- * @v flags Flags
- */
-void efi_ifr_string_op ( struct efi_ifr_builder *ifr, unsigned int prompt_id,
- unsigned int help_id, unsigned int question_id,
- unsigned int varstore_id, unsigned int varstore_info,
- unsigned int vflags, unsigned int min_size,
- unsigned int max_size, unsigned int flags ) {
- size_t dispaddr = ifr->ops_len;
- EFI_IFR_STRING *string;
-
- /* Add opcode */
- string = efi_ifr_op ( ifr, EFI_IFR_STRING_OP, sizeof ( *string ) );
- if ( ! string )
- return;
- string->Question.Header.Prompt = prompt_id;
- string->Question.Header.Help = help_id;
- string->Question.QuestionId = question_id;
- string->Question.VarStoreId = varstore_id;
- string->Question.VarStoreInfo.VarName = varstore_info;
- string->Question.Flags = vflags;
- string->MinSize = min_size;
- string->MaxSize = max_size;
- string->Flags = flags;
-
- DBGC ( ifr, "IFR %p string prompt %#04x help %#04x question %#04x "
- "varstore %#04x:%#04x\n", ifr, prompt_id, help_id, question_id,
- varstore_id, varstore_info );
- DBGC2_HDA ( ifr, dispaddr, string, sizeof ( *string ) );
-}
-
-/**
- * Add suppress-if opcode to IFR builder
- *
- * @v ifr IFR builder
- */
-void efi_ifr_suppress_if_op ( struct efi_ifr_builder *ifr ) {
- size_t dispaddr = ifr->ops_len;
- EFI_IFR_SUPPRESS_IF *suppress_if;
-
- /* Add opcode */
- suppress_if = efi_ifr_op ( ifr, EFI_IFR_SUPPRESS_IF_OP,
- sizeof ( *suppress_if ) );
- suppress_if->Header.Scope = 1;
-
- DBGC ( ifr, "IFR %p suppress-if\n", ifr );
- DBGC2_HDA ( ifr, dispaddr, suppress_if, sizeof ( *suppress_if ) );
-}
-
-/**
- * Add text opcode to IFR builder
- *
- * @v ifr IFR builder
- * @v prompt_id Prompt string identifier
- * @v help_id Help string identifier
- * @v text_id Text string identifier
- */
-void efi_ifr_text_op ( struct efi_ifr_builder *ifr, unsigned int prompt_id,
- unsigned int help_id, unsigned int text_id ) {
- size_t dispaddr = ifr->ops_len;
- EFI_IFR_TEXT *text;
-
- /* Add opcode */
- text = efi_ifr_op ( ifr, EFI_IFR_TEXT_OP, sizeof ( *text ) );
- if ( ! text )
- return;
- text->Statement.Prompt = prompt_id;
- text->Statement.Help = help_id;
- text->TextTwo = text_id;
-
- DBGC ( ifr, "IFR %p text prompt %#04x help %#04x text %#04x\n",
- ifr, prompt_id, help_id, text_id );
- DBGC2_HDA ( ifr, dispaddr, text, sizeof ( *text ) );
-}
-
-/**
- * Add true opcode to IFR builder
- *
- * @v ifr IFR builder
- */
-void efi_ifr_true_op ( struct efi_ifr_builder *ifr ) {
- size_t dispaddr = ifr->ops_len;
- EFI_IFR_TRUE *true;
-
- /* Add opcode */
- true = efi_ifr_op ( ifr, EFI_IFR_TRUE_OP, sizeof ( *true ) );
-
- DBGC ( ifr, "IFR %p true\n", ifr );
- DBGC2_HDA ( ifr, dispaddr, true, sizeof ( *true ) );
-}
-
-/**
- * Add name/value store opcode to IFR builder
- *
- * @v ifr IFR builder
- * @v guid GUID
- * @ret varstore_id Variable store identifier, or 0 on failure
- */
-unsigned int efi_ifr_varstore_name_value_op ( struct efi_ifr_builder *ifr,
- const EFI_GUID *guid ) {
- size_t dispaddr = ifr->ops_len;
- EFI_IFR_VARSTORE_NAME_VALUE *varstore;
-
- /* Add opcode */
- varstore = efi_ifr_op ( ifr, EFI_IFR_VARSTORE_NAME_VALUE_OP,
- sizeof ( *varstore ) );
- if ( ! varstore )
- return 0;
- varstore->VarStoreId = ++(ifr->varstore_id);
- memcpy ( &varstore->Guid, guid, sizeof ( varstore->Guid ) );
-
- DBGC ( ifr, "IFR %p name/value store %#04x\n",
- ifr, varstore->VarStoreId );
- DBGC2_HDA ( ifr, dispaddr, varstore, sizeof ( *varstore ) );
- return varstore->VarStoreId;
-}
-
-/**
- * Free memory used by IFR builder
- *
- * @v ifr IFR builder
- */
-void efi_ifr_free ( struct efi_ifr_builder *ifr ) {
-
- free ( ifr->ops );
- free ( ifr->strings );
- memset ( ifr, 0, sizeof ( *ifr ) );
-}
-
-/**
- * Construct package list from IFR builder
- *
- * @v ifr IFR builder
- * @v guid Package GUID
- * @v language Language
- * @v language_id Language string ID
- * @ret package Package list, or NULL
- *
- * The package list is allocated using malloc(), and must eventually
- * be freed by the caller. (The caller must also call efi_ifr_free()
- * to free the temporary storage used during construction.)
- */
-EFI_HII_PACKAGE_LIST_HEADER * efi_ifr_package ( struct efi_ifr_builder *ifr,
- const EFI_GUID *guid,
- const char *language,
- unsigned int language_id ) {
- struct {
- EFI_HII_PACKAGE_LIST_HEADER header;
- struct {
- EFI_HII_PACKAGE_HEADER header;
- uint8_t data[ifr->ops_len];
- } __attribute__ (( packed )) ops;
- struct {
- union {
- EFI_HII_STRING_PACKAGE_HDR header;
- uint8_t pad[offsetof(EFI_HII_STRING_PACKAGE_HDR,
- Language) +
- strlen ( language ) + 1 /* NUL */ ];
- } __attribute__ (( packed )) header;
- uint8_t data[ifr->strings_len];
- EFI_HII_STRING_BLOCK end;
- } __attribute__ (( packed )) strings;
- EFI_HII_PACKAGE_HEADER end;
- } __attribute__ (( packed )) *package;
-
- /* Fail if any previous allocation failed */
- if ( ifr->failed )
- return NULL;
-
- /* Allocate package list */
- package = zalloc ( sizeof ( *package ) );
- if ( ! package )
- return NULL;
-
- /* Populate package list */
- package->header.PackageLength = sizeof ( *package );
- memcpy ( &package->header.PackageListGuid, guid,
- sizeof ( package->header.PackageListGuid ) );
- package->ops.header.Length = sizeof ( package->ops );
- package->ops.header.Type = EFI_HII_PACKAGE_FORMS;
- memcpy ( package->ops.data, ifr->ops, sizeof ( package->ops.data ) );
- package->strings.header.header.Header.Length =
- sizeof ( package->strings );
- package->strings.header.header.Header.Type =
- EFI_HII_PACKAGE_STRINGS;
- package->strings.header.header.HdrSize =
- sizeof ( package->strings.header );
- package->strings.header.header.StringInfoOffset =
- sizeof ( package->strings.header );
- package->strings.header.header.LanguageName = language_id;
- strcpy ( package->strings.header.header.Language, language );
- memcpy ( package->strings.data, ifr->strings,
- sizeof ( package->strings.data ) );
- package->strings.end.BlockType = EFI_HII_SIBT_END;
- package->end.Type = EFI_HII_PACKAGE_END;
- package->end.Length = sizeof ( package->end );
-
- return &package->header;
-}
-
diff --git a/qemu/roms/ipxe/src/interface/efi/efi_init.c b/qemu/roms/ipxe/src/interface/efi/efi_init.c
deleted file mode 100644
index 93ada21d4..000000000
--- a/qemu/roms/ipxe/src/interface/efi/efi_init.c
+++ /dev/null
@@ -1,226 +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.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include <string.h>
-#include <errno.h>
-#include <ipxe/init.h>
-#include <ipxe/efi/efi.h>
-#include <ipxe/efi/efi_driver.h>
-#include <ipxe/efi/Protocol/LoadedImage.h>
-
-/** Image handle passed to entry point */
-EFI_HANDLE efi_image_handle;
-
-/** Loaded image protocol for this image */
-EFI_LOADED_IMAGE_PROTOCOL *efi_loaded_image;
-
-/** System table passed to entry point */
-EFI_SYSTEM_TABLE *efi_systab;
-
-/** Event used to signal shutdown */
-static EFI_EVENT efi_shutdown_event;
-
-/* Forward declarations */
-static EFI_STATUS EFIAPI efi_unload ( EFI_HANDLE image_handle );
-
-/**
- * Shut down in preparation for booting an OS.
- *
- * This hook gets called at ExitBootServices time in order to make
- * sure that everything is properly shut down before the OS takes
- * over.
- */
-static EFIAPI void efi_shutdown_hook ( EFI_EVENT event __unused,
- void *context __unused ) {
- shutdown_boot();
-}
-
-/**
- * Look up EFI configuration table
- *
- * @v guid Configuration table GUID
- * @ret table Configuration table, or NULL
- */
-static void * efi_find_table ( EFI_GUID *guid ) {
- unsigned int i;
-
- for ( i = 0 ; i < efi_systab->NumberOfTableEntries ; i++ ) {
- if ( memcmp ( &efi_systab->ConfigurationTable[i].VendorGuid,
- guid, sizeof ( *guid ) ) == 0 )
- return efi_systab->ConfigurationTable[i].VendorTable;
- }
-
- return NULL;
-}
-
-/**
- * Initialise EFI environment
- *
- * @v image_handle Image handle
- * @v systab System table
- * @ret efirc EFI return status code
- */
-EFI_STATUS efi_init ( EFI_HANDLE image_handle,
- EFI_SYSTEM_TABLE *systab ) {
- EFI_BOOT_SERVICES *bs;
- struct efi_protocol *prot;
- struct efi_config_table *tab;
- void *loaded_image;
- EFI_STATUS efirc;
- int rc;
-
- /* Store image handle and system table pointer for future use */
- efi_image_handle = image_handle;
- efi_systab = systab;
-
- /* Sanity checks */
- if ( ! systab ) {
- efirc = EFI_NOT_AVAILABLE_YET;
- goto err_sanity;
- }
- if ( ! systab->ConOut ) {
- efirc = EFI_NOT_AVAILABLE_YET;
- goto err_sanity;
- }
- if ( ! systab->BootServices ) {
- DBGC ( systab, "EFI provided no BootServices entry point\n" );
- efirc = EFI_NOT_AVAILABLE_YET;
- goto err_sanity;
- }
- if ( ! systab->RuntimeServices ) {
- DBGC ( systab, "EFI provided no RuntimeServices entry "
- "point\n" );
- efirc = EFI_NOT_AVAILABLE_YET;
- goto err_sanity;
- }
- DBGC ( systab, "EFI handle %p systab %p\n", image_handle, systab );
- bs = systab->BootServices;
-
- /* Look up used protocols */
- for_each_table_entry ( prot, EFI_PROTOCOLS ) {
- if ( ( efirc = bs->LocateProtocol ( &prot->guid, NULL,
- prot->protocol ) ) == 0 ) {
- DBGC ( systab, "EFI protocol %s is at %p\n",
- efi_guid_ntoa ( &prot->guid ),
- *(prot->protocol) );
- } else {
- DBGC ( systab, "EFI does not provide protocol %s\n",
- efi_guid_ntoa ( &prot->guid ) );
- /* Fail if protocol is required */
- if ( prot->required )
- goto err_missing_protocol;
- }
- }
-
- /* Look up used configuration tables */
- for_each_table_entry ( tab, EFI_CONFIG_TABLES ) {
- if ( ( *(tab->table) = efi_find_table ( &tab->guid ) ) ) {
- DBGC ( systab, "EFI configuration table %s is at %p\n",
- efi_guid_ntoa ( &tab->guid ), *(tab->table) );
- } else {
- DBGC ( systab, "EFI does not provide configuration "
- "table %s\n", efi_guid_ntoa ( &tab->guid ) );
- if ( tab->required ) {
- efirc = EFI_NOT_AVAILABLE_YET;
- goto err_missing_table;
- }
- }
- }
-
- /* Get loaded image protocol */
- if ( ( efirc = bs->OpenProtocol ( image_handle,
- &efi_loaded_image_protocol_guid,
- &loaded_image, image_handle, NULL,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL ) ) != 0 ) {
- rc = -EEFI ( efirc );
- DBGC ( systab, "EFI could not get loaded image protocol: %s",
- strerror ( rc ) );
- goto err_no_loaded_image;
- }
- efi_loaded_image = loaded_image;
- DBGC ( systab, "EFI image base address %p\n",
- efi_loaded_image->ImageBase );
-
- /* EFI is perfectly capable of gracefully shutting down any
- * loaded devices if it decides to fall back to a legacy boot.
- * For no particularly comprehensible reason, it doesn't
- * bother doing so when ExitBootServices() is called.
- */
- if ( ( efirc = bs->CreateEvent ( EVT_SIGNAL_EXIT_BOOT_SERVICES,
- TPL_CALLBACK, efi_shutdown_hook,
- NULL, &efi_shutdown_event ) ) != 0 ) {
- rc = -EEFI ( efirc );
- DBGC ( systab, "EFI could not create ExitBootServices event: "
- "%s\n", strerror ( rc ) );
- goto err_create_event;
- }
-
- /* Install driver binding protocol */
- if ( ( rc = efi_driver_install() ) != 0 ) {
- DBGC ( systab, "EFI could not install driver: %s\n",
- strerror ( rc ) );
- efirc = EFIRC ( rc );
- goto err_driver_install;
- }
-
- /* Install image unload method */
- efi_loaded_image->Unload = efi_unload;
-
- return 0;
-
- efi_driver_uninstall();
- err_driver_install:
- bs->CloseEvent ( efi_shutdown_event );
- err_create_event:
- err_no_loaded_image:
- err_missing_table:
- err_missing_protocol:
- err_sanity:
- return efirc;
-}
-
-/**
- * Shut down EFI environment
- *
- * @v image_handle Image handle
- */
-static EFI_STATUS EFIAPI efi_unload ( EFI_HANDLE image_handle __unused ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- EFI_SYSTEM_TABLE *systab = efi_systab;
-
- DBGC ( systab, "EFI image unloading\n" );
-
- /* Shut down */
- shutdown_exit();
-
- /* Disconnect any remaining devices */
- efi_driver_disconnect_all();
-
- /* Uninstall driver binding protocol */
- efi_driver_uninstall();
-
- /* Uninstall exit boot services event */
- bs->CloseEvent ( efi_shutdown_event );
-
- DBGC ( systab, "EFI image unloaded\n" );
-
- return 0;
-}
diff --git a/qemu/roms/ipxe/src/interface/efi/efi_pci.c b/qemu/roms/ipxe/src/interface/efi/efi_pci.c
deleted file mode 100644
index 97ea72bb9..000000000
--- a/qemu/roms/ipxe/src/interface/efi/efi_pci.c
+++ /dev/null
@@ -1,361 +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 <stdlib.h>
-#include <errno.h>
-#include <ipxe/pci.h>
-#include <ipxe/efi/efi.h>
-#include <ipxe/efi/efi_pci.h>
-#include <ipxe/efi/efi_driver.h>
-#include <ipxe/efi/Protocol/PciIo.h>
-#include <ipxe/efi/Protocol/PciRootBridgeIo.h>
-
-/** @file
- *
- * iPXE PCI I/O API for EFI
- *
- */
-
-/* Disambiguate the various error causes */
-#define EINFO_EEFI_PCI \
- __einfo_uniqify ( EINFO_EPLATFORM, 0x01, \
- "Could not open PCI I/O protocol" )
-#define EINFO_EEFI_PCI_NOT_PCI \
- __einfo_platformify ( EINFO_EEFI_PCI, EFI_UNSUPPORTED, \
- "Not a PCI device" )
-#define EEFI_PCI_NOT_PCI __einfo_error ( EINFO_EEFI_PCI_NOT_PCI )
-#define EINFO_EEFI_PCI_IN_USE \
- __einfo_platformify ( EINFO_EEFI_PCI, EFI_ACCESS_DENIED, \
- "PCI device already has a driver" )
-#define EEFI_PCI_IN_USE __einfo_error ( EINFO_EEFI_PCI_IN_USE )
-#define EEFI_PCI( efirc ) \
- EPLATFORM ( EINFO_EEFI_PCI, efirc, \
- EEFI_PCI_NOT_PCI, EEFI_PCI_IN_USE )
-
-/******************************************************************************
- *
- * iPXE PCI API
- *
- ******************************************************************************
- */
-
-/** PCI root bridge I/O protocol */
-static EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *efipci;
-EFI_REQUEST_PROTOCOL ( EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL, &efipci );
-
-static unsigned long efipci_address ( struct pci_device *pci,
- unsigned long location ) {
- return EFI_PCI_ADDRESS ( PCI_BUS ( pci->busdevfn ),
- PCI_SLOT ( pci->busdevfn ),
- PCI_FUNC ( pci->busdevfn ),
- EFIPCI_OFFSET ( location ) );
-}
-
-int efipci_read ( struct pci_device *pci, unsigned long location,
- void *value ) {
- EFI_STATUS efirc;
- int rc;
-
- if ( ! efipci )
- return -ENOTSUP;
-
- if ( ( efirc = efipci->Pci.Read ( efipci, EFIPCI_WIDTH ( location ),
- efipci_address ( pci, location ), 1,
- value ) ) != 0 ) {
- rc = -EEFI ( efirc );
- DBG ( "EFIPCI config read from " PCI_FMT " offset %02lx "
- "failed: %s\n", PCI_ARGS ( pci ),
- EFIPCI_OFFSET ( location ), strerror ( rc ) );
- return -EIO;
- }
-
- return 0;
-}
-
-int efipci_write ( struct pci_device *pci, unsigned long location,
- unsigned long value ) {
- EFI_STATUS efirc;
- int rc;
-
- if ( ! efipci )
- return -ENOTSUP;
-
- if ( ( efirc = efipci->Pci.Write ( efipci, EFIPCI_WIDTH ( location ),
- efipci_address ( pci, location ), 1,
- &value ) ) != 0 ) {
- rc = -EEFI ( efirc );
- DBG ( "EFIPCI config write to " PCI_FMT " offset %02lx "
- "failed: %s\n", PCI_ARGS ( pci ),
- EFIPCI_OFFSET ( location ), strerror ( rc ) );
- return -EIO;
- }
-
- return 0;
-}
-
-PROVIDE_PCIAPI_INLINE ( efi, pci_num_bus );
-PROVIDE_PCIAPI_INLINE ( efi, pci_read_config_byte );
-PROVIDE_PCIAPI_INLINE ( efi, pci_read_config_word );
-PROVIDE_PCIAPI_INLINE ( efi, pci_read_config_dword );
-PROVIDE_PCIAPI_INLINE ( efi, pci_write_config_byte );
-PROVIDE_PCIAPI_INLINE ( efi, pci_write_config_word );
-PROVIDE_PCIAPI_INLINE ( efi, pci_write_config_dword );
-
-/******************************************************************************
- *
- * EFI PCI device instantiation
- *
- ******************************************************************************
- */
-
-/**
- * Open EFI PCI device
- *
- * @v device EFI device handle
- * @v attributes Protocol opening attributes
- * @v pci PCI device to fill in
- * @ret rc Return status code
- */
-int efipci_open ( EFI_HANDLE device, UINT32 attributes,
- struct pci_device *pci ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- union {
- EFI_PCI_IO_PROTOCOL *pci_io;
- void *interface;
- } pci_io;
- UINTN pci_segment, pci_bus, pci_dev, pci_fn;
- EFI_STATUS efirc;
- int rc;
-
- /* See if device is a PCI device */
- if ( ( efirc = bs->OpenProtocol ( device, &efi_pci_io_protocol_guid,
- &pci_io.interface, efi_image_handle,
- device, attributes ) ) != 0 ) {
- rc = -EEFI_PCI ( efirc );
- DBGCP ( device, "EFIPCI %p %s cannot open PCI protocols: %s\n",
- device, efi_handle_name ( device ), strerror ( rc ) );
- goto err_open_protocol;
- }
-
- /* Get PCI bus:dev.fn address */
- if ( ( efirc = pci_io.pci_io->GetLocation ( pci_io.pci_io, &pci_segment,
- &pci_bus, &pci_dev,
- &pci_fn ) ) != 0 ) {
- rc = -EEFI ( efirc );
- DBGC ( device, "EFIPCI %p %s could not get PCI location: %s\n",
- device, efi_handle_name ( device ), strerror ( rc ) );
- goto err_get_location;
- }
- DBGC2 ( device, "EFIPCI %p %s is PCI %04lx:%02lx:%02lx.%lx\n", device,
- efi_handle_name ( device ), ( ( unsigned long ) pci_segment ),
- ( ( unsigned long ) pci_bus ), ( ( unsigned long ) pci_dev ),
- ( ( unsigned long ) pci_fn ) );
-
- /* Try to enable I/O cycles, memory cycles, and bus mastering.
- * Some platforms will 'helpfully' report errors if these bits
- * can't be enabled (for example, if the card doesn't actually
- * support I/O cycles). Work around any such platforms by
- * enabling bits individually and simply ignoring any errors.
- */
- pci_io.pci_io->Attributes ( pci_io.pci_io,
- EfiPciIoAttributeOperationEnable,
- EFI_PCI_IO_ATTRIBUTE_IO, NULL );
- pci_io.pci_io->Attributes ( pci_io.pci_io,
- EfiPciIoAttributeOperationEnable,
- EFI_PCI_IO_ATTRIBUTE_MEMORY, NULL );
- pci_io.pci_io->Attributes ( pci_io.pci_io,
- EfiPciIoAttributeOperationEnable,
- EFI_PCI_IO_ATTRIBUTE_BUS_MASTER, NULL );
-
- /* Populate PCI device */
- pci_init ( pci, PCI_BUSDEVFN ( pci_bus, pci_dev, pci_fn ) );
- if ( ( rc = pci_read_config ( pci ) ) != 0 ) {
- DBGC ( device, "EFIPCI %p %s cannot read PCI configuration: "
- "%s\n", device, efi_handle_name ( device ),
- strerror ( rc ) );
- goto err_pci_read_config;
- }
-
- return 0;
-
- err_pci_read_config:
- err_get_location:
- bs->CloseProtocol ( device, &efi_pci_io_protocol_guid,
- efi_image_handle, device );
- err_open_protocol:
- return rc;
-}
-
-/**
- * Close EFI PCI device
- *
- * @v device EFI device handle
- */
-void efipci_close ( EFI_HANDLE device ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-
- bs->CloseProtocol ( device, &efi_pci_io_protocol_guid,
- efi_image_handle, device );
-}
-
-/**
- * Get EFI PCI device information
- *
- * @v device EFI device handle
- * @v pci PCI device to fill in
- * @ret rc Return status code
- */
-int efipci_info ( EFI_HANDLE device, struct pci_device *pci ) {
- int rc;
-
- /* Open PCI device, if possible */
- if ( ( rc = efipci_open ( device, EFI_OPEN_PROTOCOL_GET_PROTOCOL,
- pci ) ) != 0 )
- return rc;
-
- /* Close PCI device */
- efipci_close ( device );
-
- return 0;
-}
-
-/******************************************************************************
- *
- * EFI PCI driver
- *
- ******************************************************************************
- */
-
-/**
- * Check to see if driver supports a device
- *
- * @v device EFI device handle
- * @ret rc Return status code
- */
-static int efipci_supported ( EFI_HANDLE device ) {
- struct pci_device pci;
- int rc;
-
- /* Get PCI device information */
- if ( ( rc = efipci_info ( device, &pci ) ) != 0 )
- return rc;
-
- /* Look for a driver */
- if ( ( rc = pci_find_driver ( &pci ) ) != 0 ) {
- DBGCP ( device, "EFIPCI %p %s has no driver\n",
- device, efi_handle_name ( device ) );
- return rc;
- }
- DBGC ( device, "EFIPCI %p %s has driver \"%s\"\n",
- device, efi_handle_name ( device ), pci.id->name );
-
- return 0;
-}
-
-/**
- * Attach driver to device
- *
- * @v efidev EFI device
- * @ret rc Return status code
- */
-static int efipci_start ( struct efi_device *efidev ) {
- EFI_HANDLE device = efidev->device;
- struct pci_device *pci;
- int rc;
-
- /* Allocate PCI device */
- pci = zalloc ( sizeof ( *pci ) );
- if ( ! pci ) {
- rc = -ENOMEM;
- goto err_alloc;
- }
-
- /* Open PCI device */
- if ( ( rc = efipci_open ( device, ( EFI_OPEN_PROTOCOL_BY_DRIVER |
- EFI_OPEN_PROTOCOL_EXCLUSIVE ),
- pci ) ) != 0 ) {
- DBGC ( device, "EFIPCI %p %s could not open PCI device: %s\n",
- device, efi_handle_name ( device ), strerror ( rc ) );
- DBGC_EFI_OPENERS ( device, device, &efi_pci_io_protocol_guid );
- goto err_open;
- }
-
- /* Find driver */
- if ( ( rc = pci_find_driver ( pci ) ) != 0 ) {
- DBGC ( device, "EFIPCI %p %s has no driver\n",
- device, efi_handle_name ( device ) );
- goto err_find_driver;
- }
-
- /* Mark PCI device as a child of the EFI device */
- pci->dev.parent = &efidev->dev;
- list_add ( &pci->dev.siblings, &efidev->dev.children );
-
- /* Probe driver */
- if ( ( rc = pci_probe ( pci ) ) != 0 ) {
- DBGC ( device, "EFIPCI %p %s could not probe driver \"%s\": "
- "%s\n", device, efi_handle_name ( device ),
- pci->id->name, strerror ( rc ) );
- goto err_probe;
- }
- DBGC ( device, "EFIPCI %p %s using driver \"%s\"\n",
- device, efi_handle_name ( device ), pci->id->name );
-
- efidev_set_drvdata ( efidev, pci );
- return 0;
-
- pci_remove ( pci );
- err_probe:
- list_del ( &pci->dev.siblings );
- err_find_driver:
- efipci_close ( device );
- err_open:
- free ( pci );
- err_alloc:
- return rc;
-}
-
-/**
- * Detach driver from device
- *
- * @v efidev EFI device
- */
-static void efipci_stop ( struct efi_device *efidev ) {
- struct pci_device *pci = efidev_get_drvdata ( efidev );
- EFI_HANDLE device = efidev->device;
-
- pci_remove ( pci );
- list_del ( &pci->dev.siblings );
- efipci_close ( device );
- free ( pci );
-}
-
-/** EFI PCI driver */
-struct efi_driver efipci_driver __efi_driver ( EFI_DRIVER_NORMAL ) = {
- .name = "PCI",
- .supported = efipci_supported,
- .start = efipci_start,
- .stop = efipci_stop,
-};
diff --git a/qemu/roms/ipxe/src/interface/efi/efi_reboot.c b/qemu/roms/ipxe/src/interface/efi/efi_reboot.c
deleted file mode 100644
index 35919221e..000000000
--- a/qemu/roms/ipxe/src/interface/efi/efi_reboot.c
+++ /dev/null
@@ -1,65 +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
- *
- * EFI reboot mechanism
- *
- */
-
-#include <errno.h>
-#include <ipxe/efi/efi.h>
-#include <ipxe/reboot.h>
-
-/**
- * Reboot system
- *
- * @v warm Perform a warm reboot
- */
-static void efi_reboot ( int warm ) {
- EFI_RUNTIME_SERVICES *rs = efi_systab->RuntimeServices;
-
- /* Use runtime services to reset system */
- rs->ResetSystem ( ( warm ? EfiResetWarm : EfiResetCold ), 0, 0, NULL );
-}
-
-/**
- * Power off system
- *
- * @ret rc Return status code
- */
-static int efi_poweroff ( void ) {
- EFI_RUNTIME_SERVICES *rs = efi_systab->RuntimeServices;
-
- /* Use runtime services to power off system */
- rs->ResetSystem ( EfiResetShutdown, 0, 0, NULL );
-
- /* Should never happen */
- return -ECANCELED;
-}
-
-PROVIDE_REBOOT ( efi, reboot, efi_reboot );
-PROVIDE_REBOOT ( efi, poweroff, efi_poweroff );
diff --git a/qemu/roms/ipxe/src/interface/efi/efi_smbios.c b/qemu/roms/ipxe/src/interface/efi/efi_smbios.c
deleted file mode 100644
index 304f95a56..000000000
--- a/qemu/roms/ipxe/src/interface/efi/efi_smbios.c
+++ /dev/null
@@ -1,67 +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.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include <errno.h>
-#include <ipxe/smbios.h>
-#include <ipxe/efi/efi.h>
-#include <ipxe/efi/Guid/SmBios.h>
-
-/** @file
- *
- * iPXE SMBIOS API for EFI
- *
- */
-
-/** SMBIOS configuration table */
-static struct smbios_entry *smbios_entry;
-EFI_USE_TABLE ( SMBIOS_TABLE, &smbios_entry, 0 );
-
-/**
- * Find SMBIOS
- *
- * @v smbios SMBIOS entry point descriptor structure to fill in
- * @ret rc Return status code
- */
-static int efi_find_smbios ( struct smbios *smbios ) {
-
- if ( ! smbios_entry ) {
- DBG ( "No SMBIOS table provided\n" );
- return -ENODEV;
- }
-
- if ( smbios_entry->signature != SMBIOS_SIGNATURE ) {
- DBG ( "Invalid SMBIOS signature\n" );
- return -ENODEV;
- }
-
- smbios->address = phys_to_user ( smbios_entry->smbios_address );
- smbios->len = smbios_entry->smbios_len;
- smbios->count = smbios_entry->smbios_count;
- smbios->version =
- SMBIOS_VERSION ( smbios_entry->major, smbios_entry->minor );
- DBG ( "Found SMBIOS v%d.%d entry point at %p (%x+%zx)\n",
- smbios_entry->major, smbios_entry->minor, smbios_entry,
- smbios_entry->smbios_address, smbios->len );
-
- return 0;
-}
-
-PROVIDE_SMBIOS ( efi, find_smbios, efi_find_smbios );
diff --git a/qemu/roms/ipxe/src/interface/efi/efi_snp.c b/qemu/roms/ipxe/src/interface/efi/efi_snp.c
deleted file mode 100644
index 3dfcc5e16..000000000
--- a/qemu/roms/ipxe/src/interface/efi/efi_snp.c
+++ /dev/null
@@ -1,1248 +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.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <byteswap.h>
-#include <ipxe/netdevice.h>
-#include <ipxe/iobuf.h>
-#include <ipxe/in.h>
-#include <ipxe/version.h>
-#include <ipxe/efi/efi.h>
-#include <ipxe/efi/efi_driver.h>
-#include <ipxe/efi/efi_strings.h>
-#include <ipxe/efi/efi_utils.h>
-#include <ipxe/efi/efi_watchdog.h>
-#include <ipxe/efi/efi_snp.h>
-#include <usr/autoboot.h>
-#include <config/general.h>
-
-/** List of SNP devices */
-static LIST_HEAD ( efi_snp_devices );
-
-/** Network devices are currently claimed for use by iPXE */
-static int efi_snp_claimed;
-
-/* Downgrade user experience if configured to do so
- *
- * The default UEFI user experience for network boot is somewhat
- * excremental: only TFTP is available as a download protocol, and if
- * anything goes wrong the user will be shown just a dot on an
- * otherwise blank screen. (Some programmer was clearly determined to
- * win a bet that they could outshine Apple at producing uninformative
- * error messages.)
- *
- * For comparison, the default iPXE user experience provides the
- * option to use protocols designed more recently than 1980 (such as
- * HTTP and iSCSI), and if anything goes wrong the the user will be
- * shown one of over 1200 different error messages, complete with a
- * link to a wiki page describing that specific error.
- *
- * We default to upgrading the user experience to match that available
- * in a "legacy" BIOS environment, by installing our own instance of
- * EFI_LOAD_FILE_PROTOCOL.
- *
- * Note that unfortunately we can't sensibly provide the choice of
- * both options to the user in the same build, because the UEFI boot
- * menu ignores the multitude of ways in which a network device handle
- * can be described and opaquely labels both menu entries as just "EFI
- * Network".
- */
-#ifdef EFI_DOWNGRADE_UX
-static EFI_GUID dummy_load_file_protocol_guid = {
- 0x6f6c7323, 0x2077, 0x7523,
- { 0x6e, 0x68, 0x65, 0x6c, 0x70, 0x66, 0x75, 0x6c }
-};
-#define efi_load_file_protocol_guid dummy_load_file_protocol_guid
-#endif
-
-/**
- * Set EFI SNP mode state
- *
- * @v snp SNP interface
- */
-static void efi_snp_set_state ( struct efi_snp_device *snpdev ) {
- struct net_device *netdev = snpdev->netdev;
- EFI_SIMPLE_NETWORK_MODE *mode = &snpdev->mode;
-
- /* Calculate state */
- if ( ! snpdev->started ) {
- /* Start() method not called; report as Stopped */
- mode->State = EfiSimpleNetworkStopped;
- } else if ( ! netdev_is_open ( netdev ) ) {
- /* Network device not opened; report as Started */
- mode->State = EfiSimpleNetworkStarted;
- } else if ( efi_snp_claimed ) {
- /* Network device opened but claimed for use by iPXE; report
- * as Started to inhibit receive polling.
- */
- mode->State = EfiSimpleNetworkStarted;
- } else {
- /* Network device opened and available for use via SNP; report
- * as Initialized.
- */
- mode->State = EfiSimpleNetworkInitialized;
- }
-}
-
-/**
- * Set EFI SNP mode based on iPXE net device parameters
- *
- * @v snp SNP interface
- */
-static void efi_snp_set_mode ( struct efi_snp_device *snpdev ) {
- struct net_device *netdev = snpdev->netdev;
- EFI_SIMPLE_NETWORK_MODE *mode = &snpdev->mode;
- struct ll_protocol *ll_protocol = netdev->ll_protocol;
- unsigned int ll_addr_len = ll_protocol->ll_addr_len;
-
- mode->HwAddressSize = ll_addr_len;
- mode->MediaHeaderSize = ll_protocol->ll_header_len;
- mode->MaxPacketSize = netdev->max_pkt_len;
- mode->ReceiveFilterMask = ( EFI_SIMPLE_NETWORK_RECEIVE_UNICAST |
- EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST |
- EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST );
- assert ( ll_addr_len <= sizeof ( mode->CurrentAddress ) );
- memcpy ( &mode->CurrentAddress, netdev->ll_addr, ll_addr_len );
- memcpy ( &mode->BroadcastAddress, netdev->ll_broadcast, ll_addr_len );
- ll_protocol->init_addr ( netdev->hw_addr, &mode->PermanentAddress );
- mode->IfType = ntohs ( ll_protocol->ll_proto );
- mode->MacAddressChangeable = TRUE;
- mode->MediaPresentSupported = TRUE;
- mode->MediaPresent = ( netdev_link_ok ( netdev ) ? TRUE : FALSE );
-}
-
-/**
- * Flush transmit ring and receive queue
- *
- * @v snpdev SNP device
- */
-static void efi_snp_flush ( struct efi_snp_device *snpdev ) {
- struct io_buffer *iobuf;
- struct io_buffer *tmp;
-
- /* Reset transmit completion ring */
- snpdev->tx_prod = 0;
- snpdev->tx_cons = 0;
-
- /* Discard any queued receive buffers */
- list_for_each_entry_safe ( iobuf, tmp, &snpdev->rx, list ) {
- list_del ( &iobuf->list );
- free_iob ( iobuf );
- }
-}
-
-/**
- * Poll net device and count received packets
- *
- * @v snpdev SNP device
- */
-static void efi_snp_poll ( struct efi_snp_device *snpdev ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- struct io_buffer *iobuf;
-
- /* Poll network device */
- netdev_poll ( snpdev->netdev );
-
- /* Retrieve any received packets */
- while ( ( iobuf = netdev_rx_dequeue ( snpdev->netdev ) ) ) {
- list_add_tail ( &iobuf->list, &snpdev->rx );
- snpdev->interrupts |= EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT;
- bs->SignalEvent ( &snpdev->snp.WaitForPacket );
- }
-}
-
-/**
- * Change SNP state from "stopped" to "started"
- *
- * @v snp SNP interface
- * @ret efirc EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_snp_start ( EFI_SIMPLE_NETWORK_PROTOCOL *snp ) {
- struct efi_snp_device *snpdev =
- container_of ( snp, struct efi_snp_device, snp );
-
- DBGC2 ( snpdev, "SNPDEV %p START\n", snpdev );
-
- /* Fail if net device is currently claimed for use by iPXE */
- if ( efi_snp_claimed )
- return EFI_NOT_READY;
-
- snpdev->started = 1;
- efi_snp_set_state ( snpdev );
- return 0;
-}
-
-/**
- * Change SNP state from "started" to "stopped"
- *
- * @v snp SNP interface
- * @ret efirc EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_snp_stop ( EFI_SIMPLE_NETWORK_PROTOCOL *snp ) {
- struct efi_snp_device *snpdev =
- container_of ( snp, struct efi_snp_device, snp );
-
- DBGC2 ( snpdev, "SNPDEV %p STOP\n", snpdev );
-
- /* Fail if net device is currently claimed for use by iPXE */
- if ( efi_snp_claimed )
- return EFI_NOT_READY;
-
- snpdev->started = 0;
- efi_snp_set_state ( snpdev );
- return 0;
-}
-
-/**
- * Open the network device
- *
- * @v snp SNP interface
- * @v extra_rx_bufsize Extra RX buffer size, in bytes
- * @v extra_tx_bufsize Extra TX buffer size, in bytes
- * @ret efirc EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_snp_initialize ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
- UINTN extra_rx_bufsize, UINTN extra_tx_bufsize ) {
- struct efi_snp_device *snpdev =
- container_of ( snp, struct efi_snp_device, snp );
- int rc;
-
- DBGC2 ( snpdev, "SNPDEV %p INITIALIZE (%ld extra RX, %ld extra TX)\n",
- snpdev, ( ( unsigned long ) extra_rx_bufsize ),
- ( ( unsigned long ) extra_tx_bufsize ) );
-
- /* Fail if net device is currently claimed for use by iPXE */
- if ( efi_snp_claimed )
- return EFI_NOT_READY;
-
- if ( ( rc = netdev_open ( snpdev->netdev ) ) != 0 ) {
- DBGC ( snpdev, "SNPDEV %p could not open %s: %s\n",
- snpdev, snpdev->netdev->name, strerror ( rc ) );
- return EFIRC ( rc );
- }
- efi_snp_set_state ( snpdev );
-
- return 0;
-}
-
-/**
- * Reset the network device
- *
- * @v snp SNP interface
- * @v ext_verify Extended verification required
- * @ret efirc EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_snp_reset ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN ext_verify ) {
- struct efi_snp_device *snpdev =
- container_of ( snp, struct efi_snp_device, snp );
- int rc;
-
- DBGC2 ( snpdev, "SNPDEV %p RESET (%s extended verification)\n",
- snpdev, ( ext_verify ? "with" : "without" ) );
-
- /* Fail if net device is currently claimed for use by iPXE */
- if ( efi_snp_claimed )
- return EFI_NOT_READY;
-
- netdev_close ( snpdev->netdev );
- efi_snp_set_state ( snpdev );
- efi_snp_flush ( snpdev );
-
- if ( ( rc = netdev_open ( snpdev->netdev ) ) != 0 ) {
- DBGC ( snpdev, "SNPDEV %p could not reopen %s: %s\n",
- snpdev, snpdev->netdev->name, strerror ( rc ) );
- return EFIRC ( rc );
- }
- efi_snp_set_state ( snpdev );
-
- return 0;
-}
-
-/**
- * Shut down the network device
- *
- * @v snp SNP interface
- * @ret efirc EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_snp_shutdown ( EFI_SIMPLE_NETWORK_PROTOCOL *snp ) {
- struct efi_snp_device *snpdev =
- container_of ( snp, struct efi_snp_device, snp );
-
- DBGC2 ( snpdev, "SNPDEV %p SHUTDOWN\n", snpdev );
-
- /* Fail if net device is currently claimed for use by iPXE */
- if ( efi_snp_claimed )
- return EFI_NOT_READY;
-
- netdev_close ( snpdev->netdev );
- efi_snp_set_state ( snpdev );
- efi_snp_flush ( snpdev );
-
- return 0;
-}
-
-/**
- * Manage receive filters
- *
- * @v snp SNP interface
- * @v enable Receive filters to enable
- * @v disable Receive filters to disable
- * @v mcast_reset Reset multicast filters
- * @v mcast_count Number of multicast filters
- * @v mcast Multicast filters
- * @ret efirc EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_snp_receive_filters ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, UINT32 enable,
- UINT32 disable, BOOLEAN mcast_reset,
- UINTN mcast_count, EFI_MAC_ADDRESS *mcast ) {
- struct efi_snp_device *snpdev =
- container_of ( snp, struct efi_snp_device, snp );
- unsigned int i;
-
- DBGC2 ( snpdev, "SNPDEV %p RECEIVE_FILTERS %08x&~%08x%s %ld mcast\n",
- snpdev, enable, disable, ( mcast_reset ? " reset" : "" ),
- ( ( unsigned long ) mcast_count ) );
- for ( i = 0 ; i < mcast_count ; i++ ) {
- DBGC2_HDA ( snpdev, i, &mcast[i],
- snpdev->netdev->ll_protocol->ll_addr_len );
- }
-
- /* Fail if net device is currently claimed for use by iPXE */
- if ( efi_snp_claimed )
- return EFI_NOT_READY;
-
- /* Lie through our teeth, otherwise MNP refuses to accept us */
- return 0;
-}
-
-/**
- * Set station address
- *
- * @v snp SNP interface
- * @v reset Reset to permanent address
- * @v new New station address
- * @ret efirc EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_snp_station_address ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN reset,
- EFI_MAC_ADDRESS *new ) {
- struct efi_snp_device *snpdev =
- container_of ( snp, struct efi_snp_device, snp );
- struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
-
- DBGC2 ( snpdev, "SNPDEV %p STATION_ADDRESS %s\n", snpdev,
- ( reset ? "reset" : ll_protocol->ntoa ( new ) ) );
-
- /* Fail if net device is currently claimed for use by iPXE */
- if ( efi_snp_claimed )
- return EFI_NOT_READY;
-
- /* Set the MAC address */
- if ( reset )
- new = &snpdev->mode.PermanentAddress;
- memcpy ( snpdev->netdev->ll_addr, new, ll_protocol->ll_addr_len );
-
- /* MAC address changes take effect only on netdev_open() */
- if ( netdev_is_open ( snpdev->netdev ) ) {
- DBGC ( snpdev, "SNPDEV %p MAC address changed while net "
- "device open\n", snpdev );
- }
-
- return 0;
-}
-
-/**
- * Get (or reset) statistics
- *
- * @v snp SNP interface
- * @v reset Reset statistics
- * @v stats_len Size of statistics table
- * @v stats Statistics table
- * @ret efirc EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_snp_statistics ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN reset,
- UINTN *stats_len, EFI_NETWORK_STATISTICS *stats ) {
- struct efi_snp_device *snpdev =
- container_of ( snp, struct efi_snp_device, snp );
- EFI_NETWORK_STATISTICS stats_buf;
-
- DBGC2 ( snpdev, "SNPDEV %p STATISTICS%s", snpdev,
- ( reset ? " reset" : "" ) );
-
- /* Fail if net device is currently claimed for use by iPXE */
- if ( efi_snp_claimed )
- return EFI_NOT_READY;
-
- /* Gather statistics */
- memset ( &stats_buf, 0, sizeof ( stats_buf ) );
- stats_buf.TxGoodFrames = snpdev->netdev->tx_stats.good;
- stats_buf.TxDroppedFrames = snpdev->netdev->tx_stats.bad;
- stats_buf.TxTotalFrames = ( snpdev->netdev->tx_stats.good +
- snpdev->netdev->tx_stats.bad );
- stats_buf.RxGoodFrames = snpdev->netdev->rx_stats.good;
- stats_buf.RxDroppedFrames = snpdev->netdev->rx_stats.bad;
- stats_buf.RxTotalFrames = ( snpdev->netdev->rx_stats.good +
- snpdev->netdev->rx_stats.bad );
- if ( *stats_len > sizeof ( stats_buf ) )
- *stats_len = sizeof ( stats_buf );
- if ( stats )
- memcpy ( stats, &stats_buf, *stats_len );
-
- /* Reset statistics if requested to do so */
- if ( reset ) {
- memset ( &snpdev->netdev->tx_stats, 0,
- sizeof ( snpdev->netdev->tx_stats ) );
- memset ( &snpdev->netdev->rx_stats, 0,
- sizeof ( snpdev->netdev->rx_stats ) );
- }
-
- return 0;
-}
-
-/**
- * Convert multicast IP address to MAC address
- *
- * @v snp SNP interface
- * @v ipv6 Address is IPv6
- * @v ip IP address
- * @v mac MAC address
- * @ret efirc EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_snp_mcast_ip_to_mac ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN ipv6,
- EFI_IP_ADDRESS *ip, EFI_MAC_ADDRESS *mac ) {
- struct efi_snp_device *snpdev =
- container_of ( snp, struct efi_snp_device, snp );
- struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
- const char *ip_str;
- int rc;
-
- ip_str = ( ipv6 ? "(IPv6)" /* FIXME when we have inet6_ntoa() */ :
- inet_ntoa ( *( ( struct in_addr * ) ip ) ) );
- DBGC2 ( snpdev, "SNPDEV %p MCAST_IP_TO_MAC %s\n", snpdev, ip_str );
-
- /* Fail if net device is currently claimed for use by iPXE */
- if ( efi_snp_claimed )
- return EFI_NOT_READY;
-
- /* Try to hash the address */
- if ( ( rc = ll_protocol->mc_hash ( ( ipv6 ? AF_INET6 : AF_INET ),
- ip, mac ) ) != 0 ) {
- DBGC ( snpdev, "SNPDEV %p could not hash %s: %s\n",
- snpdev, ip_str, strerror ( rc ) );
- return EFIRC ( rc );
- }
-
- return 0;
-}
-
-/**
- * Read or write non-volatile storage
- *
- * @v snp SNP interface
- * @v read Operation is a read
- * @v offset Starting offset within NVRAM
- * @v len Length of data buffer
- * @v data Data buffer
- * @ret efirc EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_snp_nvdata ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN read,
- UINTN offset, UINTN len, VOID *data ) {
- struct efi_snp_device *snpdev =
- container_of ( snp, struct efi_snp_device, snp );
-
- DBGC2 ( snpdev, "SNPDEV %p NVDATA %s %lx+%lx\n", snpdev,
- ( read ? "read" : "write" ), ( ( unsigned long ) offset ),
- ( ( unsigned long ) len ) );
- if ( ! read )
- DBGC2_HDA ( snpdev, offset, data, len );
-
- /* Fail if net device is currently claimed for use by iPXE */
- if ( efi_snp_claimed )
- return EFI_NOT_READY;
-
- return EFI_UNSUPPORTED;
-}
-
-/**
- * Read interrupt status and TX recycled buffer status
- *
- * @v snp SNP interface
- * @v interrupts Interrupt status, or NULL
- * @v txbuf Recycled transmit buffer address, or NULL
- * @ret efirc EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_snp_get_status ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
- UINT32 *interrupts, VOID **txbuf ) {
- struct efi_snp_device *snpdev =
- container_of ( snp, struct efi_snp_device, snp );
-
- DBGC2 ( snpdev, "SNPDEV %p GET_STATUS", snpdev );
-
- /* Fail if net device is currently claimed for use by iPXE */
- if ( efi_snp_claimed ) {
- DBGC2 ( snpdev, "\n" );
- return EFI_NOT_READY;
- }
-
- /* Poll the network device */
- efi_snp_poll ( snpdev );
-
- /* Interrupt status. In practice, this seems to be used only
- * to detect TX completions.
- */
- if ( interrupts ) {
- *interrupts = snpdev->interrupts;
- DBGC2 ( snpdev, " INTS:%02x", *interrupts );
- snpdev->interrupts = 0;
- }
-
- /* TX completions */
- if ( txbuf ) {
- if ( snpdev->tx_prod != snpdev->tx_cons ) {
- *txbuf = snpdev->tx[snpdev->tx_cons++ % EFI_SNP_NUM_TX];
- } else {
- *txbuf = NULL;
- }
- DBGC2 ( snpdev, " TX:%p", *txbuf );
- }
-
- DBGC2 ( snpdev, "\n" );
- return 0;
-}
-
-/**
- * Start packet transmission
- *
- * @v snp SNP interface
- * @v ll_header_len Link-layer header length, if to be filled in
- * @v len Length of data buffer
- * @v data Data buffer
- * @v ll_src Link-layer source address, if specified
- * @v ll_dest Link-layer destination address, if specified
- * @v net_proto Network-layer protocol (in host order)
- * @ret efirc EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_snp_transmit ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
- UINTN ll_header_len, UINTN len, VOID *data,
- EFI_MAC_ADDRESS *ll_src, EFI_MAC_ADDRESS *ll_dest,
- UINT16 *net_proto ) {
- struct efi_snp_device *snpdev =
- container_of ( snp, struct efi_snp_device, snp );
- struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
- struct io_buffer *iobuf;
- size_t payload_len;
- unsigned int tx_fill;
- int rc;
-
- DBGC2 ( snpdev, "SNPDEV %p TRANSMIT %p+%lx", snpdev, data,
- ( ( unsigned long ) len ) );
- if ( ll_header_len ) {
- if ( ll_src ) {
- DBGC2 ( snpdev, " src %s",
- ll_protocol->ntoa ( ll_src ) );
- }
- if ( ll_dest ) {
- DBGC2 ( snpdev, " dest %s",
- ll_protocol->ntoa ( ll_dest ) );
- }
- if ( net_proto ) {
- DBGC2 ( snpdev, " proto %04x", *net_proto );
- }
- }
- DBGC2 ( snpdev, "\n" );
-
- /* Fail if net device is currently claimed for use by iPXE */
- if ( efi_snp_claimed )
- return EFI_NOT_READY;
-
- /* Sanity checks */
- if ( ll_header_len ) {
- if ( ll_header_len != ll_protocol->ll_header_len ) {
- DBGC ( snpdev, "SNPDEV %p TX invalid header length "
- "%ld\n", snpdev,
- ( ( unsigned long ) ll_header_len ) );
- rc = -EINVAL;
- goto err_sanity;
- }
- if ( len < ll_header_len ) {
- DBGC ( snpdev, "SNPDEV %p invalid packet length %ld\n",
- snpdev, ( ( unsigned long ) len ) );
- rc = -EINVAL;
- goto err_sanity;
- }
- if ( ! ll_dest ) {
- DBGC ( snpdev, "SNPDEV %p TX missing destination "
- "address\n", snpdev );
- rc = -EINVAL;
- goto err_sanity;
- }
- if ( ! net_proto ) {
- DBGC ( snpdev, "SNPDEV %p TX missing network "
- "protocol\n", snpdev );
- rc = -EINVAL;
- goto err_sanity;
- }
- if ( ! ll_src )
- ll_src = &snpdev->mode.CurrentAddress;
- }
-
- /* Allocate buffer */
- payload_len = ( len - ll_protocol->ll_header_len );
- iobuf = alloc_iob ( MAX_LL_HEADER_LEN + ( ( payload_len > IOB_ZLEN ) ?
- payload_len : IOB_ZLEN ) );
- if ( ! iobuf ) {
- DBGC ( snpdev, "SNPDEV %p TX could not allocate %ld-byte "
- "buffer\n", snpdev, ( ( unsigned long ) len ) );
- rc = -ENOMEM;
- goto err_alloc_iob;
- }
- iob_reserve ( iobuf, ( MAX_LL_HEADER_LEN -
- ll_protocol->ll_header_len ) );
- memcpy ( iob_put ( iobuf, len ), data, len );
-
- /* Create link-layer header, if specified */
- if ( ll_header_len ) {
- iob_pull ( iobuf, ll_protocol->ll_header_len );
- if ( ( rc = ll_protocol->push ( snpdev->netdev,
- iobuf, ll_dest, ll_src,
- htons ( *net_proto ) )) != 0 ){
- DBGC ( snpdev, "SNPDEV %p TX could not construct "
- "header: %s\n", snpdev, strerror ( rc ) );
- goto err_ll_push;
- }
- }
-
- /* Transmit packet */
- if ( ( rc = netdev_tx ( snpdev->netdev, iob_disown ( iobuf ) ) ) != 0){
- DBGC ( snpdev, "SNPDEV %p TX could not transmit: %s\n",
- snpdev, strerror ( rc ) );
- goto err_tx;
- }
-
- /* Record in transmit completion ring. If we run out of
- * space, report the failure even though we have already
- * transmitted the packet.
- *
- * This allows us to report completions only for packets for
- * which we had reported successfully initiating transmission,
- * while continuing to support clients that never poll for
- * transmit completions.
- */
- tx_fill = ( snpdev->tx_prod - snpdev->tx_cons );
- if ( tx_fill >= EFI_SNP_NUM_TX ) {
- DBGC ( snpdev, "SNPDEV %p TX completion ring full\n", snpdev );
- rc = -ENOBUFS;
- goto err_ring_full;
- }
- snpdev->tx[ snpdev->tx_prod++ % EFI_SNP_NUM_TX ] = data;
- snpdev->interrupts |= EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;
-
- return 0;
-
- err_ring_full:
- err_tx:
- err_ll_push:
- free_iob ( iobuf );
- err_alloc_iob:
- err_sanity:
- return EFIRC ( rc );
-}
-
-/**
- * Receive packet
- *
- * @v snp SNP interface
- * @v ll_header_len Link-layer header length, if to be filled in
- * @v len Length of data buffer
- * @v data Data buffer
- * @v ll_src Link-layer source address, if specified
- * @v ll_dest Link-layer destination address, if specified
- * @v net_proto Network-layer protocol (in host order)
- * @ret efirc EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_snp_receive ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
- UINTN *ll_header_len, UINTN *len, VOID *data,
- EFI_MAC_ADDRESS *ll_src, EFI_MAC_ADDRESS *ll_dest,
- UINT16 *net_proto ) {
- struct efi_snp_device *snpdev =
- container_of ( snp, struct efi_snp_device, snp );
- struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
- struct io_buffer *iobuf;
- const void *iob_ll_dest;
- const void *iob_ll_src;
- uint16_t iob_net_proto;
- unsigned int iob_flags;
- int rc;
-
- DBGC2 ( snpdev, "SNPDEV %p RECEIVE %p(+%lx)", snpdev, data,
- ( ( unsigned long ) *len ) );
-
- /* Fail if net device is currently claimed for use by iPXE */
- if ( efi_snp_claimed )
- return EFI_NOT_READY;
-
- /* Poll the network device */
- efi_snp_poll ( snpdev );
-
- /* Dequeue a packet, if one is available */
- iobuf = list_first_entry ( &snpdev->rx, struct io_buffer, list );
- if ( ! iobuf ) {
- DBGC2 ( snpdev, "\n" );
- rc = -EAGAIN;
- goto out_no_packet;
- }
- list_del ( &iobuf->list );
- DBGC2 ( snpdev, "+%zx\n", iob_len ( iobuf ) );
-
- /* Return packet to caller */
- memcpy ( data, iobuf->data, iob_len ( iobuf ) );
- *len = iob_len ( iobuf );
-
- /* Attempt to decode link-layer header */
- if ( ( rc = ll_protocol->pull ( snpdev->netdev, iobuf, &iob_ll_dest,
- &iob_ll_src, &iob_net_proto,
- &iob_flags ) ) != 0 ) {
- DBGC ( snpdev, "SNPDEV %p could not parse header: %s\n",
- snpdev, strerror ( rc ) );
- goto out_bad_ll_header;
- }
-
- /* Return link-layer header parameters to caller, if required */
- if ( ll_header_len )
- *ll_header_len = ll_protocol->ll_header_len;
- if ( ll_src )
- memcpy ( ll_src, iob_ll_src, ll_protocol->ll_addr_len );
- if ( ll_dest )
- memcpy ( ll_dest, iob_ll_dest, ll_protocol->ll_addr_len );
- if ( net_proto )
- *net_proto = ntohs ( iob_net_proto );
-
- rc = 0;
-
- out_bad_ll_header:
- free_iob ( iobuf );
- out_no_packet:
- return EFIRC ( rc );
-}
-
-/**
- * Poll event
- *
- * @v event Event
- * @v context Event context
- */
-static VOID EFIAPI efi_snp_wait_for_packet ( EFI_EVENT event __unused,
- VOID *context ) {
- struct efi_snp_device *snpdev = context;
-
- DBGCP ( snpdev, "SNPDEV %p WAIT_FOR_PACKET\n", snpdev );
-
- /* Do nothing unless the net device is open */
- if ( ! netdev_is_open ( snpdev->netdev ) )
- return;
-
- /* Do nothing if net device is currently claimed for use by iPXE */
- if ( efi_snp_claimed )
- return;
-
- /* Poll the network device */
- efi_snp_poll ( snpdev );
-}
-
-/** SNP interface */
-static EFI_SIMPLE_NETWORK_PROTOCOL efi_snp_device_snp = {
- .Revision = EFI_SIMPLE_NETWORK_PROTOCOL_REVISION,
- .Start = efi_snp_start,
- .Stop = efi_snp_stop,
- .Initialize = efi_snp_initialize,
- .Reset = efi_snp_reset,
- .Shutdown = efi_snp_shutdown,
- .ReceiveFilters = efi_snp_receive_filters,
- .StationAddress = efi_snp_station_address,
- .Statistics = efi_snp_statistics,
- .MCastIpToMac = efi_snp_mcast_ip_to_mac,
- .NvData = efi_snp_nvdata,
- .GetStatus = efi_snp_get_status,
- .Transmit = efi_snp_transmit,
- .Receive = efi_snp_receive,
-};
-
-/******************************************************************************
- *
- * Component name protocol
- *
- ******************************************************************************
- */
-
-/**
- * Look up driver name
- *
- * @v name2 Component name protocol
- * @v language Language to use
- * @v driver_name Driver name to fill in
- * @ret efirc EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_snp_get_driver_name ( EFI_COMPONENT_NAME2_PROTOCOL *name2,
- CHAR8 *language __unused, CHAR16 **driver_name ) {
- struct efi_snp_device *snpdev =
- container_of ( name2, struct efi_snp_device, name2 );
-
- *driver_name = snpdev->driver_name;
- return 0;
-}
-
-/**
- * Look up controller name
- *
- * @v name2 Component name protocol
- * @v device Device
- * @v child Child device, or NULL
- * @v language Language to use
- * @v driver_name Device name to fill in
- * @ret efirc EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_snp_get_controller_name ( EFI_COMPONENT_NAME2_PROTOCOL *name2,
- EFI_HANDLE device __unused,
- EFI_HANDLE child __unused,
- CHAR8 *language __unused,
- CHAR16 **controller_name ) {
- struct efi_snp_device *snpdev =
- container_of ( name2, struct efi_snp_device, name2 );
-
- *controller_name = snpdev->controller_name;
- return 0;
-}
-
-/******************************************************************************
- *
- * Load file protocol
- *
- ******************************************************************************
- */
-
-/**
- * Load file
- *
- * @v loadfile Load file protocol
- * @v path File path
- * @v booting Loading as part of a boot attempt
- * @ret efirc EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_snp_load_file ( EFI_LOAD_FILE_PROTOCOL *load_file,
- EFI_DEVICE_PATH_PROTOCOL *path __unused,
- BOOLEAN booting, UINTN *len __unused,
- VOID *data __unused ) {
- struct efi_snp_device *snpdev =
- container_of ( load_file, struct efi_snp_device, load_file );
- struct net_device *netdev = snpdev->netdev;
- int rc;
-
- /* Fail unless this is a boot attempt */
- if ( ! booting ) {
- DBGC ( snpdev, "SNPDEV %p cannot load non-boot file\n",
- snpdev );
- return EFI_UNSUPPORTED;
- }
-
- /* Claim network devices for use by iPXE */
- efi_snp_claim();
-
- /* Start watchdog holdoff timer */
- efi_watchdog_start();
-
- /* Boot from network device */
- if ( ( rc = ipxe ( netdev ) ) != 0 )
- goto err_ipxe;
-
- err_ipxe:
- efi_watchdog_stop();
- efi_snp_release();
- return EFIRC ( rc );
-}
-
-/** Load file protocol */
-static EFI_LOAD_FILE_PROTOCOL efi_snp_load_file_protocol = {
- .LoadFile = efi_snp_load_file,
-};
-
-/******************************************************************************
- *
- * iPXE network driver
- *
- ******************************************************************************
- */
-
-/**
- * Locate SNP device corresponding to network device
- *
- * @v netdev Network device
- * @ret snp SNP device, or NULL if not found
- */
-static struct efi_snp_device * efi_snp_demux ( struct net_device *netdev ) {
- struct efi_snp_device *snpdev;
-
- list_for_each_entry ( snpdev, &efi_snp_devices, list ) {
- if ( snpdev->netdev == netdev )
- return snpdev;
- }
- return NULL;
-}
-
-/**
- * Create SNP device
- *
- * @v netdev Network device
- * @ret rc Return status code
- */
-static int efi_snp_probe ( struct net_device *netdev ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- struct efi_device *efidev;
- struct efi_snp_device *snpdev;
- union {
- EFI_DEVICE_PATH_PROTOCOL *path;
- void *interface;
- } path;
- EFI_DEVICE_PATH_PROTOCOL *path_end;
- MAC_ADDR_DEVICE_PATH *macpath;
- size_t path_prefix_len = 0;
- EFI_STATUS efirc;
- int rc;
-
- /* Find parent EFI device */
- efidev = efidev_parent ( netdev->dev );
- if ( ! efidev ) {
- DBG ( "SNP skipping non-EFI device %s\n", netdev->name );
- rc = 0;
- goto err_no_efidev;
- }
-
- /* Allocate the SNP device */
- snpdev = zalloc ( sizeof ( *snpdev ) );
- if ( ! snpdev ) {
- rc = -ENOMEM;
- goto err_alloc_snp;
- }
- snpdev->netdev = netdev_get ( netdev );
- snpdev->efidev = efidev;
- INIT_LIST_HEAD ( &snpdev->rx );
-
- /* Sanity check */
- if ( netdev->ll_protocol->ll_addr_len > sizeof ( EFI_MAC_ADDRESS ) ) {
- DBGC ( snpdev, "SNPDEV %p cannot support link-layer address "
- "length %d for %s\n", snpdev,
- netdev->ll_protocol->ll_addr_len, netdev->name );
- rc = -ENOTSUP;
- goto err_ll_addr_len;
- }
-
- /* Populate the SNP structure */
- memcpy ( &snpdev->snp, &efi_snp_device_snp, sizeof ( snpdev->snp ) );
- snpdev->snp.Mode = &snpdev->mode;
- if ( ( efirc = bs->CreateEvent ( EVT_NOTIFY_WAIT, TPL_NOTIFY,
- efi_snp_wait_for_packet, snpdev,
- &snpdev->snp.WaitForPacket ) ) != 0 ){
- rc = -EEFI ( efirc );
- DBGC ( snpdev, "SNPDEV %p could not create event: %s\n",
- snpdev, strerror ( rc ) );
- goto err_create_event;
- }
-
- /* Populate the SNP mode structure */
- snpdev->mode.State = EfiSimpleNetworkStopped;
- efi_snp_set_mode ( snpdev );
-
- /* Populate the NII structure */
- snpdev->nii.Revision =
- EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION;
- strncpy ( snpdev->nii.StringId, "iPXE",
- sizeof ( snpdev->nii.StringId ) );
-
- /* Populate the component name structure */
- efi_snprintf ( snpdev->driver_name,
- ( sizeof ( snpdev->driver_name ) /
- sizeof ( snpdev->driver_name[0] ) ),
- "%s %s", product_short_name, netdev->dev->driver_name );
- efi_snprintf ( snpdev->controller_name,
- ( sizeof ( snpdev->controller_name ) /
- sizeof ( snpdev->controller_name[0] ) ),
- "%s %s (%s, %s)", product_short_name,
- netdev->dev->driver_name, netdev->dev->name,
- netdev_addr ( netdev ) );
- snpdev->name2.GetDriverName = efi_snp_get_driver_name;
- snpdev->name2.GetControllerName = efi_snp_get_controller_name;
- snpdev->name2.SupportedLanguages = "en";
-
- /* Populate the load file protocol structure */
- memcpy ( &snpdev->load_file, &efi_snp_load_file_protocol,
- sizeof ( snpdev->load_file ) );
-
- /* Populate the device name */
- efi_snprintf ( snpdev->name, ( sizeof ( snpdev->name ) /
- sizeof ( snpdev->name[0] ) ),
- "%s", netdev->name );
-
- /* Get the parent device path */
- if ( ( efirc = bs->OpenProtocol ( efidev->device,
- &efi_device_path_protocol_guid,
- &path.interface, efi_image_handle,
- efidev->device,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
- rc = -EEFI ( efirc );
- DBGC ( snpdev, "SNPDEV %p cannot get %p %s device path: %s\n",
- snpdev, efidev->device,
- efi_handle_name ( efidev->device ), strerror ( rc ) );
- goto err_open_device_path;
- }
-
- /* Allocate the new device path */
- path_end = efi_devpath_end ( path.path );
- path_prefix_len = ( ( ( void * ) path_end ) - ( ( void * ) path.path ));
- snpdev->path = zalloc ( path_prefix_len + sizeof ( *macpath ) +
- sizeof ( *path_end ) );
- if ( ! snpdev->path ) {
- rc = -ENOMEM;
- goto err_alloc_device_path;
- }
-
- /* Populate the device path */
- memcpy ( snpdev->path, path.path, path_prefix_len );
- macpath = ( ( ( void * ) snpdev->path ) + path_prefix_len );
- path_end = ( ( void * ) ( macpath + 1 ) );
- memset ( macpath, 0, sizeof ( *macpath ) );
- macpath->Header.Type = MESSAGING_DEVICE_PATH;
- macpath->Header.SubType = MSG_MAC_ADDR_DP;
- macpath->Header.Length[0] = sizeof ( *macpath );
- memcpy ( &macpath->MacAddress, netdev->ll_addr,
- sizeof ( macpath->MacAddress ) );
- macpath->IfType = ntohs ( netdev->ll_protocol->ll_proto );
- memset ( path_end, 0, sizeof ( *path_end ) );
- path_end->Type = END_DEVICE_PATH_TYPE;
- path_end->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
- path_end->Length[0] = sizeof ( *path_end );
-
- /* Install the SNP */
- if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
- &snpdev->handle,
- &efi_simple_network_protocol_guid, &snpdev->snp,
- &efi_device_path_protocol_guid, snpdev->path,
- &efi_nii_protocol_guid, &snpdev->nii,
- &efi_nii31_protocol_guid, &snpdev->nii,
- &efi_component_name2_protocol_guid, &snpdev->name2,
- &efi_load_file_protocol_guid, &snpdev->load_file,
- NULL ) ) != 0 ) {
- rc = -EEFI ( efirc );
- DBGC ( snpdev, "SNPDEV %p could not install protocols: "
- "%s\n", snpdev, strerror ( rc ) );
- goto err_install_protocol_interface;
- }
-
- /* Add as child of EFI parent device */
- if ( ( rc = efi_child_add ( efidev->device, snpdev->handle ) ) != 0 ) {
- DBGC ( snpdev, "SNPDEV %p could not become child of %p %s: "
- "%s\n", snpdev, efidev->device,
- efi_handle_name ( efidev->device ), strerror ( rc ) );
- goto err_efi_child_add;
- }
-
- /* Install HII */
- if ( ( rc = efi_snp_hii_install ( snpdev ) ) != 0 ) {
- DBGC ( snpdev, "SNPDEV %p could not install HII: %s\n",
- snpdev, strerror ( rc ) );
- /* HII fails on several platforms. It's
- * non-essential, so treat this as a non-fatal
- * error.
- */
- }
-
- /* Add to list of SNP devices */
- list_add ( &snpdev->list, &efi_snp_devices );
-
- /* Close device path */
- bs->CloseProtocol ( efidev->device, &efi_device_path_protocol_guid,
- efi_image_handle, efidev->device );
-
- DBGC ( snpdev, "SNPDEV %p installed for %s as device %p %s\n",
- snpdev, netdev->name, snpdev->handle,
- efi_handle_name ( snpdev->handle ) );
- return 0;
-
- if ( snpdev->package_list )
- efi_snp_hii_uninstall ( snpdev );
- efi_child_del ( efidev->device, snpdev->handle );
- err_efi_child_add:
- bs->UninstallMultipleProtocolInterfaces (
- snpdev->handle,
- &efi_simple_network_protocol_guid, &snpdev->snp,
- &efi_device_path_protocol_guid, snpdev->path,
- &efi_nii_protocol_guid, &snpdev->nii,
- &efi_nii31_protocol_guid, &snpdev->nii,
- &efi_component_name2_protocol_guid, &snpdev->name2,
- &efi_load_file_protocol_guid, &snpdev->load_file,
- NULL );
- err_install_protocol_interface:
- free ( snpdev->path );
- err_alloc_device_path:
- bs->CloseProtocol ( efidev->device, &efi_device_path_protocol_guid,
- efi_image_handle, efidev->device );
- err_open_device_path:
- bs->CloseEvent ( snpdev->snp.WaitForPacket );
- err_create_event:
- err_ll_addr_len:
- netdev_put ( netdev );
- free ( snpdev );
- err_alloc_snp:
- err_no_efidev:
- return rc;
-}
-
-/**
- * Handle SNP device or link state change
- *
- * @v netdev Network device
- */
-static void efi_snp_notify ( struct net_device *netdev ) {
- struct efi_snp_device *snpdev;
-
- /* Locate SNP device */
- snpdev = efi_snp_demux ( netdev );
- if ( ! snpdev ) {
- DBG ( "SNP skipping non-SNP device %s\n", netdev->name );
- return;
- }
-
- /* Update link state */
- snpdev->mode.MediaPresent =
- ( netdev_link_ok ( netdev ) ? TRUE : FALSE );
- DBGC ( snpdev, "SNPDEV %p link is %s\n", snpdev,
- ( snpdev->mode.MediaPresent ? "up" : "down" ) );
-
- /* Update mode state */
- efi_snp_set_state ( snpdev );
-}
-
-/**
- * Destroy SNP device
- *
- * @v netdev Network device
- */
-static void efi_snp_remove ( struct net_device *netdev ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- struct efi_snp_device *snpdev;
-
- /* Locate SNP device */
- snpdev = efi_snp_demux ( netdev );
- if ( ! snpdev ) {
- DBG ( "SNP skipping non-SNP device %s\n", netdev->name );
- return;
- }
-
- /* Uninstall the SNP */
- if ( snpdev->package_list )
- efi_snp_hii_uninstall ( snpdev );
- efi_child_del ( snpdev->efidev->device, snpdev->handle );
- list_del ( &snpdev->list );
- bs->UninstallMultipleProtocolInterfaces (
- snpdev->handle,
- &efi_simple_network_protocol_guid, &snpdev->snp,
- &efi_device_path_protocol_guid, snpdev->path,
- &efi_nii_protocol_guid, &snpdev->nii,
- &efi_nii31_protocol_guid, &snpdev->nii,
- &efi_component_name2_protocol_guid, &snpdev->name2,
- &efi_load_file_protocol_guid, &snpdev->load_file,
- NULL );
- free ( snpdev->path );
- bs->CloseEvent ( snpdev->snp.WaitForPacket );
- netdev_put ( snpdev->netdev );
- free ( snpdev );
-}
-
-/** SNP driver */
-struct net_driver efi_snp_driver __net_driver = {
- .name = "SNP",
- .probe = efi_snp_probe,
- .notify = efi_snp_notify,
- .remove = efi_snp_remove,
-};
-
-/**
- * Find SNP device by EFI device handle
- *
- * @v handle EFI device handle
- * @ret snpdev SNP device, or NULL
- */
-struct efi_snp_device * find_snpdev ( EFI_HANDLE handle ) {
- struct efi_snp_device *snpdev;
-
- list_for_each_entry ( snpdev, &efi_snp_devices, list ) {
- if ( snpdev->handle == handle )
- return snpdev;
- }
- return NULL;
-}
-
-/**
- * Get most recently opened SNP device
- *
- * @ret snpdev Most recently opened SNP device, or NULL
- */
-struct efi_snp_device * last_opened_snpdev ( void ) {
- struct net_device *netdev;
-
- netdev = last_opened_netdev();
- if ( ! netdev )
- return NULL;
-
- return efi_snp_demux ( netdev );
-}
-
-/**
- * Set SNP claimed/released state
- *
- * @v claimed Network devices are claimed for use by iPXE
- */
-void efi_snp_set_claimed ( int claimed ) {
- struct efi_snp_device *snpdev;
-
- /* Claim SNP devices */
- efi_snp_claimed = claimed;
-
- /* Update SNP mode state for each interface */
- list_for_each_entry ( snpdev, &efi_snp_devices, list )
- efi_snp_set_state ( snpdev );
-}
diff --git a/qemu/roms/ipxe/src/interface/efi/efi_snp_hii.c b/qemu/roms/ipxe/src/interface/efi/efi_snp_hii.c
deleted file mode 100644
index 720402bdb..000000000
--- a/qemu/roms/ipxe/src/interface/efi/efi_snp_hii.c
+++ /dev/null
@@ -1,727 +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
- *
- * EFI SNP HII protocol
- *
- * The HII protocols are some of the less-well designed parts of the
- * entire EFI specification. This is a significant accomplishment.
- *
- * The face-slappingly ludicrous query string syntax seems to be
- * motivated by the desire to allow a caller to query multiple drivers
- * simultaneously via the single-instance HII_CONFIG_ROUTING_PROTOCOL,
- * which is supposed to pass relevant subsets of the query string to
- * the relevant drivers.
- *
- * Nobody uses the HII_CONFIG_ROUTING_PROTOCOL. Not even the EFI
- * setup browser uses the HII_CONFIG_ROUTING_PROTOCOL. To the best of
- * my knowledge, there has only ever been one implementation of the
- * HII_CONFIG_ROUTING_PROTOCOL (as part of EDK2), and it just doesn't
- * work. It's so badly broken that I can't even figure out what the
- * code is _trying_ to do.
- *
- * Fundamentally, the problem seems to be that Javascript programmers
- * should not be allowed to design APIs for C code.
- */
-
-#include <string.h>
-#include <strings.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <wchar.h>
-#include <errno.h>
-#include <ipxe/settings.h>
-#include <ipxe/nvo.h>
-#include <ipxe/device.h>
-#include <ipxe/netdevice.h>
-#include <ipxe/version.h>
-#include <ipxe/efi/efi.h>
-#include <ipxe/efi/efi_hii.h>
-#include <ipxe/efi/efi_snp.h>
-#include <ipxe/efi/efi_strings.h>
-#include <config/branding.h>
-
-/** EFI platform setup formset GUID */
-static EFI_GUID efi_hii_platform_setup_formset_guid
- = EFI_HII_PLATFORM_SETUP_FORMSET_GUID;
-
-/** EFI IBM UCM compliant formset GUID */
-static EFI_GUID efi_hii_ibm_ucm_compliant_formset_guid
- = EFI_HII_IBM_UCM_COMPLIANT_FORMSET_GUID;
-
-/** EFI HII database protocol */
-static EFI_HII_DATABASE_PROTOCOL *efihii;
-EFI_REQUEST_PROTOCOL ( EFI_HII_DATABASE_PROTOCOL, &efihii );
-
-/**
- * Identify settings to be exposed via HII
- *
- * @v snpdev SNP device
- * @ret settings Settings, or NULL
- */
-static struct settings * efi_snp_hii_settings ( struct efi_snp_device *snpdev ){
-
- return find_child_settings ( netdev_settings ( snpdev->netdev ),
- NVO_SETTINGS_NAME );
-}
-
-/**
- * Check whether or not setting is applicable
- *
- * @v snpdev SNP device
- * @v setting Setting
- * @ret applies Setting applies
- */
-static int efi_snp_hii_setting_applies ( struct efi_snp_device *snpdev,
- struct setting *setting ) {
-
- return nvo_applies ( efi_snp_hii_settings ( snpdev ), setting );
-}
-
-/**
- * Generate a random GUID
- *
- * @v guid GUID to fill in
- */
-static void efi_snp_hii_random_guid ( EFI_GUID *guid ) {
- uint8_t *byte = ( ( uint8_t * ) guid );
- unsigned int i;
-
- for ( i = 0 ; i < sizeof ( *guid ) ; i++ )
- *(byte++) = random();
-}
-
-/**
- * Generate EFI SNP questions
- *
- * @v snpdev SNP device
- * @v ifr IFR builder
- * @v varstore_id Variable store identifier
- */
-static void efi_snp_hii_questions ( struct efi_snp_device *snpdev,
- struct efi_ifr_builder *ifr,
- unsigned int varstore_id ) {
- struct setting *setting;
- struct setting *previous = NULL;
- unsigned int name_id;
- unsigned int prompt_id;
- unsigned int help_id;
- unsigned int question_id;
-
- /* Add all applicable settings */
- for_each_table_entry ( setting, SETTINGS ) {
- if ( ! efi_snp_hii_setting_applies ( snpdev, setting ) )
- continue;
- if ( previous && ( setting_cmp ( setting, previous ) == 0 ) )
- continue;
- previous = setting;
- name_id = efi_ifr_string ( ifr, "%s", setting->name );
- prompt_id = efi_ifr_string ( ifr, "%s", setting->description );
- help_id = efi_ifr_string ( ifr, PRODUCT_SETTING_URI,
- setting->name );
- question_id = setting->tag;
- efi_ifr_string_op ( ifr, prompt_id, help_id,
- question_id, varstore_id, name_id,
- 0, 0x00, 0xff, 0 );
- }
-}
-
-/**
- * Build HII package list for SNP device
- *
- * @v snpdev SNP device
- * @ret package Package list, or NULL on error
- */
-static EFI_HII_PACKAGE_LIST_HEADER *
-efi_snp_hii_package_list ( struct efi_snp_device *snpdev ) {
- struct net_device *netdev = snpdev->netdev;
- struct device *dev = netdev->dev;
- struct efi_ifr_builder ifr;
- EFI_HII_PACKAGE_LIST_HEADER *package;
- const char *name;
- EFI_GUID package_guid;
- EFI_GUID formset_guid;
- EFI_GUID varstore_guid;
- unsigned int title_id;
- unsigned int varstore_id;
-
- /* Initialise IFR builder */
- efi_ifr_init ( &ifr );
-
- /* Determine product name */
- name = ( product_name[0] ? product_name : product_short_name );
-
- /* Generate GUIDs */
- efi_snp_hii_random_guid ( &package_guid );
- efi_snp_hii_random_guid ( &formset_guid );
- efi_snp_hii_random_guid ( &varstore_guid );
-
- /* Generate title string (used more than once) */
- title_id = efi_ifr_string ( &ifr, "%s (%s)", name,
- netdev_addr ( netdev ) );
-
- /* Generate opcodes */
- efi_ifr_form_set_op ( &ifr, &formset_guid, title_id,
- efi_ifr_string ( &ifr, "Configure %s",
- product_short_name ),
- &efi_hii_platform_setup_formset_guid,
- &efi_hii_ibm_ucm_compliant_formset_guid, NULL );
- efi_ifr_guid_class_op ( &ifr, EFI_NETWORK_DEVICE_CLASS );
- efi_ifr_guid_subclass_op ( &ifr, 0x03 );
- varstore_id = efi_ifr_varstore_name_value_op ( &ifr, &varstore_guid );
- efi_ifr_form_op ( &ifr, title_id );
- efi_ifr_text_op ( &ifr,
- efi_ifr_string ( &ifr, "Name" ),
- efi_ifr_string ( &ifr, "Firmware product name" ),
- efi_ifr_string ( &ifr, "%s", name ) );
- efi_ifr_text_op ( &ifr,
- efi_ifr_string ( &ifr, "Version" ),
- efi_ifr_string ( &ifr, "Firmware version" ),
- efi_ifr_string ( &ifr, "%s", product_version ) );
- efi_ifr_text_op ( &ifr,
- efi_ifr_string ( &ifr, "Driver" ),
- efi_ifr_string ( &ifr, "Firmware driver" ),
- efi_ifr_string ( &ifr, "%s", dev->driver_name ) );
- efi_ifr_text_op ( &ifr,
- efi_ifr_string ( &ifr, "Device" ),
- efi_ifr_string ( &ifr, "Hardware device" ),
- efi_ifr_string ( &ifr, "%s", dev->name ) );
- efi_snp_hii_questions ( snpdev, &ifr, varstore_id );
- efi_ifr_end_op ( &ifr );
- efi_ifr_end_op ( &ifr );
-
- /* Build package */
- package = efi_ifr_package ( &ifr, &package_guid, "en-us",
- efi_ifr_string ( &ifr, "English" ) );
- if ( ! package ) {
- DBGC ( snpdev, "SNPDEV %p could not build IFR package\n",
- snpdev );
- efi_ifr_free ( &ifr );
- return NULL;
- }
-
- /* Free temporary storage */
- efi_ifr_free ( &ifr );
- return package;
-}
-
-/**
- * Append response to result string
- *
- * @v snpdev SNP device
- * @v key Key
- * @v value Value
- * @v results Result string
- * @ret rc Return status code
- *
- * The result string is allocated dynamically using
- * BootServices::AllocatePool(), and the caller is responsible for
- * eventually calling BootServices::FreePool().
- */
-static int efi_snp_hii_append ( struct efi_snp_device *snpdev __unused,
- const char *key, const char *value,
- wchar_t **results ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- size_t len;
- void *new;
-
- /* Allocate new string */
- len = ( ( *results ? ( wcslen ( *results ) + 1 /* "&" */ ) : 0 ) +
- strlen ( key ) + 1 /* "=" */ + strlen ( value ) + 1 /* NUL */ );
- bs->AllocatePool ( EfiBootServicesData, ( len * sizeof ( wchar_t ) ),
- &new );
- if ( ! new )
- return -ENOMEM;
-
- /* Populate string */
- efi_snprintf ( new, len, "%ls%s%s=%s", ( *results ? *results : L"" ),
- ( *results ? L"&" : L"" ), key, value );
- bs->FreePool ( *results );
- *results = new;
-
- return 0;
-}
-
-/**
- * Fetch HII setting
- *
- * @v snpdev SNP device
- * @v key Key
- * @v value Value
- * @v results Result string
- * @v have_setting Flag indicating detection of a setting
- * @ret rc Return status code
- */
-static int efi_snp_hii_fetch ( struct efi_snp_device *snpdev,
- const char *key, const char *value,
- wchar_t **results, int *have_setting ) {
- struct settings *settings = efi_snp_hii_settings ( snpdev );
- struct settings *origin;
- struct setting *setting;
- struct setting fetched;
- int len;
- char *buf;
- char *encoded;
- int i;
- int rc;
-
- /* Handle ConfigHdr components */
- if ( ( strcasecmp ( key, "GUID" ) == 0 ) ||
- ( strcasecmp ( key, "NAME" ) == 0 ) ||
- ( strcasecmp ( key, "PATH" ) == 0 ) ) {
- return efi_snp_hii_append ( snpdev, key, value, results );
- }
- if ( have_setting )
- *have_setting = 1;
-
- /* Do nothing more unless we have a settings block */
- if ( ! settings ) {
- rc = -ENOTSUP;
- goto err_no_settings;
- }
-
- /* Identify setting */
- setting = find_setting ( key );
- if ( ! setting ) {
- DBGC ( snpdev, "SNPDEV %p no such setting \"%s\"\n",
- snpdev, key );
- rc = -ENODEV;
- goto err_find_setting;
- }
-
- /* Encode value */
- if ( setting_exists ( settings, setting ) ) {
-
- /* Calculate formatted length */
- len = fetchf_setting ( settings, setting, &origin, &fetched,
- NULL, 0 );
- if ( len < 0 ) {
- rc = len;
- DBGC ( snpdev, "SNPDEV %p could not fetch %s: %s\n",
- snpdev, setting->name, strerror ( rc ) );
- goto err_fetchf_len;
- }
-
- /* Allocate buffer for formatted value and HII-encoded value */
- buf = zalloc ( len + 1 /* NUL */ + ( len * 4 ) + 1 /* NUL */ );
- if ( ! buf ) {
- rc = -ENOMEM;
- goto err_alloc;
- }
- encoded = ( buf + len + 1 /* NUL */ );
-
- /* Format value */
- fetchf_setting ( origin, &fetched, NULL, NULL, buf,
- ( len + 1 /* NUL */ ) );
- for ( i = 0 ; i < len ; i++ ) {
- sprintf ( ( encoded + ( 4 * i ) ), "%04x",
- *( ( uint8_t * ) buf + i ) );
- }
-
- } else {
-
- /* Non-existent or inapplicable setting */
- buf = NULL;
- encoded = "";
- }
-
- /* Append results */
- if ( ( rc = efi_snp_hii_append ( snpdev, key, encoded,
- results ) ) != 0 ) {
- goto err_append;
- }
-
- /* Success */
- rc = 0;
-
- err_append:
- free ( buf );
- err_alloc:
- err_fetchf_len:
- err_find_setting:
- err_no_settings:
- return rc;
-}
-
-/**
- * Fetch HII setting
- *
- * @v snpdev SNP device
- * @v key Key
- * @v value Value
- * @v results Result string (unused)
- * @v have_setting Flag indicating detection of a setting (unused)
- * @ret rc Return status code
- */
-static int efi_snp_hii_store ( struct efi_snp_device *snpdev,
- const char *key, const char *value,
- wchar_t **results __unused,
- int *have_setting __unused ) {
- struct settings *settings = efi_snp_hii_settings ( snpdev );
- struct setting *setting;
- char *buf;
- char tmp[5];
- char *endp;
- int len;
- int i;
- int rc;
-
- /* Handle ConfigHdr components */
- if ( ( strcasecmp ( key, "GUID" ) == 0 ) ||
- ( strcasecmp ( key, "NAME" ) == 0 ) ||
- ( strcasecmp ( key, "PATH" ) == 0 ) ) {
- /* Nothing to do */
- return 0;
- }
-
- /* Do nothing more unless we have a settings block */
- if ( ! settings ) {
- rc = -ENOTSUP;
- goto err_no_settings;
- }
-
- /* Identify setting */
- setting = find_setting ( key );
- if ( ! setting ) {
- DBGC ( snpdev, "SNPDEV %p no such setting \"%s\"\n",
- snpdev, key );
- rc = -ENODEV;
- goto err_find_setting;
- }
-
- /* Allocate buffer */
- len = ( strlen ( value ) / 4 );
- buf = zalloc ( len + 1 /* NUL */ );
- if ( ! buf ) {
- rc = -ENOMEM;
- goto err_alloc;
- }
-
- /* Decode value */
- tmp[4] = '\0';
- for ( i = 0 ; i < len ; i++ ) {
- memcpy ( tmp, ( value + ( i * 4 ) ), 4 );
- buf[i] = strtoul ( tmp, &endp, 16 );
- if ( endp != &tmp[4] ) {
- DBGC ( snpdev, "SNPDEV %p invalid character %s\n",
- snpdev, tmp );
- rc = -EINVAL;
- goto err_inval;
- }
- }
-
- /* Store value */
- if ( ( rc = storef_setting ( settings, setting, buf ) ) != 0 ) {
- DBGC ( snpdev, "SNPDEV %p could not store \"%s\" into %s: %s\n",
- snpdev, buf, setting->name, strerror ( rc ) );
- goto err_storef;
- }
-
- /* Success */
- rc = 0;
-
- err_storef:
- err_inval:
- free ( buf );
- err_alloc:
- err_find_setting:
- err_no_settings:
- return rc;
-}
-
-/**
- * Process portion of HII configuration string
- *
- * @v snpdev SNP device
- * @v string HII configuration string
- * @v progress Progress through HII configuration string
- * @v results Results string
- * @v have_setting Flag indicating detection of a setting (unused)
- * @v process Function used to process key=value pairs
- * @ret rc Return status code
- */
-static int efi_snp_hii_process ( struct efi_snp_device *snpdev,
- wchar_t *string, wchar_t **progress,
- wchar_t **results, int *have_setting,
- int ( * process ) ( struct efi_snp_device *,
- const char *key,
- const char *value,
- wchar_t **results,
- int *have_setting ) ) {
- wchar_t *wkey = string;
- wchar_t *wend = string;
- wchar_t *wvalue = NULL;
- size_t key_len;
- size_t value_len;
- void *temp;
- char *key;
- char *value;
- int rc;
-
- /* Locate key, value (if any), and end */
- while ( *wend ) {
- if ( *wend == L'&' )
- break;
- if ( *(wend++) == L'=' )
- wvalue = wend;
- }
-
- /* Allocate memory for key and value */
- key_len = ( ( wvalue ? ( wvalue - 1 ) : wend ) - wkey );
- value_len = ( wvalue ? ( wend - wvalue ) : 0 );
- temp = zalloc ( key_len + 1 /* NUL */ + value_len + 1 /* NUL */ );
- if ( ! temp )
- return -ENOMEM;
- key = temp;
- value = ( temp + key_len + 1 /* NUL */ );
-
- /* Copy key and value */
- while ( key_len-- )
- key[key_len] = wkey[key_len];
- while ( value_len-- )
- value[value_len] = wvalue[value_len];
-
- /* Process key and value */
- if ( ( rc = process ( snpdev, key, value, results,
- have_setting ) ) != 0 ) {
- goto err;
- }
-
- /* Update progress marker */
- *progress = wend;
-
- err:
- /* Free temporary storage */
- free ( temp );
-
- return rc;
-}
-
-/**
- * Fetch configuration
- *
- * @v hii HII configuration access protocol
- * @v request Configuration to fetch
- * @ret progress Progress made through configuration to fetch
- * @ret results Query results
- * @ret efirc EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_snp_hii_extract_config ( const EFI_HII_CONFIG_ACCESS_PROTOCOL *hii,
- EFI_STRING request, EFI_STRING *progress,
- EFI_STRING *results ) {
- struct efi_snp_device *snpdev =
- container_of ( hii, struct efi_snp_device, hii );
- int have_setting = 0;
- wchar_t *pos;
- int rc;
-
- DBGC ( snpdev, "SNPDEV %p ExtractConfig request \"%ls\"\n",
- snpdev, request );
-
- /* Initialise results */
- *results = NULL;
-
- /* Process all request fragments */
- for ( pos = *progress = request ; *progress && **progress ;
- pos = *progress + 1 ) {
- if ( ( rc = efi_snp_hii_process ( snpdev, pos, progress,
- results, &have_setting,
- efi_snp_hii_fetch ) ) != 0 ) {
- return EFIRC ( rc );
- }
- }
-
- /* If we have no explicit request, return all settings */
- if ( ! have_setting ) {
- struct setting *setting;
-
- for_each_table_entry ( setting, SETTINGS ) {
- if ( ! efi_snp_hii_setting_applies ( snpdev, setting ) )
- continue;
- if ( ( rc = efi_snp_hii_fetch ( snpdev, setting->name,
- NULL, results,
- NULL ) ) != 0 ) {
- return EFIRC ( rc );
- }
- }
- }
-
- DBGC ( snpdev, "SNPDEV %p ExtractConfig results \"%ls\"\n",
- snpdev, *results );
- return 0;
-}
-
-/**
- * Store configuration
- *
- * @v hii HII configuration access protocol
- * @v config Configuration to store
- * @ret progress Progress made through configuration to store
- * @ret efirc EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_snp_hii_route_config ( const EFI_HII_CONFIG_ACCESS_PROTOCOL *hii,
- EFI_STRING config, EFI_STRING *progress ) {
- struct efi_snp_device *snpdev =
- container_of ( hii, struct efi_snp_device, hii );
- wchar_t *pos;
- int rc;
-
- DBGC ( snpdev, "SNPDEV %p RouteConfig \"%ls\"\n", snpdev, config );
-
- /* Process all request fragments */
- for ( pos = *progress = config ; *progress && **progress ;
- pos = *progress + 1 ) {
- if ( ( rc = efi_snp_hii_process ( snpdev, pos, progress,
- NULL, NULL,
- efi_snp_hii_store ) ) != 0 ) {
- return EFIRC ( rc );
- }
- }
-
- return 0;
-}
-
-/**
- * Handle form actions
- *
- * @v hii HII configuration access protocol
- * @v action Form browser action
- * @v question_id Question ID
- * @v type Type of value
- * @v value Value
- * @ret action_request Action requested by driver
- * @ret efirc EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_snp_hii_callback ( const EFI_HII_CONFIG_ACCESS_PROTOCOL *hii,
- EFI_BROWSER_ACTION action __unused,
- EFI_QUESTION_ID question_id __unused,
- UINT8 type __unused, EFI_IFR_TYPE_VALUE *value __unused,
- EFI_BROWSER_ACTION_REQUEST *action_request __unused ) {
- struct efi_snp_device *snpdev =
- container_of ( hii, struct efi_snp_device, hii );
-
- DBGC ( snpdev, "SNPDEV %p Callback\n", snpdev );
- return EFI_UNSUPPORTED;
-}
-
-/** HII configuration access protocol */
-static EFI_HII_CONFIG_ACCESS_PROTOCOL efi_snp_device_hii = {
- .ExtractConfig = efi_snp_hii_extract_config,
- .RouteConfig = efi_snp_hii_route_config,
- .Callback = efi_snp_hii_callback,
-};
-
-/**
- * Install HII protocol and packages for SNP device
- *
- * @v snpdev SNP device
- * @ret rc Return status code
- */
-int efi_snp_hii_install ( struct efi_snp_device *snpdev ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- int efirc;
- int rc;
-
- /* Do nothing if HII database protocol is not supported */
- if ( ! efihii ) {
- rc = -ENOTSUP;
- goto err_no_hii;
- }
-
- /* Initialise HII protocol */
- memcpy ( &snpdev->hii, &efi_snp_device_hii, sizeof ( snpdev->hii ) );
-
- /* Create HII package list */
- snpdev->package_list = efi_snp_hii_package_list ( snpdev );
- if ( ! snpdev->package_list ) {
- DBGC ( snpdev, "SNPDEV %p could not create HII package list\n",
- snpdev );
- rc = -ENOMEM;
- goto err_build_package_list;
- }
-
- /* Add HII packages */
- if ( ( efirc = efihii->NewPackageList ( efihii, snpdev->package_list,
- snpdev->handle,
- &snpdev->hii_handle ) ) != 0 ) {
- rc = -EEFI ( efirc );
- DBGC ( snpdev, "SNPDEV %p could not add HII packages: %s\n",
- snpdev, strerror ( rc ) );
- goto err_new_package_list;
- }
-
- /* Install HII protocol */
- if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
- &snpdev->handle,
- &efi_hii_config_access_protocol_guid, &snpdev->hii,
- NULL ) ) != 0 ) {
- rc = -EEFI ( efirc );
- DBGC ( snpdev, "SNPDEV %p could not install HII protocol: %s\n",
- snpdev, strerror ( rc ) );
- goto err_install_protocol;
- }
-
- return 0;
-
- bs->UninstallMultipleProtocolInterfaces (
- snpdev->handle,
- &efi_hii_config_access_protocol_guid, &snpdev->hii,
- NULL );
- err_install_protocol:
- efihii->RemovePackageList ( efihii, snpdev->hii_handle );
- err_new_package_list:
- free ( snpdev->package_list );
- snpdev->package_list = NULL;
- err_build_package_list:
- err_no_hii:
- return rc;
-}
-
-/**
- * Uninstall HII protocol and package for SNP device
- *
- * @v snpdev SNP device
- */
-void efi_snp_hii_uninstall ( struct efi_snp_device *snpdev ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-
- /* Do nothing if HII database protocol is not supported */
- if ( ! efihii )
- return;
-
- /* Uninstall protocols and remove package list */
- bs->UninstallMultipleProtocolInterfaces (
- snpdev->handle,
- &efi_hii_config_access_protocol_guid, &snpdev->hii,
- NULL );
- efihii->RemovePackageList ( efihii, snpdev->hii_handle );
- free ( snpdev->package_list );
- snpdev->package_list = NULL;
-}
diff --git a/qemu/roms/ipxe/src/interface/efi/efi_strings.c b/qemu/roms/ipxe/src/interface/efi/efi_strings.c
deleted file mode 100644
index aa3afc64f..000000000
--- a/qemu/roms/ipxe/src/interface/efi/efi_strings.c
+++ /dev/null
@@ -1,152 +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 );
-
-#include <stddef.h>
-#include <stdarg.h>
-#include <ipxe/vsprintf.h>
-#include <ipxe/efi/efi_strings.h>
-
-/** Context used by efi_vsnprintf() and friends */
-struct efi_sputc_context {
- /** printf context */
- struct printf_context ctx;
- /** Buffer for formatted string (used by efi_printf_sputc()) */
- wchar_t *buf;
- /** Buffer length (used by efi_printf_sputc())
- *
- * Note that this is a number of wide characters, not a number
- * of bytes.
- */
- size_t max_wlen;
-};
-
-/**
- * Write wide character to buffer
- *
- * @v ctx Context
- * @v c Character
- */
-static void efi_printf_sputc ( struct printf_context *ctx, unsigned int c ) {
- struct efi_sputc_context * sctx =
- container_of ( ctx, struct efi_sputc_context, ctx );
-
- if ( ctx->len < sctx->max_wlen )
- sctx->buf[ctx->len] = c;
-}
-
-/**
- * Write a formatted string to a wide-character buffer
- *
- * @v wbuf Buffer into which to write the string
- * @v wsize Size of buffer (in wide characters)
- * @v fmt Format string
- * @v args Arguments corresponding to the format string
- * @ret wlen Length of formatted string (in wide characters)
- *
- * If the buffer is too small to contain the string, the returned
- * length is the length that would have been written had enough space
- * been available.
- */
-int efi_vsnprintf ( wchar_t *wbuf, size_t wsize, const char *fmt,
- va_list args ) {
- struct efi_sputc_context sctx;
- size_t wlen;
- size_t wend;
-
- /* Hand off to vcprintf */
- sctx.ctx.handler = efi_printf_sputc;
- sctx.buf = wbuf;
- sctx.max_wlen = wsize;
- wlen = vcprintf ( &sctx.ctx, fmt, args );
-
- /* Add trailing NUL */
- if ( wsize ) {
- wend = wsize - 1;
- if ( wlen < wend )
- wend = wlen;
- wbuf[wend] = '\0';
- }
-
- return wlen;
-}
-
-/**
- * Write a formatted string to a buffer
- *
- * @v wbuf Buffer into which to write the string
- * @v wsize Size of buffer (in wide characters)
- * @v fmt Format string
- * @v ... Arguments corresponding to the format string
- * @ret wlen Length of formatted string (in wide characters)
- */
-int efi_snprintf ( wchar_t *wbuf, size_t wsize, const char *fmt, ... ) {
- va_list args;
- int i;
-
- va_start ( args, fmt );
- i = efi_vsnprintf ( wbuf, wsize, fmt, args );
- va_end ( args );
- return i;
-}
-
-/**
- * Version of efi_vsnprintf() that accepts a signed buffer size
- *
- * @v wbuf Buffer into which to write the string
- * @v swsize Size of buffer (in wide characters)
- * @v fmt Format string
- * @v args Arguments corresponding to the format string
- * @ret wlen Length of formatted string (in wide characters)
- */
-int efi_vssnprintf ( wchar_t *wbuf, ssize_t swsize, const char *fmt,
- va_list args ) {
-
- /* Treat negative buffer size as zero buffer size */
- if ( swsize < 0 )
- swsize = 0;
-
- /* Hand off to vsnprintf */
- return efi_vsnprintf ( wbuf, swsize, fmt, args );
-}
-
-/**
- * Version of efi_vsnprintf() that accepts a signed buffer size
- *
- * @v wbuf Buffer into which to write the string
- * @v swsize Size of buffer (in wide characters)
- * @v fmt Format string
- * @v ... Arguments corresponding to the format string
- * @ret wlen Length of formatted string (in wide characters)
- */
-int efi_ssnprintf ( wchar_t *wbuf, ssize_t swsize, const char *fmt, ... ) {
- va_list args;
- int len;
-
- /* Hand off to vssnprintf */
- va_start ( args, fmt );
- len = efi_vssnprintf ( wbuf, swsize, fmt, args );
- va_end ( args );
- return len;
-}
diff --git a/qemu/roms/ipxe/src/interface/efi/efi_time.c b/qemu/roms/ipxe/src/interface/efi/efi_time.c
deleted file mode 100644
index 983a0ef5c..000000000
--- a/qemu/roms/ipxe/src/interface/efi/efi_time.c
+++ /dev/null
@@ -1,75 +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 <string.h>
-#include <errno.h>
-#include <time.h>
-#include <ipxe/time.h>
-#include <ipxe/efi/efi.h>
-
-/** @file
- *
- * EFI time source
- *
- */
-
-/**
- * Get current time in seconds
- *
- * @ret time Time, in seconds
- */
-static time_t efi_get_time ( void ) {
- EFI_RUNTIME_SERVICES *rs = efi_systab->RuntimeServices;
- EFI_TIME time;
- struct tm tm;
- EFI_STATUS efirc;
- int rc;
-
- /* Get current time and date */
- if ( ( efirc = rs->GetTime ( &time, NULL ) ) != 0 ) {
- rc = -EEFI ( efirc );
- DBGC ( rs, "EFITIME could not get system time: %s\n",
- strerror ( rc ) );
- /* Nothing meaningful we can return */
- return 0;
- }
-
- /* Construct broken-down time */
- memset ( &tm, 0, sizeof ( tm ) );
- tm.tm_sec = time.Second;
- tm.tm_min = time.Minute;
- tm.tm_hour = time.Hour;
- tm.tm_mday = time.Day;
- tm.tm_mon = ( time.Month - 1 );
- tm.tm_year = ( time.Year - 1900 );
- DBGC ( rs, "EFITIME is %04d-%02d-%02d %02d:%02d:%02d\n",
- ( tm.tm_year + 1900 ), ( tm.tm_mon + 1 ),
- tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec );
-
- /* Convert to seconds since the Epoch */
- return mktime ( &tm );
-}
-
-PROVIDE_TIME ( efi, time_now, efi_get_time );
diff --git a/qemu/roms/ipxe/src/interface/efi/efi_timer.c b/qemu/roms/ipxe/src/interface/efi/efi_timer.c
deleted file mode 100644
index 81620c92c..000000000
--- a/qemu/roms/ipxe/src/interface/efi/efi_timer.c
+++ /dev/null
@@ -1,128 +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 <string.h>
-#include <errno.h>
-#include <limits.h>
-#include <assert.h>
-#include <unistd.h>
-#include <ipxe/timer.h>
-#include <ipxe/efi/efi.h>
-#include <ipxe/efi/Protocol/Cpu.h>
-
-/** @file
- *
- * iPXE timer API for EFI
- *
- */
-
-/** Scale factor to apply to CPU timer 0
- *
- * The timer is scaled down in order to ensure that reasonable values
- * for "number of ticks" don't exceed the size of an unsigned long.
- */
-#define EFI_TIMER0_SHIFT 12
-
-/** Calibration time */
-#define EFI_CALIBRATE_DELAY_MS 1
-
-/** CPU protocol */
-static EFI_CPU_ARCH_PROTOCOL *cpu_arch;
-EFI_REQUIRE_PROTOCOL ( EFI_CPU_ARCH_PROTOCOL, &cpu_arch );
-
-/**
- * Delay for a fixed number of microseconds
- *
- * @v usecs Number of microseconds for which to delay
- */
-static void efi_udelay ( unsigned long usecs ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- EFI_STATUS efirc;
- int rc;
-
- if ( ( efirc = bs->Stall ( usecs ) ) != 0 ) {
- rc = -EEFI ( efirc );
- DBG ( "EFI could not delay for %ldus: %s\n",
- usecs, strerror ( rc ) );
- /* Probably screwed */
- }
-}
-
-/**
- * Get current system time in ticks
- *
- * @ret ticks Current time, in ticks
- */
-static unsigned long efi_currticks ( void ) {
- UINT64 time;
- EFI_STATUS efirc;
- int rc;
-
- /* Read CPU timer 0 (TSC) */
- if ( ( efirc = cpu_arch->GetTimerValue ( cpu_arch, 0, &time,
- NULL ) ) != 0 ) {
- rc = -EEFI ( efirc );
- DBG ( "EFI could not read CPU timer: %s\n", strerror ( rc ) );
- /* Probably screwed */
- return -1UL;
- }
-
- return ( time >> EFI_TIMER0_SHIFT );
-}
-
-/**
- * Get number of ticks per second
- *
- * @ret ticks_per_sec Number of ticks per second
- */
-static unsigned long efi_ticks_per_sec ( void ) {
- static unsigned long ticks_per_sec = 0;
-
- /* Calibrate timer, if necessary. EFI does nominally provide
- * the timer speed via the (optional) TimerPeriod parameter to
- * the GetTimerValue() call, but it gets the speed slightly
- * wrong. By up to three orders of magnitude. Not helpful.
- */
- if ( ! ticks_per_sec ) {
- unsigned long start;
- unsigned long elapsed;
-
- DBG ( "Calibrating EFI timer with a %d ms delay\n",
- EFI_CALIBRATE_DELAY_MS );
- start = currticks();
- mdelay ( EFI_CALIBRATE_DELAY_MS );
- elapsed = ( currticks() - start );
- ticks_per_sec = ( elapsed * ( 1000 / EFI_CALIBRATE_DELAY_MS ));
- DBG ( "EFI CPU timer calibrated at %ld ticks in %d ms (%ld "
- "ticks/sec)\n", elapsed, EFI_CALIBRATE_DELAY_MS,
- ticks_per_sec );
- }
-
- return ticks_per_sec;
-}
-
-PROVIDE_TIMER ( efi, udelay, efi_udelay );
-PROVIDE_TIMER ( efi, currticks, efi_currticks );
-PROVIDE_TIMER ( efi, ticks_per_sec, efi_ticks_per_sec );
diff --git a/qemu/roms/ipxe/src/interface/efi/efi_uaccess.c b/qemu/roms/ipxe/src/interface/efi/efi_uaccess.c
deleted file mode 100644
index e058be66b..000000000
--- a/qemu/roms/ipxe/src/interface/efi/efi_uaccess.c
+++ /dev/null
@@ -1,44 +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 <ipxe/uaccess.h>
-#include <ipxe/efi/efi.h>
-
-/** @file
- *
- * iPXE user access API for EFI
- *
- */
-
-PROVIDE_UACCESS_INLINE ( efi, phys_to_user );
-PROVIDE_UACCESS_INLINE ( efi, user_to_phys );
-PROVIDE_UACCESS_INLINE ( efi, virt_to_user );
-PROVIDE_UACCESS_INLINE ( efi, user_to_virt );
-PROVIDE_UACCESS_INLINE ( efi, userptr_add );
-PROVIDE_UACCESS_INLINE ( efi, memcpy_user );
-PROVIDE_UACCESS_INLINE ( efi, memmove_user );
-PROVIDE_UACCESS_INLINE ( efi, memset_user );
-PROVIDE_UACCESS_INLINE ( efi, strlen_user );
-PROVIDE_UACCESS_INLINE ( efi, memchr_user );
diff --git a/qemu/roms/ipxe/src/interface/efi/efi_umalloc.c b/qemu/roms/ipxe/src/interface/efi/efi_umalloc.c
deleted file mode 100644
index e3f1dacc2..000000000
--- a/qemu/roms/ipxe/src/interface/efi/efi_umalloc.c
+++ /dev/null
@@ -1,108 +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 <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <ipxe/umalloc.h>
-#include <ipxe/efi/efi.h>
-
-/** @file
- *
- * iPXE user memory allocation API for EFI
- *
- */
-
-/** Equivalent of NOWHERE for user pointers */
-#define UNOWHERE ( ~UNULL )
-
-/**
- * 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 efi_urealloc ( userptr_t old_ptr, size_t new_size ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- EFI_PHYSICAL_ADDRESS phys_addr;
- unsigned int new_pages, old_pages;
- userptr_t new_ptr = UNOWHERE;
- size_t old_size;
- EFI_STATUS efirc;
- int rc;
-
- /* Allocate new memory if necessary. If allocation fails,
- * return without touching the old block.
- */
- if ( new_size ) {
- new_pages = ( EFI_SIZE_TO_PAGES ( new_size ) + 1 );
- if ( ( efirc = bs->AllocatePages ( AllocateAnyPages,
- EfiBootServicesData,
- new_pages,
- &phys_addr ) ) != 0 ) {
- rc = -EEFI ( efirc );
- DBG ( "EFI could not allocate %d pages: %s\n",
- new_pages, strerror ( rc ) );
- return UNULL;
- }
- assert ( phys_addr != 0 );
- new_ptr = phys_to_user ( phys_addr + EFI_PAGE_SIZE );
- copy_to_user ( new_ptr, -EFI_PAGE_SIZE,
- &new_size, sizeof ( new_size ) );
- DBG ( "EFI allocated %d pages at %llx\n",
- new_pages, phys_addr );
- }
-
- /* Copy across relevant part of the old data region (if any),
- * then free it. Note that at this point either (a) new_ptr
- * is valid, or (b) new_size is 0; either way, the memcpy() is
- * valid.
- */
- if ( old_ptr && ( old_ptr != UNOWHERE ) ) {
- copy_from_user ( &old_size, old_ptr, -EFI_PAGE_SIZE,
- sizeof ( old_size ) );
- memcpy_user ( new_ptr, 0, old_ptr, 0,
- ( (old_size < new_size) ? old_size : new_size ));
- old_pages = ( EFI_SIZE_TO_PAGES ( old_size ) + 1 );
- phys_addr = user_to_phys ( old_ptr, -EFI_PAGE_SIZE );
- if ( ( efirc = bs->FreePages ( phys_addr, old_pages ) ) != 0 ){
- rc = -EEFI ( efirc );
- DBG ( "EFI could not free %d pages at %llx: %s\n",
- old_pages, phys_addr, strerror ( rc ) );
- /* Not fatal; we have leaked memory but successfully
- * allocated (if asked to do so).
- */
- }
- DBG ( "EFI freed %d pages at %llx\n", old_pages, phys_addr );
- }
-
- return new_ptr;
-}
-
-PROVIDE_UMALLOC ( efi, urealloc, efi_urealloc );
diff --git a/qemu/roms/ipxe/src/interface/efi/efi_utils.c b/qemu/roms/ipxe/src/interface/efi/efi_utils.c
deleted file mode 100644
index 936ad48ec..000000000
--- a/qemu/roms/ipxe/src/interface/efi/efi_utils.c
+++ /dev/null
@@ -1,218 +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.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <ipxe/efi/efi.h>
-#include <ipxe/efi/efi_pci.h>
-#include <ipxe/efi/efi_utils.h>
-
-/** @file
- *
- * EFI utilities
- *
- */
-
-/**
- * Find end of device path
- *
- * @v path Path to device
- * @ret path_end End of device path
- */
-EFI_DEVICE_PATH_PROTOCOL * efi_devpath_end ( EFI_DEVICE_PATH_PROTOCOL *path ) {
-
- while ( path->Type != END_DEVICE_PATH_TYPE ) {
- path = ( ( ( void * ) path ) +
- /* There's this amazing new-fangled thing known as
- * a UINT16, but who wants to use one of those? */
- ( ( path->Length[1] << 8 ) | path->Length[0] ) );
- }
-
- return path;
-}
-
-/**
- * Locate parent device supporting a given protocol
- *
- * @v device EFI device handle
- * @v protocol Protocol GUID
- * @v parent Parent EFI device handle to fill in
- * @ret rc Return status code
- */
-int efi_locate_device ( EFI_HANDLE device, EFI_GUID *protocol,
- EFI_HANDLE *parent ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- union {
- EFI_DEVICE_PATH_PROTOCOL *path;
- void *interface;
- } path;
- EFI_DEVICE_PATH_PROTOCOL *devpath;
- EFI_STATUS efirc;
- int rc;
-
- /* Get device path */
- if ( ( efirc = bs->OpenProtocol ( device,
- &efi_device_path_protocol_guid,
- &path.interface,
- efi_image_handle, device,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
- rc = -EEFI ( efirc );
- DBGC ( device, "EFIDEV %p %s cannot open device path: %s\n",
- device, efi_handle_name ( device ), strerror ( rc ) );
- goto err_open_device_path;
- }
- devpath = path.path;
-
- /* Check for presence of specified protocol */
- if ( ( efirc = bs->LocateDevicePath ( protocol, &devpath,
- parent ) ) != 0 ) {
- rc = -EEFI ( efirc );
- DBGC ( device, "EFIDEV %p %s has no parent supporting %s: %s\n",
- device, efi_handle_name ( device ),
- efi_guid_ntoa ( protocol ), strerror ( rc ) );
- goto err_locate_protocol;
- }
-
- /* Success */
- rc = 0;
-
- err_locate_protocol:
- bs->CloseProtocol ( device, &efi_device_path_protocol_guid,
- efi_image_handle, device );
- err_open_device_path:
- return rc;
-}
-
-/**
- * Add EFI device as child of another EFI device
- *
- * @v parent EFI parent device handle
- * @v child EFI child device handle
- * @ret rc Return status code
- */
-int efi_child_add ( EFI_HANDLE parent, EFI_HANDLE child ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- void *devpath;
- EFI_STATUS efirc;
- int rc;
-
- /* Re-open the device path protocol */
- if ( ( efirc = bs->OpenProtocol ( parent,
- &efi_device_path_protocol_guid,
- &devpath,
- efi_image_handle, child,
- EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
- ) ) != 0 ) {
- rc = -EEFI ( efirc );
- DBGC ( parent, "EFIDEV %p %s could not add child",
- parent, efi_handle_name ( parent ) );
- DBGC ( parent, " %p %s: %s\n", child,
- efi_handle_name ( child ), strerror ( rc ) );
- DBGC_EFI_OPENERS ( parent, parent,
- &efi_device_path_protocol_guid );
- return rc;
- }
-
- DBGC2 ( parent, "EFIDEV %p %s added child",
- parent, efi_handle_name ( parent ) );
- DBGC2 ( parent, " %p %s\n", child, efi_handle_name ( child ) );
- return 0;
-}
-
-/**
- * Remove EFI device as child of another EFI device
- *
- * @v parent EFI parent device handle
- * @v child EFI child device handle
- */
-void efi_child_del ( EFI_HANDLE parent, EFI_HANDLE child ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-
- bs->CloseProtocol ( parent, &efi_device_path_protocol_guid,
- efi_image_handle, child );
- DBGC2 ( parent, "EFIDEV %p %s removed child",
- parent, efi_handle_name ( parent ) );
- DBGC2 ( parent, " %p %s\n",
- child, efi_handle_name ( child ) );
-}
-
-/**
- * Get underlying PCI device information
- *
- * @v device EFI device handle
- * @v prefix Device name prefix
- * @v dev Generic device to fill in
- * @ret rc Return status code
- */
-static int efi_pci_info ( EFI_HANDLE device, const char *prefix,
- struct device *dev ) {
- EFI_HANDLE pci_device;
- struct pci_device pci;
- int rc;
-
- /* Find parent PCI device */
- if ( ( rc = efi_locate_device ( device, &efi_pci_io_protocol_guid,
- &pci_device ) ) != 0 ) {
- DBGC ( device, "EFIDEV %p %s is not a PCI device: %s\n",
- device, efi_handle_name ( device ), strerror ( rc ) );
- return rc;
- }
-
- /* Get PCI device information */
- if ( ( rc = efipci_info ( pci_device, &pci ) ) != 0 ) {
- DBGC ( device, "EFIDEV %p %s could not get PCI information: "
- "%s\n", device, efi_handle_name ( device ),
- strerror ( rc ) );
- return rc;
- }
-
- /* Populate device information */
- memcpy ( &dev->desc, &pci.dev.desc, sizeof ( dev->desc ) );
- snprintf ( dev->name, sizeof ( dev->name ), "%s-%s",
- prefix, pci.dev.name );
-
- return 0;
-}
-
-/**
- * Get underlying device information
- *
- * @v device EFI device handle
- * @v prefix Device name prefix
- * @v dev Generic device to fill in
- */
-void efi_device_info ( EFI_HANDLE device, const char *prefix,
- struct device *dev ) {
- int rc;
-
- /* Try getting underlying PCI device information */
- if ( ( rc = efi_pci_info ( device, prefix, dev ) ) == 0 )
- return;
-
- /* If we cannot get any underlying device information, fall
- * back to providing information about the EFI handle.
- */
- DBGC ( device, "EFIDEV %p %s could not get underlying device "
- "information\n", device, efi_handle_name ( device ) );
- dev->desc.bus_type = BUS_TYPE_EFI;
- snprintf ( dev->name, sizeof ( dev->name ), "%s-%p", prefix, device );
-}
diff --git a/qemu/roms/ipxe/src/interface/efi/efi_watchdog.c b/qemu/roms/ipxe/src/interface/efi/efi_watchdog.c
deleted file mode 100644
index 7061f81d8..000000000
--- a/qemu/roms/ipxe/src/interface/efi/efi_watchdog.c
+++ /dev/null
@@ -1,82 +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 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
- *
- * EFI watchdog holdoff timer
- *
- */
-
-#include <errno.h>
-#include <string.h>
-#include <ipxe/retry.h>
-#include <ipxe/timer.h>
-#include <ipxe/efi/efi.h>
-#include <ipxe/efi/efi_watchdog.h>
-
-/** Watchdog holdoff interval (in seconds) */
-#define WATCHDOG_HOLDOFF_SECS 10
-
-/** Watchdog timeout (in seconds) */
-#define WATCHDOG_TIMEOUT_SECS ( 5 * 60 )
-
-/** Watchdog code (to be logged on watchdog timeout) */
-#define WATCHDOG_CODE 0x6950584544454144ULL
-
-/** Watchdog data (to be logged on watchdog timeout) */
-#define WATCHDOG_DATA L"iPXE";
-
-/**
- * Hold off watchdog timer
- *
- * @v retry Retry timer
- * @v over Failure indicator
- */
-static void efi_watchdog_expired ( struct retry_timer *timer,
- int over __unused ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- static CHAR16 data[] = WATCHDOG_DATA;
- EFI_STATUS efirc;
- int rc;
-
- DBGC2 ( timer, "EFI holding off watchdog timer\n" );
-
- /* Restart this holdoff timer */
- start_timer_fixed ( timer, ( WATCHDOG_HOLDOFF_SECS * TICKS_PER_SEC ) );
-
- /* Reset watchdog timer */
- if ( ( efirc = bs->SetWatchdogTimer ( WATCHDOG_TIMEOUT_SECS,
- WATCHDOG_CODE, sizeof ( data ),
- data ) ) != 0 ) {
- rc = -EEFI ( efirc );
- DBGC ( timer, "EFI could not set watchdog timer: %s\n",
- strerror ( rc ) );
- return;
- }
-}
-
-/** Watchdog holdoff timer */
-struct retry_timer efi_watchdog = TIMER_INIT ( efi_watchdog_expired );
diff --git a/qemu/roms/ipxe/src/interface/efi/efi_wrap.c b/qemu/roms/ipxe/src/interface/efi/efi_wrap.c
deleted file mode 100644
index 2ea184e97..000000000
--- a/qemu/roms/ipxe/src/interface/efi/efi_wrap.c
+++ /dev/null
@@ -1,319 +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
- *
- * EFI image wrapping
- *
- */
-
-#include <string.h>
-#include <stdio.h>
-#include <errno.h>
-#include <ipxe/efi/efi.h>
-#include <ipxe/efi/Protocol/LoadedImage.h>
-#include <ipxe/efi/efi_wrap.h>
-
-/** EFI system table wrapper */
-static EFI_SYSTEM_TABLE efi_systab_wrapper;
-
-/** EFI boot services table wrapper */
-static EFI_BOOT_SERVICES efi_bs_wrapper;
-
-/** Colour for debug messages */
-#define colour &efi_systab_wrapper
-
-/**
- * Convert EFI status code to text
- *
- * @v efirc EFI status code
- * @ret text EFI status code text
- */
-static const char * efi_status ( EFI_STATUS efirc ) {
- static char buf[ 19 /* "0xXXXXXXXXXXXXXXXX" + NUL */ ];
-
- switch ( efirc ) {
- case EFI_SUCCESS : return "0";
- case EFI_LOAD_ERROR : return "LOAD_ERROR";
- case EFI_INVALID_PARAMETER : return "INVALID_PARAMETER";
- case EFI_UNSUPPORTED : return "UNSUPPORTED";
- case EFI_BAD_BUFFER_SIZE : return "BAD_BUFFER_SIZE";
- case EFI_BUFFER_TOO_SMALL : return "BUFFER_TOO_SMALL";
- case EFI_NOT_READY : return "NOT_READY";
- case EFI_DEVICE_ERROR : return "DEVICE_ERROR";
- case EFI_WRITE_PROTECTED : return "WRITE_PROTECTED";
- case EFI_OUT_OF_RESOURCES : return "OUT_OF_RESOURCES";
- case EFI_VOLUME_CORRUPTED : return "VOLUME_CORRUPTED";
- case EFI_VOLUME_FULL : return "VOLUME_FULL";
- case EFI_NO_MEDIA : return "NO_MEDIA";
- case EFI_MEDIA_CHANGED : return "MEDIA_CHANGED";
- case EFI_NOT_FOUND : return "NOT_FOUND";
- case EFI_ACCESS_DENIED : return "ACCESS_DENIED";
- case EFI_NO_RESPONSE : return "NO_RESPONSE";
- case EFI_NO_MAPPING : return "NO_MAPPING";
- case EFI_TIMEOUT : return "TIMEOUT";
- case EFI_NOT_STARTED : return "NOT_STARTED";
- case EFI_ALREADY_STARTED : return "ALREADY_STARTED";
- case EFI_ABORTED : return "ABORTED";
- case EFI_ICMP_ERROR : return "ICMP_ERROR";
- case EFI_TFTP_ERROR : return "TFTP_ERROR";
- case EFI_PROTOCOL_ERROR : return "PROTOCOL_ERROR";
- case EFI_INCOMPATIBLE_VERSION : return "INCOMPATIBLE_VERSION";
- case EFI_SECURITY_VIOLATION : return "SECURITY_VIOLATION";
- case EFI_CRC_ERROR : return "CRC_ERROR";
- case EFI_END_OF_MEDIA : return "END_OF_MEDIA";
- case EFI_END_OF_FILE : return "END_OF_FILE";
- case EFI_INVALID_LANGUAGE : return "INVALID_LANGUAGE";
- case EFI_COMPROMISED_DATA : return "COMPROMISED_DATA";
- case EFI_WARN_UNKNOWN_GLYPH : return "WARN_UNKNOWN_GLYPH";
- case EFI_WARN_DELETE_FAILURE : return "WARN_DELETE_FAILURE";
- case EFI_WARN_WRITE_FAILURE : return "WARN_WRITE_FAILURE";
- case EFI_WARN_BUFFER_TOO_SMALL : return "WARN_BUFFER_TOO_SMALL";
- case EFI_WARN_STALE_DATA : return "WARN_STALE_DATA";
- default:
- snprintf ( buf, sizeof ( buf ), "%#lx",
- ( unsigned long ) efirc );
- return buf;
- }
-}
-
-/**
- * Wrap HandleProtocol()
- *
- */
-static EFI_STATUS EFIAPI
-efi_handle_protocol_wrapper ( EFI_HANDLE handle, EFI_GUID *protocol,
- VOID **interface ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- void *retaddr = __builtin_return_address ( 0 );
- EFI_STATUS efirc;
-
- DBGC ( colour, "HandleProtocol ( %p %s, %s, ... ) ", handle,
- efi_handle_name ( handle ), efi_guid_ntoa ( protocol ) );
- efirc = bs->HandleProtocol ( handle, protocol, interface );
- DBGC ( colour, "= %s ( %p ) -> %p\n",
- efi_status ( efirc ), *interface, retaddr );
- return efirc;
-}
-
-/**
- * Wrap LocateHandle()
- *
- */
-static EFI_STATUS EFIAPI
-efi_locate_handle_wrapper ( EFI_LOCATE_SEARCH_TYPE search_type,
- EFI_GUID *protocol, VOID *search_key,
- UINTN *buffer_size, EFI_HANDLE *buffer ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- void *retaddr = __builtin_return_address ( 0 );
- EFI_STATUS efirc;
-
- DBGC ( colour, "LocateHandle ( %d, %s, ..., %zd, ... ) ", search_type,
- efi_guid_ntoa ( protocol ), ( ( size_t ) *buffer_size ) );
- efirc = bs->LocateHandle ( search_type, protocol, search_key,
- buffer_size, buffer );
- DBGC ( colour, "= %s ( %zd ) -> %p\n",
- efi_status ( efirc ), ( ( size_t ) *buffer_size ), retaddr );
- return efirc;
-}
-
-/**
- * Wrap LocateDevicePath()
- *
- */
-static EFI_STATUS EFIAPI
-efi_locate_device_path_wrapper ( EFI_GUID *protocol,
- EFI_DEVICE_PATH_PROTOCOL **device_path,
- EFI_HANDLE *device ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- void *retaddr = __builtin_return_address ( 0 );
- EFI_STATUS efirc;
-
- DBGC ( colour, "LocateDevicePath ( %s, %s, ... ) ",
- efi_guid_ntoa ( protocol ), efi_devpath_text ( *device_path ) );
- efirc = bs->LocateDevicePath ( protocol, device_path, device );
- DBGC ( colour, "= %s ( %p, ",
- efi_status ( efirc ), efi_devpath_text ( *device_path ) );
- DBGC ( colour, "%p %s ) -> %p\n",
- *device, efi_handle_name ( *device ), retaddr );
- return efirc;
-}
-
-/**
- * Wrap LoadImage()
- *
- */
-static EFI_STATUS EFIAPI
-efi_load_image_wrapper ( BOOLEAN boot_policy, EFI_HANDLE parent_image_handle,
- EFI_DEVICE_PATH_PROTOCOL *device_path,
- VOID *source_buffer, UINTN source_size,
- EFI_HANDLE *image_handle ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- void *retaddr = __builtin_return_address ( 0 );
- EFI_STATUS efirc;
-
- DBGC ( colour, "LoadImage ( %d, %p %s, ", boot_policy,
- parent_image_handle, efi_handle_name ( parent_image_handle ) );
- DBGC ( colour, "%s, %p, %#llx, ... ) ",
- efi_devpath_text ( device_path ), source_buffer,
- ( ( unsigned long long ) source_size ) );
- efirc = bs->LoadImage ( boot_policy, parent_image_handle, device_path,
- source_buffer, source_size, image_handle );
- DBGC ( colour, "= %s ( ", efi_status ( efirc ) );
- if ( efirc == 0 ) {
- DBGC ( colour, "%p %s ", *image_handle,
- efi_handle_name ( *image_handle ) );
- }
- DBGC ( colour, ") -> %p\n", retaddr );
-
- /* Wrap the new image */
- if ( efirc == 0 )
- efi_wrap ( *image_handle );
-
- return efirc;
-}
-
-/**
- * Wrap ExitBootServices()
- *
- */
-static EFI_STATUS EFIAPI
-efi_exit_boot_services_wrapper ( EFI_HANDLE image_handle, UINTN map_key ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- void *retaddr = __builtin_return_address ( 0 );
- EFI_STATUS efirc;
-
- DBGC ( colour, "ExitBootServices ( %p %s, %#llx ) ",
- image_handle, efi_handle_name ( image_handle ),
- ( ( unsigned long long ) map_key ) );
- efirc = bs->ExitBootServices ( image_handle, map_key );
- DBGC ( colour, "= %s -> %p\n", efi_status ( efirc ), retaddr );
- return efirc;
-}
-
-/**
- * Wrap OpenProtocol()
- *
- */
-static EFI_STATUS EFIAPI
-efi_open_protocol_wrapper ( EFI_HANDLE handle, EFI_GUID *protocol,
- VOID **interface, EFI_HANDLE agent_handle,
- EFI_HANDLE controller_handle, UINT32 attributes ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- void *retaddr = __builtin_return_address ( 0 );
- EFI_STATUS efirc;
-
- DBGC ( colour, "OpenProtocol ( %p %s, %s, ..., ", handle,
- efi_handle_name ( handle ), efi_guid_ntoa ( protocol ) );
- DBGC ( colour, "%p %s, ", agent_handle,
- efi_handle_name ( agent_handle ) );
- DBGC ( colour, "%p %s, %#x ) ", controller_handle,
- efi_handle_name ( controller_handle ), attributes );
- efirc = bs->OpenProtocol ( handle, protocol, interface, agent_handle,
- controller_handle, attributes );
- DBGC ( colour, "= %s ( %p ) -> %p\n",
- efi_status ( efirc ), *interface, retaddr );
- return efirc;
-}
-
-/**
- * Wrap LocateProtocol()
- *
- */
-static EFI_STATUS EFIAPI
-efi_locate_protocol_wrapper ( EFI_GUID *protocol, VOID *registration,
- VOID **interface ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- void *retaddr = __builtin_return_address ( 0 );
- EFI_STATUS efirc;
-
- DBGC ( colour, "LocateProtocol ( %s, %p, ... ) ",
- efi_guid_ntoa ( protocol ), registration );
- efirc = bs->LocateProtocol ( protocol, registration, interface );
- DBGC ( colour, "= %s ( %p ) -> %p\n",
- efi_status ( efirc ), *interface, retaddr );
- return efirc;
-}
-
-/**
- * Wrap the calls made by a loaded image
- *
- * @v handle Image handle
- */
- void efi_wrap ( EFI_HANDLE handle ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- union {
- EFI_LOADED_IMAGE_PROTOCOL *image;
- void *intf;
- } loaded;
- EFI_STATUS efirc;
- int rc;
-
- /* Do nothing unless debugging is enabled */
- if ( ! DBG_LOG )
- return;
-
- /* Populate table wrappers */
- memcpy ( &efi_systab_wrapper, efi_systab,
- sizeof ( efi_systab_wrapper ) );
- memcpy ( &efi_bs_wrapper, bs, sizeof ( efi_bs_wrapper ) );
- efi_systab_wrapper.BootServices = &efi_bs_wrapper;
- efi_bs_wrapper.HandleProtocol = efi_handle_protocol_wrapper;
- efi_bs_wrapper.LocateHandle = efi_locate_handle_wrapper;
- efi_bs_wrapper.LocateDevicePath = efi_locate_device_path_wrapper;
- efi_bs_wrapper.LoadImage = efi_load_image_wrapper;
- efi_bs_wrapper.ExitBootServices = efi_exit_boot_services_wrapper;
- efi_bs_wrapper.OpenProtocol = efi_open_protocol_wrapper;
- efi_bs_wrapper.LocateProtocol = efi_locate_protocol_wrapper;
-
- /* Open loaded image protocol */
- if ( ( efirc = bs->OpenProtocol ( handle,
- &efi_loaded_image_protocol_guid,
- &loaded.intf, efi_image_handle, NULL,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
- rc = -EEFI ( efirc );
- DBGC ( colour, "Could not get loaded image protocol for %p %s: "
- "%s\n", handle, efi_handle_name ( handle ),
- strerror ( rc ) );
- return;
- }
-
- /* Provide system table wrapper to image */
- loaded.image->SystemTable = &efi_systab_wrapper;
- DBGC ( colour, "Wrapped image %p %s at base %p has protocols:\n",
- handle, efi_handle_name ( handle ), loaded.image->ImageBase );
- DBGC_EFI_PROTOCOLS ( colour, handle );
- DBGC ( colour, "Parent image %p %s\n", loaded.image->ParentHandle,
- efi_handle_name ( loaded.image->ParentHandle ) );
- DBGC ( colour, "Device %p %s ", loaded.image->DeviceHandle,
- efi_handle_name ( loaded.image->DeviceHandle ) );
- DBGC ( colour, "file %p %s\n", loaded.image->FilePath,
- efi_devpath_text ( loaded.image->FilePath ) );
-
- /* Close loaded image protocol */
- bs->CloseProtocol ( handle, &efi_loaded_image_protocol_guid,
- efi_image_handle, NULL );
-}
diff --git a/qemu/roms/ipxe/src/interface/hyperv/vmbus.c b/qemu/roms/ipxe/src/interface/hyperv/vmbus.c
deleted file mode 100644
index 795929eae..000000000
--- a/qemu/roms/ipxe/src/interface/hyperv/vmbus.c
+++ /dev/null
@@ -1,1333 +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 (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 );
-
-/** @file
- *
- * Hyper-V virtual machine bus
- *
- */
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <byteswap.h>
-#include <ipxe/nap.h>
-#include <ipxe/malloc.h>
-#include <ipxe/iobuf.h>
-#include <ipxe/hyperv.h>
-#include <ipxe/vmbus.h>
-
-/** VMBus initial GPADL ID
- *
- * This is an opaque value with no meaning. The Linux kernel uses
- * 0xe1e10.
- */
-#define VMBUS_GPADL_MAGIC 0x18ae0000
-
-/**
- * Post message
- *
- * @v hv Hyper-V hypervisor
- * @v header Message header
- * @v len Length of message (including header)
- * @ret rc Return status code
- */
-static int vmbus_post_message ( struct hv_hypervisor *hv,
- const struct vmbus_message_header *header,
- size_t len ) {
- struct vmbus *vmbus = hv->vmbus;
- int rc;
-
- /* Post message */
- if ( ( rc = hv_post_message ( hv, VMBUS_MESSAGE_ID, VMBUS_MESSAGE_TYPE,
- header, len ) ) != 0 ) {
- DBGC ( vmbus, "VMBUS %p could not post message: %s\n",
- vmbus, strerror ( rc ) );
- return rc;
- }
-
- return 0;
-}
-
-/**
- * Post empty message
- *
- * @v hv Hyper-V hypervisor
- * @v type Message type
- * @ret rc Return status code
- */
-static int vmbus_post_empty_message ( struct hv_hypervisor *hv,
- unsigned int type ) {
- struct vmbus_message_header header = { .type = cpu_to_le32 ( type ) };
-
- return vmbus_post_message ( hv, &header, sizeof ( header ) );
-}
-
-/**
- * Wait for received message
- *
- * @v hv Hyper-V hypervisor
- * @ret rc Return status code
- */
-static int vmbus_wait_for_message ( struct hv_hypervisor *hv ) {
- struct vmbus *vmbus = hv->vmbus;
- int rc;
-
- /* Wait for message */
- if ( ( rc = hv_wait_for_message ( hv, VMBUS_MESSAGE_SINT ) ) != 0 ) {
- DBGC ( vmbus, "VMBUS %p failed waiting for message: %s\n",
- vmbus, strerror ( rc ) );
- return rc;
- }
-
- /* Sanity check */
- if ( hv->message->received.type != cpu_to_le32 ( VMBUS_MESSAGE_TYPE ) ){
- DBGC ( vmbus, "VMBUS %p invalid message type %d\n",
- vmbus, le32_to_cpu ( hv->message->received.type ) );
- return -EINVAL;
- }
-
- return 0;
-}
-
-/**
- * Initiate contact
- *
- * @v hv Hyper-V hypervisor
- * @v raw VMBus protocol (raw) version
- * @ret rc Return status code
- */
-static int vmbus_initiate_contact ( struct hv_hypervisor *hv,
- unsigned int raw ) {
- struct vmbus *vmbus = hv->vmbus;
- const struct vmbus_version_response *version = &vmbus->message->version;
- struct vmbus_initiate_contact initiate;
- int rc;
-
- /* Construct message */
- memset ( &initiate, 0, sizeof ( initiate ) );
- initiate.header.type = cpu_to_le32 ( VMBUS_INITIATE_CONTACT );
- initiate.version.raw = cpu_to_le32 ( raw );
- initiate.intr = virt_to_phys ( vmbus->intr );
- initiate.monitor_in = virt_to_phys ( vmbus->monitor_in );
- initiate.monitor_out = virt_to_phys ( vmbus->monitor_out );
-
- /* Post message */
- if ( ( rc = vmbus_post_message ( hv, &initiate.header,
- sizeof ( initiate ) ) ) != 0 )
- return rc;
-
- /* Wait for response */
- if ( ( rc = vmbus_wait_for_message ( hv ) ) != 0 )
- return rc;
-
- /* Check response */
- if ( version->header.type != cpu_to_le32 ( VMBUS_VERSION_RESPONSE ) ) {
- DBGC ( vmbus, "VMBUS %p unexpected version response type %d\n",
- vmbus, le32_to_cpu ( version->header.type ) );
- return -EPROTO;
- }
- if ( ! version->supported ) {
- DBGC ( vmbus, "VMBUS %p requested version not supported\n",
- vmbus );
- return -ENOTSUP;
- }
- if ( version->version.raw != cpu_to_le32 ( raw ) ) {
- DBGC ( vmbus, "VMBUS %p unexpected version %d.%d\n",
- vmbus, le16_to_cpu ( version->version.major ),
- le16_to_cpu ( version->version.minor ) );
- return -EPROTO;
- }
-
- DBGC ( vmbus, "VMBUS %p initiated contact using version %d.%d\n",
- vmbus, le16_to_cpu ( version->version.major ),
- le16_to_cpu ( version->version.minor ) );
- return 0;
-}
-
-/**
- * Terminate contact
- *
- * @v hv Hyper-V hypervisor
- * @ret rc Return status code
- */
-static int vmbus_unload ( struct hv_hypervisor *hv ) {
- struct vmbus *vmbus = hv->vmbus;
- const struct vmbus_message_header *header = &vmbus->message->header;
- int rc;
-
- /* Post message */
- if ( ( rc = vmbus_post_empty_message ( hv, VMBUS_UNLOAD ) ) != 0 )
- return rc;
-
- /* Wait for response */
- if ( ( rc = vmbus_wait_for_message ( hv ) ) != 0 )
- return rc;
-
- /* Check response */
- if ( header->type != cpu_to_le32 ( VMBUS_UNLOAD_RESPONSE ) ) {
- DBGC ( vmbus, "VMBUS %p unexpected unload response type %d\n",
- vmbus, le32_to_cpu ( header->type ) );
- return -EPROTO;
- }
-
- return 0;
-}
-
-/**
- * Negotiate protocol version
- *
- * @v hv Hyper-V hypervisor
- * @ret rc Return status code
- */
-static int vmbus_negotiate_version ( struct hv_hypervisor *hv ) {
- int rc;
-
- /* We require the ability to disconnect from and reconnect to
- * VMBus; if we don't have this then there is no (viable) way
- * for a loaded operating system to continue to use any VMBus
- * devices. (There is also a small but non-zero risk that the
- * host will continue to write to our interrupt and monitor
- * pages, since the VMBUS_UNLOAD message in earlier versions
- * is essentially a no-op.)
- *
- * This requires us to ensure that the host supports protocol
- * version 3.0 (VMBUS_VERSION_WIN8_1). However, we can't
- * actually _use_ protocol version 3.0, since doing so causes
- * an iSCSI-booted Windows Server 2012 R2 VM to crash due to a
- * NULL pointer dereference in vmbus.sys.
- *
- * To work around this problem, we first ensure that we can
- * connect using protocol v3.0, then disconnect and reconnect
- * using the oldest known protocol.
- */
-
- /* Initiate contact to check for required protocol support */
- if ( ( rc = vmbus_initiate_contact ( hv, VMBUS_VERSION_WIN8_1 ) ) != 0 )
- return rc;
-
- /* Terminate contact */
- if ( ( rc = vmbus_unload ( hv ) ) != 0 )
- return rc;
-
- /* Reinitiate contact using the oldest known protocol version */
- if ( ( rc = vmbus_initiate_contact ( hv, VMBUS_VERSION_WS2008 ) ) != 0 )
- return rc;
-
- return 0;
-}
-
-/**
- * Establish GPA descriptor list
- *
- * @v vmdev VMBus device
- * @v data Data buffer
- * @v len Length of data buffer
- * @ret gpadl GPADL ID, or negative error
- */
-int vmbus_establish_gpadl ( struct vmbus_device *vmdev, userptr_t data,
- size_t len ) {
- struct hv_hypervisor *hv = vmdev->hv;
- struct vmbus *vmbus = hv->vmbus;
- physaddr_t addr = user_to_phys ( data, 0 );
- unsigned int pfn_count = hv_pfn_count ( addr, len );
- struct {
- struct vmbus_gpadl_header gpadlhdr;
- struct vmbus_gpa_range range;
- uint64_t pfn[pfn_count];
- } __attribute__ (( packed )) gpadlhdr;
- const struct vmbus_gpadl_created *created = &vmbus->message->created;
- static unsigned int gpadl = VMBUS_GPADL_MAGIC;
- unsigned int i;
- int rc;
-
- /* Allocate GPADL ID */
- gpadl++;
-
- /* Construct message */
- memset ( &gpadlhdr, 0, sizeof ( gpadlhdr ) );
- gpadlhdr.gpadlhdr.header.type = cpu_to_le32 ( VMBUS_GPADL_HEADER );
- gpadlhdr.gpadlhdr.channel = cpu_to_le32 ( vmdev->channel );
- gpadlhdr.gpadlhdr.gpadl = cpu_to_le32 ( gpadl );
- gpadlhdr.gpadlhdr.range_len =
- cpu_to_le16 ( ( sizeof ( gpadlhdr.range ) +
- sizeof ( gpadlhdr.pfn ) ) );
- gpadlhdr.gpadlhdr.range_count = cpu_to_le16 ( 1 );
- gpadlhdr.range.len = cpu_to_le32 ( len );
- gpadlhdr.range.offset = cpu_to_le32 ( addr & ( PAGE_SIZE - 1 ) );
- for ( i = 0 ; i < pfn_count ; i++ )
- gpadlhdr.pfn[i] = ( ( addr / PAGE_SIZE ) + i );
-
- /* Post message */
- if ( ( rc = vmbus_post_message ( hv, &gpadlhdr.gpadlhdr.header,
- sizeof ( gpadlhdr ) ) ) != 0 )
- return rc;
-
- /* Wait for response */
- if ( ( rc = vmbus_wait_for_message ( hv ) ) != 0 )
- return rc;
-
- /* Check response */
- if ( created->header.type != cpu_to_le32 ( VMBUS_GPADL_CREATED ) ) {
- DBGC ( vmdev, "VMBUS %s unexpected GPADL response type %d\n",
- vmdev->dev.name, le32_to_cpu ( created->header.type ) );
- return -EPROTO;
- }
- if ( created->channel != cpu_to_le32 ( vmdev->channel ) ) {
- DBGC ( vmdev, "VMBUS %s unexpected GPADL channel %d\n",
- vmdev->dev.name, le32_to_cpu ( created->channel ) );
- return -EPROTO;
- }
- if ( created->gpadl != cpu_to_le32 ( gpadl ) ) {
- DBGC ( vmdev, "VMBUS %s unexpected GPADL ID %#08x\n",
- vmdev->dev.name, le32_to_cpu ( created->gpadl ) );
- return -EPROTO;
- }
- if ( created->status != 0 ) {
- DBGC ( vmdev, "VMBUS %s GPADL creation failed: %#08x\n",
- vmdev->dev.name, le32_to_cpu ( created->status ) );
- return -EPROTO;
- }
-
- DBGC ( vmdev, "VMBUS %s GPADL %#08x is [%08lx,%08lx)\n",
- vmdev->dev.name, gpadl, addr, ( addr + len ) );
- return gpadl;
-}
-
-/**
- * Tear down GPA descriptor list
- *
- * @v vmdev VMBus device
- * @v gpadl GPADL ID
- * @ret rc Return status code
- */
-int vmbus_gpadl_teardown ( struct vmbus_device *vmdev, unsigned int gpadl ) {
- struct hv_hypervisor *hv = vmdev->hv;
- struct vmbus *vmbus = hv->vmbus;
- struct vmbus_gpadl_teardown teardown;
- const struct vmbus_gpadl_torndown *torndown = &vmbus->message->torndown;
- int rc;
-
- /* Construct message */
- memset ( &teardown, 0, sizeof ( teardown ) );
- teardown.header.type = cpu_to_le32 ( VMBUS_GPADL_TEARDOWN );
- teardown.channel = cpu_to_le32 ( vmdev->channel );
- teardown.gpadl = cpu_to_le32 ( gpadl );
-
- /* Post message */
- if ( ( rc = vmbus_post_message ( hv, &teardown.header,
- sizeof ( teardown ) ) ) != 0 )
- return rc;
-
- /* Wait for response */
- if ( ( rc = vmbus_wait_for_message ( hv ) ) != 0 )
- return rc;
-
- /* Check response */
- if ( torndown->header.type != cpu_to_le32 ( VMBUS_GPADL_TORNDOWN ) ) {
- DBGC ( vmdev, "VMBUS %s unexpected GPADL response type %d\n",
- vmdev->dev.name, le32_to_cpu ( torndown->header.type ) );
- return -EPROTO;
- }
- if ( torndown->gpadl != cpu_to_le32 ( gpadl ) ) {
- DBGC ( vmdev, "VMBUS %s unexpected GPADL ID %#08x\n",
- vmdev->dev.name, le32_to_cpu ( torndown->gpadl ) );
- return -EPROTO;
- }
-
- return 0;
-}
-
-/**
- * Open VMBus channel
- *
- * @v vmdev VMBus device
- * @v op Channel operations
- * @v out_len Outbound ring buffer length
- * @v in_len Inbound ring buffer length
- * @v mtu Maximum expected data packet length (including headers)
- * @ret rc Return status code
- *
- * Both outbound and inbound ring buffer lengths must be a power of
- * two and a multiple of PAGE_SIZE. The requirement to be a power of
- * two is a policy decision taken to simplify the ring buffer indexing
- * logic.
- */
-int vmbus_open ( struct vmbus_device *vmdev,
- struct vmbus_channel_operations *op,
- size_t out_len, size_t in_len, size_t mtu ) {
- struct hv_hypervisor *hv = vmdev->hv;
- struct vmbus *vmbus = hv->vmbus;
- struct vmbus_open_channel open;
- const struct vmbus_open_channel_result *opened =
- &vmbus->message->opened;
- size_t len;
- void *ring;
- void *packet;
- int gpadl;
- uint32_t open_id;
- int rc;
-
- /* Sanity checks */
- assert ( ( out_len % PAGE_SIZE ) == 0 );
- assert ( ( out_len & ( out_len - 1 ) ) == 0 );
- assert ( ( in_len % PAGE_SIZE ) == 0 );
- assert ( ( in_len & ( in_len - 1 ) ) == 0 );
- assert ( mtu >= ( sizeof ( struct vmbus_packet_header ) +
- sizeof ( struct vmbus_packet_footer ) ) );
-
- /* Allocate packet buffer */
- packet = malloc ( mtu );
- if ( ! packet ) {
- rc = -ENOMEM;
- goto err_alloc_packet;
- }
-
- /* Allocate ring buffer */
- len = ( sizeof ( *vmdev->out ) + out_len +
- sizeof ( *vmdev->in ) + in_len );
- assert ( ( len % PAGE_SIZE ) == 0 );
- ring = malloc_dma ( len, PAGE_SIZE );
- if ( ! ring ) {
- rc = -ENOMEM;
- goto err_alloc_ring;
- }
- memset ( ring, 0, len );
-
- /* Establish GPADL for ring buffer */
- gpadl = vmbus_establish_gpadl ( vmdev, virt_to_user ( ring ), len );
- if ( gpadl < 0 ) {
- rc = gpadl;
- goto err_establish;
- }
-
- /* Construct message */
- memset ( &open, 0, sizeof ( open ) );
- open.header.type = cpu_to_le32 ( VMBUS_OPEN_CHANNEL );
- open.channel = cpu_to_le32 ( vmdev->channel );
- open_id = random();
- open.id = open_id; /* Opaque random value: endianness irrelevant */
- open.gpadl = cpu_to_le32 ( gpadl );
- open.out_pages = ( ( sizeof ( *vmdev->out ) / PAGE_SIZE ) +
- ( out_len / PAGE_SIZE ) );
-
- /* Post message */
- if ( ( rc = vmbus_post_message ( hv, &open.header,
- sizeof ( open ) ) ) != 0 )
- return rc;
-
- /* Wait for response */
- if ( ( rc = vmbus_wait_for_message ( hv ) ) != 0 )
- return rc;
-
- /* Check response */
- if ( opened->header.type != cpu_to_le32 ( VMBUS_OPEN_CHANNEL_RESULT ) ){
- DBGC ( vmdev, "VMBUS %s unexpected open response type %d\n",
- vmdev->dev.name, le32_to_cpu ( opened->header.type ) );
- return -EPROTO;
- }
- if ( opened->channel != cpu_to_le32 ( vmdev->channel ) ) {
- DBGC ( vmdev, "VMBUS %s unexpected opened channel %#08x\n",
- vmdev->dev.name, le32_to_cpu ( opened->channel ) );
- return -EPROTO;
- }
- if ( opened->id != open_id /* Non-endian */ ) {
- DBGC ( vmdev, "VMBUS %s unexpected open ID %#08x\n",
- vmdev->dev.name, le32_to_cpu ( opened->id ) );
- return -EPROTO;
- }
- if ( opened->status != 0 ) {
- DBGC ( vmdev, "VMBUS %s open failed: %#08x\n",
- vmdev->dev.name, le32_to_cpu ( opened->status ) );
- return -EPROTO;
- }
-
- /* Store channel parameters */
- vmdev->out_len = out_len;
- vmdev->in_len = in_len;
- vmdev->out = ring;
- vmdev->in = ( ring + sizeof ( *vmdev->out ) + out_len );
- vmdev->gpadl = gpadl;
- vmdev->op = op;
- vmdev->mtu = mtu;
- vmdev->packet = packet;
-
- DBGC ( vmdev, "VMBUS %s channel GPADL %#08x ring "
- "[%#08lx,%#08lx,%#08lx)\n", vmdev->dev.name, vmdev->gpadl,
- virt_to_phys ( vmdev->out ), virt_to_phys ( vmdev->in ),
- ( virt_to_phys ( vmdev->out ) + len ) );
- return 0;
-
- vmbus_gpadl_teardown ( vmdev, vmdev->gpadl );
- err_establish:
- free_dma ( ring, len );
- err_alloc_ring:
- free ( packet );
- err_alloc_packet:
- return rc;
-}
-
-/**
- * Close VMBus channel
- *
- * @v vmdev VMBus device
- */
-void vmbus_close ( struct vmbus_device *vmdev ) {
- struct hv_hypervisor *hv = vmdev->hv;
- struct vmbus_close_channel close;
- size_t len;
- int rc;
-
- /* Construct message */
- memset ( &close, 0, sizeof ( close ) );
- close.header.type = cpu_to_le32 ( VMBUS_CLOSE_CHANNEL );
- close.channel = cpu_to_le32 ( vmdev->channel );
-
- /* Post message */
- if ( ( rc = vmbus_post_message ( hv, &close.header,
- sizeof ( close ) ) ) != 0 ) {
- DBGC ( vmdev, "VMBUS %s failed to close: %s\n",
- vmdev->dev.name, strerror ( rc ) );
- /* Continue to attempt to tear down GPADL, so that our
- * memory is no longer accessible by the remote VM.
- */
- }
-
- /* Tear down GPADL */
- if ( ( rc = vmbus_gpadl_teardown ( vmdev,
- vmdev->gpadl ) ) != 0 ) {
- DBGC ( vmdev, "VMBUS %s failed to tear down channel GPADL: "
- "%s\n", vmdev->dev.name, strerror ( rc ) );
- /* We can't prevent the remote VM from continuing to
- * access this memory, so leak it.
- */
- return;
- }
-
- /* Free ring buffer */
- len = ( sizeof ( *vmdev->out ) + vmdev->out_len +
- sizeof ( *vmdev->in ) + vmdev->in_len );
- free_dma ( vmdev->out, len );
- vmdev->out = NULL;
- vmdev->in = NULL;
-
- /* Free packet buffer */
- free ( vmdev->packet );
- vmdev->packet = NULL;
-
- DBGC ( vmdev, "VMBUS %s closed\n", vmdev->dev.name );
-}
-
-/**
- * Signal channel via monitor page
- *
- * @v vmdev VMBus device
- */
-static void vmbus_signal_monitor ( struct vmbus_device *vmdev ) {
- struct hv_hypervisor *hv = vmdev->hv;
- struct vmbus *vmbus = hv->vmbus;
- struct hv_monitor_trigger *trigger;
- unsigned int group;
- unsigned int bit;
-
- /* Set bit in monitor trigger group */
- group = ( vmdev->monitor / ( 8 * sizeof ( trigger->pending ) ));
- bit = ( vmdev->monitor % ( 8 * sizeof ( trigger->pending ) ) );
- trigger = &vmbus->monitor_out->trigger[group];
- hv_set_bit ( trigger, bit );
-}
-
-/**
- * Signal channel via hypervisor event
- *
- * @v vmdev VMBus device
- */
-static void vmbus_signal_event ( struct vmbus_device *vmdev ) {
- struct hv_hypervisor *hv = vmdev->hv;
- int rc;
-
- /* Signal hypervisor event */
- if ( ( rc = hv_signal_event ( hv, VMBUS_EVENT_ID, 0 ) ) != 0 ) {
- DBGC ( vmdev, "VMBUS %s could not signal event: %s\n",
- vmdev->dev.name, strerror ( rc ) );
- return;
- }
-}
-
-/**
- * Fill outbound ring buffer
- *
- * @v vmdev VMBus device
- * @v prod Producer index
- * @v data Data
- * @v len Length
- * @ret prod New producer index
- *
- * The caller must ensure that there is sufficient space in the ring
- * buffer.
- */
-static size_t vmbus_produce ( struct vmbus_device *vmdev, size_t prod,
- const void *data, size_t len ) {
- size_t first;
- size_t second;
-
- /* Determine fragment lengths */
- first = ( vmdev->out_len - prod );
- if ( first > len )
- first = len;
- second = ( len - first );
-
- /* Copy fragment(s) */
- memcpy ( &vmdev->out->data[prod], data, first );
- if ( second )
- memcpy ( &vmdev->out->data[0], ( data + first ), second );
-
- return ( ( prod + len ) & ( vmdev->out_len - 1 ) );
-}
-
-/**
- * Consume inbound ring buffer
- *
- * @v vmdev VMBus device
- * @v cons Consumer index
- * @v data Data buffer, or NULL
- * @v len Length to consume
- * @ret cons New consumer index
- */
-static size_t vmbus_consume ( struct vmbus_device *vmdev, size_t cons,
- void *data, size_t len ) {
- size_t first;
- size_t second;
-
- /* Determine fragment lengths */
- first = ( vmdev->in_len - cons );
- if ( first > len )
- first = len;
- second = ( len - first );
-
- /* Copy fragment(s) */
- memcpy ( data, &vmdev->in->data[cons], first );
- if ( second )
- memcpy ( ( data + first ), &vmdev->in->data[0], second );
-
- return ( ( cons + len ) & ( vmdev->in_len - 1 ) );
-}
-
-/**
- * Send packet via ring buffer
- *
- * @v vmdev VMBus device
- * @v header Packet header
- * @v data Data
- * @v len Length of data
- * @ret rc Return status code
- *
- * Send a packet via the outbound ring buffer. All fields in the
- * packet header must be filled in, with the exception of the total
- * packet length.
- */
-static int vmbus_send ( struct vmbus_device *vmdev,
- struct vmbus_packet_header *header,
- const void *data, size_t len ) {
- struct hv_hypervisor *hv = vmdev->hv;
- struct vmbus *vmbus = hv->vmbus;
- static uint8_t padding[ 8 - 1 ];
- struct vmbus_packet_footer footer;
- size_t header_len;
- size_t pad_len;
- size_t footer_len;
- size_t ring_len;
- size_t cons;
- size_t prod;
- size_t old_prod;
- size_t fill;
-
- /* Sanity check */
- assert ( vmdev->out != NULL );
-
- /* Calculate lengths */
- header_len = ( le16_to_cpu ( header->hdr_qlen ) * 8 );
- pad_len = ( ( -len ) & ( 8 - 1 ) );
- footer_len = sizeof ( footer );
- ring_len = ( header_len + len + pad_len + footer_len );
-
- /* Check that we have enough room in the outbound ring buffer */
- cons = le32_to_cpu ( vmdev->out->cons );
- prod = le32_to_cpu ( vmdev->out->prod );
- old_prod = prod;
- fill = ( ( prod - cons ) & ( vmdev->out_len - 1 ) );
- if ( ( fill + ring_len ) >= vmdev->out_len ) {
- DBGC ( vmdev, "VMBUS %s ring buffer full\n", vmdev->dev.name );
- return -ENOBUFS;
- }
-
- /* Complete header */
- header->qlen = cpu_to_le16 ( ( ring_len - footer_len ) / 8 );
-
- /* Construct footer */
- footer.reserved = 0;
- footer.prod = vmdev->out->prod;
-
- /* Copy packet to buffer */
- DBGC2 ( vmdev, "VMBUS %s sending:\n", vmdev->dev.name );
- DBGC2_HDA ( vmdev, prod, header, header_len );
- prod = vmbus_produce ( vmdev, prod, header, header_len );
- DBGC2_HDA ( vmdev, prod, data, len );
- prod = vmbus_produce ( vmdev, prod, data, len );
- prod = vmbus_produce ( vmdev, prod, padding, pad_len );
- DBGC2_HDA ( vmdev, prod, &footer, sizeof ( footer ) );
- prod = vmbus_produce ( vmdev, prod, &footer, sizeof ( footer ) );
- assert ( ( ( prod - old_prod ) & ( vmdev->out_len - 1 ) ) == ring_len );
-
- /* Update producer index */
- wmb();
- vmdev->out->prod = cpu_to_le32 ( prod );
-
- /* Return if we do not need to signal the host. This follows
- * the logic of hv_need_to_signal() in the Linux driver.
- */
- mb();
- if ( vmdev->out->intr_mask )
- return 0;
- rmb();
- cons = le32_to_cpu ( vmdev->out->cons );
- if ( cons != old_prod )
- return 0;
-
- /* Set channel bit in interrupt page */
- hv_set_bit ( vmbus->intr->out, vmdev->channel );
-
- /* Signal the host */
- vmdev->signal ( vmdev );
-
- return 0;
-}
-
-/**
- * Send control packet via ring buffer
- *
- * @v vmdev VMBus device
- * @v xid Transaction ID (or zero to not request completion)
- * @v data Data
- * @v len Length of data
- * @ret rc Return status code
- *
- * Send data using a VMBUS_DATA_INBAND packet.
- */
-int vmbus_send_control ( struct vmbus_device *vmdev, uint64_t xid,
- const void *data, size_t len ) {
- struct vmbus_packet_header *header = vmdev->packet;
-
- /* Construct header in packet buffer */
- assert ( header != NULL );
- header->type = cpu_to_le16 ( VMBUS_DATA_INBAND );
- header->hdr_qlen = cpu_to_le16 ( sizeof ( *header ) / 8 );
- header->flags = ( xid ?
- cpu_to_le16 ( VMBUS_COMPLETION_REQUESTED ) : 0 );
- header->xid = xid; /* Non-endian */
-
- return vmbus_send ( vmdev, header, data, len );
-}
-
-/**
- * Send data packet via ring buffer
- *
- * @v vmdev VMBus device
- * @v xid Transaction ID
- * @v data Data
- * @v len Length of data
- * @v iobuf I/O buffer
- * @ret rc Return status code
- *
- * Send data using a VMBUS_DATA_GPA_DIRECT packet. The caller is
- * responsible for ensuring that the I/O buffer remains untouched
- * until the corresponding completion has been received.
- */
-int vmbus_send_data ( struct vmbus_device *vmdev, uint64_t xid,
- const void *data, size_t len, struct io_buffer *iobuf ) {
- physaddr_t addr = virt_to_phys ( iobuf->data );
- unsigned int pfn_count = hv_pfn_count ( addr, iob_len ( iobuf ) );
- struct {
- struct vmbus_gpa_direct_header gpa;
- struct vmbus_gpa_range range;
- uint64_t pfn[pfn_count];
- } __attribute__ (( packed )) *header = vmdev->packet;
- unsigned int i;
-
- /* Sanity check */
- assert ( header != NULL );
- assert ( sizeof ( *header ) <= vmdev->mtu );
-
- /* Construct header in packet buffer */
- header->gpa.header.type = cpu_to_le16 ( VMBUS_DATA_GPA_DIRECT );
- header->gpa.header.hdr_qlen = cpu_to_le16 ( sizeof ( *header ) / 8 );
- header->gpa.header.flags = cpu_to_le16 ( VMBUS_COMPLETION_REQUESTED );
- header->gpa.header.xid = xid; /* Non-endian */
- header->gpa.range_count = 1;
- header->range.len = cpu_to_le32 ( iob_len ( iobuf ) );
- header->range.offset = cpu_to_le32 ( addr & ( PAGE_SIZE - 1 ) );
- for ( i = 0 ; i < pfn_count ; i++ )
- header->pfn[i] = ( ( addr / PAGE_SIZE ) + i );
-
- return vmbus_send ( vmdev, &header->gpa.header, data, len );
-}
-
-/**
- * Send completion packet via ring buffer
- *
- * @v vmdev VMBus device
- * @v xid Transaction ID
- * @v data Data
- * @v len Length of data
- * @ret rc Return status code
- *
- * Send data using a VMBUS_COMPLETION packet.
- */
-int vmbus_send_completion ( struct vmbus_device *vmdev, uint64_t xid,
- const void *data, size_t len ) {
- struct vmbus_packet_header *header = vmdev->packet;
-
- /* Construct header in packet buffer */
- assert ( header != NULL );
- header->type = cpu_to_le16 ( VMBUS_COMPLETION );
- header->hdr_qlen = cpu_to_le16 ( sizeof ( *header ) / 8 );
- header->flags = 0;
- header->xid = xid; /* Non-endian */
-
- return vmbus_send ( vmdev, header, data, len );
-}
-
-/**
- * Send cancellation packet via ring buffer
- *
- * @v vmdev VMBus device
- * @v xid Transaction ID
- * @ret rc Return status code
- *
- * Send data using a VMBUS_CANCELLATION packet.
- */
-int vmbus_send_cancellation ( struct vmbus_device *vmdev, uint64_t xid ) {
- struct vmbus_packet_header *header = vmdev->packet;
-
- /* Construct header in packet buffer */
- assert ( header != NULL );
- header->type = cpu_to_le16 ( VMBUS_CANCELLATION );
- header->hdr_qlen = cpu_to_le16 ( sizeof ( *header ) / 8 );
- header->flags = 0;
- header->xid = xid; /* Non-endian */
-
- return vmbus_send ( vmdev, header, NULL, 0 );
-}
-
-/**
- * Get transfer page set from pageset ID
- *
- * @v vmdev VMBus device
- * @v pageset Page set ID (in protocol byte order)
- * @ret pages Page set, or NULL if not found
- */
-static struct vmbus_xfer_pages * vmbus_xfer_pages ( struct vmbus_device *vmdev,
- uint16_t pageset ) {
- struct vmbus_xfer_pages *pages;
-
- /* Locate page set */
- list_for_each_entry ( pages, &vmdev->pages, list ) {
- if ( pages->pageset == pageset )
- return pages;
- }
-
- DBGC ( vmdev, "VMBUS %s unrecognised page set ID %#04x\n",
- vmdev->dev.name, le16_to_cpu ( pageset ) );
- return NULL;
-}
-
-/**
- * Construct I/O buffer list from transfer pages
- *
- * @v vmdev VMBus device
- * @v header Transfer page header
- * @v list I/O buffer list to populate
- * @ret rc Return status code
- */
-static int vmbus_xfer_page_iobufs ( struct vmbus_device *vmdev,
- struct vmbus_packet_header *header,
- struct list_head *list ) {
- struct vmbus_xfer_page_header *page_header =
- container_of ( header, struct vmbus_xfer_page_header, header );
- struct vmbus_xfer_pages *pages;
- struct io_buffer *iobuf;
- struct io_buffer *tmp;
- size_t len;
- size_t offset;
- unsigned int range_count;
- unsigned int i;
- int rc;
-
- /* Sanity check */
- assert ( header->type == cpu_to_le16 ( VMBUS_DATA_XFER_PAGES ) );
-
- /* Locate page set */
- pages = vmbus_xfer_pages ( vmdev, page_header->pageset );
- if ( ! pages ) {
- rc = -ENOENT;
- goto err_pages;
- }
-
- /* Allocate and populate I/O buffers */
- range_count = le32_to_cpu ( page_header->range_count );
- for ( i = 0 ; i < range_count ; i++ ) {
-
- /* Parse header */
- len = le32_to_cpu ( page_header->range[i].len );
- offset = le32_to_cpu ( page_header->range[i].offset );
-
- /* Allocate I/O buffer */
- iobuf = alloc_iob ( len );
- if ( ! iobuf ) {
- DBGC ( vmdev, "VMBUS %s could not allocate %zd-byte "
- "I/O buffer\n", vmdev->dev.name, len );
- rc = -ENOMEM;
- goto err_alloc;
- }
-
- /* Add I/O buffer to list */
- list_add ( &iobuf->list, list );
-
- /* Populate I/O buffer */
- if ( ( rc = pages->op->copy ( pages, iob_put ( iobuf, len ),
- offset, len ) ) != 0 ) {
- DBGC ( vmdev, "VMBUS %s could not populate I/O buffer "
- "range [%zd,%zd): %s\n",
- vmdev->dev.name, offset, len, strerror ( rc ) );
- goto err_copy;
- }
- }
-
- return 0;
-
- err_copy:
- err_alloc:
- list_for_each_entry_safe ( iobuf, tmp, list, list ) {
- list_del ( &iobuf->list );
- free_iob ( iobuf );
- }
- err_pages:
- return rc;
-}
-
-/**
- * Poll ring buffer
- *
- * @v vmdev VMBus device
- * @ret rc Return status code
- */
-int vmbus_poll ( struct vmbus_device *vmdev ) {
- struct vmbus_packet_header *header = vmdev->packet;
- struct list_head list;
- void *data;
- size_t header_len;
- size_t len;
- size_t footer_len;
- size_t ring_len;
- size_t cons;
- size_t old_cons;
- uint64_t xid;
- int rc;
-
- /* Sanity checks */
- assert ( vmdev->packet != NULL );
- assert ( vmdev->in != NULL );
-
- /* Return immediately if buffer is empty */
- if ( ! vmbus_has_data ( vmdev ) )
- return 0;
- cons = le32_to_cpu ( vmdev->in->cons );
- old_cons = cons;
-
- /* Consume (start of) header */
- cons = vmbus_consume ( vmdev, cons, header, sizeof ( *header ) );
-
- /* Parse and sanity check header */
- header_len = ( le16_to_cpu ( header->hdr_qlen ) * 8 );
- if ( header_len < sizeof ( *header ) ) {
- DBGC ( vmdev, "VMBUS %s received underlength header (%zd "
- "bytes)\n", vmdev->dev.name, header_len );
- return -EINVAL;
- }
- len = ( ( le16_to_cpu ( header->qlen ) * 8 ) - header_len );
- footer_len = sizeof ( struct vmbus_packet_footer );
- ring_len = ( header_len + len + footer_len );
- if ( ring_len > vmdev->mtu ) {
- DBGC ( vmdev, "VMBUS %s received overlength packet (%zd "
- "bytes)\n", vmdev->dev.name, ring_len );
- return -ERANGE;
- }
- xid = le64_to_cpu ( header->xid );
-
- /* Consume remainder of packet */
- cons = vmbus_consume ( vmdev, cons,
- ( ( ( void * ) header ) + sizeof ( *header ) ),
- ( ring_len - sizeof ( *header ) ) );
- DBGC2 ( vmdev, "VMBUS %s received:\n", vmdev->dev.name );
- DBGC2_HDA ( vmdev, old_cons, header, ring_len );
- assert ( ( ( cons - old_cons ) & ( vmdev->in_len - 1 ) ) == ring_len );
-
- /* Allocate I/O buffers, if applicable */
- INIT_LIST_HEAD ( &list );
- if ( header->type == cpu_to_le16 ( VMBUS_DATA_XFER_PAGES ) ) {
- if ( ( rc = vmbus_xfer_page_iobufs ( vmdev, header,
- &list ) ) != 0 )
- return rc;
- }
-
- /* Update producer index */
- rmb();
- vmdev->in->cons = cpu_to_le32 ( cons );
-
- /* Handle packet */
- data = ( ( ( void * ) header ) + header_len );
- switch ( header->type ) {
-
- case cpu_to_le16 ( VMBUS_DATA_INBAND ) :
- if ( ( rc = vmdev->op->recv_control ( vmdev, xid, data,
- len ) ) != 0 ) {
- DBGC ( vmdev, "VMBUS %s could not handle control "
- "packet: %s\n",
- vmdev->dev.name, strerror ( rc ) );
- return rc;
- }
- break;
-
- case cpu_to_le16 ( VMBUS_DATA_XFER_PAGES ) :
- if ( ( rc = vmdev->op->recv_data ( vmdev, xid, data, len,
- &list ) ) != 0 ) {
- DBGC ( vmdev, "VMBUS %s could not handle data packet: "
- "%s\n", vmdev->dev.name, strerror ( rc ) );
- return rc;
- }
- break;
-
- case cpu_to_le16 ( VMBUS_COMPLETION ) :
- if ( ( rc = vmdev->op->recv_completion ( vmdev, xid, data,
- len ) ) != 0 ) {
- DBGC ( vmdev, "VMBUS %s could not handle completion: "
- "%s\n", vmdev->dev.name, strerror ( rc ) );
- return rc;
- }
- break;
-
- case cpu_to_le16 ( VMBUS_CANCELLATION ) :
- if ( ( rc = vmdev->op->recv_cancellation ( vmdev, xid ) ) != 0){
- DBGC ( vmdev, "VMBUS %s could not handle cancellation: "
- "%s\n", vmdev->dev.name, strerror ( rc ) );
- return rc;
- }
- break;
-
- default:
- DBGC ( vmdev, "VMBUS %s unknown packet type %d\n",
- vmdev->dev.name, le16_to_cpu ( header->type ) );
- return -ENOTSUP;
- }
-
- return 0;
-}
-
-/**
- * Dump channel status (for debugging)
- *
- * @v vmdev VMBus device
- */
-void vmbus_dump_channel ( struct vmbus_device *vmdev ) {
- size_t out_prod = le32_to_cpu ( vmdev->out->prod );
- size_t out_cons = le32_to_cpu ( vmdev->out->cons );
- size_t in_prod = le32_to_cpu ( vmdev->in->prod );
- size_t in_cons = le32_to_cpu ( vmdev->in->cons );
- size_t in_len;
- size_t first;
- size_t second;
-
- /* Dump ring status */
- DBGC ( vmdev, "VMBUS %s out %03zx:%03zx%s in %03zx:%03zx%s\n",
- vmdev->dev.name, out_prod, out_cons,
- ( vmdev->out->intr_mask ? "(m)" : "" ), in_prod, in_cons,
- ( vmdev->in->intr_mask ? "(m)" : "" ) );
-
- /* Dump inbound ring contents, if any */
- if ( in_prod != in_cons ) {
- in_len = ( ( in_prod - in_cons ) &
- ( vmdev->in_len - 1 ) );
- first = ( vmdev->in_len - in_cons );
- if ( first > in_len )
- first = in_len;
- second = ( in_len - first );
- DBGC_HDA ( vmdev, in_cons, &vmdev->in->data[in_cons], first );
- DBGC_HDA ( vmdev, 0, &vmdev->in->data[0], second );
- }
-}
-
-/**
- * Find driver for VMBus device
- *
- * @v vmdev VMBus device
- * @ret driver Driver, or NULL
- */
-static struct vmbus_driver * vmbus_find_driver ( const union uuid *type ) {
- struct vmbus_driver *vmdrv;
-
- for_each_table_entry ( vmdrv, VMBUS_DRIVERS ) {
- if ( memcmp ( &vmdrv->type, type, sizeof ( *type ) ) == 0 )
- return vmdrv;
- }
- return NULL;
-}
-
-/**
- * Probe channels
- *
- * @v hv Hyper-V hypervisor
- * @v parent Parent device
- * @ret rc Return status code
- */
-static int vmbus_probe_channels ( struct hv_hypervisor *hv,
- struct device *parent ) {
- struct vmbus *vmbus = hv->vmbus;
- const struct vmbus_message_header *header = &vmbus->message->header;
- const struct vmbus_offer_channel *offer = &vmbus->message->offer;
- const union uuid *type;
- struct vmbus_driver *driver;
- struct vmbus_device *vmdev;
- struct vmbus_device *tmp;
- unsigned int channel;
- int rc;
-
- /* Post message */
- if ( ( rc = vmbus_post_empty_message ( hv, VMBUS_REQUEST_OFFERS ) ) !=0)
- goto err_post_message;
-
- /* Collect responses */
- while ( 1 ) {
-
- /* Wait for response */
- if ( ( rc = vmbus_wait_for_message ( hv ) ) != 0 )
- goto err_wait_for_message;
-
- /* Handle response */
- if ( header->type == cpu_to_le32 ( VMBUS_OFFER_CHANNEL ) ) {
-
- /* Parse offer */
- type = &offer->type;
- channel = le32_to_cpu ( offer->channel );
- DBGC2 ( vmbus, "VMBUS %p offer %d type %s",
- vmbus, channel, uuid_ntoa ( type ) );
- if ( offer->monitored )
- DBGC2 ( vmbus, " monitor %d", offer->monitor );
- DBGC2 ( vmbus, "\n" );
-
- /* Look for a driver */
- driver = vmbus_find_driver ( type );
- if ( ! driver ) {
- DBGC2 ( vmbus, "VMBUS %p has no driver for "
- "type %s\n", vmbus, uuid_ntoa ( type ));
- /* Not a fatal error */
- continue;
- }
-
- /* Allocate and initialise device */
- vmdev = zalloc ( sizeof ( *vmdev ) );
- if ( ! vmdev ) {
- rc = -ENOMEM;
- goto err_alloc_vmdev;
- }
- snprintf ( vmdev->dev.name, sizeof ( vmdev->dev.name ),
- "vmbus:%02x", channel );
- vmdev->dev.desc.bus_type = BUS_TYPE_HV;
- INIT_LIST_HEAD ( &vmdev->dev.children );
- list_add_tail ( &vmdev->dev.siblings,
- &parent->children );
- vmdev->dev.parent = parent;
- vmdev->hv = hv;
- vmdev->channel = channel;
- vmdev->monitor = offer->monitor;
- vmdev->signal = ( offer->monitored ?
- vmbus_signal_monitor :
- vmbus_signal_event );
- INIT_LIST_HEAD ( &vmdev->pages );
- vmdev->driver = driver;
- vmdev->dev.driver_name = driver->name;
- DBGC ( vmdev, "VMBUS %s has driver \"%s\"\n",
- vmdev->dev.name, vmdev->driver->name );
-
- } else if ( header->type ==
- cpu_to_le32 ( VMBUS_ALL_OFFERS_DELIVERED ) ) {
-
- break;
-
- } else {
- DBGC ( vmbus, "VMBUS %p unexpected offer response type "
- "%d\n", vmbus, le32_to_cpu ( header->type ) );
- rc = -EPROTO;
- goto err_unexpected_offer;
- }
- }
-
- /* Probe all devices. We do this only after completing
- * enumeration since devices will need to send and receive
- * VMBus messages.
- */
- list_for_each_entry ( vmdev, &parent->children, dev.siblings ) {
- if ( ( rc = vmdev->driver->probe ( vmdev ) ) != 0 ) {
- DBGC ( vmdev, "VMBUS %s could not probe: %s\n",
- vmdev->dev.name, strerror ( rc ) );
- goto err_probe;
- }
- }
-
- return 0;
-
- err_probe:
- /* Remove driver from each device that was already probed */
- list_for_each_entry_continue_reverse ( vmdev, &parent->children,
- dev.siblings ) {
- vmdev->driver->remove ( vmdev );
- }
- err_unexpected_offer:
- err_alloc_vmdev:
- err_wait_for_message:
- /* Free any devices allocated (but potentially not yet probed) */
- list_for_each_entry_safe ( vmdev, tmp, &parent->children,
- dev.siblings ) {
- list_del ( &vmdev->dev.siblings );
- free ( vmdev );
- }
- err_post_message:
- return rc;
-}
-
-/**
- * Remove channels
- *
- * @v hv Hyper-V hypervisor
- * @v parent Parent device
- */
-static void vmbus_remove_channels ( struct hv_hypervisor *hv __unused,
- struct device *parent ) {
- struct vmbus_device *vmdev;
- struct vmbus_device *tmp;
-
- /* Remove devices */
- list_for_each_entry_safe ( vmdev, tmp, &parent->children,
- dev.siblings ) {
- vmdev->driver->remove ( vmdev );
- assert ( list_empty ( &vmdev->dev.children ) );
- assert ( vmdev->out == NULL );
- assert ( vmdev->in == NULL );
- assert ( vmdev->packet == NULL );
- assert ( list_empty ( &vmdev->pages ) );
- list_del ( &vmdev->dev.siblings );
- free ( vmdev );
- }
-}
-
-/**
- * Probe Hyper-V virtual machine bus
- *
- * @v hv Hyper-V hypervisor
- * @v parent Parent device
- * @ret rc Return status code
- */
-int vmbus_probe ( struct hv_hypervisor *hv, struct device *parent ) {
- struct vmbus *vmbus;
- int rc;
-
- /* Allocate and initialise structure */
- vmbus = zalloc ( sizeof ( *vmbus ) );
- if ( ! vmbus ) {
- rc = -ENOMEM;
- goto err_alloc;
- }
- hv->vmbus = vmbus;
-
- /* Initialise message buffer pointer
- *
- * We use a pointer to the fixed-size Hyper-V received message
- * buffer. This allows us to access fields within received
- * messages without first checking the message size: any
- * fields beyond the end of the message will read as zero.
- */
- vmbus->message = ( ( void * ) hv->message->received.data );
- assert ( sizeof ( *vmbus->message ) <=
- sizeof ( hv->message->received.data ) );
-
- /* Allocate interrupt and monitor pages */
- if ( ( rc = hv_alloc_pages ( hv, &vmbus->intr, &vmbus->monitor_in,
- &vmbus->monitor_out, NULL ) ) != 0 )
- goto err_alloc_pages;
-
- /* Enable message interrupt */
- hv_enable_sint ( hv, VMBUS_MESSAGE_SINT );
-
- /* Negotiate protocol version */
- if ( ( rc = vmbus_negotiate_version ( hv ) ) != 0 )
- goto err_negotiate_version;
-
- /* Enumerate channels */
- if ( ( rc = vmbus_probe_channels ( hv, parent ) ) != 0 )
- goto err_probe_channels;
-
- return 0;
-
- vmbus_remove_channels ( hv, parent );
- err_probe_channels:
- vmbus_unload ( hv );
- err_negotiate_version:
- hv_disable_sint ( hv, VMBUS_MESSAGE_SINT );
- hv_free_pages ( hv, vmbus->intr, vmbus->monitor_in, vmbus->monitor_out,
- NULL );
- err_alloc_pages:
- free ( vmbus );
- err_alloc:
- return rc;
-}
-
-/**
- * Remove Hyper-V virtual machine bus
- *
- * @v hv Hyper-V hypervisor
- * @v parent Parent device
- */
-void vmbus_remove ( struct hv_hypervisor *hv, struct device *parent ) {
- struct vmbus *vmbus = hv->vmbus;
-
- vmbus_remove_channels ( hv, parent );
- vmbus_unload ( hv );
- hv_disable_sint ( hv, VMBUS_MESSAGE_SINT );
- hv_free_pages ( hv, vmbus->intr, vmbus->monitor_in, vmbus->monitor_out,
- NULL );
- free ( vmbus );
-}
diff --git a/qemu/roms/ipxe/src/interface/linux/linux_console.c b/qemu/roms/ipxe/src/interface/linux/linux_console.c
deleted file mode 100644
index 5105eaa94..000000000
--- a/qemu/roms/ipxe/src/interface/linux/linux_console.c
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (C) 2010 Piotr Jaroszyński <p.jaroszynski@gmail.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-FILE_LICENCE(GPL2_OR_LATER);
-
-/** @file
- *
- * Linux console implementation.
- *
- */
-
-#include <ipxe/console.h>
-
-#include <ipxe/init.h>
-#include <ipxe/keys.h>
-#include <linux_api.h>
-
-#include <linux/termios.h>
-#include <asm/errno.h>
-
-#include <config/console.h>
-
-/* Set default console usage if applicable */
-#if ! ( defined ( CONSOLE_LINUX ) && CONSOLE_EXPLICIT ( CONSOLE_LINUX ) )
-#undef CONSOLE_LINUX
-#define CONSOLE_LINUX ( CONSOLE_USAGE_ALL & ~CONSOLE_USAGE_LOG )
-#endif
-
-static void linux_console_putchar(int c)
-{
- /* write to stdout */
- if (linux_write(1, &c, 1) != 1)
- DBG("linux_console write failed (%s)\n", linux_strerror(linux_errno));
-}
-
-static int linux_console_getchar()
-{
- char c;
-
- /* read from stdin */
- if (linux_read(0, &c, 1) < 0) {
- DBG("linux_console read failed (%s)\n", linux_strerror(linux_errno));
- return 0;
- }
- /* backspace seems to be returned as ascii del, map it here */
- if (c == 0x7f)
- return KEY_BACKSPACE;
- else
- return c;
-}
-
-static int linux_console_iskey()
-{
- struct pollfd pfd;
- pfd.fd = 0;
- pfd.events = POLLIN;
-
- /* poll for data to be read on stdin */
- if (linux_poll(&pfd, 1, 0) == -1) {
- DBG("linux_console poll failed (%s)\n", linux_strerror(linux_errno));
- return 0;
- }
-
- if (pfd.revents & POLLIN)
- return 1;
- else
- return 0;
-}
-
-struct console_driver linux_console __console_driver = {
- .disabled = 0,
- .putchar = linux_console_putchar,
- .getchar = linux_console_getchar,
- .iskey = linux_console_iskey,
- .usage = CONSOLE_LINUX,
-};
-
-static int linux_tcgetattr(int fd, struct termios *termios_p)
-{
- return linux_ioctl(fd, TCGETS, termios_p);
-}
-
-static int linux_tcsetattr(int fd, int optional_actions, const struct termios *termios_p)
-{
- unsigned long int cmd;
-
- switch (optional_actions)
- {
- case TCSANOW:
- cmd = TCSETS;
- break;
- case TCSADRAIN:
- cmd = TCSETSW;
- break;
- case TCSAFLUSH:
- cmd = TCSETSF;
- break;
- default:
- linux_errno = EINVAL;
- return -1;
- }
-
- return linux_ioctl(fd, cmd, termios_p);
-}
-
-/** Saved termios attributes */
-static struct termios saved_termios;
-
-/** Setup the terminal for our use */
-static void linux_console_startup(void)
-{
- struct termios t;
-
- if (linux_tcgetattr(0, &t)) {
- DBG("linux_console tcgetattr failed (%s)", linux_strerror(linux_errno));
- return;
- }
-
- saved_termios = t;
-
- /* Disable canonical mode and echo. Let readline handle that */
- t.c_lflag &= ~(ECHO | ICANON);
- /* stop ^C from sending a signal */
- t.c_cc[VINTR] = 0;
-
- if (linux_tcsetattr(0, TCSAFLUSH, &t))
- DBG("linux_console tcsetattr failed (%s)", linux_strerror(linux_errno));
-}
-
-/** Restores original terminal attributes on shutdown */
-static void linux_console_shutdown(int flags __unused)
-{
- if (linux_tcsetattr(0, TCSAFLUSH, &saved_termios))
- DBG("linux_console tcsetattr failed (%s)", linux_strerror(linux_errno));
-}
-
-struct startup_fn linux_console_startup_fn __startup_fn(STARTUP_EARLY) = {
- .startup = linux_console_startup,
- .shutdown = linux_console_shutdown,
-};
diff --git a/qemu/roms/ipxe/src/interface/linux/linux_entropy.c b/qemu/roms/ipxe/src/interface/linux/linux_entropy.c
deleted file mode 100644
index 0f8e45d36..000000000
--- a/qemu/roms/ipxe/src/interface/linux/linux_entropy.c
+++ /dev/null
@@ -1,101 +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
- *
- * Linux entropy source
- *
- */
-
-#include <stdint.h>
-#include <errno.h>
-#include <linux_api.h>
-#include <ipxe/entropy.h>
-
-/** Entropy source filename */
-static const char entropy_filename[] = "/dev/random";
-
-/** Entropy source file handle */
-static int entropy_fd;
-
-/**
- * Enable entropy gathering
- *
- * @ret rc Return status code
- */
-static int linux_entropy_enable ( void ) {
-
- /* Open entropy source */
- entropy_fd = linux_open ( entropy_filename, O_RDONLY );
- if ( entropy_fd < 0 ) {
- DBGC ( &entropy_fd, "ENTROPY could not open %s: %s\n",
- entropy_filename, linux_strerror ( linux_errno ) );
- return entropy_fd;
- }
-
- return 0;
-}
-
-/**
- * Disable entropy gathering
- *
- */
-static void linux_entropy_disable ( void ) {
-
- /* Close entropy source */
- linux_close ( entropy_fd );
-}
-
-/**
- * Get noise sample
- *
- * @ret noise Noise sample
- * @ret rc Return status code
- */
-static int linux_get_noise ( noise_sample_t *noise ) {
- uint8_t byte;
- ssize_t len;
-
- /* Read a single byte from entropy source */
- len = linux_read ( entropy_fd, &byte, sizeof ( byte ) );
- if ( len < 0 ) {
- DBGC ( &entropy_fd, "ENTROPY could not read from %s: %s\n",
- entropy_filename, linux_strerror ( linux_errno ) );
- return len;
- }
- if ( len == 0 ) {
- DBGC ( &entropy_fd, "ENTROPY EOF on reading from %s: %s\n",
- entropy_filename, linux_strerror ( linux_errno ) );
- return -EPIPE;
- }
- *noise = byte;
-
- return 0;
-}
-
-PROVIDE_ENTROPY_INLINE ( linux, min_entropy_per_sample );
-PROVIDE_ENTROPY ( linux, entropy_enable, linux_entropy_enable );
-PROVIDE_ENTROPY ( linux, entropy_disable, linux_entropy_disable );
-PROVIDE_ENTROPY ( linux, get_noise, linux_get_noise );
diff --git a/qemu/roms/ipxe/src/interface/linux/linux_nap.c b/qemu/roms/ipxe/src/interface/linux/linux_nap.c
deleted file mode 100644
index f1d3cd962..000000000
--- a/qemu/roms/ipxe/src/interface/linux/linux_nap.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2010 Piotr Jaroszyński <p.jaroszynski@gmail.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE(GPL2_OR_LATER);
-
-#include <ipxe/nap.h>
-
-#include <linux_api.h>
-
-/** @file
- *
- * iPXE CPU sleeping API for linux
- *
- */
-
-/**
- * Sleep until next CPU interrupt
- *
- */
-static void linux_cpu_nap(void)
-{
- linux_usleep(0);
-}
-
-PROVIDE_NAP(linux, cpu_nap, linux_cpu_nap);
diff --git a/qemu/roms/ipxe/src/interface/linux/linux_pci.c b/qemu/roms/ipxe/src/interface/linux/linux_pci.c
deleted file mode 100644
index 0c140cb89..000000000
--- a/qemu/roms/ipxe/src/interface/linux/linux_pci.c
+++ /dev/null
@@ -1,189 +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 (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 <stdio.h>
-#include <errno.h>
-#include <byteswap.h>
-#include <linux_api.h>
-#include <ipxe/linux.h>
-#include <ipxe/pci.h>
-
-/** @file
- *
- * iPXE PCI API for Linux
- *
- */
-
-/**
- * Open PCI configuration space
- *
- * @v pci PCI device
- * @v flags Access mode flags
- * @v where Address within configuration space
- * @ret fd File handle, or negative error
- */
-static int linux_pci_open ( struct pci_device *pci, int flags,
- unsigned long where ) {
- char filename[ 22 /* "/proc/bus/pci/xx/xx.x" + NUL */ ];
- int fd;
- int rc;
-
- /* Construct filename */
- snprintf ( filename, sizeof ( filename ), "/proc/bus/pci/%02x/%02x.%x",
- PCI_BUS ( pci->busdevfn ), PCI_SLOT ( pci->busdevfn ),
- PCI_FUNC ( pci->busdevfn ) );
-
- /* Open file */
- fd = linux_open ( filename, flags );
- if ( fd < 0 ) {
- DBGC ( pci, "PCI could not open %s: %s\n", filename,
- linux_strerror ( linux_errno ) );
- rc = -ELINUX ( linux_errno );
- goto err_open;
- }
-
- /* Seek to location */
- if ( linux_lseek ( fd, where, SEEK_SET ) < 0 ) {
- DBGC ( pci, "PCI could not seek to %s offset %#02lx: %s\n",
- filename, where, linux_strerror ( linux_errno ) );
- rc = -ELINUX ( linux_errno );
- goto err_seek;
- }
-
- return fd;
-
- err_seek:
- linux_close ( fd );
- err_open:
- return rc;
-}
-
-/**
- * Read from PCI configuration space
- *
- * @v pci PCI device
- * @v where Address within configuration space
- * @v value Data buffer
- * @v len Length to read
- * @ret rc Return status code
- */
-int linux_pci_read ( struct pci_device *pci, unsigned long where,
- unsigned long *value, size_t len ) {
- uint32_t tmp = 0;
- int fd;
- int check_len;
- int rc;
-
- /* Return "missing device" in case of error */
- *value = -1UL;
-
- /* Open configuration space */
- fd = linux_pci_open ( pci, O_RDONLY, where );
- if ( fd < 0 ) {
- rc = fd;
- goto err_open;
- }
-
- /* Read value */
- check_len = linux_read ( fd, &tmp, len );
- if ( check_len < 0 ) {
- DBGC ( pci, "PCI could not read from " PCI_FMT " %#02lx+%#zx: "
- "%s\n", PCI_ARGS ( pci ), where, len,
- linux_strerror ( linux_errno ) );
- rc = -ELINUX ( linux_errno );
- goto err_read;
- }
- if ( ( size_t ) check_len != len ) {
- DBGC ( pci, "PCI read only %#x bytes from " PCI_FMT
- " %#02lx+%#zx\n", check_len, PCI_ARGS ( pci ),
- where, len );
- rc = -EIO;
- goto err_read;
- }
-
- /* Return value */
- *value = le32_to_cpu ( tmp );
-
- /* Success */
- rc = 0;
-
- err_read:
- linux_close ( fd );
- err_open:
- return rc;
-}
-
-/**
- * Write to PCI configuration space
- *
- * @v pci PCI device
- * @v where Address within configuration space
- * @v value Value to write
- * @v len Length of value
- * @ret rc Return status code
- */
-int linux_pci_write ( struct pci_device *pci, unsigned long where,
- unsigned long value, size_t len ) {
- uint32_t tmp;
- int fd;
- int check_len;
- int rc;
-
- /* Open configuration space */
- fd = linux_pci_open ( pci, O_WRONLY, where );
- if ( fd < 0 ) {
- rc = fd;
- goto err_open;
- }
-
- /* Prepare value for writing */
- tmp = cpu_to_le32 ( value );
- assert ( len <= sizeof ( tmp ) );
-
- /* Write value */
- check_len = linux_write ( fd, &tmp, len );
- if ( check_len < 0 ) {
- DBGC ( pci, "PCI could not write to " PCI_FMT " %#02lx+%#zx: "
- "%s\n", PCI_ARGS ( pci ), where, len,
- linux_strerror ( linux_errno ) );
- rc = -ELINUX ( linux_errno );
- goto err_write;
- }
- if ( ( size_t ) check_len != len ) {
- DBGC ( pci, "PCI wrote only %#x bytes to " PCI_FMT
- " %#02lx+%#zx\n", check_len, PCI_ARGS ( pci ),
- where, len );
- rc = -EIO;
- goto err_write;
- }
-
- /* Success */
- rc = 0;
-
- err_write:
- linux_close ( fd );
- err_open:
- return rc;
-}
diff --git a/qemu/roms/ipxe/src/interface/linux/linux_smbios.c b/qemu/roms/ipxe/src/interface/linux/linux_smbios.c
deleted file mode 100644
index 6e5174d23..000000000
--- a/qemu/roms/ipxe/src/interface/linux/linux_smbios.c
+++ /dev/null
@@ -1,115 +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.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include <errno.h>
-#include <linux_api.h>
-#include <ipxe/linux.h>
-#include <ipxe/smbios.h>
-
-/** SMBIOS filename */
-static const char smbios_filename[] = "/dev/mem";
-
-/** SMBIOS entry point scan region start address */
-#define SMBIOS_ENTRY_START 0xf0000
-
-/** SMBIOS entry point scan region length */
-#define SMBIOS_ENTRY_LEN 0x10000
-
-/** SMBIOS mapping alignment */
-#define SMBIOS_ALIGN 0x1000
-
-/**
- * Find SMBIOS
- *
- * @v smbios SMBIOS entry point descriptor structure to fill in
- * @ret rc Return status code
- */
-static int linux_find_smbios ( struct smbios *smbios ) {
- struct smbios_entry entry;
- void *entry_mem;
- void *smbios_mem;
- size_t smbios_offset;
- size_t smbios_indent;
- size_t smbios_len;
- int fd;
- int rc;
-
- /* Open SMBIOS file */
- fd = linux_open ( smbios_filename, O_RDONLY );
- if ( fd < 0 ) {
- rc = -ELINUX ( linux_errno );
- DBGC ( smbios, "SMBIOS could not open %s: %s\n",
- smbios_filename, linux_strerror ( linux_errno ) );
- goto err_open;
- }
-
- /* Map the region potentially containing the SMBIOS entry point */
- entry_mem = linux_mmap ( NULL, SMBIOS_ENTRY_LEN, PROT_READ, MAP_SHARED,
- fd, SMBIOS_ENTRY_START );
- if ( entry_mem == MAP_FAILED ) {
- rc = -ELINUX ( linux_errno );
- DBGC ( smbios, "SMBIOS could not mmap %s (%#x+%#x): %s\n",
- smbios_filename, SMBIOS_ENTRY_START, SMBIOS_ENTRY_LEN,
- linux_strerror ( linux_errno ) );
- goto err_mmap_entry;
- }
-
- /* Scan for the SMBIOS entry point */
- if ( ( rc = find_smbios_entry ( virt_to_user ( entry_mem ),
- SMBIOS_ENTRY_LEN, &entry ) ) != 0 )
- goto err_find_entry;
-
- /* Map the region containing the SMBIOS structures */
- smbios_indent = ( entry.smbios_address & ( SMBIOS_ALIGN - 1 ) );
- smbios_offset = ( entry.smbios_address - smbios_indent );
- smbios_len = ( entry.smbios_len + smbios_indent );
- smbios_mem = linux_mmap ( NULL, smbios_len, PROT_READ, MAP_SHARED,
- fd, smbios_offset );
- if ( smbios_mem == MAP_FAILED ) {
- rc = -ELINUX ( linux_errno );
- DBGC ( smbios, "SMBIOS could not mmap %s (%#zx+%#zx): %s\n",
- smbios_filename, smbios_offset, smbios_len,
- linux_strerror ( linux_errno ) );
- goto err_mmap_smbios;
- }
-
- /* Fill in entry point descriptor structure */
- smbios->address = virt_to_user ( smbios_mem + smbios_indent );
- smbios->len = entry.smbios_len;
- smbios->count = entry.smbios_count;
- smbios->version = SMBIOS_VERSION ( entry.major, entry.minor );
-
- /* Unmap the entry point region (no longer required) */
- linux_munmap ( entry_mem, SMBIOS_ENTRY_LEN );
-
- return 0;
-
- linux_munmap ( smbios_mem, smbios_len );
- err_mmap_smbios:
- err_find_entry:
- linux_munmap ( entry_mem, SMBIOS_ENTRY_LEN );
- err_mmap_entry:
- linux_close ( fd );
- err_open:
- return rc;
-}
-
-PROVIDE_SMBIOS ( linux, find_smbios, linux_find_smbios );
diff --git a/qemu/roms/ipxe/src/interface/linux/linux_time.c b/qemu/roms/ipxe/src/interface/linux/linux_time.c
deleted file mode 100644
index 9e99fe9cd..000000000
--- a/qemu/roms/ipxe/src/interface/linux/linux_time.c
+++ /dev/null
@@ -1,50 +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 );
-
-/** @file
- *
- * Linux time source
- *
- */
-
-#include <stdint.h>
-#include <stddef.h>
-#include <errno.h>
-#include <linux_api.h>
-#include <ipxe/time.h>
-
-/**
- * Get current time in seconds
- *
- * @ret time Time, in seconds
- */
-static time_t linux_now ( void ) {
- struct timeval now;
-
- linux_gettimeofday ( &now, NULL );
- return now.tv_sec;
-}
-
-PROVIDE_TIME ( linux, time_now, linux_now );
diff --git a/qemu/roms/ipxe/src/interface/linux/linux_timer.c b/qemu/roms/ipxe/src/interface/linux/linux_timer.c
deleted file mode 100644
index 7a994517b..000000000
--- a/qemu/roms/ipxe/src/interface/linux/linux_timer.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2010 Piotr Jaroszyński <p.jaroszynski@gmail.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-FILE_LICENCE(GPL2_OR_LATER);
-
-#include <stddef.h>
-#include <ipxe/timer.h>
-
-#include <linux_api.h>
-
-/** @file
- *
- * iPXE timer API for linux
- *
- */
-
-/**
- * Delay for a fixed number of microseconds
- *
- * @v usecs Number of microseconds for which to delay
- */
-static void linux_udelay(unsigned long usecs)
-{
- linux_usleep(usecs);
-}
-
-/**
- * Get number of ticks per second
- *
- * @ret ticks_per_sec Number of ticks per second
- */
-static unsigned long linux_ticks_per_sec(void)
-{
- return 1000;
-}
-
-/**
- * Get current system time in ticks
- *
- * linux doesn't provide an easy access to jiffies so implement it by measuring
- * the time since the first call to this function.
- *
- * Since this function is used to seed the (non-cryptographic) random
- * number generator, we round the start time down to the nearest whole
- * second. This minimises the chances of generating identical RNG
- * sequences (and hence identical TCP port numbers, etc) on
- * consecutive invocations of iPXE.
- *
- * @ret ticks Current time, in ticks
- */
-static unsigned long linux_currticks(void)
-{
- static struct timeval start;
- static int initialized = 0;
-
- if (! initialized) {
- linux_gettimeofday(&start, NULL);
- initialized = 1;
- }
-
- struct timeval now;
- linux_gettimeofday(&now, NULL);
-
- unsigned long ticks = (now.tv_sec - start.tv_sec) * linux_ticks_per_sec();
- ticks += now.tv_usec / (long)(1000000 / linux_ticks_per_sec());
-
- return ticks;
-}
-
-PROVIDE_TIMER(linux, udelay, linux_udelay);
-PROVIDE_TIMER(linux, currticks, linux_currticks);
-PROVIDE_TIMER(linux, ticks_per_sec, linux_ticks_per_sec);
diff --git a/qemu/roms/ipxe/src/interface/linux/linux_uaccess.c b/qemu/roms/ipxe/src/interface/linux/linux_uaccess.c
deleted file mode 100644
index ea2d8057c..000000000
--- a/qemu/roms/ipxe/src/interface/linux/linux_uaccess.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2010 Piotr Jaroszyński <p.jaroszynski@gmail.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE(GPL2_OR_LATER);
-
-#include <ipxe/uaccess.h>
-
-/** @file
- *
- * iPXE user access API for linux
- *
- */
-
-PROVIDE_UACCESS_INLINE(linux, user_to_phys);
-PROVIDE_UACCESS_INLINE(linux, virt_to_user);
-PROVIDE_UACCESS_INLINE(linux, user_to_virt);
-PROVIDE_UACCESS_INLINE(linux, userptr_add);
-PROVIDE_UACCESS_INLINE(linux, memcpy_user);
-PROVIDE_UACCESS_INLINE(linux, memmove_user);
-PROVIDE_UACCESS_INLINE(linux, memset_user);
-PROVIDE_UACCESS_INLINE(linux, strlen_user);
-PROVIDE_UACCESS_INLINE(linux, memchr_user);
diff --git a/qemu/roms/ipxe/src/interface/linux/linux_umalloc.c b/qemu/roms/ipxe/src/interface/linux/linux_umalloc.c
deleted file mode 100644
index aa0052c53..000000000
--- a/qemu/roms/ipxe/src/interface/linux/linux_umalloc.c
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2010 Piotr Jaroszyński <p.jaroszynski@gmail.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-FILE_LICENCE(GPL2_OR_LATER);
-
-#include <valgrind/memcheck.h>
-
-/** @file
- *
- * iPXE user memory allocation API for linux
- *
- */
-
-#include <assert.h>
-#include <ipxe/umalloc.h>
-
-#include <linux_api.h>
-
-/** Special address returned for empty allocations */
-#define NOWHERE ((void *)-1)
-
-/** Poison to make the metadata more unique */
-#define POISON 0xa5a5a5a5
-#define min(a,b) (((a)<(b))?(a):(b))
-
-/** Metadata stored at the beginning of all allocations */
-struct metadata
-{
- unsigned poison;
- size_t size;
-};
-
-#define SIZE_MD (sizeof(struct metadata))
-
-/** Simple realloc which passes most of the work to mmap(), mremap() and munmap() */
-static void * linux_realloc(void *ptr, size_t size)
-{
- struct metadata md = {0, 0};
- struct metadata * mdptr = NULL;
-
- DBG2("linux_realloc(%p, %zd)\n", ptr, size);
-
- /* Check whether we have a valid pointer */
- if (ptr != NULL && ptr != NOWHERE) {
- mdptr = ptr - SIZE_MD;
- VALGRIND_MAKE_MEM_DEFINED(mdptr, SIZE_MD);
- md = *mdptr;
- VALGRIND_MAKE_MEM_NOACCESS(mdptr, SIZE_MD);
-
- /* Check for poison in the metadata */
- if (md.poison != POISON) {
- DBG("linux_realloc bad poison: 0x%x (expected 0x%x)\n", md.poison, POISON);
- return NULL;
- }
- } else {
- /* Handle NOWHERE as NULL */
- ptr = NULL;
- }
-
- /*
- * At this point, ptr is either NULL or pointing to a region allocated by us.
- * In the latter case mdptr is pointing to a valid metadata, otherwise it is NULL.
- */
-
- /* Handle deallocation or allocation of size 0 */
- if (size == 0) {
- if (mdptr) {
- if (linux_munmap(mdptr, md.size))
- DBG("linux_realloc munmap failed: %s\n", linux_strerror(linux_errno));
- VALGRIND_FREELIKE_BLOCK(ptr, sizeof(*mdptr));
- }
- return NOWHERE;
- }
-
- if (ptr) {
- char *vbits = NULL;
-
- if (RUNNING_ON_VALGRIND > 0)
- vbits = linux_realloc(NULL, min(size, md.size));
-
-/* prevent an unused variable warning when building w/o valgrind support */
-#ifndef NVALGRIND
- VALGRIND_GET_VBITS(ptr, vbits, min(size, md.size));
-#endif
-
- VALGRIND_FREELIKE_BLOCK(ptr, SIZE_MD);
-
- mdptr = linux_mremap(mdptr, md.size + SIZE_MD, size + SIZE_MD, MREMAP_MAYMOVE);
- if (mdptr == MAP_FAILED) {
- DBG("linux_realloc mremap failed: %s\n", linux_strerror(linux_errno));
- return NULL;
- }
- ptr = ((void *)mdptr) + SIZE_MD;
-
- VALGRIND_MALLOCLIKE_BLOCK(ptr, size, SIZE_MD, 0);
-/* prevent an unused variable warning when building w/o valgrind support */
-#ifndef NVALGRIND
- VALGRIND_SET_VBITS(ptr, vbits, min(size, md.size));
-#endif
-
- if (RUNNING_ON_VALGRIND > 0)
- linux_realloc(vbits, 0);
- } else {
- mdptr = linux_mmap(NULL, size + SIZE_MD, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
- if (mdptr == MAP_FAILED) {
- DBG("linux_realloc mmap failed: %s\n", linux_strerror(linux_errno));
- return NULL;
- }
- ptr = ((void *)mdptr) + SIZE_MD;
- VALGRIND_MALLOCLIKE_BLOCK(ptr, size, SIZE_MD, 0);
- }
-
- /* Update the metadata */
- VALGRIND_MAKE_MEM_DEFINED(mdptr, SIZE_MD);
- mdptr->poison = POISON;
- mdptr->size = size;
- VALGRIND_MAKE_MEM_NOACCESS(mdptr, SIZE_MD);
- // VALGRIND_MALLOCLIKE_BLOCK ignores redzones currently, make our own
- VALGRIND_MAKE_MEM_NOACCESS(ptr + size, SIZE_MD);
-
- return ptr;
-}
-
-/**
- * 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 linux_urealloc(userptr_t old_ptr, size_t new_size)
-{
- return (userptr_t)linux_realloc((void *)old_ptr, new_size);
-}
-
-PROVIDE_UMALLOC(linux, urealloc, linux_urealloc);
diff --git a/qemu/roms/ipxe/src/interface/smbios/smbios.c b/qemu/roms/ipxe/src/interface/smbios/smbios.c
deleted file mode 100644
index 1dcf819c2..000000000
--- a/qemu/roms/ipxe/src/interface/smbios/smbios.c
+++ /dev/null
@@ -1,252 +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>
-
-/** @file
- *
- * System Management BIOS
- *
- */
-
-/** SMBIOS entry point descriptor */
-static struct smbios smbios = {
- .address = UNULL,
-};
-
-/**
- * Scan for SMBIOS entry point structure
- *
- * @v start Start address of region to scan
- * @v len Length of region to scan
- * @v entry SMBIOS entry point structure to fill in
- * @ret rc Return status code
- */
-int find_smbios_entry ( userptr_t start, size_t len,
- struct smbios_entry *entry ) {
- uint8_t buf[256]; /* 256 is maximum length possible */
- static size_t offset = 0; /* Avoid repeated attempts to locate SMBIOS */
- size_t entry_len;
- unsigned int i;
- uint8_t sum;
-
- /* Try to find SMBIOS */
- for ( ; offset < len ; offset += 0x10 ) {
-
- /* Read start of header and verify signature */
- copy_from_user ( entry, start, offset, sizeof ( *entry ) );
- if ( entry->signature != SMBIOS_SIGNATURE )
- continue;
-
- /* Read whole header and verify checksum */
- entry_len = entry->len;
- assert ( entry_len <= sizeof ( buf ) );
- copy_from_user ( buf, start, offset, entry_len );
- for ( i = 0, sum = 0 ; i < entry_len ; i++ ) {
- sum += buf[i];
- }
- if ( sum != 0 ) {
- DBG ( "SMBIOS at %08lx has bad checksum %02x\n",
- user_to_phys ( start, offset ), sum );
- continue;
- }
-
- /* Fill result structure */
- DBG ( "Found SMBIOS v%d.%d entry point at %08lx\n",
- entry->major, entry->minor,
- user_to_phys ( start, offset ) );
- return 0;
- }
-
- DBG ( "No SMBIOS found\n" );
- return -ENODEV;
-}
-
-/**
- * Find SMBIOS strings terminator
- *
- * @v offset Offset to start of strings
- * @ret offset Offset to strings terminator, or 0 if not found
- */
-static size_t find_strings_terminator ( size_t offset ) {
- size_t max_offset = ( smbios.len - 2 );
- uint16_t nulnul;
-
- for ( ; offset <= max_offset ; offset++ ) {
- copy_from_user ( &nulnul, smbios.address, offset, 2 );
- if ( nulnul == 0 )
- return ( offset + 1 );
- }
- return 0;
-}
-
-/**
- * Find specific structure type within SMBIOS
- *
- * @v type Structure type to search for
- * @v instance Instance of this type of structure
- * @v structure SMBIOS structure descriptor to fill in
- * @ret rc Return status code
- */
-int find_smbios_structure ( unsigned int type, unsigned int instance,
- struct smbios_structure *structure ) {
- unsigned int count = 0;
- size_t offset = 0;
- size_t strings_offset;
- size_t terminator_offset;
- int rc;
-
- /* Find SMBIOS */
- if ( ( smbios.address == UNULL ) &&
- ( ( rc = find_smbios ( &smbios ) ) != 0 ) )
- return rc;
- assert ( smbios.address != UNULL );
-
- /* Scan through list of structures */
- while ( ( ( offset + sizeof ( structure->header ) ) < smbios.len )
- && ( count < smbios.count ) ) {
-
- /* Read next SMBIOS structure header */
- copy_from_user ( &structure->header, smbios.address, offset,
- sizeof ( structure->header ) );
-
- /* Determine start and extent of strings block */
- strings_offset = ( offset + structure->header.len );
- if ( strings_offset > smbios.len ) {
- DBG ( "SMBIOS structure at offset %zx with length "
- "%x extends beyond SMBIOS\n", offset,
- structure->header.len );
- return -ENOENT;
- }
- terminator_offset = find_strings_terminator ( strings_offset );
- if ( ! terminator_offset ) {
- DBG ( "SMBIOS structure at offset %zx has "
- "unterminated strings section\n", offset );
- return -ENOENT;
- }
- structure->strings_len = ( terminator_offset - strings_offset);
-
- DBG ( "SMBIOS structure at offset %zx has type %d, length %x, "
- "strings length %zx\n", offset, structure->header.type,
- structure->header.len, structure->strings_len );
-
- /* If this is the structure we want, return */
- if ( ( structure->header.type == type ) &&
- ( instance-- == 0 ) ) {
- structure->offset = offset;
- return 0;
- }
-
- /* Move to next SMBIOS structure */
- offset = ( terminator_offset + 1 );
- count++;
- }
-
- DBG ( "SMBIOS structure type %d not found\n", type );
- return -ENOENT;
-}
-
-/**
- * Copy SMBIOS structure
- *
- * @v structure SMBIOS structure descriptor
- * @v data Buffer to hold SMBIOS structure
- * @v len Length of buffer
- * @ret rc Return status code
- */
-int read_smbios_structure ( struct smbios_structure *structure,
- void *data, size_t len ) {
-
- assert ( smbios.address != UNULL );
-
- if ( len > structure->header.len )
- len = structure->header.len;
- copy_from_user ( data, smbios.address, structure->offset, len );
- return 0;
-}
-
-/**
- * Find indexed string within SMBIOS structure
- *
- * @v structure SMBIOS structure descriptor
- * @v index String index
- * @v data Buffer for string
- * @v len Length of string buffer
- * @ret rc Length of string, or negative error
- */
-int read_smbios_string ( struct smbios_structure *structure,
- unsigned int index, void *data, size_t len ) {
- size_t strings_start = ( structure->offset + structure->header.len );
- size_t strings_end = ( strings_start + structure->strings_len );
- size_t offset;
- size_t string_len;
-
- assert ( smbios.address != UNULL );
-
- /* String numbers start at 1 (0 is used to indicate "no string") */
- if ( ! index )
- return -ENOENT;
-
- for ( offset = strings_start ; offset < strings_end ;
- offset += ( string_len + 1 ) ) {
- /* Get string length. This is known safe, since the
- * smbios_strings struct is constructed so as to
- * always end on a string boundary.
- */
- string_len = strlen_user ( smbios.address, offset );
- if ( --index == 0 ) {
- /* Copy string, truncating as necessary. */
- if ( len > string_len )
- len = string_len;
- copy_from_user ( data, smbios.address, offset, len );
- return string_len;
- }
- }
-
- DBG ( "SMBIOS string index %d not found\n", index );
- return -ENOENT;
-}
-
-/**
- * Get SMBIOS version
- *
- * @ret version Version, or negative error
- */
-int smbios_version ( void ) {
- int rc;
-
- /* Find SMBIOS */
- if ( ( smbios.address == UNULL ) &&
- ( ( rc = find_smbios ( &smbios ) ) != 0 ) )
- return rc;
- assert ( smbios.address != UNULL );
-
- return smbios.version;
-}
diff --git a/qemu/roms/ipxe/src/interface/smbios/smbios_settings.c b/qemu/roms/ipxe/src/interface/smbios/smbios_settings.c
deleted file mode 100644
index 5eadfa081..000000000
--- a/qemu/roms/ipxe/src/interface/smbios/smbios_settings.c
+++ /dev/null
@@ -1,259 +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 <stdint.h>
-#include <string.h>
-#include <errno.h>
-#include <ipxe/settings.h>
-#include <ipxe/init.h>
-#include <ipxe/uuid.h>
-#include <ipxe/smbios.h>
-
-/** SMBIOS settings scope */
-static const struct settings_scope smbios_settings_scope;
-
-/**
- * Construct SMBIOS raw-data tag
- *
- * @v _type SMBIOS structure type number
- * @v _structure SMBIOS structure data type
- * @v _field Field within SMBIOS structure data type
- * @ret tag SMBIOS setting tag
- */
-#define SMBIOS_RAW_TAG( _type, _structure, _field ) \
- ( ( (_type) << 16 ) | \
- ( offsetof ( _structure, _field ) << 8 ) | \
- ( sizeof ( ( ( _structure * ) 0 )->_field ) ) )
-
-/**
- * Construct SMBIOS string tag
- *
- * @v _type SMBIOS structure type number
- * @v _structure SMBIOS structure data type
- * @v _field Field within SMBIOS structure data type
- * @ret tag SMBIOS setting tag
- */
-#define SMBIOS_STRING_TAG( _type, _structure, _field ) \
- ( ( (_type) << 16 ) | \
- ( offsetof ( _structure, _field ) << 8 ) )
-
-/**
- * Check applicability of SMBIOS setting
- *
- * @v settings Settings block
- * @v setting Setting
- * @ret applies Setting applies within this settings block
- */
-static int smbios_applies ( struct settings *settings __unused,
- const struct setting *setting ) {
-
- return ( setting->scope == &smbios_settings_scope );
-}
-
-/**
- * Fetch value of SMBIOS setting
- *
- * @v settings Settings block, or NULL to search all blocks
- * @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 smbios_fetch ( struct settings *settings __unused,
- struct setting *setting,
- void *data, size_t len ) {
- struct smbios_structure structure;
- unsigned int tag_instance;
- unsigned int tag_type;
- unsigned int tag_offset;
- unsigned int tag_len;
- int rc;
-
- /* Split tag into instance, type, offset and length */
- tag_instance = ( ( setting->tag >> 24 ) & 0xff );
- tag_type = ( ( setting->tag >> 16 ) & 0xff );
- tag_offset = ( ( setting->tag >> 8 ) & 0xff );
- tag_len = ( setting->tag & 0xff );
-
- /* Find SMBIOS structure */
- if ( ( rc = find_smbios_structure ( tag_type, tag_instance,
- &structure ) ) != 0 )
- return rc;
-
- {
- uint8_t buf[structure.header.len];
- const void *raw;
- union uuid uuid;
- unsigned int index;
-
- /* Read SMBIOS structure */
- if ( ( rc = read_smbios_structure ( &structure, buf,
- sizeof ( buf ) ) ) != 0 )
- return rc;
-
- /* A <length> of zero indicates that the byte at
- * <offset> contains a string index. An <offset> of
- * zero indicates that the <length> contains a literal
- * string index.
- */
- if ( ( tag_len == 0 ) || ( tag_offset == 0 ) ) {
- index = ( ( tag_offset == 0 ) ?
- tag_len : buf[tag_offset] );
- if ( ( rc = read_smbios_string ( &structure, index,
- data, len ) ) < 0 ) {
- return rc;
- }
- if ( ! setting->type )
- setting->type = &setting_type_string;
- return rc;
- }
-
- /* Mangle UUIDs if necessary. iPXE treats UUIDs as
- * being in network byte order (big-endian). SMBIOS
- * specification version 2.6 states that UUIDs are
- * stored with little-endian values in the first three
- * fields; earlier versions did not specify an
- * endianness. dmidecode assumes that the byte order
- * is little-endian if and only if the SMBIOS version
- * is 2.6 or higher; we match this behaviour.
- */
- raw = &buf[tag_offset];
- if ( ( setting->type == &setting_type_uuid ) &&
- ( tag_len == sizeof ( uuid ) ) &&
- ( smbios_version() >= SMBIOS_VERSION ( 2, 6 ) ) ) {
- DBG ( "SMBIOS detected mangled UUID\n" );
- memcpy ( &uuid, &buf[tag_offset], sizeof ( uuid ) );
- uuid_mangle ( &uuid );
- raw = &uuid;
- }
-
- /* Return data */
- if ( len > tag_len )
- len = tag_len;
- memcpy ( data, raw, len );
- if ( ! setting->type )
- setting->type = &setting_type_hex;
- return tag_len;
- }
-}
-
-/** SMBIOS settings operations */
-static struct settings_operations smbios_settings_operations = {
- .applies = smbios_applies,
- .fetch = smbios_fetch,
-};
-
-/** SMBIOS settings */
-static struct settings smbios_settings = {
- .refcnt = NULL,
- .siblings = LIST_HEAD_INIT ( smbios_settings.siblings ),
- .children = LIST_HEAD_INIT ( smbios_settings.children ),
- .op = &smbios_settings_operations,
- .default_scope = &smbios_settings_scope,
-};
-
-/** Initialise SMBIOS settings */
-static void smbios_init ( void ) {
- int rc;
-
- if ( ( rc = register_settings ( &smbios_settings, NULL,
- "smbios" ) ) != 0 ) {
- DBG ( "SMBIOS could not register settings: %s\n",
- strerror ( rc ) );
- return;
- }
-}
-
-/** SMBIOS settings initialiser */
-struct init_fn smbios_init_fn __init_fn ( INIT_NORMAL ) = {
- .initialise = smbios_init,
-};
-
-/** UUID setting obtained via SMBIOS */
-const struct setting uuid_setting __setting ( SETTING_HOST, uuid ) = {
- .name = "uuid",
- .description = "UUID",
- .tag = SMBIOS_RAW_TAG ( SMBIOS_TYPE_SYSTEM_INFORMATION,
- struct smbios_system_information, uuid ),
- .type = &setting_type_uuid,
- .scope = &smbios_settings_scope,
-};
-
-/** Manufacturer name setting */
-const struct setting manufacturer_setting __setting ( SETTING_HOST_EXTRA,
- manufacturer ) = {
- .name = "manufacturer",
- .description = "Manufacturer",
- .tag = SMBIOS_STRING_TAG ( SMBIOS_TYPE_SYSTEM_INFORMATION,
- struct smbios_system_information,
- manufacturer ),
- .type = &setting_type_string,
- .scope = &smbios_settings_scope,
-};
-
-/** Product name setting */
-const struct setting product_setting __setting ( SETTING_HOST_EXTRA, product )={
- .name = "product",
- .description = "Product name",
- .tag = SMBIOS_STRING_TAG ( SMBIOS_TYPE_SYSTEM_INFORMATION,
- struct smbios_system_information,
- product ),
- .type = &setting_type_string,
- .scope = &smbios_settings_scope,
-};
-
-/** Serial number setting */
-const struct setting serial_setting __setting ( SETTING_HOST_EXTRA, serial ) = {
- .name = "serial",
- .description = "Serial number",
- .tag = SMBIOS_STRING_TAG ( SMBIOS_TYPE_SYSTEM_INFORMATION,
- struct smbios_system_information,
- serial ),
- .type = &setting_type_string,
- .scope = &smbios_settings_scope,
-};
-
-/** Asset tag setting */
-const struct setting asset_setting __setting ( SETTING_HOST_EXTRA, asset ) = {
- .name = "asset",
- .description = "Asset tag",
- .tag = SMBIOS_STRING_TAG ( SMBIOS_TYPE_ENCLOSURE_INFORMATION,
- struct smbios_enclosure_information,
- asset_tag ),
- .type = &setting_type_string,
- .scope = &smbios_settings_scope,
-};
-
-/** Board serial number setting (may differ from chassis serial number) */
-const struct setting board_serial_setting __setting ( SETTING_HOST_EXTRA,
- board_serial ) = {
- .name = "board-serial",
- .description = "Base board serial",
- .tag = SMBIOS_STRING_TAG ( SMBIOS_TYPE_BASE_BOARD_INFORMATION,
- struct smbios_base_board_information,
- serial ),
- .type = &setting_type_string,
- .scope = &smbios_settings_scope,
-};
diff --git a/qemu/roms/ipxe/src/interface/xen/xenbus.c b/qemu/roms/ipxe/src/interface/xen/xenbus.c
deleted file mode 100644
index c328af443..000000000
--- a/qemu/roms/ipxe/src/interface/xen/xenbus.c
+++ /dev/null
@@ -1,397 +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 (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 <stdio.h>
-#include <errno.h>
-#include <ipxe/malloc.h>
-#include <ipxe/device.h>
-#include <ipxe/timer.h>
-#include <ipxe/nap.h>
-#include <ipxe/xen.h>
-#include <ipxe/xenstore.h>
-#include <ipxe/xenbus.h>
-
-/** @file
- *
- * Xen device bus
- *
- */
-
-/* Disambiguate the various error causes */
-#define ETIMEDOUT_UNKNOWN \
- __einfo_error ( EINFO_ETIMEDOUT_UNKNOWN )
-#define EINFO_ETIMEDOUT_UNKNOWN \
- __einfo_uniqify ( EINFO_ETIMEDOUT, XenbusStateUnknown, \
- "Unknown" )
-#define ETIMEDOUT_INITIALISING \
- __einfo_error ( EINFO_ETIMEDOUT_INITIALISING )
-#define EINFO_ETIMEDOUT_INITIALISING \
- __einfo_uniqify ( EINFO_ETIMEDOUT, XenbusStateInitialising, \
- "Initialising" )
-#define ETIMEDOUT_INITWAIT \
- __einfo_error ( EINFO_ETIMEDOUT_INITWAIT )
-#define EINFO_ETIMEDOUT_INITWAIT \
- __einfo_uniqify ( EINFO_ETIMEDOUT, XenbusStateInitWait, \
- "InitWait" )
-#define ETIMEDOUT_INITIALISED \
- __einfo_error ( EINFO_ETIMEDOUT_INITIALISED )
-#define EINFO_ETIMEDOUT_INITIALISED \
- __einfo_uniqify ( EINFO_ETIMEDOUT, XenbusStateInitialised, \
- "Initialised" )
-#define ETIMEDOUT_CONNECTED \
- __einfo_error ( EINFO_ETIMEDOUT_CONNECTED )
-#define EINFO_ETIMEDOUT_CONNECTED \
- __einfo_uniqify ( EINFO_ETIMEDOUT, XenbusStateConnected, \
- "Connected" )
-#define ETIMEDOUT_CLOSING \
- __einfo_error ( EINFO_ETIMEDOUT_CLOSING )
-#define EINFO_ETIMEDOUT_CLOSING \
- __einfo_uniqify ( EINFO_ETIMEDOUT, XenbusStateClosing, \
- "Closing" )
-#define ETIMEDOUT_CLOSED \
- __einfo_error ( EINFO_ETIMEDOUT_CLOSED )
-#define EINFO_ETIMEDOUT_CLOSED \
- __einfo_uniqify ( EINFO_ETIMEDOUT, XenbusStateClosed, \
- "Closed" )
-#define ETIMEDOUT_RECONFIGURING \
- __einfo_error ( EINFO_ETIMEDOUT_RECONFIGURING )
-#define EINFO_ETIMEDOUT_RECONFIGURING \
- __einfo_uniqify ( EINFO_ETIMEDOUT, XenbusStateReconfiguring, \
- "Reconfiguring" )
-#define ETIMEDOUT_RECONFIGURED \
- __einfo_error ( EINFO_ETIMEDOUT_RECONFIGURED )
-#define EINFO_ETIMEDOUT_RECONFIGURED \
- __einfo_uniqify ( EINFO_ETIMEDOUT, XenbusStateReconfigured, \
- "Reconfigured" )
-#define ETIMEDOUT_STATE( state ) \
- EUNIQ ( EINFO_ETIMEDOUT, (state), ETIMEDOUT_UNKNOWN, \
- ETIMEDOUT_INITIALISING, ETIMEDOUT_INITWAIT, \
- ETIMEDOUT_INITIALISED, ETIMEDOUT_CONNECTED, \
- ETIMEDOUT_CLOSING, ETIMEDOUT_CLOSED, \
- ETIMEDOUT_RECONFIGURING, ETIMEDOUT_RECONFIGURED )
-
-/** Maximum time to wait for backend to reach a given state, in ticks */
-#define XENBUS_BACKEND_TIMEOUT ( 5 * TICKS_PER_SEC )
-
-/**
- * Set device state
- *
- * @v xendev Xen device
- * @v state New state
- * @ret rc Return status code
- */
-int xenbus_set_state ( struct xen_device *xendev, int state ) {
- int rc;
-
- /* Attempt to set state */
- if ( ( rc = xenstore_write_num ( xendev->xen, state, xendev->key,
- "state", NULL ) ) != 0 ) {
- DBGC ( xendev, "XENBUS %s could not set state=\"%d\": %s\n",
- xendev->key, state, strerror ( rc ) );
- return rc;
- }
-
- return 0;
-}
-
-/**
- * Get backend state
- *
- * @v xendev Xen device
- * @ret state Backend state, or negative error
- */
-int xenbus_backend_state ( struct xen_device *xendev ) {
- unsigned long state;
- int rc;
-
- /* Attempt to get backend state */
- if ( ( rc = xenstore_read_num ( xendev->xen, &state, xendev->backend,
- "state", NULL ) ) != 0 ) {
- DBGC ( xendev, "XENBUS %s could not read %s/state: %s\n",
- xendev->key, xendev->backend, strerror ( rc ) );
- return rc;
- }
-
- return state;
-}
-
-/**
- * Wait for backend to reach a given state
- *
- * @v xendev Xen device
- * @v state Desired backend state
- * @ret rc Return status code
- */
-int xenbus_backend_wait ( struct xen_device *xendev, int state ) {
- unsigned long started = currticks();
- unsigned long elapsed;
- unsigned int attempts = 0;
- int current_state;
- int rc;
-
- /* Wait for backend to reach this state */
- do {
-
- /* Get current backend state */
- current_state = xenbus_backend_state ( xendev );
- if ( current_state < 0 ) {
- rc = current_state;
- return rc;
- }
- if ( current_state == state )
- return 0;
-
- /* Allow time for backend to react */
- cpu_nap();
-
- /* XenStore is a very slow interface; any fixed delay
- * time would be dwarfed by the XenStore access time.
- * We therefore use wall clock to time out this
- * operation.
- */
- elapsed = ( currticks() - started );
- attempts++;
-
- } while ( elapsed < XENBUS_BACKEND_TIMEOUT );
-
- /* Construct status code from current backend state */
- rc = -ETIMEDOUT_STATE ( current_state );
- DBGC ( xendev, "XENBUS %s timed out after %d attempts waiting for "
- "%s/state=\"%d\": %s\n", xendev->key, attempts, xendev->backend,
- state, strerror ( rc ) );
-
- return rc;
-}
-
-/**
- * Find driver for Xen device
- *
- * @v type Device type
- * @ret driver Driver, or NULL
- */
-static struct xen_driver * xenbus_find_driver ( const char *type ) {
- struct xen_driver *xendrv;
-
- for_each_table_entry ( xendrv, XEN_DRIVERS ) {
- if ( strcmp ( xendrv->type, type ) == 0 )
- return xendrv;
- }
- return NULL;
-}
-
-/**
- * Probe Xen device
- *
- * @v xen Xen hypervisor
- * @v parent Parent device
- * @v type Device type
- * @v instance Device instance
- * @ret rc Return status code
- */
-static int xenbus_probe_device ( struct xen_hypervisor *xen,
- struct device *parent, const char *type,
- const char *instance ) {
- struct xen_device *xendev;
- size_t key_len;
- int rc;
-
- /* Allocate and initialise structure */
- key_len = ( 7 /* "device/" */ + strlen ( type ) + 1 /* "/" */ +
- strlen ( instance ) + 1 /* NUL */ );
- xendev = zalloc ( sizeof ( *xendev ) + key_len );
- if ( ! xendev ) {
- rc = -ENOMEM;
- goto err_alloc;
- }
- snprintf ( xendev->dev.name, sizeof ( xendev->dev.name ), "%s/%s",
- type, instance );
- xendev->dev.desc.bus_type = BUS_TYPE_XEN;
- INIT_LIST_HEAD ( &xendev->dev.children );
- list_add_tail ( &xendev->dev.siblings, &parent->children );
- xendev->dev.parent = parent;
- xendev->xen = xen;
- xendev->key = ( ( void * ) ( xendev + 1 ) );
- snprintf ( xendev->key, key_len, "device/%s/%s", type, instance );
-
- /* Read backend key */
- if ( ( rc = xenstore_read ( xen, &xendev->backend, xendev->key,
- "backend", NULL ) ) != 0 ) {
- DBGC ( xendev, "XENBUS %s could not read backend: %s\n",
- xendev->key, strerror ( rc ) );
- goto err_read_backend;
- }
-
- /* Read backend domain ID */
- if ( ( rc = xenstore_read_num ( xen, &xendev->backend_id, xendev->key,
- "backend-id", NULL ) ) != 0 ) {
- DBGC ( xendev, "XENBUS %s could not read backend-id: %s\n",
- xendev->key, strerror ( rc ) );
- goto err_read_backend_id;
- }
- DBGC ( xendev, "XENBUS %s backend=\"%s\" in domain %ld\n",
- xendev->key, xendev->backend, xendev->backend_id );
-
- /* Look for a driver */
- xendev->driver = xenbus_find_driver ( type );
- if ( ! xendev->driver ) {
- DBGC ( xendev, "XENBUS %s has no driver\n", xendev->key );
- /* Not a fatal error */
- rc = 0;
- goto err_no_driver;
- }
- xendev->dev.driver_name = xendev->driver->name;
- DBGC ( xendev, "XENBUS %s has driver \"%s\"\n", xendev->key,
- xendev->driver->name );
-
- /* Probe driver */
- if ( ( rc = xendev->driver->probe ( xendev ) ) != 0 ) {
- DBGC ( xendev, "XENBUS could not probe %s: %s\n",
- xendev->key, strerror ( rc ) );
- goto err_probe;
- }
-
- return 0;
-
- xendev->driver->remove ( xendev );
- err_probe:
- err_no_driver:
- err_read_backend_id:
- free ( xendev->backend );
- err_read_backend:
- list_del ( &xendev->dev.siblings );
- free ( xendev );
- err_alloc:
- return rc;
-}
-
-/**
- * Remove Xen device
- *
- * @v xendev Xen device
- */
-static void xenbus_remove_device ( struct xen_device *xendev ) {
-
- /* Remove device */
- xendev->driver->remove ( xendev );
- free ( xendev->backend );
- list_del ( &xendev->dev.siblings );
- free ( xendev );
-}
-
-/**
- * Probe Xen devices of a given type
- *
- * @v xen Xen hypervisor
- * @v parent Parent device
- * @v type Device type
- * @ret rc Return status code
- */
-static int xenbus_probe_type ( struct xen_hypervisor *xen,
- struct device *parent, const char *type ) {
- char *children;
- char *child;
- size_t len;
- int rc;
-
- /* Get children of this key */
- if ( ( rc = xenstore_directory ( xen, &children, &len, "device",
- type, NULL ) ) != 0 ) {
- DBGC ( xen, "XENBUS could not list \"%s\" devices: %s\n",
- type, strerror ( rc ) );
- goto err_directory;
- }
-
- /* Probe each child */
- for ( child = children ; child < ( children + len ) ;
- child += ( strlen ( child ) + 1 /* NUL */ ) ) {
- if ( ( rc = xenbus_probe_device ( xen, parent, type,
- child ) ) != 0 )
- goto err_probe_device;
- }
-
- free ( children );
- return 0;
-
- err_probe_device:
- free ( children );
- err_directory:
- return rc;
-}
-
-/**
- * Probe Xen bus
- *
- * @v xen Xen hypervisor
- * @v parent Parent device
- * @ret rc Return status code
- */
-int xenbus_probe ( struct xen_hypervisor *xen, struct device *parent ) {
- char *types;
- char *type;
- size_t len;
- int rc;
-
- /* Get children of "device" key */
- if ( ( rc = xenstore_directory ( xen, &types, &len, "device",
- NULL ) ) != 0 ) {
- DBGC ( xen, "XENBUS could not list device types: %s\n",
- strerror ( rc ) );
- goto err_directory;
- }
-
- /* Probe each child type */
- for ( type = types ; type < ( types + len ) ;
- type += ( strlen ( type ) + 1 /* NUL */ ) ) {
- if ( ( rc = xenbus_probe_type ( xen, parent, type ) ) != 0 )
- goto err_probe_type;
- }
-
- free ( types );
- return 0;
-
- xenbus_remove ( xen, parent );
- err_probe_type:
- free ( types );
- err_directory:
- return rc;
-}
-
-/**
- * Remove Xen bus
- *
- * @v xen Xen hypervisor
- * @v parent Parent device
- */
-void xenbus_remove ( struct xen_hypervisor *xen __unused,
- struct device *parent ) {
- struct xen_device *xendev;
- struct xen_device *tmp;
-
- /* Remove devices */
- list_for_each_entry_safe ( xendev, tmp, &parent->children,
- dev.siblings ) {
- xenbus_remove_device ( xendev );
- }
-}
diff --git a/qemu/roms/ipxe/src/interface/xen/xengrant.c b/qemu/roms/ipxe/src/interface/xen/xengrant.c
deleted file mode 100644
index 269cd5836..000000000
--- a/qemu/roms/ipxe/src/interface/xen/xengrant.c
+++ /dev/null
@@ -1,232 +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 (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 <strings.h>
-#include <errno.h>
-#include <assert.h>
-#include <ipxe/io.h>
-#include <ipxe/xen.h>
-#include <ipxe/xengrant.h>
-
-/** @file
- *
- * Xen grant tables
- *
- */
-
-/** Grant table version to try setting
- *
- * Using version 1 grant tables limits guests to using 16TB of
- * grantable RAM, and prevents the use of subpage grants. Some
- * versions of the Xen hypervisor refuse to allow the grant table
- * version to be set after the first grant references have been
- * created, so the loaded operating system may be stuck with whatever
- * choice we make here. We therefore currently use version 2 grant
- * tables, since they give the most flexibility to the loaded OS.
- *
- * Current versions (7.2.0) of the Windows PV drivers have no support
- * for version 2 grant tables, and will merrily create version 1
- * entries in what the hypervisor believes to be a version 2 table.
- * This causes some confusion.
- *
- * Avoid this problem by attempting to use version 1 tables, since
- * otherwise we may render Windows unable to boot.
- *
- * Play nicely with other potential bootloaders by accepting either
- * version 1 or version 2 grant tables (if we are unable to set our
- * requested version).
- */
-#define XENGRANT_TRY_VERSION 1
-
-/**
- * Initialise grant table
- *
- * @v xen Xen hypervisor
- * @ret rc Return status code
- */
-int xengrant_init ( struct xen_hypervisor *xen ) {
- struct gnttab_query_size size;
- struct gnttab_set_version set_version;
- struct gnttab_get_version get_version;
- struct grant_entry_v1 *v1;
- union grant_entry_v2 *v2;
- unsigned int version;
- int xenrc;
- int rc;
-
- /* Get grant table size */
- size.dom = DOMID_SELF;
- if ( ( xenrc = xengrant_query_size ( xen, &size ) ) != 0 ) {
- rc = -EXEN ( xenrc );
- DBGC ( xen, "XENGRANT could not get table size: %s\n",
- strerror ( rc ) );
- return rc;
- }
- xen->grant.len = ( size.nr_frames * PAGE_SIZE );
-
- /* Set grant table version, if applicable */
- set_version.version = XENGRANT_TRY_VERSION;
- if ( ( xenrc = xengrant_set_version ( xen, &set_version ) ) != 0 ) {
- rc = -EXEN ( xenrc );
- DBGC ( xen, "XENGRANT could not set version %d: %s\n",
- XENGRANT_TRY_VERSION, strerror ( rc ) );
- /* Continue; use whatever version is current */
- }
-
- /* Get grant table version */
- get_version.dom = DOMID_SELF;
- get_version.pad = 0;
- if ( ( xenrc = xengrant_get_version ( xen, &get_version ) ) == 0 ) {
- version = get_version.version;
- switch ( version ) {
-
- case 0:
- /* Version not yet specified: will be version 1 */
- version = 1;
- break;
-
- case 1 :
- /* Version 1 table: nothing special to do */
- break;
-
- case 2:
- /* Version 2 table: configure shift appropriately */
- xen->grant.shift = ( fls ( sizeof ( *v2 ) /
- sizeof ( *v1 ) ) - 1 );
- break;
-
- default:
- /* Unsupported version */
- DBGC ( xen, "XENGRANT detected unsupported version "
- "%d\n", version );
- return -ENOTSUP;
-
- }
- } else {
- rc = -EXEN ( xenrc );
- DBGC ( xen, "XENGRANT could not get version (assuming v1): "
- "%s\n", strerror ( rc ) );
- version = 1;
- }
-
- DBGC ( xen, "XENGRANT using v%d table with %d entries\n",
- version, xengrant_entries ( xen ) );
- return 0;
-}
-
-/**
- * Allocate grant references
- *
- * @v xen Xen hypervisor
- * @v refs Grant references to fill in
- * @v count Number of references
- * @ret rc Return status code
- */
-int xengrant_alloc ( struct xen_hypervisor *xen, grant_ref_t *refs,
- unsigned int count ) {
- struct grant_entry_header *hdr;
- unsigned int entries = xengrant_entries ( xen );
- unsigned int mask = ( entries - 1 );
- unsigned int check = 0;
- unsigned int avail;
- unsigned int ref;
-
- /* Fail unless we have enough references available */
- avail = ( entries - xen->grant.used - GNTTAB_NR_RESERVED_ENTRIES );
- if ( avail < count ) {
- DBGC ( xen, "XENGRANT cannot allocate %d references (only %d "
- "of %d available)\n", count, avail, entries );
- return -ENOBUFS;
- }
- DBGC ( xen, "XENGRANT allocating %d references (from %d of %d "
- "available)\n", count, avail, entries );
-
- /* Update number of references used */
- xen->grant.used += count;
-
- /* Find unused references */
- for ( ref = xen->grant.ref ; count ; ref = ( ( ref + 1 ) & mask ) ) {
-
- /* Sanity check */
- assert ( check++ < entries );
-
- /* Skip reserved references */
- if ( ref < GNTTAB_NR_RESERVED_ENTRIES )
- continue;
-
- /* Skip in-use references */
- hdr = xengrant_header ( xen, ref );
- if ( readw ( &hdr->flags ) & GTF_type_mask )
- continue;
- if ( readw ( &hdr->domid ) == DOMID_SELF )
- continue;
-
- /* Zero reference */
- xengrant_zero ( xen, hdr );
-
- /* Mark reference as in-use. We leave the flags as
- * empty (to avoid creating a valid grant table entry)
- * and set the domid to DOMID_SELF.
- */
- writew ( DOMID_SELF, &hdr->domid );
- DBGC2 ( xen, "XENGRANT allocated ref %d\n", ref );
-
- /* Record reference */
- refs[--count] = ref;
- }
-
- /* Update cursor */
- xen->grant.ref = ref;
-
- return 0;
-}
-
-/**
- * Free grant references
- *
- * @v xen Xen hypervisor
- * @v refs Grant references
- * @v count Number of references
- */
-void xengrant_free ( struct xen_hypervisor *xen, grant_ref_t *refs,
- unsigned int count ) {
- struct grant_entry_header *hdr;
- unsigned int ref;
- unsigned int i;
-
- /* Free references */
- for ( i = 0 ; i < count ; i++ ) {
-
- /* Sanity check */
- ref = refs[i];
- assert ( ref < xengrant_entries ( xen ) );
-
- /* Zero reference */
- hdr = xengrant_header ( xen, ref );
- xengrant_zero ( xen, hdr );
- DBGC2 ( xen, "XENGRANT freed ref %d\n", ref );
- }
-}
diff --git a/qemu/roms/ipxe/src/interface/xen/xenstore.c b/qemu/roms/ipxe/src/interface/xen/xenstore.c
deleted file mode 100644
index 23424a926..000000000
--- a/qemu/roms/ipxe/src/interface/xen/xenstore.c
+++ /dev/null
@@ -1,555 +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 (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 <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <ipxe/io.h>
-#include <ipxe/nap.h>
-#include <ipxe/malloc.h>
-#include <ipxe/xen.h>
-#include <ipxe/xenevent.h>
-#include <ipxe/xenstore.h>
-
-/*
- * xs_wire.h attempts to define a static error table xsd_errors, which
- * interacts badly with the dynamically generated error numbers used
- * by iPXE. Prevent this table from being constructed by including
- * errno.h only after including xs_wire.h.
- *
- */
-#include <xen/io/xs_wire.h>
-#include <errno.h>
-
-/** @file
- *
- * XenStore interface
- *
- */
-
-/** Request identifier */
-static uint32_t xenstore_req_id;
-
-/**
- * Send XenStore request raw data
- *
- * @v xen Xen hypervisor
- * @v data Data buffer
- * @v len Length of data
- */
-static void xenstore_send ( struct xen_hypervisor *xen, const void *data,
- size_t len ) {
- struct xenstore_domain_interface *intf = xen->store.intf;
- XENSTORE_RING_IDX prod = readl ( &intf->req_prod );
- XENSTORE_RING_IDX cons;
- XENSTORE_RING_IDX idx;
- const char *bytes = data;
- size_t offset = 0;
- size_t fill;
-
- DBGCP ( intf, "XENSTORE raw request:\n" );
- DBGCP_HDA ( intf, MASK_XENSTORE_IDX ( prod ), data, len );
-
- /* Write one byte at a time */
- while ( offset < len ) {
-
- /* Wait for space to become available */
- while ( 1 ) {
- cons = readl ( &intf->req_cons );
- fill = ( prod - cons );
- if ( fill < XENSTORE_RING_SIZE )
- break;
- DBGC2 ( xen, "." );
- cpu_nap();
- rmb();
- }
-
- /* Write byte */
- idx = MASK_XENSTORE_IDX ( prod++ );
- writeb ( bytes[offset++], &intf->req[idx] );
- }
-
- /* Update producer counter */
- wmb();
- writel ( prod, &intf->req_prod );
- wmb();
-}
-
-/**
- * Send XenStore request string (excluding terminating NUL)
- *
- * @v xen Xen hypervisor
- * @v string String
- */
-static void xenstore_send_string ( struct xen_hypervisor *xen,
- const char *string ) {
-
- xenstore_send ( xen, string, strlen ( string ) );
-}
-
-/**
- * Receive XenStore response raw data
- *
- * @v xen Xen hypervisor
- * @v data Data buffer, or NULL to discard data
- * @v len Length of data
- */
-static void xenstore_recv ( struct xen_hypervisor *xen, void *data,
- size_t len ) {
- struct xenstore_domain_interface *intf = xen->store.intf;
- XENSTORE_RING_IDX cons = readl ( &intf->rsp_cons );
- XENSTORE_RING_IDX prod;
- XENSTORE_RING_IDX idx;
- char *bytes = data;
- size_t offset = 0;
- size_t fill;
-
- DBGCP ( intf, "XENSTORE raw response:\n" );
-
- /* Read one byte at a time */
- while ( offset < len ) {
-
- /* Wait for data to be ready */
- while ( 1 ) {
- prod = readl ( &intf->rsp_prod );
- fill = ( prod - cons );
- if ( fill > 0 )
- break;
- DBGC2 ( xen, "." );
- cpu_nap();
- rmb();
- }
-
- /* Read byte */
- idx = MASK_XENSTORE_IDX ( cons++ );
- if ( data )
- bytes[offset++] = readb ( &intf->rsp[idx] );
- }
- if ( data )
- DBGCP_HDA ( intf, MASK_XENSTORE_IDX ( cons - len ), data, len );
-
- /* Update consumer counter */
- writel ( cons, &intf->rsp_cons );
- wmb();
-}
-
-/**
- * Send XenStore request
- *
- * @v xen Xen hypervisor
- * @v type Message type
- * @v req_id Request ID
- * @v value Value, or NULL to omit
- * @v key Key path components
- * @ret rc Return status code
- */
-static int xenstore_request ( struct xen_hypervisor *xen,
- enum xsd_sockmsg_type type, uint32_t req_id,
- const char *value, va_list key ) {
- struct xsd_sockmsg msg;
- struct evtchn_send event;
- const char *string;
- va_list tmp;
- int xenrc;
- int rc;
-
- /* Construct message header */
- msg.type = type;
- msg.req_id = req_id;
- msg.tx_id = 0;
- msg.len = 0;
- DBGC2 ( xen, "XENSTORE request ID %d type %d ", req_id, type );
-
- /* Calculate total length */
- va_copy ( tmp, key );
- while ( ( string = va_arg ( tmp, const char * ) ) != NULL ) {
- DBGC2 ( xen, "%s%s", ( msg.len ? "/" : "" ), string );
- msg.len += ( strlen ( string ) + 1 /* '/' or NUL */ );
- }
- va_end ( tmp );
- if ( value ) {
- DBGC2 ( xen, " = \"%s\"", value );
- msg.len += strlen ( value );
- }
- DBGC2 ( xen, "\n" );
-
- /* Send message */
- xenstore_send ( xen, &msg, sizeof ( msg ) );
- string = va_arg ( key, const char * );
- assert ( string != NULL );
- xenstore_send_string ( xen, string );
- while ( ( string = va_arg ( key, const char * ) ) != NULL ) {
- xenstore_send_string ( xen, "/" );
- xenstore_send_string ( xen, string );
- }
- xenstore_send ( xen, "", 1 ); /* Separating NUL */
- if ( value )
- xenstore_send_string ( xen, value );
-
- /* Notify the back end */
- event.port = xen->store.port;
- if ( ( xenrc = xenevent_send ( xen, &event ) ) != 0 ) {
- rc = -EXEN ( xenrc );
- DBGC ( xen, "XENSTORE could not notify back end: %s\n",
- strerror ( rc ) );
- return rc;
- }
-
- return 0;
-}
-
-/**
- * Receive XenStore response
- *
- * @v xen Xen hypervisor
- * @v req_id Request ID
- * @v value Value to fill in
- * @v len Length to fill in
- * @ret rc Return status code
- *
- * The caller is responsible for eventually calling free() on the
- * returned value. Note that the value may comprise multiple
- * NUL-terminated strings concatenated together. A terminating NUL
- * will always be appended to the returned value.
- */
-static int xenstore_response ( struct xen_hypervisor *xen, uint32_t req_id,
- char **value, size_t *len ) {
- struct xsd_sockmsg msg;
- char *string;
- int rc;
-
- /* Wait for response to become available */
- while ( ! xenevent_pending ( xen, xen->store.port ) )
- cpu_nap();
-
- /* Receive message header */
- xenstore_recv ( xen, &msg, sizeof ( msg ) );
- *len = msg.len;
-
- /* Allocate space for response */
- *value = zalloc ( msg.len + 1 /* terminating NUL */ );
-
- /* Receive data. Do this even if allocation failed, or if the
- * request ID was incorrect, to avoid leaving data in the
- * ring.
- */
- xenstore_recv ( xen, *value, msg.len );
-
- /* Validate request ID */
- if ( msg.req_id != req_id ) {
- DBGC ( xen, "XENSTORE response ID mismatch (got %d, expected "
- "%d)\n", msg.req_id, req_id );
- rc = -EPROTO;
- goto err_req_id;
- }
-
- /* Check for allocation failure */
- if ( ! *value ) {
- DBGC ( xen, "XENSTORE could not allocate %d bytes for "
- "response\n", msg.len );
- rc = -ENOMEM;
- goto err_alloc;
- }
-
- /* Check for explicit errors */
- if ( msg.type == XS_ERROR ) {
- DBGC ( xen, "XENSTORE response error \"%s\"\n", *value );
- rc = -EIO;
- goto err_explicit;
- }
-
- DBGC2 ( xen, "XENSTORE response ID %d\n", req_id );
- if ( DBG_EXTRA ) {
- for ( string = *value ; string < ( *value + msg.len ) ;
- string += ( strlen ( string ) + 1 /* NUL */ ) ) {
- DBGC2 ( xen, " - \"%s\"\n", string );
- }
- }
- return 0;
-
- err_explicit:
- err_alloc:
- err_req_id:
- free ( *value );
- *value = NULL;
- return rc;
-}
-
-/**
- * Issue a XenStore message
- *
- * @v xen Xen hypervisor
- * @v type Message type
- * @v response Response value to fill in, or NULL to discard
- * @v len Response length to fill in, or NULL to ignore
- * @v request Request value, or NULL to omit
- * @v key Key path components
- * @ret rc Return status code
- */
-static int xenstore_message ( struct xen_hypervisor *xen,
- enum xsd_sockmsg_type type, char **response,
- size_t *len, const char *request, va_list key ) {
- char *response_value;
- size_t response_len;
- int rc;
-
- /* Send request */
- if ( ( rc = xenstore_request ( xen, type, ++xenstore_req_id,
- request, key ) ) != 0 )
- return rc;
-
- /* Receive response */
- if ( ( rc = xenstore_response ( xen, xenstore_req_id, &response_value,
- &response_len ) ) != 0 )
- return rc;
-
- /* Return response, if applicable */
- if ( response ) {
- *response = response_value;
- } else {
- free ( response_value );
- }
- if ( len )
- *len = response_len;
-
- return 0;
-}
-
-/**
- * Read XenStore value
- *
- * @v xen Xen hypervisor
- * @v value Value to fill in
- * @v key Key path components
- * @ret rc Return status code
- *
- * On a successful return, the caller is responsible for calling
- * free() on the returned value.
- */
-static int xenstore_vread ( struct xen_hypervisor *xen, char **value,
- va_list key ) {
-
- return xenstore_message ( xen, XS_READ, value, NULL, NULL, key );
-}
-
-/**
- * Read XenStore value
- *
- * @v xen Xen hypervisor
- * @v value Value to fill in
- * @v ... Key path components
- * @ret rc Return status code
- *
- * On a successful return, the caller is responsible for calling
- * free() on the returned value.
- */
-__attribute__ (( sentinel )) int
-xenstore_read ( struct xen_hypervisor *xen, char **value, ... ) {
- va_list key;
- int rc;
-
- va_start ( key, value );
- rc = xenstore_vread ( xen, value, key );
- va_end ( key );
- return rc;
-}
-
-/**
- * Read XenStore numeric value
- *
- * @v xen Xen hypervisor
- * @v num Numeric value to fill in
- * @v ... Key path components
- * @ret rc Return status code
- */
-__attribute__ (( sentinel )) int
-xenstore_read_num ( struct xen_hypervisor *xen, unsigned long *num, ... ) {
- va_list key;
- char *value;
- char *endp;
- int rc;
-
- /* Try to read text value */
- va_start ( key, num );
- rc = xenstore_vread ( xen, &value, key );
- va_end ( key );
- if ( rc != 0 )
- goto err_read;
-
- /* Try to parse as numeric value */
- *num = strtoul ( value, &endp, 10 );
- if ( ( *value == '\0' ) || ( *endp != '\0' ) ) {
- DBGC ( xen, "XENSTORE found invalid numeric value \"%s\"\n",
- value );
- rc = -EINVAL;
- goto err_strtoul;
- }
-
- err_strtoul:
- free ( value );
- err_read:
- return rc;
-}
-
-/**
- * Write XenStore value
- *
- * @v xen Xen hypervisor
- * @v value Value
- * @v key Key path components
- * @ret rc Return status code
- */
-static int xenstore_vwrite ( struct xen_hypervisor *xen, const char *value,
- va_list key ) {
-
- return xenstore_message ( xen, XS_WRITE, NULL, NULL, value, key );
-}
-
-/**
- * Write XenStore value
- *
- * @v xen Xen hypervisor
- * @v value Value
- * @v ... Key path components
- * @ret rc Return status code
- */
-__attribute__ (( sentinel )) int
-xenstore_write ( struct xen_hypervisor *xen, const char *value, ... ) {
- va_list key;
- int rc;
-
- va_start ( key, value );
- rc = xenstore_vwrite ( xen, value, key );
- va_end ( key );
- return rc;
-}
-
-/**
- * Write XenStore numeric value
- *
- * @v xen Xen hypervisor
- * @v num Numeric value
- * @v ... Key path components
- * @ret rc Return status code
- */
-__attribute__ (( sentinel )) int
-xenstore_write_num ( struct xen_hypervisor *xen, unsigned long num, ... ) {
- char value[ 21 /* "18446744073709551615" + NUL */ ];
- va_list key;
- int rc;
-
- /* Construct value */
- snprintf ( value, sizeof ( value ), "%ld", num );
-
- /* Write value */
- va_start ( key, num );
- rc = xenstore_vwrite ( xen, value, key );
- va_end ( key );
- return rc;
-}
-
-/**
- * Delete XenStore value
- *
- * @v xen Xen hypervisor
- * @v ... Key path components
- * @ret rc Return status code
- */
-__attribute__ (( sentinel )) int
-xenstore_rm ( struct xen_hypervisor *xen, ... ) {
- va_list key;
- int rc;
-
- va_start ( key, xen );
- rc = xenstore_message ( xen, XS_RM, NULL, NULL, NULL, key );
- va_end ( key );
- return rc;
-}
-
-/**
- * Read XenStore directory
- *
- * @v xen Xen hypervisor
- * @v children Child key names to fill in
- * @v len Length of child key names to fill in
- * @v ... Key path components
- * @ret rc Return status code
- */
-__attribute__ (( sentinel )) int
-xenstore_directory ( struct xen_hypervisor *xen, char **children, size_t *len,
- ... ) {
- va_list key;
- int rc;
-
- va_start ( key, len );
- rc = xenstore_message ( xen, XS_DIRECTORY, children, len, NULL, key );
- va_end ( key );
- return rc;
-}
-
-/**
- * Dump XenStore directory contents (for debugging)
- *
- * @v xen Xen hypervisor
- * @v key Key
- */
-void xenstore_dump ( struct xen_hypervisor *xen, const char *key ) {
- char *value;
- char *children;
- char *child;
- char *child_key;
- size_t len;
- int rc;
-
- /* Try to dump current key as a value */
- if ( ( rc = xenstore_read ( xen, &value, key, NULL ) ) == 0 ) {
- DBGC ( xen, "%s = \"%s\"\n", key, value );
- free ( value );
- }
-
- /* Try to recurse into each child in turn */
- if ( ( rc = xenstore_directory ( xen, &children, &len, key,
- NULL ) ) == 0 ) {
- for ( child = children ; child < ( children + len ) ;
- child += ( strlen ( child ) + 1 /* NUL */ ) ) {
-
- /* Construct child key */
- asprintf ( &child_key, "%s/%s", key, child );
- if ( ! child_key ) {
- DBGC ( xen, "XENSTORE could not allocate child "
- "key \"%s/%s\"\n", key, child );
- rc = -ENOMEM;
- break;
- }
-
- /* Recurse into child key, continuing on error */
- xenstore_dump ( xen, child_key );
- free ( child_key );
- }
- free ( children );
- }
-}