[-]
[+]
|
Added |
ipxe.tar.bz2/contrib/errdb/.gitignore
|
@@ -0,0 +1 @@
+errors.db
|
[-]
[+]
|
Changed |
ipxe.tar.bz2/contrib/rom-o-matic/bottom.php
^
|
@@ -27,25 +27,25 @@
<ul>
<li>
Source code for iPXE images is available at
- <a href="http://etherboot.org/wiki/download" target="_blank">
- http://etherboot.org/wiki/download</a>
+ <a href="http://www.ipxe.org/download" target="_blank">
+ http://www.ipxe.org/download</a>
<br><br>
</li>
<li>
For general information about using iPXE, please visit the
- <a href="http://www.etherboot.org/" target="_blank">
- Etherboot Project Home Page</a>
+ <a href="http://www.ipxe.org/" target="_blank">
+ iPXE Project Home Page</a>
<br><br>
</li>
<li>
For Email-based support for iPXE please join
- <a href="http://etherboot.org/wiki/mailinglists" target="_blank">
- Etherboot Project mailing lists.</a>
+ <a href="http://www.ipxe.org/contact" target="_blank">
+ iPXE Project mailing lists.</a>
<br><br>
</li>
<li>
For real-time online iPXE support via IRC please visit the
- <a href="irc://irc.freenode.net/%23etherboot"> #etherboot channel
+ <a href="irc://irc.freenode.net/%23ipxe"> #ipxe channel
of irc.freenode.net</a>.
<br><br>
</li>
|
[-]
[+]
|
Changed |
ipxe.tar.bz2/contrib/rom-o-matic/build.php
^
|
@@ -179,7 +179,7 @@
// Make the requested image. $status is set to 0 on success
$make_target = "bin/${nic}.${fmt_extension}";
-$make_cmd = "make -C '$build_dir' '$make_target' $emb_script_cmd $2>&1";
+$make_cmd = "make -C '$build_dir' '$make_target' $emb_script_cmd 2>&1";
exec ( $make_cmd, $maketxt, $status );
|
[-]
[+]
|
Changed |
ipxe.tar.bz2/contrib/rom-o-matic/directions.php
^
|
@@ -37,7 +37,7 @@
<em>PCI VENDOR CODE</em> and <em>PCI DEVICE CODE</em> <br>
that match the NIC device for which you are making this image.<br><br>
Information on how to determine NIC PCI IDs may be found
- <a href="http://etherboot.org/wiki/romburning"
+ <a href="http://www.ipxe.org/howto/romburning"
target="_blank">here</a>.
<br><br>
PCI VENDOR CODE: <? echo textbox ( "pci_vendor_code",
|
[-]
[+]
|
Changed |
ipxe.tar.bz2/contrib/rom-o-matic/flag-table.php
^
|
@@ -98,6 +98,17 @@
"cfgsec" => "general"
),
+ "KEYBOARD_MAP"
+ => array (
+ "flag" => "KEYBOARD_MAP",
+ "type" => "choice",
+ "options" => array("al","az","bg","by","cf","cz","de","dk","es","et","fi","fr",
+ "gr","hu","il","it","lt","mk","mt","nl","no","pl","pt","ro","ru","sg","sr",
+ "th","ua","uk","us","wo"),
+ "value" => "us",
+ "cfgsec" => "console"
+ ),
+
// End Console Options
// Begin Network Protocol Options:
@@ -487,6 +498,17 @@
// End Wireless options
+ // Obscure options required to compile
+ "NETDEV_DISCARD_RATE"
+ => array (
+ "flag" => "NETDEV_DISCARD_RATE",
+ "type" => "integer",
+ "value" => "0",
+ "cfgsec" => "general",
+ "hide_from_user" => true
+ )
+
+ // End Obscure options
);
// For emacs:
|
[-]
[+]
|
Added |
ipxe.tar.bz2/contrib/vm/.gitignore
^
|
@@ -0,0 +1,6 @@
+bochsout.txt
+parport.out
+ne2k-tx.log
+ne2k-txdump.txt
+bochs
+qemu
|
[-]
[+]
|
Added |
ipxe.tar.bz2/src/.gitignore
^
|
@@ -0,0 +1,4 @@
+.toolcheck
+.echocheck
+TAGS*
+bin*
|
[-]
[+]
|
Changed |
ipxe.tar.bz2/src/Makefile.housekeeping
^
|
@@ -601,21 +601,22 @@
# This is needed in order to correctly rebuild embedded.o whenever the
# list of objects changes.
#
+EMBED := $(EMBEDDED_IMAGE) # Maintain backwards compatibility
EMBEDDED_LIST := $(BIN)/.embedded.list
ifeq ($(wildcard $(EMBEDDED_LIST)),)
-EMBEDDED_IMAGE_OLD := <invalid>
+EMBED_OLD := <invalid>
else
-EMBEDDED_IMAGE_OLD := $(shell cat $(EMBEDDED_LIST))
+EMBED_OLD := $(shell cat $(EMBEDDED_LIST))
endif
-ifneq ($(EMBEDDED_IMAGE_OLD),$(EMBEDDED_IMAGE))
-$(shell $(ECHO) "$(EMBEDDED_IMAGE)" > $(EMBEDDED_LIST))
+ifneq ($(EMBED_OLD),$(EMBED))
+$(shell $(ECHO) "$(EMBED)" > $(EMBEDDED_LIST))
endif
$(EMBEDDED_LIST) :
VERYCLEANUP += $(EMBEDDED_LIST)
-EMBEDDED_FILES := $(subst $(COMMA), ,$(EMBEDDED_IMAGE))
+EMBEDDED_FILES := $(subst $(COMMA), ,$(EMBED))
EMBED_ALL := $(foreach i,$(call seq,1,$(words $(EMBEDDED_FILES))),\
EMBED ( $(i), \"$(word $(i), $(EMBEDDED_FILES))\",\
\"$(notdir $(word $(i),$(EMBEDDED_FILES)))\" ))
|
[-]
[+]
|
Changed |
ipxe.tar.bz2/src/arch/i386/core/linux/linuxprefix.S
^
|
(renamed to src/arch/i386/core/linux/linuxprefix.S)
|
[-]
[+]
|
Changed |
ipxe.tar.bz2/src/arch/i386/core/linux/linuxprefix.S
^
|
(renamed to src/arch/i386/core/linux/linuxprefix.S)
|
[-]
[+]
|
Changed |
ipxe.tar.bz2/src/arch/i386/drivers/net/undinet.c
^
|
@@ -558,8 +558,10 @@
DBGC ( undinic, "UNDINIC %p has type %s, speed %d, flags %08x\n",
undinic, undi_iface.IfaceType, undi_iface.LinkSpeed,
undi_iface.ServiceFlags );
- if ( undi_iface.ServiceFlags & SUPPORTED_IRQ )
+ if ( ( undi_iface.ServiceFlags & SUPPORTED_IRQ ) &&
+ ( undinic->irq != 0 ) ) {
undinic->irq_supported = 1;
+ }
DBGC ( undinic, "UNDINIC %p using %s mode\n", undinic,
( undinic->irq_supported ? "interrupt" : "polling" ) );
if ( strncmp ( ( ( char * ) undi_iface.IfaceType ), "Etherboot",
|
[-]
[+]
|
Changed |
ipxe.tar.bz2/src/arch/i386/include/int13.h
^
|
@@ -45,6 +45,8 @@
#define INT13_GET_EXTENDED_PARAMETERS 0x48
/** Get CD-ROM status / terminate emulation */
#define INT13_CDROM_STATUS_TERMINATE 0x4b
+/** Read CD-ROM boot catalog */
+#define INT13_CDROM_READ_BOOT_CATALOG 0x4d
/** @} */
@@ -217,6 +219,18 @@
uint8_t head;
} __attribute__ (( packed ));
+/** Bootable CD-ROM boot catalog command packet */
+struct int13_cdrom_boot_catalog_command {
+ /** Size of packet in bytes */
+ uint8_t size;
+ /** Number of sectors of boot catalog to read */
+ uint8_t count;
+ /** Buffer for boot catalog */
+ uint32_t buffer;
+ /** First sector in boot catalog to transfer */
+ uint16_t start;
+} __attribute__ (( packed ));
+
/** A C/H/S address within a partition table entry */
struct partition_chs {
/** Head number */
@@ -261,7 +275,123 @@
uint16_t magic;
} __attribute__ (( packed ));
-/** Use natural BIOS drive number */
-#define INT13_USE_NATURAL_DRIVE 0xff
+/** MBR magic signature */
+#define INT13_MBR_MAGIC 0xaa55
+
+/** ISO9660 block size */
+#define ISO9660_BLKSIZE 2048
+
+/** An ISO9660 Primary Volume Descriptor (fixed portion) */
+struct iso9660_primary_descriptor_fixed {
+ /** Descriptor type */
+ uint8_t type;
+ /** Identifier ("CD001") */
+ uint8_t id[5];
+} __attribute__ (( packed ));
+
+/** An ISO9660 Primary Volume Descriptor */
+struct iso9660_primary_descriptor {
+ /** Fixed portion */
+ struct iso9660_primary_descriptor_fixed fixed;
+} __attribute__ (( packed ));
+
+/** ISO9660 Primary Volume Descriptor type */
+#define ISO9660_TYPE_PRIMARY 0x01
+
+/** ISO9660 identifier */
+#define ISO9660_ID "CD001"
+
+/** ISO9660 Primary Volume Descriptor block address */
+#define ISO9660_PRIMARY_LBA 16
+
+/** An El Torito Boot Record Volume Descriptor (fixed portion) */
+struct eltorito_descriptor_fixed {
+ /** Descriptor type */
+ uint8_t type;
+ /** Identifier ("CD001") */
+ uint8_t id[5];
+ /** Version, must be 1 */
+ uint8_t version;
+ /** Boot system indicator; must be "EL TORITO SPECIFICATION" */
+ uint8_t system_id[32];
+} __attribute__ (( packed ));
+
+/** An El Torito Boot Record Volume Descriptor */
+struct eltorito_descriptor {
+ /** Fixed portion */
+ struct eltorito_descriptor_fixed fixed;
+ /** Unused */
+ uint8_t unused[32];
+ /** Boot catalog sector */
+ uint32_t sector;
+} __attribute__ (( packed ));
+
+/** ISO9660 Boot Volume Descriptor type */
+#define ISO9660_TYPE_BOOT 0x00
+
+/** El Torito Boot Record Volume Descriptor block address */
+#define ELTORITO_LBA 17
+
+/** An El Torito Boot Catalog Validation Entry */
+struct eltorito_validation_entry {
+ /** Header ID; must be 1 */
+ uint8_t header_id;
+ /** Platform ID
+ *
+ * 0 = 80x86
+ * 1 = PowerPC
+ * 2 = Mac
+ */
+ uint8_t platform_id;
+ /** Reserved */
+ uint16_t reserved;
+ /** ID string */
+ uint8_t id_string[24];
+ /** Checksum word */
+ uint16_t checksum;
+ /** Signature; must be 0xaa55 */
+ uint16_t signature;
+} __attribute__ (( packed ));
+
+/** El Torito platform IDs */
+enum eltorito_platform_id {
+ ELTORITO_PLATFORM_X86 = 0x00,
+ ELTORITO_PLATFORM_POWERPC = 0x01,
+ ELTORITO_PLATFORM_MAC = 0x02,
+};
+
+/** A bootable entry in the El Torito Boot Catalog */
+struct eltorito_boot_entry {
+ /** Boot indicator
+ *
+ * Must be @c ELTORITO_BOOTABLE for a bootable ISO image
+ */
+ uint8_t indicator;
+ /** Media type
+ *
+ */
+ uint8_t media_type;
+ /** Load segment */
+ uint16_t load_segment;
+ /** System type */
+ uint8_t filesystem;
+ /** Unused */
+ uint8_t reserved_a;
+ /** Sector count */
+ uint16_t length;
+ /** Starting sector */
+ uint32_t start;
+ /** Unused */
+ uint8_t reserved_b[20];
+} __attribute__ (( packed ));
+
+/** Boot indicator for a bootable ISO image */
+#define ELTORITO_BOOTABLE 0x88
+
+/** El Torito media types */
+enum eltorito_media_type {
+ /** No emulation */
+ ELTORITO_NO_EMULATION = 0,
+};
#endif /* INT13_H */
|
[-]
[+]
|
Changed |
ipxe.tar.bz2/src/arch/i386/include/ipxe/bios_sanboot.h
^
|
@@ -15,4 +15,15 @@
#define SANBOOT_PREFIX_pcbios __pcbios_
#endif
+/**
+ * Get default SAN drive number
+ *
+ * @ret drive Default drive number
+ */
+static inline __always_inline unsigned int
+SANBOOT_INLINE ( pcbios, san_default_drive ) ( void ) {
+ /* Default to booting from first hard disk */
+ return 0x80;
+}
+
#endif /* _IPXE_BIOS_SANBOOT_H */
|
[-]
[+]
|
Changed |
ipxe.tar.bz2/src/arch/i386/interface/pcbios/int13.c
^
|
@@ -91,6 +91,13 @@
/** Block device capacity */
struct block_device_capacity capacity;
+ /** INT 13 emulated blocksize shift
+ *
+ * To allow for emulation of CD-ROM access, this represents
+ * the left-shift required to translate from INT 13 blocks to
+ * underlying blocks.
+ */
+ unsigned int blksize_shift;
/** Number of cylinders
*
@@ -117,6 +124,11 @@
*/
unsigned int sectors_per_track;
+ /** Drive is a CD-ROM */
+ int is_cdrom;
+ /** Address of El Torito boot catalog (if any) */
+ unsigned int boot_catalog;
+
/** Underlying device status, if in error */
int block_rc;
/** Status of last operation */
@@ -142,6 +154,37 @@
*/
static uint8_t num_drives;
+/**
+ * Calculate INT 13 drive sector size
+ *
+ * @v int13 Emulated drive
+ * @ret blksize Sector size
+ */
+static inline unsigned int int13_blksize ( struct int13_drive *int13 ) {
+ return ( int13->capacity.blksize << int13->blksize_shift );
+}
+
+/**
+ * Calculate INT 13 drive capacity
+ *
+ * @v int13 Emulated drive
+ * @ret blocks Number of blocks
+ */
+static inline uint64_t int13_capacity ( struct int13_drive *int13 ) {
+ return ( int13->capacity.blocks >> int13->blksize_shift );
+}
+
+/**
+ * Calculate INT 13 drive capacity (limited to 32 bits)
+ *
+ * @v int13 Emulated drive
+ * @ret blocks Number of blocks
+ */
+static inline uint32_t int13_capacity32 ( struct int13_drive *int13 ) {
+ uint64_t capacity = int13_capacity ( int13 );
+ return ( ( capacity <= 0xffffffffUL ) ? capacity : 0xffffffff );
+}
+
/** An INT 13 command */
struct int13_command {
/** Status */
@@ -319,6 +362,10 @@
size_t frag_len;
int rc;
+ /* Translate to underlying blocksize */
+ lba <<= int13->blksize_shift;
+ count <<= int13->blksize_shift;
+
while ( count ) {
/* Determine fragment length */
@@ -371,29 +418,111 @@
}
/**
+ * Parse ISO9660 parameters
+ *
+ * @v int13 Emulated drive
+ * @v scratch Scratch area for single-sector reads
+ * @ret rc Return status code
+ *
+ * Reads and parses ISO9660 parameters, if present.
+ */
+static int int13_parse_iso9660 ( struct int13_drive *int13, void *scratch ) {
+ static const struct iso9660_primary_descriptor_fixed primary_check = {
+ .type = ISO9660_TYPE_PRIMARY,
+ .id = ISO9660_ID,
+ };
+ struct iso9660_primary_descriptor *primary = scratch;
+ static const struct eltorito_descriptor_fixed boot_check = {
+ .type = ISO9660_TYPE_BOOT,
+ .id = ISO9660_ID,
+ .version = 1,
+ .system_id = "EL TORITO SPECIFICATION",
+ };
+ struct eltorito_descriptor *boot = scratch;
+ unsigned int blksize;
+ unsigned int blksize_shift;
+ int rc;
+
+ /* Calculate required blocksize shift */
+ blksize = int13_blksize ( int13 );
+ blksize_shift = 0;
+ while ( blksize < ISO9660_BLKSIZE ) {
+ blksize <<= 1;
+ blksize_shift++;
+ }
+ if ( blksize > ISO9660_BLKSIZE ) {
+ /* Do nothing if the blksize is invalid for CD-ROM access */
+ return 0;
+ }
+
+ /* Read primary volume descriptor */
+ if ( ( rc = int13_rw ( int13,
+ ( ISO9660_PRIMARY_LBA << blksize_shift ), 1,
+ virt_to_user ( primary ), block_read ) ) != 0 ){
+ DBGC ( int13, "INT13 drive %02x could not read ISO9660 "
+ "primary volume descriptor: %s\n",
+ int13->drive, strerror ( rc ) );
+ return rc;
+ }
+
+ /* Do nothing unless this is an ISO image */
+ if ( memcmp ( primary, &primary_check, sizeof ( primary_check ) ) != 0 )
+ return 0;
+ DBGC ( int13, "INT13 drive %02x contains an ISO9660 filesystem; "
+ "treating as CD-ROM\n", int13->drive );
+ int13->is_cdrom = 1;
+
+ /* Read boot record volume descriptor */
+ if ( ( rc = int13_rw ( int13,
+ ( ELTORITO_LBA << blksize_shift ), 1,
+ virt_to_user ( boot ), block_read ) ) != 0 ) {
+ DBGC ( int13, "INT13 drive %02x could not read El Torito boot "
+ "record volume descriptor: %s\n",
+ int13->drive, strerror ( rc ) );
+ return rc;
+ }
+
+ /* Check for an El Torito boot catalog */
+ if ( memcmp ( boot, &boot_check, sizeof ( boot_check ) ) == 0 ) {
+ int13->boot_catalog = boot->sector;
+ DBGC ( int13, "INT13 drive %02x has an El Torito boot catalog "
+ "at LBA %08x\n", int13->drive, int13->boot_catalog );
+ } else {
+ DBGC ( int13, "INT13 drive %02x has no El Torito boot "
+ "catalog\n", int13->drive );
+ }
+
+ /* Configure drive for no-emulation CD-ROM access */
+ int13->blksize_shift += blksize_shift;
+
+ return 0;
+}
+
+/**
* Guess INT 13 drive geometry
*
* @v int13 Emulated drive
+ * @v scratch Scratch area for single-sector reads
* @ret rc Return status code
*
* Guesses the drive geometry by inspecting the partition table.
*/
-static int int13_guess_geometry ( struct int13_drive *int13 ) {
- struct master_boot_record mbr;
+static int int13_guess_geometry ( struct int13_drive *int13, void *scratch ) {
+ struct master_boot_record *mbr = scratch;
struct partition_table_entry *partition;
unsigned int guessed_heads = 255;
unsigned int guessed_sectors_per_track = 63;
- unsigned long blocks;
- unsigned long blocks_per_cyl;
+ unsigned int blocks;
+ unsigned int blocks_per_cyl;
unsigned int i;
int rc;
/* Don't even try when the blksize is invalid for C/H/S access */
- if ( int13->capacity.blksize != INT13_BLKSIZE )
+ if ( int13_blksize ( int13 ) != INT13_BLKSIZE )
return 0;
/* Read partition table */
- if ( ( rc = int13_rw ( int13, 0, 1, virt_to_user ( &mbr ),
+ if ( ( rc = int13_rw ( int13, 0, 1, virt_to_user ( mbr ),
block_read ) ) != 0 ) {
DBGC ( int13, "INT13 drive %02x could not read partition "
"table to guess geometry: %s\n",
@@ -401,15 +530,15 @@
return rc;
}
DBGC2 ( int13, "INT13 drive %02x has MBR:\n", int13->drive );
- DBGC2_HDA ( int13, 0, &mbr, sizeof ( mbr ) );
+ DBGC2_HDA ( int13, 0, mbr, sizeof ( *mbr ) );
DBGC ( int13, "INT13 drive %02x has signature %08x\n",
- int13->drive, mbr.signature );
+ int13->drive, mbr->signature );
/* Scan through partition table and modify guesses for heads
* and sectors_per_track if we find any used partitions.
*/
for ( i = 0 ; i < 4 ; i++ ) {
- partition = &mbr.partitions[i];
+ partition = &mbr->partitions[i];
if ( ! partition->type )
continue;
guessed_heads = ( PART_HEAD ( partition->chs_end ) + 1 );
@@ -426,8 +555,7 @@
int13->sectors_per_track = guessed_sectors_per_track;
if ( ! int13->cylinders ) {
/* Avoid attempting a 64-bit divide on a 32-bit system */
- blocks = ( ( int13->capacity.blocks <= ULONG_MAX ) ?
- int13->capacity.blocks : ULONG_MAX );
+ blocks = int13_capacity32 ( int13 );
blocks_per_cyl = ( int13->heads * int13->sectors_per_track );
assert ( blocks_per_cyl != 0 );
int13->cylinders = ( blocks / blocks_per_cyl );
@@ -535,10 +663,10 @@
int rc;
/* Validate blocksize */
- if ( int13->capacity.blksize != INT13_BLKSIZE ) {
+ if ( int13_blksize ( int13 ) != INT13_BLKSIZE ) {
DBGC ( int13, "\nINT 13 drive %02x invalid blocksize (%zd) "
"for non-extended read/write\n",
- int13->drive, int13->capacity.blksize );
+ int13->drive, int13_blksize ( int13 ) );
return -INT13_STATUS_INVALID;
}
@@ -625,6 +753,14 @@
DBGC2 ( int13, "Get drive parameters\n" );
+ /* Validate blocksize */
+ if ( int13_blksize ( int13 ) != INT13_BLKSIZE ) {
+ DBGC ( int13, "\nINT 13 drive %02x invalid blocksize (%zd) "
+ "for non-extended parameters\n",
+ int13->drive, int13_blksize ( int13 ) );
+ return -INT13_STATUS_INVALID;
+ }
+
ix86->regs.ch = ( max_cylinder & 0xff );
ix86->regs.cl = ( ( ( max_cylinder >> 8 ) << 6 ) | max_sector );
ix86->regs.dh = max_head;
@@ -645,8 +781,7 @@
uint32_t blocks;
DBGC2 ( int13, "Get disk type\n" );
- blocks = ( ( int13->capacity.blocks <= 0xffffffffUL ) ?
- int13->capacity.blocks : 0xffffffffUL );
+ blocks = int13_capacity32 ( int13 );
ix86->regs.cx = ( blocks >> 16 );
ix86->regs.dx = ( blocks & 0xffff );
return INT13_DISK_TYPE_HDD;
@@ -916,14 +1051,14 @@
memset ( ¶ms, 0, sizeof ( params ) );
params.flags = INT13_FL_DMA_TRANSPARENT;
if ( ( int13->cylinders < 1024 ) &&
- ( int13->capacity.blocks <= INT13_MAX_CHS_SECTORS ) ) {
+ ( int13_capacity ( int13 ) <= INT13_MAX_CHS_SECTORS ) ) {
params.flags |= INT13_FL_CHS_VALID;
}
params.cylinders = int13->cylinders;
params.heads = int13->heads;
params.sectors_per_track = int13->sectors_per_track;
- params.sectors = int13->capacity.blocks;
- params.sector_size = int13->capacity.blksize;
+ params.sectors = int13_capacity ( int13 );
+ params.sector_size = int13_blksize ( int13 );
memset ( ¶ms.dpte, 0xff, sizeof ( params.dpte ) );
if ( ( rc = int13_device_path_info ( int13, ¶ms.dpi ) ) != 0 ) {
DBGC ( int13, "INT13 drive %02x could not provide device "
@@ -959,6 +1094,77 @@
}
/**
+ * INT 13, 4b - Get status or terminate CD-ROM emulation
+ *
+ * @v int13 Emulated drive
+ * @v ds:si Specification packet
+ * @ret status Status code
+ */
+static int int13_cdrom_status_terminate ( struct int13_drive *int13,
+ struct i386_all_regs *ix86 ) {
+ struct int13_cdrom_specification specification;
+
+ DBGC2 ( int13, "Get CD-ROM emulation status to %04x:%04x%s\n",
+ ix86->segs.ds, ix86->regs.si,
+ ( ix86->regs.al ? "" : " and terminate" ) );
+
+ /* Fail if we are not a CD-ROM */
+ if ( ! int13->is_cdrom ) {
+ DBGC ( int13, "INT13 drive %02x is not a CD-ROM\n",
+ int13->drive );
+ return -INT13_STATUS_INVALID;
+ }
+
+ /* Build specification packet */
+ memset ( &specification, 0, sizeof ( specification ) );
+ specification.size = sizeof ( specification );
+ specification.drive = int13->drive;
+
+ /* Return specification packet */
+ copy_to_real ( ix86->segs.ds, ix86->regs.si, &specification,
+ sizeof ( specification ) );
+
+ return 0;
+}
+
+
+/**
+ * INT 13, 4d - Read CD-ROM boot catalog
+ *
+ * @v int13 Emulated drive
+ * @v ds:si Command packet
+ * @ret status Status code
+ */
+static int int13_cdrom_read_boot_catalog ( struct int13_drive *int13,
+ struct i386_all_regs *ix86 ) {
+ struct int13_cdrom_boot_catalog_command command;
+ int rc;
+
+ /* Read parameters from command packet */
+ copy_from_real ( &command, ix86->segs.ds, ix86->regs.si,
+ sizeof ( command ) );
+ DBGC2 ( int13, "Read CD-ROM boot catalog to %08x\n", command.buffer );
+
+ /* Fail if we have no boot catalog */
+ if ( ! int13->boot_catalog ) {
+ DBGC ( int13, "INT13 drive %02x has no boot catalog\n",
+ int13->drive );
+ return -INT13_STATUS_INVALID;
+ }
+
+ /* Read from boot catalog */
+ if ( ( rc = int13_rw ( int13, ( int13->boot_catalog + command.start ),
+ command.count, phys_to_user ( command.buffer ),
+ block_read ) ) != 0 ) {
+ DBGC ( int13, "INT13 drive %02x could not read boot catalog: "
+ "%s\n", int13->drive, strerror ( rc ) );
+ return -INT13_STATUS_READ_ERROR;
+ }
+
+ return 0;
+}
+
+/**
* INT 13 handler
*
*/
@@ -981,12 +1187,17 @@
bios_drive, int13->drive );
ix86->regs.dl = int13->drive;
return;
+ } else if ( ( ( bios_drive & 0x7f ) == 0x7f ) &&
+ ( command == INT13_CDROM_STATUS_TERMINATE )
+ && int13->is_cdrom ) {
+ /* Catch non-drive-specific CD-ROM calls */
+ } else {
+ continue;
}
- continue;
}
DBGC2 ( int13, "INT13,%02x (%02x): ",
- ix86->regs.ah, int13->drive );
+ ix86->regs.ah, bios_drive );
switch ( command ) {
case INT13_RESET:
@@ -1025,6 +1236,12 @@
case INT13_GET_EXTENDED_PARAMETERS:
status = int13_get_extended_parameters ( int13, ix86 );
break;
+ case INT13_CDROM_STATUS_TERMINATE:
+ status = int13_cdrom_status_terminate ( int13, ix86 );
+ break;
+ case INT13_CDROM_READ_BOOT_CATALOG:
+ status = int13_cdrom_read_boot_catalog ( int13, ix86 );
+ break;
default:
DBGC2 ( int13, "*** Unrecognised INT13 ***\n" );
status = -INT13_STATUS_INVALID;
@@ -1164,8 +1381,8 @@
* Hook INT 13 emulated drive
*
* @v uri URI
- * @v drive Requested drive number
- * @ret drive Assigned drive number, or negative error
+ * @v drive Drive number
+ * @ret rc Return status code
*
* Registers the drive with the INT 13 emulation subsystem, and hooks
* the INT 13 interrupt vector (if not already hooked).
@@ -1174,14 +1391,12 @@
struct int13_drive *int13;
uint8_t num_drives;
unsigned int natural_drive;
+ void *scratch;
int rc;
- /* Calculate drive number */
+ /* Calculate natural drive number */
get_real ( num_drives, BDA_SEG, BDA_NUM_DRIVES );
natural_drive = ( num_drives | 0x80 );
- if ( drive == INT13_USE_NATURAL_DRIVE )
- drive = natural_drive;
- drive |= 0x80;
/* Check that drive number is not in use */
list_for_each_entry ( int13, &int13s, list ) {
@@ -1209,10 +1424,19 @@
/* Read device capacity */
if ( ( rc = int13_read_capacity ( int13 ) ) != 0 )
- return rc;
+ goto err_read_capacity;
+
+ /* Allocate scratch area */
+ scratch = malloc ( int13_blksize ( int13 ) );
+ if ( ! scratch )
+ goto err_alloc_scratch;
+
+ /* Parse parameters, if present */
+ if ( ( rc = int13_parse_iso9660 ( int13, scratch ) ) != 0 )
+ goto err_parse_iso9660;
/* Give drive a default geometry */
- if ( ( rc = int13_guess_geometry ( int13 ) ) != 0 )
+ if ( ( rc = int13_guess_geometry ( int13, scratch ) ) != 0 )
goto err_guess_geometry;
DBGC ( int13, "INT13 drive %02x (naturally %02x) registered with C/H/S "
@@ -1231,9 +1455,14 @@
/* Update BIOS drive count */
int13_set_num_drives();
- return int13->drive;
+ free ( scratch );
+ return 0;
err_guess_geometry:
+ err_parse_iso9660:
+ free ( scratch );
+ err_alloc_scratch:
+ err_read_capacity:
err_reopen_block:
intf_shutdown ( &int13->block, rc );
ref_put ( &int13->refcnt );
@@ -1300,52 +1529,171 @@
}
/**
- * Attempt to boot from an INT 13 drive
+ * Load and verify master boot record from INT 13 drive
*
* @v drive Drive number
+ * @v address Boot code address to fill in
* @ret rc Return status code
- *
- * This boots from the specified INT 13 drive by loading the Master
- * Boot Record to 0000:7c00 and jumping to it. INT 18 is hooked to
- * capture an attempt by the MBR to boot the next device. (This is
- * the closest thing to a return path from an MBR).
- *
- * Note that this function can never return success, by definition.
*/
-static int int13_boot ( unsigned int drive ) {
- struct memory_map memmap;
- int status, signature;
- int discard_c, discard_d;
- int rc;
-
- DBG ( "INT13 drive %02x booting\n", drive );
-
- /* Use INT 13 to read the boot sector */
+static int int13_load_mbr ( unsigned int drive, struct segoff *address ) {
+ uint8_t status;
+ int discard_b, discard_c, discard_d;
+ uint16_t magic;
+
+ /* Use INT 13, 02 to read the MBR */
+ address->segment = 0;
+ address->offset = 0x7c00;
__asm__ __volatile__ ( REAL_CODE ( "pushw %%es\n\t"
- "pushw $0\n\t"
+ "pushl %%ebx\n\t"
+ "popw %%bx\n\t"
"popw %%es\n\t"
"stc\n\t"
"sti\n\t"
"int $0x13\n\t"
"sti\n\t" /* BIOS bugs */
"jc 1f\n\t"
- "xorl %%eax, %%eax\n\t"
+ "xorw %%ax, %%ax\n\t"
"\n1:\n\t"
- "movzwl %%es:0x7dfe, %%ebx\n\t"
"popw %%es\n\t" )
- : "=a" ( status ), "=b" ( signature ),
+ : "=a" ( status ), "=b" ( discard_b ),
"=c" ( discard_c ), "=d" ( discard_d )
- : "a" ( 0x0201 ), "b" ( 0x7c00 ),
+ : "a" ( 0x0201 ), "b" ( *address ),
"c" ( 1 ), "d" ( drive ) );
- if ( status )
+ if ( status ) {
+ DBG ( "INT13 drive %02x could not read MBR (status %02x)\n",
+ drive, status );
+ return -EIO;
+ }
+
+ /* Check magic signature */
+ get_real ( magic, address->segment,
+ ( address->offset +
+ offsetof ( struct master_boot_record, magic ) ) );
+ if ( magic != INT13_MBR_MAGIC ) {
+ DBG ( "INT13 drive %02x does not contain a valid MBR\n",
+ drive );
+ return -ENOEXEC;
+ }
+
+ return 0;
+}
+
+/** El Torito boot catalog command packet */
+static struct int13_cdrom_boot_catalog_command __data16 ( eltorito_cmd ) = {
+ .size = sizeof ( struct int13_cdrom_boot_catalog_command ),
+ .count = 1,
+ .buffer = 0x7c00,
+ .start = 0,
+};
+#define eltorito_cmd __use_data16 ( eltorito_cmd )
+
+/** El Torito disk address packet */
+static struct int13_disk_address __bss16 ( eltorito_address );
+#define eltorito_address __use_data16 ( eltorito_address )
+
+/**
+ * Load and verify El Torito boot record from INT 13 drive
+ *
+ * @v drive Drive number
+ * @v address Boot code address to fill in
+ * @ret rc Return status code
+ */
+static int int13_load_eltorito ( unsigned int drive, struct segoff *address ) {
+ struct {
+ struct eltorito_validation_entry valid;
+ struct eltorito_boot_entry boot;
+ } __attribute__ (( packed )) catalog;
+ uint8_t status;
+
+ /* Use INT 13, 4d to read the boot catalog */
+ __asm__ __volatile__ ( REAL_CODE ( "stc\n\t"
+ "sti\n\t"
+ "int $0x13\n\t"
+ "sti\n\t" /* BIOS bugs */
+ "jc 1f\n\t"
+ "xorw %%ax, %%ax\n\t"
+ "\n1:\n\t" )
+ : "=a" ( status )
+ : "a" ( 0x4d00 ), "d" ( drive ),
+ "S" ( __from_data16 ( &eltorito_cmd ) ) );
+ if ( status ) {
+ DBG ( "INT13 drive %02x could not read El Torito boot catalog "
+ "(status %02x)\n", drive, status );
return -EIO;
+ }
+ copy_from_user ( &catalog, phys_to_user ( eltorito_cmd.buffer ), 0,
+ sizeof ( catalog ) );
- /* Check signature is correct */
- if ( signature != be16_to_cpu ( 0x55aa ) ) {
- DBG ( "INT13 drive %02x invalid disk signature %#04x (should "
- "be 0x55aa)\n", drive, cpu_to_be16 ( signature ) );
+ /* Sanity checks */
+ if ( catalog.valid.platform_id != ELTORITO_PLATFORM_X86 ) {
+ DBG ( "INT13 drive %02x El Torito specifies unknown platform "
+ "%02x\n", drive, catalog.valid.platform_id );
return -ENOEXEC;
}
+ if ( catalog.boot.indicator != ELTORITO_BOOTABLE ) {
+ DBG ( "INT13 drive %02x El Torito is not bootable\n", drive );
+ return -ENOEXEC;
+ }
+ if ( catalog.boot.media_type != ELTORITO_NO_EMULATION ) {
+ DBG ( "INT13 drive %02x El Torito requires emulation "
+ "type %02x\n", drive, catalog.boot.media_type );
+ return -ENOTSUP;
+ }
+ DBG ( "INT13 drive %02x El Torito boot image at LBA %08x (count %d)\n",
+ drive, catalog.boot.start, catalog.boot.length );
+ address->segment = ( catalog.boot.load_segment ?
+ catalog.boot.load_segment : 0x7c0 );
+ address->offset = 0;
+ DBG ( "INT13 drive %02x El Torito boot image loads at %04x:%04x\n",
+ drive, address->segment, address->offset );
+
+ /* Use INT 13, 42 to read the boot image */
+ eltorito_address.bufsize =
+ offsetof ( typeof ( eltorito_address ), buffer_phys );
+ eltorito_address.count = catalog.boot.length;
+ eltorito_address.buffer = *address;
+ eltorito_address.lba = catalog.boot.start;
+ __asm__ __volatile__ ( REAL_CODE ( "stc\n\t"
+ "sti\n\t"
+ "int $0x13\n\t"
+ "sti\n\t" /* BIOS bugs */
+ "jc 1f\n\t"
+ "xorw %%ax, %%ax\n\t"
+ "\n1:\n\t" )
+ : "=a" ( status )
+ : "a" ( 0x4200 ), "d" ( drive ),
+ "S" ( __from_data16 ( &eltorito_address ) ) );
+ if ( status ) {
+ DBG ( "INT13 drive %02x could not read El Torito boot image "
+ "(status %02x)\n", drive, status );
+ return -EIO;
+ }
+
+ return 0;
+}
+
+/**
+ * Attempt to boot from an INT 13 drive
+ *
+ * @v drive Drive number
+ * @ret rc Return status code
+ *
+ * This boots from the specified INT 13 drive by loading the Master
+ * Boot Record to 0000:7c00 and jumping to it. INT 18 is hooked to
+ * capture an attempt by the MBR to boot the next device. (This is
+ * the closest thing to a return path from an MBR).
+ *
+ * Note that this function can never return success, by definition.
+ */
+static int int13_boot ( unsigned int drive ) {
+ struct memory_map memmap;
+ struct segoff address;
+ int rc;
+
+ /* Look for a usable boot sector */
+ if ( ( ( rc = int13_load_mbr ( drive, &address ) ) != 0 ) &&
+ ( ( rc = int13_load_eltorito ( drive, &address ) ) != 0 ) )
+ return rc;
/* Dump out memory map prior to boot, if memmap debugging is
* enabled. Not required for program flow, but we have so
@@ -1355,7 +1703,8 @@
get_memmap ( &memmap );
/* Jump to boot sector */
- if ( ( rc = call_bootsector ( 0x0, 0x7c00, drive ) ) != 0 ) {
+ if ( ( rc = call_bootsector ( address.segment, address.offset,
+ drive ) ) != 0 ) {
DBG ( "INT13 drive %02x boot returned: %s\n",
drive, strerror ( rc ) );
return rc;
@@ -1428,6 +1777,7 @@
return 0;
}
+PROVIDE_SANBOOT_INLINE ( pcbios, san_default_drive );
PROVIDE_SANBOOT ( pcbios, san_hook, int13_hook );
PROVIDE_SANBOOT ( pcbios, san_unhook, int13_unhook );
PROVIDE_SANBOOT ( pcbios, san_boot, int13_boot );
|
[-]
[+]
|
Changed |
ipxe.tar.bz2/src/arch/i386/prefix/romprefix.S
^
|
@@ -104,6 +104,11 @@
.long 0
.previous
+ /* PnP doesn't require any particular alignment, but IBM
+ * BIOSes will scan on 16-byte boundaries rather than using
+ * the offset stored at 0x1a
+ */
+ .align 16
pnpheader:
.ascii "$PnP" /* Signature */
.byte 0x01 /* Structure revision */
@@ -286,6 +291,7 @@
call print_message
jmp pnp_done
no_pnp: /* Not PnP-compliant - hook INT 19 */
+#ifdef NONPNP_HOOK_INT19
movw $init_message_int19, %si
xorw %di, %di
call print_message
@@ -296,6 +302,7 @@
pushw %gs /* %gs contains runtime %cs */
pushw $int19_entry
popl %es:( 0x19 * 4 )
+#endif /* NONPNP_HOOK_INT19 */
pnp_done:
/* Check for PMM */
|
[-]
[+]
|
Changed |
ipxe.tar.bz2/src/arch/i386/scripts/i386.lds
^
|
@@ -39,8 +39,8 @@
} .bss.prefix (NOLOAD) : AT ( _end_lma ) {
_eprefix = .;
}
- _prefix_filesz = ABSOLUTE ( _mprefix - _prefix );
- _prefix_memsz = ABSOLUTE ( _eprefix - _prefix );
+ _prefix_filesz = ABSOLUTE ( _mprefix ) - ABSOLUTE ( _prefix );
+ _prefix_memsz = ABSOLUTE ( _eprefix ) - ABSOLUTE ( _prefix );
/*
* The 16-bit (real-mode) code section
@@ -63,11 +63,11 @@
} .bss.text16 (NOLOAD) : AT ( _end_lma ) {
_etext16 = .;
}
- _text16_early_filesz = ABSOLUTE ( _etext16_early - _text16 );
- _text16_early_memsz = ABSOLUTE ( _etext16_early - _text16 );
- _text16_late_filesz = ABSOLUTE ( _mtext16 - _text16_late );
- _text16_late_memsz = ABSOLUTE ( _etext16 - _text16_late );
- _text16_memsz = ABSOLUTE ( _etext16 - _text16 );
+ _text16_early_filesz = ABSOLUTE ( _etext16_early ) - ABSOLUTE ( _text16 );
+ _text16_early_memsz = ABSOLUTE ( _etext16_early ) - ABSOLUTE ( _text16 );
+ _text16_late_filesz = ABSOLUTE ( _mtext16 ) - ABSOLUTE ( _text16_late );
+ _text16_late_memsz = ABSOLUTE ( _etext16 ) - ABSOLUTE ( _text16_late );
+ _text16_memsz = ABSOLUTE ( _etext16 ) - ABSOLUTE ( _text16 );
/*
* The 16-bit (real-mode) data section
@@ -89,8 +89,8 @@
*(.stack16.*)
_edata16 = .;
}
- _data16_filesz = ABSOLUTE ( _mdata16 - _data16 );
- _data16_memsz = ABSOLUTE ( _edata16 - _data16 );
+ _data16_filesz = ABSOLUTE ( _mdata16 ) - ABSOLUTE ( _data16 );
+ _data16_memsz = ABSOLUTE ( _edata16 ) - ABSOLUTE ( _data16 );
/*
* The 32-bit sections
@@ -118,8 +118,8 @@
*(.stack.*)
_etextdata = .;
}
- _textdata_filesz = ABSOLUTE ( _mtextdata - _textdata );
- _textdata_memsz = ABSOLUTE ( _etextdata - _textdata );
+ _textdata_filesz = ABSOLUTE ( _mtextdata ) - ABSOLUTE ( _textdata );
+ _textdata_memsz = ABSOLUTE ( _etextdata ) - ABSOLUTE ( _textdata );
/*
* Compressor information block
@@ -134,8 +134,8 @@
} .bss.zinfo (NOLOAD) : AT ( _end_lma ) {
_ezinfo = .;
}
- _zinfo_filesz = ABSOLUTE ( _mzinfo - _zinfo );
- _zinfo_memsz = ABSOLUTE ( _ezinfo - _zinfo );
+ _zinfo_filesz = ABSOLUTE ( _mzinfo ) - ABSOLUTE ( _zinfo );
+ _zinfo_memsz = ABSOLUTE ( _ezinfo ) - ABSOLUTE ( _zinfo );
/*
* Weak symbols that need zero values if not otherwise defined
|
[-]
[+]
|
Changed |
ipxe.tar.bz2/src/arch/x86_64/core/linux/linuxprefix.S
^
|
(renamed to src/arch/x86_64/core/linux/linuxprefix.S)
|
[-]
[+]
|
Changed |
ipxe.tar.bz2/src/arch/x86_64/core/linux/linuxprefix.S
^
|
(renamed to src/arch/x86_64/core/linux/linuxprefix.S)
|
[-]
[+]
|
Deleted |
ipxe.tar.bz2/src/arch/x86_64/prefix
^
|
-(directory)
|
[-]
[+]
|
Added |
ipxe.tar.bz2/src/bin/.gitignore
^
|
@@ -0,0 +1 @@
+*
|
[-]
[+]
|
Added |
ipxe.tar.bz2/src/config/.gitignore
^
|
@@ -0,0 +1 @@
+.buildserial.*
|
[-]
[+]
|
Changed |
ipxe.tar.bz2/src/config/general.h
^
|
@@ -128,6 +128,12 @@
#undef REBOOT_CMD /* Reboot command */
/*
+ * ROM-specific options
+ *
+ */
+#undef NONPNP_HOOK_INT19 /* Hook INT19 on non-PnP BIOSes */
+
+/*
* Error message tables to include
*
*/
|
[-]
[+]
|
Added |
ipxe.tar.bz2/src/config/local/.gitignore
^
|
@@ -0,0 +1 @@
+*
|
[-]
[+]
|
Changed |
ipxe.tar.bz2/src/core/null_sanboot.c
^
|
@@ -38,6 +38,7 @@
return -EOPNOTSUPP;
}
+PROVIDE_SANBOOT_INLINE ( null, san_default_drive );
PROVIDE_SANBOOT ( null, san_hook, null_san_hook );
PROVIDE_SANBOOT ( null, san_unhook, null_san_unhook );
PROVIDE_SANBOOT ( null, san_boot, null_san_boot );
|
[-]
[+]
|
Changed |
ipxe.tar.bz2/src/core/parseopt.c
^
|
@@ -40,6 +40,17 @@
#define EINFO_ECANCELED_NO_OP \
__einfo_uniqify ( EINFO_ECANCELED, 0x01, "Nothing to do" )
+/* Disambiguate the various error codes */
+#define EINVAL_INTEGER __einfo_error ( EINFO_EINVAL_INTEGER )
+#define EINFO_EINVAL_INTEGER \
+ __einfo_uniqify ( EINFO_EINVAL, 0x01, "Invalid integer value" )
+#define EINVAL_UNKNOWN_OPTION __einfo_error ( EINFO_EINVAL_UNKNOWN_OPTION )
+#define EINFO_EINVAL_UNKNOWN_OPTION \
+ __einfo_uniqify ( EINFO_EINVAL, 0x02, "Unrecognised option" )
+#define EINVAL_MISSING_ARGUMENT __einfo_error ( EINFO_EINVAL_MISSING_ARGUMENT )
+#define EINFO_EINVAL_MISSING_ARGUMENT \
+ __einfo_uniqify ( EINFO_EINVAL, 0x03, "Missing argument" )
+
/**
* Parse string value
*
@@ -75,7 +86,7 @@
*value = strtoul ( text, &endp, 0 );
if ( *endp ) {
printf ( "\"%s\": invalid integer value\n", text );
- return -EINVAL;
+ return -EINVAL_INTEGER;
}
return 0;
@@ -152,16 +163,16 @@
}
/**
- * Parse command-line options
+ * Reparse command-line options
*
* @v argc Argument count
* @v argv Argument list
* @v cmd Command descriptor
- * @v opts Options
+ * @v opts Options (already initialised with default values)
* @ret rc Return status code
*/
-int parse_options ( int argc, char **argv, struct command_descriptor *cmd,
- void *opts ) {
+int reparse_options ( int argc, char **argv, struct command_descriptor *cmd,
+ void *opts ) {
struct option longopts[ cmd->num_options + 1 /* help */ + 1 /* end */ ];
char shortopts[ cmd->num_options * 3 /* possible "::" */ + 1 /* "h" */
+ 1 /* NUL */ ];
@@ -193,9 +204,6 @@
DBGC ( cmd, "Command \"%s\" has options \"%s\", %d-%d args, len %d\n",
argv[0], shortopts, cmd->min_args, cmd->max_args, cmd->len );
- /* Clear options */
- memset ( opts, 0, cmd->len );
-
/* Parse options */
while ( ( c = getopt_long ( argc, argv, shortopts, longopts,
NULL ) ) >= 0 ) {
@@ -205,10 +213,13 @@
print_usage ( cmd, argv );
return -ECANCELED_NO_OP;
case '?' :
+ /* Print usage message */
+ print_usage ( cmd, argv );
+ return -EINVAL_UNKNOWN_OPTION;
case ':' :
/* Print usage message */
print_usage ( cmd, argv );
- return -EINVAL;
+ return -EINVAL_MISSING_ARGUMENT;
default:
/* Search for an option to parse */
for ( i = 0 ; i < cmd->num_options ; i++ ) {
@@ -233,3 +244,21 @@
return 0;
}
+
+/**
+ * Parse command-line options
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @v cmd Command descriptor
+ * @v opts Options (may be uninitialised)
+ * @ret rc Return status code
+ */
+int parse_options ( int argc, char **argv, struct command_descriptor *cmd,
+ void *opts ) {
+
+ /* Clear options */
+ memset ( opts, 0, cmd->len );
+
+ return reparse_options ( argc, argv, cmd, opts );
+}
|
[-]
[+]
|
Changed |
ipxe.tar.bz2/src/drivers/infiniband/hermon.c
^
|
@@ -3382,56 +3382,32 @@
union {
uint8_t bytes[8];
uint32_t dwords[2];
- uint64_t qword;
} buf;
- uint8_t *mac_copy = &buf.bytes[ sizeof ( buf.bytes ) - ETH_ALEN ];
int rc;
/* Prepare MAC address */
memset ( &buf, 0, sizeof ( buf ) );
- memcpy ( mac_copy, mac, ETH_ALEN );
+ memcpy ( &buf.bytes[ sizeof ( buf.bytes ) - ETH_ALEN ], mac,
+ ETH_ALEN );
- /* Current BOFM versions are unable to create entries with
- * mport>1, which means that only the port 1 MAC address can
- * be explicitly specified. Work around this by using the
- * provided MAC address as a base address for all subsequent
- * ports. For example, if BOFM assigns the address
- *
- * 00:1A:64:76:00:09 for port 1
- *
- * then we will assign the addresses
- *
- * 00:1A:64:76:00:09 for port 1
- * 00:1A:64:76:00:0a for port 2
- *
- * Note that hermon->cap.num_ports is not yet defined at this
- * point.
- */
- for ( ; mport <= HERMON_MAX_PORTS ; mport++ ) {
-
- /* Modify static configuration */
- memset ( &stat_cfg, 0, sizeof ( stat_cfg ) );
- MLX_FILL_2 ( &stat_cfg, 36,
- mac_m, 1,
- mac_high, ntohl ( buf.dwords[0] ) );
- MLX_FILL_1 ( &stat_cfg, 37, mac_low, ntohl ( buf.dwords[1] ) );
- if ( ( rc = hermon_mod_stat_cfg ( hermon, mport,
+ /* Modify static configuration */
+ memset ( &stat_cfg, 0, sizeof ( stat_cfg ) );
+ MLX_FILL_2 ( &stat_cfg, 36,
+ mac_m, 1,
+ mac_high, ntohl ( buf.dwords[0] ) );
+ MLX_FILL_1 ( &stat_cfg, 37, mac_low, ntohl ( buf.dwords[1] ) );
+ if ( ( rc = hermon_mod_stat_cfg ( hermon, mport,
HERMON_MOD_STAT_CFG_SET,
HERMON_MOD_STAT_CFG_OFFSET ( mac_m ),
&stat_cfg ) ) != 0 ) {
- DBGC ( hermon, "Hermon %p port %d could not modify "
- "configuration: %s\n",
- hermon, mport, strerror ( rc ) );
- return rc;
- }
-
- DBGC ( hermon, "Hermon %p port %d updated MAC address to %s\n",
- hermon, mport, eth_ntoa ( mac_copy ) );
-
- /* Increment MAC address */
- buf.qword = cpu_to_be64 ( be64_to_cpu ( buf.qword ) + 1 );
+ DBGC ( hermon, "Hermon %p port %d could not modify "
+ "configuration: %s\n", hermon, mport, strerror ( rc ) );
+ return rc;
}
+ DBGC ( hermon, "Hermon %p port %d updated MAC address to %s\n",
+ hermon, mport, eth_ntoa ( mac ) );
+
return 0;
}
|
[-]
[+]
|
Changed |
ipxe.tar.bz2/src/drivers/net/forcedeth.c
^
|
@@ -61,6 +61,7 @@
static inline void pci_push ( void *ioaddr )
{
/* force out pending posted writes */
+ wmb();
readl ( ioaddr );
}
@@ -334,6 +335,7 @@
void *ioaddr = priv->mmio_addr;
writel ( 0, ioaddr + NvRegIrqMask );
+ pci_push ( ioaddr );
}
static void
@@ -764,7 +766,6 @@
ioaddr + NvRegPowerState );
nv_disable_hw_interrupts ( priv );
- pci_push ( ioaddr );
writel ( NVREG_MIISTAT_MASK_ALL, ioaddr + NvRegMIIStatus );
writel ( NVREG_IRQSTAT_MASK, ioaddr + NvRegIrqStatus );
pci_push ( ioaddr );
@@ -1018,7 +1019,6 @@
forcedeth_close ( struct net_device *netdev )
{
struct forcedeth_private *priv = netdev_priv ( netdev );
- void *ioaddr = priv->mmio_addr;
DBGP ( "forcedeth_close\n" );
@@ -1028,7 +1028,6 @@
/* Disable interrupts on the nic or we will lock up */
nv_disable_hw_interrupts ( priv );
- pci_push ( ioaddr );
nv_free_rxtx_resources ( priv );
|
[-]
[+]
|
Changed |
ipxe.tar.bz2/src/hci/commands/sanboot_cmd.c
^
|
@@ -23,6 +23,7 @@
#include <ipxe/command.h>
#include <ipxe/parseopt.h>
#include <ipxe/uri.h>
+#include <ipxe/sanboot.h>
#include <usr/autoboot.h>
FILE_LICENCE ( GPL2_OR_LATER );
@@ -34,47 +35,92 @@
*/
/** "sanboot" options */
-struct sanboot_options {};
+struct sanboot_options {
+ /** Drive number */
+ unsigned int drive;
+ /** Do not describe SAN device */
+ int no_describe;
+ /** Keep SAN device */
+ int keep;
+};
/** "sanboot" option list */
-static struct option_descriptor sanboot_opts[] = {};
+static struct option_descriptor sanboot_opts[] = {
+ OPTION_DESC ( "drive", 'd', required_argument,
+ struct sanboot_options, drive, parse_integer ),
+ OPTION_DESC ( "no-describe", 'n', no_argument,
+ struct sanboot_options, no_describe, parse_flag ),
+ OPTION_DESC ( "keep", 'k', no_argument,
+ struct sanboot_options, keep, parse_flag ),
+};
+
+/** "sanhook" command descriptor */
+static struct command_descriptor sanhook_cmd =
+ COMMAND_DESC ( struct sanboot_options, sanboot_opts, 1, 1,
+ "[--drive <drive>] [--no-describe] <root-path>" );
/** "sanboot" command descriptor */
static struct command_descriptor sanboot_cmd =
- COMMAND_DESC ( struct sanboot_options, sanboot_opts, 1, 1,
- "<root-path>" );
+ COMMAND_DESC ( struct sanboot_options, sanboot_opts, 0, 1,
+ "[--drive <drive>] [--no-describe] [--keep] "
+ "[<root-path>]" );
+
+/** "sanunhook" command descriptor */
+static struct command_descriptor sanunhook_cmd =
+ COMMAND_DESC ( struct sanboot_options, sanboot_opts, 0, 0,
+ "[--drive <drive>]" );
/**
- * The "sanboot" command
+ * The "sanboot", "sanhook" and "sanunhook" commands
*
* @v argc Argument count
* @v argv Argument list
+ * @v default_flags Default set of flags for uriboot()
+ * @v no_root_path_flags Additional flags to apply if no root path is present
* @ret rc Return status code
*/
-static int sanboot_exec ( int argc, char **argv ) {
+static int sanboot_core_exec ( int argc, char **argv,
+ struct command_descriptor *cmd,
+ int default_flags, int no_root_path_flags ) {
struct sanboot_options opts;
const char *root_path;
struct uri *uri;
+ int flags;
int rc;
+ /* Initialise options */
+ memset ( &opts, 0, sizeof ( opts ) );
+ opts.drive = san_default_drive();
+
/* Parse options */
- if ( ( rc = parse_options ( argc, argv, &sanboot_cmd, &opts ) ) != 0 )
+ if ( ( rc = reparse_options ( argc, argv, cmd, &opts ) ) != 0 )
goto err_parse_options;
- /* Parse root path */
- root_path = argv[optind];
- uri = parse_uri ( root_path );
- if ( ! uri ) {
- rc = -ENOMEM;
- goto err_parse_uri;
+ /* Parse root path, if present */
+ if ( argc > optind ) {
+ root_path = argv[optind];
+ uri = parse_uri ( root_path );
+ if ( ! uri ) {
+ rc = -ENOMEM;
+ goto err_parse_uri;
+ }
+ } else {
+ root_path = NULL;
+ uri = NULL;
}
+ /* Construct flags */
+ flags = default_flags;
+ if ( opts.no_describe )
+ flags |= URIBOOT_NO_SAN_DESCRIBE;
+ if ( opts.keep )
+ flags |= URIBOOT_NO_SAN_UNHOOK;
+ if ( ! root_path )
+ flags |= no_root_path_flags;
+
/* Boot from root path */
- if ( ( rc = uriboot ( NULL, uri ) ) != 0 ) {
- printf ( "Could not boot from %s: %s\n",
- root_path, strerror ( rc ) );
+ if ( ( rc = uriboot ( NULL, uri, opts.drive, flags ) ) != 0 )
goto err_uriboot;
- }
err_uriboot:
uri_put ( uri );
@@ -83,8 +129,56 @@
return rc;
}
+/**
+ * The "sanhook" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int sanhook_exec ( int argc, char **argv ) {
+ return sanboot_core_exec ( argc, argv, &sanhook_cmd,
+ ( URIBOOT_NO_SAN_BOOT |
+ URIBOOT_NO_SAN_UNHOOK ), 0 );
+}
+
+/**
+ * The "sanboot" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int sanboot_exec ( int argc, char **argv ) {
+ return sanboot_core_exec ( argc, argv, &sanboot_cmd,
+ 0, URIBOOT_NO_SAN_UNHOOK );
+}
+
+/**
+ * The "sanunhook" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int sanunhook_exec ( int argc, char **argv ) {
+ return sanboot_core_exec ( argc, argv, &sanunhook_cmd,
+ ( URIBOOT_NO_SAN_DESCRIBE |
+ URIBOOT_NO_SAN_BOOT ), 0 );
+}
+
/** SAN commands */
-struct command sanboot_command __command = {
- .name = "sanboot",
- .exec = sanboot_exec,
+struct command sanboot_commands[] __command = {
+ {
+ .name = "sanhook",
+ .exec = sanhook_exec,
+ },
+ {
+ .name = "sanboot",
+ .exec = sanboot_exec,
+ },
+ {
+ .name = "sanunhook",
+ .exec = sanunhook_exec,
+ },
};
|
[-]
[+]
|
Added |
ipxe.tar.bz2/src/include/.gitignore
^
|
@@ -0,0 +1 @@
+.buildserial.h
|
[-]
[+]
|
Changed |
ipxe.tar.bz2/src/include/ipxe/list.h
^
|
@@ -212,4 +212,23 @@
pos = tmp, \
tmp = list_entry ( tmp->member.next, typeof ( *tmp ), member ) )
+/**
+ * Check list contains a specified entry
+ *
+ * @v entry Entry
+ * @v head List head
+ * @v member Name of list field within iterator's type
+ */
+#define list_check_contains( entry, head, member ) do { \
+ if ( ASSERTING ) { \
+ typeof ( entry ) tmp; \
+ int found = 0; \
+ list_for_each_entry ( tmp, head, member ) { \
+ if ( tmp == entry ) \
+ found = 1; \
+ } \
+ assert ( found ); \
+ } \
+ } while ( 0 )
+
#endif /* _IPXE_LIST_H */
|
[-]
[+]
|
Changed |
ipxe.tar.bz2/src/include/ipxe/null_sanboot.h
^
|
@@ -15,4 +15,9 @@
#define SANBOOT_PREFIX_null __null_
#endif
+static inline __always_inline unsigned int
+SANBOOT_INLINE ( null, san_default_drive ) ( void ) {
+ return 0;
+}
+
#endif /* _IPXE_NULL_SANBOOT_H */
|
[-]
[+]
|
Changed |
ipxe.tar.bz2/src/include/ipxe/parseopt.h
^
|
@@ -120,6 +120,8 @@
extern int parse_image ( const char *text, struct image **image );
extern int parse_flag ( const char *text __unused, int *flag );
extern void print_usage ( struct command_descriptor *cmd, char **argv );
+extern int reparse_options ( int argc, char **argv,
+ struct command_descriptor *cmd, void *opts );
extern int parse_options ( int argc, char **argv,
struct command_descriptor *cmd, void *opts );
|
[-]
[+]
|
Changed |
ipxe.tar.bz2/src/include/ipxe/sanboot.h
^
|
@@ -59,11 +59,18 @@
#include <bits/sanboot.h>
/**
+ * Get default SAN drive number
+ *
+ * @ret drive Default drive number
+ */
+unsigned int san_default_drive ( void );
+
+/**
* Hook SAN device
*
* @v uri URI
- * @v drive Requested drive number
- * @ret drive Assigned drive number, or negative error
+ * @v drive Drive number
+ * @ret rc Return status code
*/
int san_hook ( struct uri *uri, unsigned int drive );
|
[-]
[+]
|
Changed |
ipxe.tar.bz2/src/include/usr/autoboot.h
^
|
@@ -14,7 +14,19 @@
struct uri;
struct settings;
-extern int uriboot ( struct uri *filename, struct uri *root_path );
+/** uriboot() flags */
+enum uriboot_flags {
+ URIBOOT_NO_SAN_DESCRIBE = 0x0001,
+ URIBOOT_NO_SAN_BOOT = 0x0002,
+ URIBOOT_NO_SAN_UNHOOK = 0x0004,
+};
+
+#define URIBOOT_NO_SAN ( URIBOOT_NO_SAN_DESCRIBE | \
+ URIBOOT_NO_SAN_BOOT | \
+ URIBOOT_NO_SAN_UNHOOK )
+
+extern int uriboot ( struct uri *filename, struct uri *root_path, int drive,
+ unsigned int flags );
extern struct uri *
fetch_next_server_and_filename ( struct settings *settings );
extern int netboot ( struct net_device *netdev );
|
[-]
[+]
|
Changed |
ipxe.tar.bz2/src/interface/bofm/bofm.c
^
|
@@ -181,14 +181,14 @@
/* Retrieve current MAC address */
if ( ( rc = bofm->op->harvest ( bofm, en->mport, mac ) ) != 0 ) {
- DBG ( "BOFM: " PCI_FMT " port %d could not harvest: %s\n",
+ 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 " port %d harvested MAC %s\n",
+ 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 );
@@ -197,7 +197,7 @@
/* 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 " port %d MAC %s",
+ 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;
@@ -207,7 +207,7 @@
if ( ( en->options & BOFM_EN_EN_A ) &&
( en->options & BOFM_EN_USAGE_ENTRY ) &&
( ! ( en->options & BOFM_EN_USAGE_HARVEST ) ) ) {
- DBG ( "BOFM: " PCI_FMT " port %d applied MAC %s\n",
+ 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 ) );
@@ -215,7 +215,7 @@
/* Store MAC address */
if ( ( rc = bofm->op->update ( bofm, en->mport, mac ) ) != 0 ) {
- DBG ( "BOFM: " PCI_FMT " port %d could not update: %s\n",
+ DBG ( "BOFM: " PCI_FMT " mport %d could not update: %s\n",
PCI_ARGS ( bofm->pci ), en->mport, strerror ( rc ) );
return rc;
}
@@ -303,14 +303,19 @@
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 );
+ 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 " ignored\n",
+ DBG ( "BOFM: " PCI_FMT " mport %d ignored\n",
PCI_BUS ( en.busdevfn ), PCI_SLOT ( en.busdevfn ),
- PCI_FUNC ( en.busdevfn ) );
+ PCI_FUNC ( en.busdevfn ), en.mport );
continue;
}
if ( ( rc = bofm_en ( bofm, &en ) ) == 0 ) {
|
[-]
[+]
|
Changed |
ipxe.tar.bz2/src/interface/efi/efi_bofm.c
^
|
@@ -97,6 +97,9 @@
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,
@@ -112,20 +115,27 @@
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;
};
-typedef struct _IBM_BOFM_DRIVER_CONFIGURATION_PROTOCOL2 {
+struct _IBM_BOFM_DRIVER_CONFIGURATION_PROTOCOL2 {
UINT32 Signature;
UINT32 Reserved1;
UINT64 Reserved2;
- IBM_BOFM_DRIVER_CONFIGURATION_STATUS SetStatus;
+ IBM_BOFM_DRIVER_CONFIGURATION_STATUS2 SetStatus;
IBM_BOFM_DRIVER_CONFIGURATION_SUPPORT RegisterSupport;
IBM_BOFM_TABLE BofmTable;
-} IBM_BOFM_DRIVER_CONFIGURATION_PROTOCOL2;
+};
/***************************************************************************
*
@@ -165,7 +175,7 @@
EFI_STATUS efirc;
int rc;
- DBGCP ( efidrv, "BOFM DRIVER_SUPPORTED %p (%p)\n", device, child );
+ DBGCP ( efidrv, "EFIBOFM DRIVER_SUPPORTED %p (%p)\n", device, child );
/* Create corresponding PCI device, if any */
efipci = efipci_create ( efidrv, device );
@@ -176,7 +186,7 @@
/* Look for a BOFM driver */
if ( ( rc = bofm_find_driver ( &efipci->pci ) ) != 0 ) {
- DBGC2 ( efidrv, "BOFM " PCI_FMT " has no driver\n",
+ DBGCP ( efidrv, "EFIBOFM " PCI_FMT " has no driver\n",
PCI_ARGS ( &efipci->pci ) );
efirc = EFI_UNSUPPORTED;
goto err_no_driver;
@@ -185,8 +195,8 @@
/* Locate BOFM protocol */
if ( ( efirc = bs->LocateProtocol ( &bofm1_protocol_guid, NULL,
&bofm1.interface ) ) != 0 ) {
- DBGC ( efidrv, "BOFM " PCI_FMT " cannot find BOFM protocol\n",
- PCI_ARGS ( &efipci->pci ) );
+ DBGC ( efidrv, "EFIBOFM " PCI_FMT " cannot find BOFM "
+ "protocol\n", PCI_ARGS ( &efipci->pci ) );
efirc = EFI_UNSUPPORTED;
goto err_not_bofm;
}
@@ -196,13 +206,13 @@
0x04 /* Can change MAC */,
0x00 /* No iSCSI */,
0x02 /* Version */ ))!=0){
- DBGC ( efidrv, "BOFM " PCI_FMT " could not register support: "
- "%s\n", PCI_ARGS ( &efipci->pci ),
+ DBGC ( efidrv, "EFIBOFM " PCI_FMT " could not register "
+ "support: %s\n", PCI_ARGS ( &efipci->pci ),
efi_strerror ( efirc ) );
goto err_cannot_register;
}
- DBGC ( efidrv, "BOFM " PCI_FMT " is supported by driver \"%s\"\n",
+ DBGC ( efidrv, "EFIBOFM " PCI_FMT " is supported by driver \"%s\"\n",
PCI_ARGS ( &efipci->pci ), efipci->pci.id->name );
/* Destroy temporary PCI device */
@@ -241,11 +251,12 @@
void *interface;
} bofm2;
struct efi_pci_device *efipci;
- userptr_t bofmtab;
+ IBM_BOFM_TABLE *bofmtab;
+ IBM_BOFM_TABLE *bofmtab2;
EFI_STATUS efirc;
int bofmrc;
- DBGCP ( efidrv, "BOFM DRIVER_START %p (%p)\n", device, child );
+ DBGCP ( efidrv, "EFIBOFM DRIVER_START %p (%p)\n", device, child );
/* Create corresponding PCI device */
efipci = efipci_create ( efidrv, device );
@@ -261,46 +272,70 @@
/* Locate BOFM protocol */
if ( ( efirc = bs->LocateProtocol ( &bofm1_protocol_guid, NULL,
&bofm1.interface ) ) != 0 ) {
- DBGC ( efidrv, "BOFM " PCI_FMT " cannot find BOFM protocol\n",
- PCI_ARGS ( &efipci->pci ) );
+ DBGC ( efidrv, "EFIBOFM " PCI_FMT " cannot find BOFM "
+ "protocol\n", PCI_ARGS ( &efipci->pci ) );
goto err_locate_bofm;
}
+ bofmtab = &bofm1.bofm1->BofmTable;
+ DBGC ( efidrv, "EFIBOFM " PCI_FMT " found version 1 BOFM table at "
+ "%p+%04x\n", PCI_ARGS ( &efipci->pci ), bofmtab,
+ bofmtab->Parameters.Length );
/* Locate BOFM2 protocol, if available */
if ( ( efirc = bs->LocateProtocol ( &bofm2_protocol_guid, NULL,
- &bofm2.interface ) ) != 0 ) {
- DBGC ( efidrv, "BOFM " PCI_FMT " cannot find BOFM2 protocol\n",
- PCI_ARGS ( &efipci->pci ) );
- /* Not a fatal error; may be a BOFM1-only system */
- bofm2.bofm2 = NULL;
- }
-
- /* Select appropriate BOFM table (v1 or v2) to use */
- if ( bofm2.bofm2 ) {
- DBGC ( efidrv, "BOFM " PCI_FMT " using version 2 BOFM table\n",
- PCI_ARGS ( &efipci->pci ) );
+ &bofm2.interface ) ) == 0 ) {
+ bofmtab2 = &bofm2.bofm2->BofmTable;
+ DBGC ( efidrv, "EFIBOFM " PCI_FMT " found version 2 BOFM table "
+ "at %p+%04x\n", PCI_ARGS ( &efipci->pci ), bofmtab2,
+ bofmtab2->Parameters.Length );
assert ( bofm2.bofm2->RegisterSupport ==
bofm1.bofm1->RegisterSupport );
- assert ( bofm2.bofm2->SetStatus == bofm1.bofm1->SetStatus );
- bofmtab = virt_to_user ( &bofm2.bofm2->BofmTable );
} else {
- DBGC ( efidrv, "BOFM " PCI_FMT " using version 1 BOFM table\n",
- PCI_ARGS ( &efipci->pci ) );
- bofmtab = virt_to_user ( &bofm1.bofm1->BofmTable );
+ DBGC ( efidrv, "EFIBOFM " PCI_FMT " cannot find BOFM2 "
+ "protocol\n", PCI_ARGS ( &efipci->pci ) );
+ /* Not a fatal error; may be a BOFM1-only system */
+ bofmtab2 = NULL;
}
/* Process BOFM table */
- bofmrc = bofm ( bofmtab, &efipci->pci );
- DBGC ( efidrv, "BOFM " PCI_FMT " status %08x\n",
+ DBGC2 ( efidrv, "EFIBOFM " PCI_FMT " version 1 before processing:\n",
+ PCI_ARGS ( &efipci->pci ) );
+ DBGC2_HD ( efidrv, bofmtab, bofmtab->Parameters.Length );
+ if ( bofmtab2 ) {
+ DBGC2 ( efidrv, "EFIBOFM " PCI_FMT " version 2 before "
+ "processing:\n", PCI_ARGS ( &efipci->pci ) );
+ DBGC2_HD ( efidrv, bofmtab2, bofmtab2->Parameters.Length );
+ }
+ bofmrc = bofm ( virt_to_user ( bofmtab2 ? bofmtab2 : bofmtab ),
+ &efipci->pci );
+ DBGC ( efidrv, "EFIBOFM " PCI_FMT " status %08x\n",
PCI_ARGS ( &efipci->pci ), bofmrc );
+ DBGC2 ( efidrv, "EFIBOFM " PCI_FMT " version 1 after processing:\n",
+ PCI_ARGS ( &efipci->pci ) );
+ DBGC2_HD ( efidrv, bofmtab, bofmtab->Parameters.Length );
+ if ( bofmtab2 ) {
+ DBGC2 ( efidrv, "EFIBOFM " PCI_FMT " version 2 after "
+ "processing:\n", PCI_ARGS ( &efipci->pci ) );
+ DBGC2_HD ( efidrv, bofmtab2, bofmtab2->Parameters.Length );
+ }
/* Return BOFM status */
- if ( ( efirc = bofm1.bofm1->SetStatus ( bofm1.bofm1, device, FALSE,
- bofmrc ) ) != 0 ) {
- DBGC ( efidrv, "BOFM " PCI_FMT " could not set BOFM status: "
- "%s\n", PCI_ARGS ( &efipci->pci ),
- efi_strerror ( efirc ) );
- goto err_set_status;
+ if ( bofmtab2 ) {
+ if ( ( efirc = bofm2.bofm2->SetStatus ( bofm2.bofm2, device,
+ FALSE, bofmrc ) ) != 0){
+ DBGC ( efidrv, "EFIBOFM " PCI_FMT " could not set "
+ "BOFM2 status: %s\n", PCI_ARGS ( &efipci->pci ),
+ efi_strerror ( efirc ) );
+ goto err_set_status;
+ }
+ } else {
+ if ( ( efirc = bofm1.bofm1->SetStatus ( bofm1.bofm1, device,
+ FALSE, bofmrc ) ) != 0){
+ DBGC ( efidrv, "EFIBOFM " PCI_FMT " could not set "
+ "BOFM status: %s\n", PCI_ARGS ( &efipci->pci ),
+ efi_strerror ( efirc ) );
+ goto err_set_status;
+ }
}
/* Destroy the PCI device anyway; we have no further use for it */
@@ -332,7 +367,7 @@
struct efi_driver *efidrv =
container_of ( driver, struct efi_driver, driver );
- DBGCP ( efidrv, "BOFM DRIVER_STOP %p (%ld %p)\n",
+ DBGCP ( efidrv, "EFIBOFM DRIVER_STOP %p (%ld %p)\n",
device, ( ( unsigned long ) num_children ), children );
return 0;
@@ -353,12 +388,12 @@
/* Install driver */
if ( ( efirc = efi_driver_install ( efidrv ) ) != 0 ) {
- DBGC ( efidrv, "BOFM could not install driver: %s\n",
+ DBGC ( efidrv, "EFIBOFM could not install driver: %s\n",
efi_strerror ( efirc ) );
return;
}
- DBGC ( efidrv, "BOFM driver installed\n" );
+ DBGC ( efidrv, "EFIBOFM driver installed\n" );
}
/** EFI BOFM startup function */
|
[-]
[+]
|
Changed |
ipxe.tar.bz2/src/interface/efi/efi_snp.c
^
|
@@ -769,8 +769,8 @@
static EFI_HII_DATABASE_PROTOCOL *efihii;
EFI_REQUIRE_PROTOCOL ( EFI_HII_DATABASE_PROTOCOL, &efihii );
-/** Local GUID used for our EFI SNP formset */
-#define EFI_SNP_FORMSET_GUID \
+/** Local base GUID used for our EFI SNP formset */
+#define EFI_SNP_FORMSET_GUID_BASE \
{ 0xc4f84019, 0x6dfd, 0x4a27, \
{ 0x9b, 0x94, 0xb7, 0x2e, 0x1f, 0xbc, 0xad, 0xca } }
@@ -815,7 +815,7 @@
.Length = sizeof ( efi_snp_formset ),
.Type = EFI_HII_PACKAGE_FORMS,
},
- .FormSet = EFI_IFR_FORM_SET ( EFI_SNP_FORMSET_GUID,
+ .FormSet = EFI_IFR_FORM_SET ( EFI_SNP_FORMSET_GUID_BASE,
EFI_SNP_FORMSET_TITLE,
EFI_SNP_FORMSET_HELP,
typeof ( efi_snp_formset.FormSet ),
@@ -992,6 +992,9 @@
if ( ! package_list )
return NULL;
+ /* Create a unique GUID for this package list and formset */
+ efi_snp_formset.FormSet.FormSet.Guid.Data1++;
+
/* Populate package list */
memcpy ( &package_list->header.PackageListGuid,
&efi_snp_formset.FormSet.FormSet.Guid,
|
[-]
[+]
|
Changed |
ipxe.tar.bz2/src/net/ipv4.c
^
|
@@ -23,8 +23,8 @@
FILE_LICENCE ( GPL2_OR_LATER );
-/* Unique IP datagram identification number */
-static uint16_t next_ident = 0;
+/* Unique IP datagram identification number (high byte) */
+static uint8_t next_ident_high = 0;
/** List of IPv4 miniroutes */
struct list_head ipv4_miniroutes = LIST_HEAD_INIT ( ipv4_miniroutes );
@@ -314,7 +314,6 @@
iphdr->verhdrlen = ( IP_VER | ( sizeof ( *iphdr ) / 4 ) );
iphdr->service = IP_TOS;
iphdr->len = htons ( iob_len ( iobuf ) );
- iphdr->ident = htons ( ++next_ident );
iphdr->ttl = IP_TTL;
iphdr->protocol = tcpip_protocol->tcpip_proto;
iphdr->dest = sin_dest->sin_addr;
@@ -335,6 +334,14 @@
goto err;
}
+ /* (Ab)use the "ident" field to convey metadata about the
+ * network device statistics into packet traces. Useful for
+ * extracting debug information from non-debug builds.
+ */
+ iphdr->ident = htons ( ( (++next_ident_high) << 8 ) |
+ ( ( netdev->rx_stats.bad & 0xf ) << 4 ) |
+ ( ( netdev->rx_stats.good & 0xf ) << 0 ) );
+
/* Determine link-layer destination address */
if ( ( rc = ipv4_ll_addr ( next_hop, iphdr->src, netdev,
ll_dest ) ) != 0 ) {
|
[-]
[+]
|
Changed |
ipxe.tar.bz2/src/net/netdevice.c
^
|
@@ -163,8 +163,8 @@
int netdev_tx ( struct net_device *netdev, struct io_buffer *iobuf ) {
int rc;
- DBGC ( netdev, "NETDEV %s transmitting %p (%p+%zx)\n",
- netdev->name, iobuf, iobuf->data, iob_len ( iobuf ) );
+ DBGC2 ( netdev, "NETDEV %s transmitting %p (%p+%zx)\n",
+ netdev->name, iobuf, iobuf->data, iob_len ( iobuf ) );
/* Enqueue packet */
list_add_tail ( &iobuf->list, &netdev->tx_queue );
@@ -208,16 +208,15 @@
/* Update statistics counter */
netdev_record_stat ( &netdev->tx_stats, rc );
if ( rc == 0 ) {
- DBGC ( netdev, "NETDEV %s transmission %p complete\n",
- netdev->name, iobuf );
+ DBGC2 ( netdev, "NETDEV %s transmission %p complete\n",
+ netdev->name, iobuf );
} else {
DBGC ( netdev, "NETDEV %s transmission %p failed: %s\n",
netdev->name, iobuf, strerror ( rc ) );
}
/* Catch data corruption as early as possible */
- assert ( iobuf->list.next != NULL );
- assert ( iobuf->list.prev != NULL );
+ list_check_contains ( iobuf, &netdev->tx_queue, list );
/* Dequeue and free I/O buffer */
list_del ( &iobuf->list );
@@ -265,8 +264,8 @@
*/
void netdev_rx ( struct net_device *netdev, struct io_buffer *iobuf ) {
- DBGC ( netdev, "NETDEV %s received %p (%p+%zx)\n",
- netdev->name, iobuf, iobuf->data, iob_len ( iobuf ) );
+ DBGC2 ( netdev, "NETDEV %s received %p (%p+%zx)\n",
+ netdev->name, iobuf, iobuf->data, iob_len ( iobuf ) );
/* Discard packet (for test purposes) if applicable */
if ( ( NETDEV_DISCARD_RATE > 0 ) &&
@@ -718,9 +717,9 @@
*/
if ( ( iobuf = netdev_rx_dequeue ( netdev ) ) ) {
- DBGC ( netdev, "NETDEV %s processing %p (%p+%zx)\n",
- netdev->name, iobuf, iobuf->data,
- iob_len ( iobuf ) );
+ DBGC2 ( netdev, "NETDEV %s processing %p (%p+%zx)\n",
+ netdev->name, iobuf, iobuf->data,
+ iob_len ( iobuf ) );
/* Remove link-layer header */
ll_protocol = netdev->ll_protocol;
|
[-]
[+]
|
Changed |
ipxe.tar.bz2/src/net/tcp/http.c
^
|
@@ -52,7 +52,9 @@
enum http_rx_state {
HTTP_RX_RESPONSE = 0,
HTTP_RX_HEADER,
+ HTTP_RX_CHUNK_LEN,
HTTP_RX_DATA,
+ HTTP_RX_TRAILER,
HTTP_RX_DEAD,
};
@@ -78,6 +80,10 @@
unsigned int response;
/** HTTP Content-Length */
size_t content_length;
+ /** HTTP is using Transfer-Encoding: chunked */
+ int chunked;
+ /** Current chunk length */
+ size_t chunk_len;
/** Received length */
size_t rx_len;
/** RX state */
@@ -229,6 +235,24 @@
return 0;
}
+/**
+ * Handle HTTP Transfer-Encoding header
+ *
+ * @v http HTTP request
+ * @v value HTTP header value
+ * @ret rc Return status code
+ */
+static int http_rx_transfer_encoding ( struct http_request *http,
+ const char *value ) {
+
+ if ( strcmp ( value, "chunked" ) == 0 ) {
+ /* Mark connection as using chunked transfer encoding */
+ http->chunked = 1;
+ }
+
+ return 0;
+}
+
/** An HTTP header handler */
struct http_header_handler {
/** Name (e.g. "Content-Length") */
@@ -254,6 +278,10 @@
.header = "Content-Length",
.rx = http_rx_content_length,
},
+ {
+ .header = "Transfer-Encoding",
+ .rx = http_rx_transfer_encoding,
+ },
{ NULL, NULL }
};
@@ -270,12 +298,19 @@
char *value;
int rc;
- /* An empty header line marks the transition to the data phase */
+ /* An empty header line marks the end of this phase */
if ( ! header[0] ) {
- DBGC ( http, "HTTP %p start of data\n", http );
empty_line_buffer ( &http->linebuf );
- http->rx_state = HTTP_RX_DATA;
- return 0;
+ if ( http->rx_state == HTTP_RX_HEADER ) {
+ DBGC ( http, "HTTP %p start of data\n", http );
+ http->rx_state = ( http->chunked ?
+ HTTP_RX_CHUNK_LEN : HTTP_RX_DATA );
+ return 0;
+ } else {
+ DBGC ( http, "HTTP %p end of trailer\n", http );
+ http_done ( http, 0 );
+ return 0;
+ }
}
DBGC ( http, "HTTP %p header \"%s\"\n", http, header );
@@ -300,6 +335,48 @@
return 0;
}
+/**
+ * Handle HTTP chunk length
+ *
+ * @v http HTTP request
+ * @v length HTTP chunk length
+ * @ret rc Return status code
+ */
+static int http_rx_chunk_len ( struct http_request *http, char *length ) {
+ char *endp;
+
+ /* Skip blank lines between chunks */
+ if ( length[0] == '\0' )
+ return 0;
+
+ /* Parse chunk length */
+ http->chunk_len = strtoul ( length, &endp, 16 );
+ if ( *endp != '\0' ) {
+ DBGC ( http, "HTTP %p invalid chunk length \"%s\"\n",
+ http, length );
+ return -EIO;
+ }
+
+ /* Terminate chunked encoding if applicable */
+ if ( http->chunk_len == 0 ) {
+ DBGC ( http, "HTTP %p end of chunks\n", http );
+ http->chunked = 0;
+ http->rx_state = HTTP_RX_TRAILER;
+ return 0;
+ }
+
+ /* Use seek() to notify recipient of new filesize */
+ DBGC ( http, "HTTP %p start of chunk of length %zd\n",
+ http, http->chunk_len );
+ xfer_seek ( &http->xfer, ( http->rx_len + http->chunk_len ) );
+ xfer_seek ( &http->xfer, http->rx_len );
+
+ /* Start receiving data */
+ http->rx_state = HTTP_RX_DATA;
+
+ return 0;
+}
+
/** An HTTP line-based data handler */
struct http_line_handler {
/** Handle line
@@ -315,36 +392,11 @@
static struct http_line_handler http_line_handlers[] = {
[HTTP_RX_RESPONSE] = { .rx = http_rx_response },
[HTTP_RX_HEADER] = { .rx = http_rx_header },
+ [HTTP_RX_CHUNK_LEN] = { .rx = http_rx_chunk_len },
+ [HTTP_RX_TRAILER] = { .rx = http_rx_header },
};
/**
- * Handle new data arriving via HTTP connection in the data phase
- *
- * @v http HTTP request
- * @v iobuf I/O buffer
- * @ret rc Return status code
- */
-static int http_rx_data ( struct http_request *http,
- struct io_buffer *iobuf ) {
- int rc;
-
- /* Update received length */
- http->rx_len += iob_len ( iobuf );
-
- /* Hand off data buffer */
- if ( ( rc = xfer_deliver_iob ( &http->xfer, iobuf ) ) != 0 )
- return rc;
-
- /* If we have reached the content-length, stop now */
- if ( http->content_length &&
- ( http->rx_len >= http->content_length ) ) {
- http_done ( http, 0 );
- }
-
- return 0;
-}
-
-/**
* Handle new data arriving via HTTP connection
*
* @v http HTTP request
@@ -357,34 +409,57 @@
struct xfer_metadata *meta __unused ) {
struct http_line_handler *lh;
char *line;
- ssize_t len;
+ size_t data_len;
+ ssize_t line_len;
int rc = 0;
- while ( iob_len ( iobuf ) ) {
+ while ( iobuf && iob_len ( iobuf ) ) {
switch ( http->rx_state ) {
case HTTP_RX_DEAD:
/* Do no further processing */
goto done;
case HTTP_RX_DATA:
- /* Once we're into the data phase, just fill
- * the data buffer
- */
- rc = http_rx_data ( http, iob_disown ( iobuf ) );
- goto done;
+ /* Pass received data to caller */
+ data_len = iob_len ( iobuf );
+ if ( http->chunk_len && ( http->chunk_len < data_len )){
+ data_len = http->chunk_len;
+ rc = xfer_deliver_raw ( &http->xfer,
+ iobuf->data, data_len );
+ iob_pull ( iobuf, data_len );
+ } else {
+ rc = xfer_deliver_iob ( &http->xfer,
+ iob_disown ( iobuf ) );
+ }
+ if ( rc != 0 )
+ goto done;
+ if ( http->chunk_len ) {
+ http->chunk_len -= data_len;
+ if ( http->chunk_len == 0 )
+ http->rx_state = HTTP_RX_CHUNK_LEN;
+ }
+ http->rx_len += data_len;
+ if ( http->content_length &&
+ ( http->rx_len >= http->content_length ) ) {
+ http_done ( http, 0 );
+ goto done;
+ }
+ break;
case HTTP_RX_RESPONSE:
case HTTP_RX_HEADER:
+ case HTTP_RX_CHUNK_LEN:
+ case HTTP_RX_TRAILER:
/* In the other phases, buffer and process a
* line at a time
*/
- len = line_buffer ( &http->linebuf, iobuf->data,
- iob_len ( iobuf ) );
- if ( len < 0 ) {
- rc = len;
+ line_len = line_buffer ( &http->linebuf, iobuf->data,
+ iob_len ( iobuf ) );
+ if ( line_len < 0 ) {
+ rc = line_len;
DBGC ( http, "HTTP %p could not buffer line: "
"%s\n", http, strerror ( rc ) );
goto done;
}
- iob_pull ( iobuf, len );
+ iob_pull ( iobuf, line_len );
line = buffered_line ( &http->linebuf );
if ( line ) {
lh = &http_line_handlers[http->rx_state];
@@ -448,7 +523,7 @@
/* Send GET request */
if ( ( rc = xfer_printf ( &http->socket,
- "GET %s%s HTTP/1.0\r\n"
+ "GET %s%s HTTP/1.1\r\n"
"User-Agent: iPXE/" VERSION "\r\n"
"%s%s%s"
"Host: %s\r\n"
|
[-]
[+]
|
Changed |
ipxe.tar.bz2/src/usr/autoboot.c
^
|
@@ -119,54 +119,37 @@
*
* @v filename Filename
* @v root_path Root path
+ * @v drive SAN drive (if applicable)
+ * @v flags Boot action flags
* @ret rc Return status code
+ *
+ * The somewhat tortuous flow of control in this function exists in
+ * order to ensure that the "sanboot" command remains identical in
+ * function to a SAN boot via a DHCP-specified root path, and to
+ * provide backwards compatibility for the "keep-san" and
+ * "skip-san-boot" options.
*/
-int uriboot ( struct uri *filename, struct uri *root_path ) {
- int drive;
+int uriboot ( struct uri *filename, struct uri *root_path, int drive,
+ unsigned int flags ) {
int rc;
- /* Treat empty URIs as absent */
- if ( filename && ( ! uri_has_path ( filename ) ) )
- filename = NULL;
- if ( root_path && ( ! uri_is_absolute ( root_path ) ) )
- root_path = NULL;
-
- /* If we have both a filename and a root path, ignore an
- * unsupported URI scheme in the root path, since it may
- * represent an NFS root.
- */
- if ( filename && root_path &&
- ( xfer_uri_opener ( root_path->scheme ) == NULL ) ) {
- printf ( "Ignoring unsupported root path\n" );
- root_path = NULL;
- }
-
- /* Check that we have something to boot */
- if ( ! ( filename || root_path ) ) {
- rc = -ENOENT_BOOT;
- printf ( "Nothing to boot: %s\n", strerror ( rc ) );
- goto err_no_boot;
- }
-
/* Hook SAN device, if applicable */
if ( root_path ) {
- drive = san_hook ( root_path, 0 );
- if ( drive < 0 ) {
- rc = drive;
+ if ( ( rc = san_hook ( root_path, drive ) ) != 0 ) {
printf ( "Could not open SAN device: %s\n",
strerror ( rc ) );
goto err_san_hook;
}
- printf ( "Registered as SAN device %#02x\n", drive );
- } else {
- drive = -ENODEV;
+ printf ( "Registered SAN device %#02x\n", drive );
}
/* Describe SAN device, if applicable */
- if ( ( drive >= 0 ) && ( ( rc = san_describe ( drive ) ) != 0 ) ) {
- printf ( "Could not describe SAN device %#02x: %s\n",
- drive, strerror ( rc ) );
- goto err_san_describe;
+ if ( ( drive >= 0 ) && ! ( flags & URIBOOT_NO_SAN_DESCRIBE ) ) {
+ if ( ( rc = san_describe ( drive ) ) != 0 ) {
+ printf ( "Could not describe SAN device %#02x: %s\n",
+ drive, strerror ( rc ) );
+ goto err_san_describe;
+ }
}
/* Allow a root-path-only boot with skip-san enabled to succeed */
@@ -192,7 +175,7 @@
}
/* Attempt SAN boot if applicable */
- if ( root_path ) {
+ if ( ( drive >= 0 ) && ! ( flags & URIBOOT_NO_SAN_BOOT ) ) {
if ( fetch_intz_setting ( NULL, &skip_san_boot_setting) == 0 ) {
printf ( "Booting from SAN device %#02x\n", drive );
rc = san_boot ( drive );
@@ -209,17 +192,15 @@
err_san_describe:
/* Unhook SAN device, if applicable */
- if ( drive >= 0 ) {
+ if ( ( drive >= 0 ) && ! ( flags & URIBOOT_NO_SAN_UNHOOK ) ) {
if ( fetch_intz_setting ( NULL, &keep_san_setting ) == 0 ) {
- printf ( "Unregistering SAN device %#02x\n", drive );
san_unhook ( drive );
+ printf ( "Unregistered SAN device %#02x\n", drive );
} else {
- printf ( "Preserving connection to SAN device %#02x\n",
- drive );
+ printf ( "Preserving SAN device %#02x\n", drive );
}
}
err_san_hook:
- err_no_boot:
return rc;
}
@@ -360,19 +341,51 @@
goto err_pxe_menu_boot;
}
- /* Fetch next server, filename and root path */
+ /* Fetch next server and filename */
filename = fetch_next_server_and_filename ( NULL );
if ( ! filename )
goto err_filename;
+ if ( ! uri_has_path ( filename ) ) {
+ /* Ignore empty filename */
+ uri_put ( filename );
+ filename = NULL;
+ }
+
+ /* Fetch root path */
root_path = fetch_root_path ( NULL );
if ( ! root_path )
goto err_root_path;
+ if ( ! uri_is_absolute ( root_path ) ) {
+ /* Ignore empty root path */
+ uri_put ( root_path );
+ root_path = NULL;
+ }
+
+ /* If we have both a filename and a root path, ignore an
+ * unsupported URI scheme in the root path, since it may
+ * represent an NFS root.
+ */
+ if ( filename && root_path &&
+ ( xfer_uri_opener ( root_path->scheme ) == NULL ) ) {
+ printf ( "Ignoring unsupported root path\n" );
+ uri_put ( root_path );
+ root_path = NULL;
+ }
+
+ /* Check that we have something to boot */
+ if ( ! ( filename || root_path ) ) {
+ rc = -ENOENT_BOOT;
+ printf ( "Nothing to boot: %s\n", strerror ( rc ) );
+ goto err_no_boot;
+ }
/* Boot using next server, filename and root path */
- if ( ( rc = uriboot ( filename, root_path ) ) != 0 )
+ if ( ( rc = uriboot ( filename, root_path, san_default_drive(),
+ ( root_path ? 0 : URIBOOT_NO_SAN ) ) ) != 0 )
goto err_uriboot;
err_uriboot:
+ err_no_boot:
uri_put ( root_path );
err_root_path:
uri_put ( filename );
|
[-]
[+]
|
Added |
ipxe.tar.bz2/src/util/.gitignore
^
|
@@ -0,0 +1,9 @@
+nrv2b
+zbin
+hijack
+prototester
+elf2efi32
+elf2efi64
+efirom
+iccfix
+einfo
|
[-]
[+]
|
Changed |
ipxe.tar.bz2/src/util/geniso
^
|
@@ -56,7 +56,7 @@
g=${g//[^a-z0-9]}.krn
case "$first" in
"")
- echo DEFAULT $g
+ echo DEFAULT $b
;;
esac
first=$g
|