summaryrefslogtreecommitdiffstats
path: root/qemu/roms/ipxe/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/roms/ipxe/src/core')
-rw-r--r--qemu/roms/ipxe/src/core/acpi.c6
-rw-r--r--qemu/roms/ipxe/src/core/ansicol.c6
-rw-r--r--qemu/roms/ipxe/src/core/ansicoldef.c6
-rw-r--r--qemu/roms/ipxe/src/core/ansiesc.c6
-rw-r--r--qemu/roms/ipxe/src/core/asprintf.c2
-rw-r--r--qemu/roms/ipxe/src/core/assert.c6
-rw-r--r--qemu/roms/ipxe/src/core/base16.c96
-rw-r--r--qemu/roms/ipxe/src/core/base64.c106
-rw-r--r--qemu/roms/ipxe/src/core/basename.c6
-rw-r--r--qemu/roms/ipxe/src/core/bitmap.c6
-rw-r--r--qemu/roms/ipxe/src/core/blockdev.c6
-rw-r--r--qemu/roms/ipxe/src/core/blocktrans.c261
-rw-r--r--qemu/roms/ipxe/src/core/console.c2
-rw-r--r--qemu/roms/ipxe/src/core/cpio.c6
-rw-r--r--qemu/roms/ipxe/src/core/ctype.c13
-rw-r--r--qemu/roms/ipxe/src/core/cwuri.c6
-rw-r--r--qemu/roms/ipxe/src/core/debug.c6
-rw-r--r--qemu/roms/ipxe/src/core/debug_md5.c6
-rw-r--r--qemu/roms/ipxe/src/core/device.c6
-rw-r--r--qemu/roms/ipxe/src/core/downloader.c112
-rw-r--r--qemu/roms/ipxe/src/core/edd.c6
-rw-r--r--qemu/roms/ipxe/src/core/errno.c2
-rw-r--r--qemu/roms/ipxe/src/core/exec.c6
-rw-r--r--qemu/roms/ipxe/src/core/fault.c82
-rw-r--r--qemu/roms/ipxe/src/core/fbcon.c6
-rw-r--r--qemu/roms/ipxe/src/core/fnrec.c6
-rw-r--r--qemu/roms/ipxe/src/core/gdbserial.c80
-rw-r--r--qemu/roms/ipxe/src/core/gdbstub.c6
-rw-r--r--qemu/roms/ipxe/src/core/gdbudp.c6
-rw-r--r--qemu/roms/ipxe/src/core/getkey.c6
-rw-r--r--qemu/roms/ipxe/src/core/getopt.c6
-rw-r--r--qemu/roms/ipxe/src/core/image.c89
-rw-r--r--qemu/roms/ipxe/src/core/init.c6
-rw-r--r--qemu/roms/ipxe/src/core/interface.c31
-rw-r--r--qemu/roms/ipxe/src/core/iobuf.c36
-rw-r--r--qemu/roms/ipxe/src/core/isqrt.c6
-rw-r--r--qemu/roms/ipxe/src/core/job.c6
-rw-r--r--qemu/roms/ipxe/src/core/linebuf.c59
-rw-r--r--qemu/roms/ipxe/src/core/lineconsole.c6
-rw-r--r--qemu/roms/ipxe/src/core/list.c6
-rw-r--r--qemu/roms/ipxe/src/core/log.c6
-rw-r--r--qemu/roms/ipxe/src/core/main.c11
-rw-r--r--qemu/roms/ipxe/src/core/malloc.c63
-rw-r--r--qemu/roms/ipxe/src/core/memblock.c6
-rw-r--r--qemu/roms/ipxe/src/core/memmap_settings.c6
-rw-r--r--qemu/roms/ipxe/src/core/menu.c6
-rw-r--r--qemu/roms/ipxe/src/core/misc.c85
-rw-r--r--qemu/roms/ipxe/src/core/monojob.c6
-rw-r--r--qemu/roms/ipxe/src/core/null_reboot.c6
-rw-r--r--qemu/roms/ipxe/src/core/null_sanboot.c6
-rw-r--r--qemu/roms/ipxe/src/core/null_time.c6
-rw-r--r--qemu/roms/ipxe/src/core/nvo.c6
-rw-r--r--qemu/roms/ipxe/src/core/open.c6
-rw-r--r--qemu/roms/ipxe/src/core/params.c6
-rw-r--r--qemu/roms/ipxe/src/core/parseopt.c9
-rw-r--r--qemu/roms/ipxe/src/core/pending.c6
-rw-r--r--qemu/roms/ipxe/src/core/pinger.c6
-rw-r--r--qemu/roms/ipxe/src/core/pixbuf.c6
-rw-r--r--qemu/roms/ipxe/src/core/pool.c114
-rw-r--r--qemu/roms/ipxe/src/core/posix_io.c6
-rw-r--r--qemu/roms/ipxe/src/core/process.c6
-rw-r--r--qemu/roms/ipxe/src/core/profile.c6
-rw-r--r--qemu/roms/ipxe/src/core/random.c2
-rw-r--r--qemu/roms/ipxe/src/core/refcnt.c6
-rw-r--r--qemu/roms/ipxe/src/core/resolv.c6
-rw-r--r--qemu/roms/ipxe/src/core/serial.c349
-rw-r--r--qemu/roms/ipxe/src/core/serial_console.c42
-rw-r--r--qemu/roms/ipxe/src/core/settings.c102
-rw-r--r--qemu/roms/ipxe/src/core/string.c648
-rw-r--r--qemu/roms/ipxe/src/core/stringextra.c188
-rw-r--r--qemu/roms/ipxe/src/core/strtoull.c60
-rw-r--r--qemu/roms/ipxe/src/core/time.c6
-rw-r--r--qemu/roms/ipxe/src/core/timer.c6
-rw-r--r--qemu/roms/ipxe/src/core/uart.c153
-rw-r--r--qemu/roms/ipxe/src/core/uri.c15
-rw-r--r--qemu/roms/ipxe/src/core/uuid.c6
-rw-r--r--qemu/roms/ipxe/src/core/version.c7
-rw-r--r--qemu/roms/ipxe/src/core/vsprintf.c6
-rw-r--r--qemu/roms/ipxe/src/core/wchar.c6
-rw-r--r--qemu/roms/ipxe/src/core/xfer.c49
-rw-r--r--qemu/roms/ipxe/src/core/xferbuf.c262
81 files changed, 2174 insertions, 1256 deletions
diff --git a/qemu/roms/ipxe/src/core/acpi.c b/qemu/roms/ipxe/src/core/acpi.c
index 330f50631..b0ccfa78d 100644
--- a/qemu/roms/ipxe/src/core/acpi.c
+++ b/qemu/roms/ipxe/src/core/acpi.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <errno.h>
#include <ipxe/acpi.h>
diff --git a/qemu/roms/ipxe/src/core/ansicol.c b/qemu/roms/ipxe/src/core/ansicol.c
index 142a00f8d..ddf9ba77c 100644
--- a/qemu/roms/ipxe/src/core/ansicol.c
+++ b/qemu/roms/ipxe/src/core/ansicol.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdio.h>
#include <errno.h>
diff --git a/qemu/roms/ipxe/src/core/ansicoldef.c b/qemu/roms/ipxe/src/core/ansicoldef.c
index dd89f3b70..6d8598e11 100644
--- a/qemu/roms/ipxe/src/core/ansicoldef.c
+++ b/qemu/roms/ipxe/src/core/ansicoldef.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdio.h>
#include <errno.h>
diff --git a/qemu/roms/ipxe/src/core/ansiesc.c b/qemu/roms/ipxe/src/core/ansiesc.c
index ca9a73ce0..7f545db0e 100644
--- a/qemu/roms/ipxe/src/core/ansiesc.c
+++ b/qemu/roms/ipxe/src/core/ansiesc.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <string.h>
#include <assert.h>
diff --git a/qemu/roms/ipxe/src/core/asprintf.c b/qemu/roms/ipxe/src/core/asprintf.c
index 03cf45cfc..00edf8e11 100644
--- a/qemu/roms/ipxe/src/core/asprintf.c
+++ b/qemu/roms/ipxe/src/core/asprintf.c
@@ -4,7 +4,7 @@
#include <stdio.h>
#include <errno.h>
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/**
* Write a formatted string to newly allocated memory.
diff --git a/qemu/roms/ipxe/src/core/assert.c b/qemu/roms/ipxe/src/core/assert.c
index 0791ea7b9..294e766be 100644
--- a/qemu/roms/ipxe/src/core/assert.c
+++ b/qemu/roms/ipxe/src/core/assert.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** @file
*
diff --git a/qemu/roms/ipxe/src/core/base16.c b/qemu/roms/ipxe/src/core/base16.c
index bf9cc21bb..f9e0f3364 100644
--- a/qemu/roms/ipxe/src/core/base16.c
+++ b/qemu/roms/ipxe/src/core/base16.c
@@ -15,14 +15,20 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
-#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
+#include <assert.h>
+#include <ipxe/string.h>
+#include <ipxe/vsprintf.h>
#include <ipxe/base16.h>
/** @file
@@ -32,48 +38,42 @@ FILE_LICENCE ( GPL2_OR_LATER );
*/
/**
- * Base16-encode data
+ * Encode hexadecimal string (with optional byte separator character)
*
+ * @v separator Byte separator character, or 0 for no separator
* @v raw Raw data
- * @v len Length of raw data
- * @v encoded Buffer for encoded string
- *
- * The buffer must be the correct length for the encoded string. Use
- * something like
- *
- * char buf[ base16_encoded_len ( len ) + 1 ];
- *
- * (the +1 is for the terminating NUL) to provide a buffer of the
- * correct size.
+ * @v raw_len Length of raw data
+ * @v data Buffer
+ * @v len Length of buffer
+ * @ret len Encoded length
*/
-void base16_encode ( const uint8_t *raw, size_t len, char *encoded ) {
- const uint8_t *raw_bytes = raw;
- char *encoded_bytes = encoded;
- size_t remaining = len;
-
- /* Encode each byte */
- for ( ; remaining-- ; encoded_bytes += 2 ) {
- sprintf ( encoded_bytes, "%02x", *(raw_bytes++) );
+size_t hex_encode ( char separator, const void *raw, size_t raw_len,
+ char *data, size_t len ) {
+ const uint8_t *bytes = raw;
+ const char delimiter[2] = { separator, '\0' };
+ size_t used = 0;
+ unsigned int i;
+
+ if ( len )
+ data[0] = 0; /* Ensure that a terminating NUL exists */
+ for ( i = 0 ; i < raw_len ; i++ ) {
+ used += ssnprintf ( ( data + used ), ( len - used ),
+ "%s%02x", ( used ? delimiter : "" ),
+ bytes[i] );
}
-
- /* Ensure terminating NUL exists even if length was zero */
- *encoded_bytes = '\0';
-
- DBG ( "Base16-encoded to \"%s\":\n", encoded );
- DBG_HDA ( 0, raw, len );
- assert ( strlen ( encoded ) == base16_encoded_len ( len ) );
+ return used;
}
/**
- * Decode hexadecimal string
+ * Decode hexadecimal string (with optional byte separator character)
*
- * @v encoded Encoded string
* @v separator Byte separator character, or 0 for no separator
+ * @v encoded Encoded string
* @v data Buffer
* @v len Length of buffer
* @ret len Length of data, or negative error
*/
-int hex_decode ( const char *encoded, char separator, void *data, size_t len ) {
+int hex_decode ( char separator, const char *encoded, void *data, size_t len ) {
uint8_t *out = data;
unsigned int count = 0;
unsigned int sixteens;
@@ -87,13 +87,13 @@ int hex_decode ( const char *encoded, char separator, void *data, size_t len ) {
/* Extract digits. Note that either digit may be NUL,
* which would be interpreted as an invalid value by
- * strtoul_charval(); there is therefore no need for an
+ * digit_value(); there is therefore no need for an
* explicit end-of-string check.
*/
- sixteens = strtoul_charval ( *(encoded++) );
+ sixteens = digit_value ( *(encoded++) );
if ( sixteens >= 16 )
return -EINVAL;
- units = strtoul_charval ( *(encoded++) );
+ units = digit_value ( *(encoded++) );
if ( units >= 16 )
return -EINVAL;
@@ -105,31 +105,3 @@ int hex_decode ( const char *encoded, char separator, void *data, size_t len ) {
}
return count;
}
-
-/**
- * Base16-decode data
- *
- * @v encoded Encoded string
- * @v raw Raw data
- * @ret len Length of raw data, or negative error
- *
- * The buffer must be large enough to contain the decoded data. Use
- * something like
- *
- * char buf[ base16_decoded_max_len ( encoded ) ];
- *
- * to provide a buffer of the correct size.
- */
-int base16_decode ( const char *encoded, uint8_t *raw ) {
- int len;
-
- len = hex_decode ( encoded, 0, raw, -1UL );
- if ( len < 0 )
- return len;
-
- DBG ( "Base16-decoded \"%s\" to:\n", encoded );
- DBG_HDA ( 0, raw, len );
- assert ( len <= ( int ) base16_decoded_max_len ( encoded ) );
-
- return len;
-}
diff --git a/qemu/roms/ipxe/src/core/base64.c b/qemu/roms/ipxe/src/core/base64.c
index bdaf70957..e452f7d41 100644
--- a/qemu/roms/ipxe/src/core/base64.c
+++ b/qemu/roms/ipxe/src/core/base64.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <string.h>
@@ -39,80 +43,73 @@ static const char base64[64] =
* Base64-encode data
*
* @v raw Raw data
- * @v len Length of raw data
- * @v encoded Buffer for encoded string
- *
- * The buffer must be the correct length for the encoded string. Use
- * something like
- *
- * char buf[ base64_encoded_len ( len ) + 1 ];
- *
- * (the +1 is for the terminating NUL) to provide a buffer of the
- * correct size.
+ * @v raw_len Length of raw data
+ * @v data Buffer
+ * @v len Length of buffer
+ * @ret len Encoded length
*/
-void base64_encode ( const uint8_t *raw, size_t len, char *encoded ) {
+size_t base64_encode ( const void *raw, size_t raw_len, char *data,
+ size_t len ) {
const uint8_t *raw_bytes = ( ( const uint8_t * ) raw );
- uint8_t *encoded_bytes = ( ( uint8_t * ) encoded );
- size_t raw_bit_len = ( 8 * len );
+ size_t raw_bit_len = ( 8 * raw_len );
+ size_t used = 0;
unsigned int bit;
unsigned int byte;
unsigned int shift;
unsigned int tmp;
- for ( bit = 0 ; bit < raw_bit_len ; bit += 6 ) {
+ for ( bit = 0 ; bit < raw_bit_len ; bit += 6, used++ ) {
byte = ( bit / 8 );
shift = ( bit % 8 );
tmp = ( raw_bytes[byte] << shift );
- if ( ( byte + 1 ) < len )
+ if ( ( byte + 1 ) < raw_len )
tmp |= ( raw_bytes[ byte + 1 ] >> ( 8 - shift ) );
tmp = ( ( tmp >> 2 ) & 0x3f );
- *(encoded_bytes++) = base64[tmp];
+ if ( used < len )
+ data[used] = base64[tmp];
+ }
+ for ( ; ( bit % 8 ) != 0 ; bit += 6, used++ ) {
+ if ( used < len )
+ data[used] = '=';
}
- for ( ; ( bit % 8 ) != 0 ; bit += 6 )
- *(encoded_bytes++) = '=';
- *(encoded_bytes++) = '\0';
+ if ( used < len )
+ data[used] = '\0';
+ if ( len )
+ data[ len - 1 ] = '\0'; /* Ensure terminator exists */
- DBG ( "Base64-encoded to \"%s\":\n", encoded );
- DBG_HDA ( 0, raw, len );
- assert ( strlen ( encoded ) == base64_encoded_len ( len ) );
+ return used;
}
/**
* Base64-decode string
*
* @v encoded Encoded string
- * @v raw Raw data
- * @ret len Length of raw data, or negative error
- *
- * The buffer must be large enough to contain the decoded data. Use
- * something like
- *
- * char buf[ base64_decoded_max_len ( encoded ) ];
- *
- * to provide a buffer of the correct size.
+ * @v data Buffer
+ * @v len Length of buffer
+ * @ret len Length of data, or negative error
*/
-int base64_decode ( const char *encoded, uint8_t *raw ) {
- const uint8_t *encoded_bytes = ( ( const uint8_t * ) encoded );
- uint8_t *raw_bytes = ( ( uint8_t * ) raw );
- uint8_t encoded_byte;
+int base64_decode ( const char *encoded, void *data, size_t len ) {
+ const char *in = encoded;
+ uint8_t *out = data;
+ uint8_t in_char;
char *match;
- int decoded;
+ int in_bits;
unsigned int bit = 0;
unsigned int pad_count = 0;
- size_t len;
+ size_t offset;
- /* Zero the raw data */
- memset ( raw, 0, base64_decoded_max_len ( encoded ) );
+ /* Zero the output buffer */
+ memset ( data, 0, len );
/* Decode string */
- while ( ( encoded_byte = *(encoded_bytes++) ) ) {
+ while ( ( in_char = *(in++) ) ) {
/* Ignore whitespace characters */
- if ( isspace ( encoded_byte ) )
+ if ( isspace ( in_char ) )
continue;
/* Process pad characters */
- if ( encoded_byte == '=' ) {
+ if ( in_char == '=' ) {
if ( pad_count >= 2 ) {
DBG ( "Base64-encoded string \"%s\" has too "
"many pad characters\n", encoded );
@@ -129,18 +126,22 @@ int base64_decode ( const char *encoded, uint8_t *raw ) {
}
/* Process normal characters */
- match = strchr ( base64, encoded_byte );
+ match = strchr ( base64, in_char );
if ( ! match ) {
DBG ( "Base64-encoded string \"%s\" contains invalid "
- "character '%c'\n", encoded, encoded_byte );
+ "character '%c'\n", encoded, in_char );
return -EINVAL;
}
- decoded = ( match - base64 );
+ in_bits = ( match - base64 );
/* Add to raw data */
- decoded <<= 2;
- raw_bytes[ bit / 8 ] |= ( decoded >> ( bit % 8 ) );
- raw_bytes[ bit / 8 + 1 ] |= ( decoded << ( 8 - ( bit % 8 ) ) );
+ in_bits <<= 2;
+ offset = ( bit / 8 );
+ if ( offset < len )
+ out[offset] |= ( in_bits >> ( bit % 8 ) );
+ offset++;
+ if ( offset < len )
+ out[offset] |= ( in_bits << ( 8 - ( bit % 8 ) ) );
bit += 6;
}
@@ -150,12 +151,7 @@ int base64_decode ( const char *encoded, uint8_t *raw ) {
"%d\n", encoded, bit );
return -EINVAL;
}
- len = ( bit / 8 );
-
- DBG ( "Base64-decoded \"%s\" to:\n", encoded );
- DBG_HDA ( 0, raw, len );
- assert ( len <= base64_decoded_max_len ( encoded ) );
/* Return length in bytes */
- return ( len );
+ return ( bit / 8 );
}
diff --git a/qemu/roms/ipxe/src/core/basename.c b/qemu/roms/ipxe/src/core/basename.c
index b534a7886..f4f929517 100644
--- a/qemu/roms/ipxe/src/core/basename.c
+++ b/qemu/roms/ipxe/src/core/basename.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/**
* @file
diff --git a/qemu/roms/ipxe/src/core/bitmap.c b/qemu/roms/ipxe/src/core/bitmap.c
index 0d1152327..2aac33870 100644
--- a/qemu/roms/ipxe/src/core/bitmap.c
+++ b/qemu/roms/ipxe/src/core/bitmap.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <errno.h>
#include <ipxe/bitmap.h>
diff --git a/qemu/roms/ipxe/src/core/blockdev.c b/qemu/roms/ipxe/src/core/blockdev.c
index 9d118cb2f..c219d9673 100644
--- a/qemu/roms/ipxe/src/core/blockdev.c
+++ b/qemu/roms/ipxe/src/core/blockdev.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <errno.h>
#include <ipxe/interface.h>
diff --git a/qemu/roms/ipxe/src/core/blocktrans.c b/qemu/roms/ipxe/src/core/blocktrans.c
new file mode 100644
index 000000000..3f32f9cf8
--- /dev/null
+++ b/qemu/roms/ipxe/src/core/blocktrans.c
@@ -0,0 +1,261 @@
+/*
+ * 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
+ *
+ * Block device translator
+ *
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <assert.h>
+#include <ipxe/iobuf.h>
+#include <ipxe/xfer.h>
+#include <ipxe/blockdev.h>
+#include <ipxe/blocktrans.h>
+
+/**
+ * Reallocate block device translator data buffer
+ *
+ * @v xferbuf Data transfer buffer
+ * @v len New length (or zero to free buffer)
+ * @ret rc Return status code
+ */
+static int blktrans_xferbuf_realloc ( struct xfer_buffer *xferbuf,
+ size_t len ) {
+ struct block_translator *blktrans =
+ container_of ( xferbuf, struct block_translator, xferbuf );
+
+ /* Record length, if applicable */
+ if ( blktrans->buffer ) {
+
+ /* We have a (non-reallocatable) data buffer */
+ return -ENOTSUP;
+
+ } else {
+
+ /* Record length (for block device capacity) */
+ xferbuf->len = len;
+ return 0;
+ }
+}
+
+/**
+ * Write data to block device translator data buffer
+ *
+ * @v xferbuf Data transfer buffer
+ * @v offset Starting offset
+ * @v data Data to copy
+ * @v len Length of data
+ */
+static void blktrans_xferbuf_write ( struct xfer_buffer *xferbuf, size_t offset,
+ const void *data, size_t len ) {
+ struct block_translator *blktrans =
+ container_of ( xferbuf, struct block_translator, xferbuf );
+
+ /* Write data to buffer, if applicable */
+ if ( blktrans->buffer ) {
+
+ /* Write data to buffer */
+ copy_to_user ( blktrans->buffer, offset, data, len );
+
+ } else {
+
+ /* Sanity check */
+ assert ( len == 0 );
+ }
+}
+
+/**
+ * Read data from block device translator data buffer
+ *
+ * @v xferbuf Data transfer buffer
+ * @v offset Starting offset
+ * @v data Data to read
+ * @v len Length of data
+ */
+static void blktrans_xferbuf_read ( struct xfer_buffer *xferbuf, size_t offset,
+ void *data, size_t len ) {
+ struct block_translator *blktrans =
+ container_of ( xferbuf, struct block_translator, xferbuf );
+
+ /* Read data from buffer, if applicable */
+ if ( blktrans->buffer ) {
+
+ /* Read data from buffer */
+ copy_from_user ( data, blktrans->buffer, offset, len );
+
+ } else {
+
+ /* Sanity check */
+ assert ( len == 0 );
+ }
+}
+
+/** Block device translator data transfer buffer operations */
+static struct xfer_buffer_operations blktrans_xferbuf_operations = {
+ .realloc = blktrans_xferbuf_realloc,
+ .write = blktrans_xferbuf_write,
+ .read = blktrans_xferbuf_read,
+};
+
+/**
+ * Close block device translator
+ *
+ * @v blktrans Block device translator
+ * @v rc Reason for close
+ */
+static void blktrans_close ( struct block_translator *blktrans, int rc ) {
+ struct block_device_capacity capacity;
+
+ /* Report block device capacity, if applicable */
+ if ( ( rc == 0 ) && ( blktrans->blksize ) ) {
+
+ /* Construct block device capacity */
+ capacity.blocks =
+ ( blktrans->xferbuf.len / blktrans->blksize );
+ capacity.blksize = blktrans->blksize;
+ capacity.max_count = -1U;
+
+ /* Report block device capacity */
+ block_capacity ( &blktrans->block, &capacity );
+ }
+
+ /* Shut down interfaces */
+ intf_shutdown ( &blktrans->xfer, rc );
+ intf_shutdown ( &blktrans->block, rc );
+}
+
+/**
+ * Deliver data
+ *
+ * @v blktrans Block device translator
+ * @v iobuf I/O buffer
+ * @v meta Data transfer metadata
+ * @ret rc Return status code
+ */
+static int blktrans_deliver ( struct block_translator *blktrans,
+ struct io_buffer *iobuf,
+ struct xfer_metadata *meta ) {
+ int rc;
+
+ /* Deliver to buffer */
+ if ( ( rc = xferbuf_deliver ( &blktrans->xferbuf, iob_disown ( iobuf ),
+ meta ) ) != 0 ) {
+ DBGC ( blktrans, "BLKTRANS %p could not deliver: %s\n",
+ blktrans, strerror ( rc ) );
+ goto err;
+ }
+
+ return 0;
+
+ err:
+ blktrans_close ( blktrans, rc );
+ return rc;
+}
+
+/**
+ * Get underlying data transfer buffer
+ *
+ * @v blktrans Block device translator
+ * @ret xferbuf Data transfer buffer
+ */
+static struct xfer_buffer *
+blktrans_buffer ( struct block_translator *blktrans ) {
+
+ return &blktrans->xferbuf;
+}
+
+/** Block device translator block device interface operations */
+static struct interface_operation blktrans_block_operations[] = {
+ INTF_OP ( intf_close, struct block_translator *, blktrans_close ),
+};
+
+/** Block device translator block device interface descriptor */
+static struct interface_descriptor blktrans_block_desc =
+ INTF_DESC_PASSTHRU ( struct block_translator, block,
+ blktrans_block_operations, xfer );
+
+/** Block device translator data transfer interface operations */
+static struct interface_operation blktrans_xfer_operations[] = {
+ INTF_OP ( xfer_deliver, struct block_translator *, blktrans_deliver ),
+ INTF_OP ( xfer_buffer, struct block_translator *, blktrans_buffer ),
+ INTF_OP ( intf_close, struct block_translator *, blktrans_close ),
+};
+
+/** Block device translator data transfer interface descriptor */
+static struct interface_descriptor blktrans_xfer_desc =
+ INTF_DESC_PASSTHRU ( struct block_translator, xfer,
+ blktrans_xfer_operations, block );
+
+/**
+ * Insert block device translator
+ *
+ * @v block Block device interface
+ * @v buffer Data buffer (or UNULL)
+ * @v size Length of data buffer, or block size
+ * @ret rc Return status code
+ */
+int block_translate ( struct interface *block, userptr_t buffer, size_t size ) {
+ struct block_translator *blktrans;
+ int rc;
+
+ /* Allocate and initialise structure */
+ blktrans = zalloc ( sizeof ( *blktrans ) );
+ if ( ! blktrans ) {
+ rc = -ENOMEM;
+ goto err_alloc;
+ }
+ ref_init ( &blktrans->refcnt, NULL );
+ intf_init ( &blktrans->block, &blktrans_block_desc, &blktrans->refcnt );
+ intf_init ( &blktrans->xfer, &blktrans_xfer_desc, &blktrans->refcnt );
+ blktrans->xferbuf.op = &blktrans_xferbuf_operations;
+ blktrans->buffer = buffer;
+ if ( buffer ) {
+ blktrans->xferbuf.len = size;
+ } else {
+ blktrans->blksize = size;
+ }
+
+ /* Attach to interfaces, mortalise self, and return */
+ assert ( block->dest != &null_intf );
+ intf_plug_plug ( &blktrans->xfer, block->dest );
+ intf_plug_plug ( &blktrans->block, block );
+ ref_put ( &blktrans->refcnt );
+
+ DBGC2 ( blktrans, "BLKTRANS %p created", blktrans );
+ if ( buffer ) {
+ DBGC2 ( blktrans, " for %#lx+%#zx",
+ user_to_phys ( buffer, 0 ), size );
+ }
+ DBGC2 ( blktrans, "\n" );
+ return 0;
+
+ ref_put ( &blktrans->refcnt );
+ err_alloc:
+ return rc;
+}
diff --git a/qemu/roms/ipxe/src/core/console.c b/qemu/roms/ipxe/src/core/console.c
index 141d8f0f0..7fd00036f 100644
--- a/qemu/roms/ipxe/src/core/console.c
+++ b/qemu/roms/ipxe/src/core/console.c
@@ -5,7 +5,7 @@
/** @file */
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** Current console usage */
int console_usage = CONSOLE_USAGE_STDOUT;
diff --git a/qemu/roms/ipxe/src/core/cpio.c b/qemu/roms/ipxe/src/core/cpio.c
index 3a5f4d2b6..080c72daf 100644
--- a/qemu/roms/ipxe/src/core/cpio.c
+++ b/qemu/roms/ipxe/src/core/cpio.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** @file
*
diff --git a/qemu/roms/ipxe/src/core/ctype.c b/qemu/roms/ipxe/src/core/ctype.c
index c812346a0..891af71ea 100644
--- a/qemu/roms/ipxe/src/core/ctype.c
+++ b/qemu/roms/ipxe/src/core/ctype.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/**
* @file
@@ -31,11 +35,12 @@ FILE_LICENCE ( GPL2_OR_LATER );
/**
* Check to see if character is a space
*
- * @v c Character
+ * @v character Character
* @ret isspace Character is a space
*/
-int isspace ( int c ) {
- switch ( c ) {
+int isspace ( int character ) {
+
+ switch ( character ) {
case ' ' :
case '\f' :
case '\n' :
diff --git a/qemu/roms/ipxe/src/core/cwuri.c b/qemu/roms/ipxe/src/core/cwuri.c
index 5865552a0..612f0b179 100644
--- a/qemu/roms/ipxe/src/core/cwuri.c
+++ b/qemu/roms/ipxe/src/core/cwuri.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stddef.h>
#include <ipxe/uri.h>
diff --git a/qemu/roms/ipxe/src/core/debug.c b/qemu/roms/ipxe/src/core/debug.c
index 7ded47089..def5d8b09 100644
--- a/qemu/roms/ipxe/src/core/debug.c
+++ b/qemu/roms/ipxe/src/core/debug.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdio.h>
#include <stdint.h>
diff --git a/qemu/roms/ipxe/src/core/debug_md5.c b/qemu/roms/ipxe/src/core/debug_md5.c
index f049ac757..d0dbad9ed 100644
--- a/qemu/roms/ipxe/src/core/debug_md5.c
+++ b/qemu/roms/ipxe/src/core/debug_md5.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdio.h>
#include <stdint.h>
diff --git a/qemu/roms/ipxe/src/core/device.c b/qemu/roms/ipxe/src/core/device.c
index 330f95c5a..77d7b719b 100644
--- a/qemu/roms/ipxe/src/core/device.c
+++ b/qemu/roms/ipxe/src/core/device.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <string.h>
#include <ipxe/list.h>
diff --git a/qemu/roms/ipxe/src/core/downloader.c b/qemu/roms/ipxe/src/core/downloader.c
index ec69db6b1..d745f3617 100644
--- a/qemu/roms/ipxe/src/core/downloader.c
+++ b/qemu/roms/ipxe/src/core/downloader.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdlib.h>
#include <errno.h>
@@ -29,7 +33,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <ipxe/uaccess.h>
#include <ipxe/umalloc.h>
#include <ipxe/image.h>
-#include <ipxe/profile.h>
+#include <ipxe/xferbuf.h>
#include <ipxe/downloader.h>
/** @file
@@ -38,14 +42,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
*
*/
-/** Receive profiler */
-static struct profiler downloader_rx_profiler __profiler =
- { .name = "downloader.rx" };
-
-/** Data copy profiler */
-static struct profiler downloader_copy_profiler __profiler =
- { .name = "downloader.copy" };
-
/** A downloader */
struct downloader {
/** Reference count for this object */
@@ -58,8 +54,8 @@ struct downloader {
/** Image to contain downloaded file */
struct image *image;
- /** Current position within image buffer */
- size_t pos;
+ /** Data transfer buffer */
+ struct xfer_buffer buffer;
};
/**
@@ -92,42 +88,14 @@ static void downloader_finished ( struct downloader *downloader, int rc ) {
downloader->image->name, strerror ( rc ) );
}
+ /* Update image length */
+ downloader->image->len = downloader->buffer.len;
+
/* Shut down interfaces */
intf_shutdown ( &downloader->xfer, rc );
intf_shutdown ( &downloader->job, rc );
}
-/**
- * Ensure that download buffer is large enough for the specified size
- *
- * @v downloader Downloader
- * @v len Required minimum size
- * @ret rc Return status code
- */
-static int downloader_ensure_size ( struct downloader *downloader,
- size_t len ) {
- userptr_t new_buffer;
-
- /* If buffer is already large enough, do nothing */
- if ( len <= downloader->image->len )
- return 0;
-
- DBGC ( downloader, "Downloader %p extending to %zd bytes\n",
- downloader, len );
-
- /* Extend buffer */
- new_buffer = urealloc ( downloader->image->data, len );
- if ( ! new_buffer ) {
- DBGC ( downloader, "Downloader %p could not extend buffer to "
- "%zd bytes\n", downloader, len );
- return -ENOSPC;
- }
- downloader->image->data = new_buffer;
- downloader->image->len = len;
-
- return 0;
-}
-
/****************************************************************************
*
* Job control interface
@@ -148,8 +116,8 @@ static int downloader_progress ( struct downloader *downloader,
* arrive out of order (e.g. with multicast protocols), but
* it's a reasonable first approximation.
*/
- progress->completed = downloader->pos;
- progress->total = downloader->image->len;
+ progress->completed = downloader->buffer.pos;
+ progress->total = downloader->buffer.len;
return 0;
}
@@ -171,44 +139,37 @@ static int downloader_progress ( struct downloader *downloader,
static int downloader_xfer_deliver ( struct downloader *downloader,
struct io_buffer *iobuf,
struct xfer_metadata *meta ) {
- size_t len;
- size_t max;
int rc;
- /* Start profiling */
- profile_start ( &downloader_rx_profiler );
-
- /* Calculate new buffer position */
- if ( meta->flags & XFER_FL_ABS_OFFSET )
- downloader->pos = 0;
- downloader->pos += meta->offset;
-
- /* Ensure that we have enough buffer space for this data */
- len = iob_len ( iobuf );
- max = ( downloader->pos + len );
- if ( ( rc = downloader_ensure_size ( downloader, max ) ) != 0 )
- goto done;
-
- /* Copy data to buffer */
- profile_start ( &downloader_copy_profiler );
- copy_to_user ( downloader->image->data, downloader->pos,
- iobuf->data, len );
- profile_stop ( &downloader_copy_profiler );
-
- /* Update current buffer position */
- downloader->pos += len;
-
- done:
- free_iob ( iobuf );
- if ( rc != 0 )
- downloader_finished ( downloader, rc );
- profile_stop ( &downloader_rx_profiler );
+ /* Add data to buffer */
+ if ( ( rc = xferbuf_deliver ( &downloader->buffer, iob_disown ( iobuf ),
+ meta ) ) != 0 )
+ goto err_deliver;
+
+ return 0;
+
+ err_deliver:
+ downloader_finished ( downloader, rc );
return rc;
}
+/**
+ * Get underlying data transfer buffer
+ *
+ * @v downloader Downloader
+ * @ret xferbuf Data transfer buffer, or NULL on error
+ */
+static struct xfer_buffer *
+downloader_xfer_buffer ( struct downloader *downloader ) {
+
+ /* Provide direct access to underlying data transfer buffer */
+ return &downloader->buffer;
+}
+
/** Downloader data transfer interface operations */
static struct interface_operation downloader_xfer_operations[] = {
INTF_OP ( xfer_deliver, struct downloader *, downloader_xfer_deliver ),
+ INTF_OP ( xfer_buffer, struct downloader *, downloader_xfer_buffer ),
INTF_OP ( intf_close, struct downloader *, downloader_finished ),
};
@@ -262,6 +223,7 @@ int create_downloader ( struct interface *job, struct image *image ) {
intf_init ( &downloader->xfer, &downloader_xfer_desc,
&downloader->refcnt );
downloader->image = image_get ( image );
+ xferbuf_umalloc_init ( &downloader->buffer, &image->data );
/* Instantiate child objects and attach to our interfaces */
if ( ( rc = xfer_open_uri ( &downloader->xfer, image->uri ) ) != 0 )
diff --git a/qemu/roms/ipxe/src/core/edd.c b/qemu/roms/ipxe/src/core/edd.c
index d574ea6c0..a50b74ab1 100644
--- a/qemu/roms/ipxe/src/core/edd.c
+++ b/qemu/roms/ipxe/src/core/edd.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <errno.h>
#include <ipxe/interface.h>
diff --git a/qemu/roms/ipxe/src/core/errno.c b/qemu/roms/ipxe/src/core/errno.c
index 06905561f..5de15bb92 100644
--- a/qemu/roms/ipxe/src/core/errno.c
+++ b/qemu/roms/ipxe/src/core/errno.c
@@ -1,6 +1,6 @@
#include <errno.h>
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** @file
*
diff --git a/qemu/roms/ipxe/src/core/exec.c b/qemu/roms/ipxe/src/core/exec.c
index 1c85705ae..2c2ade0a5 100644
--- a/qemu/roms/ipxe/src/core/exec.c
+++ b/qemu/roms/ipxe/src/core/exec.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <string.h>
diff --git a/qemu/roms/ipxe/src/core/fault.c b/qemu/roms/ipxe/src/core/fault.c
new file mode 100644
index 000000000..63d3ccacf
--- /dev/null
+++ b/qemu/roms/ipxe/src/core/fault.c
@@ -0,0 +1,82 @@
+/*
+ * 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 <stdlib.h>
+#include <errno.h>
+#include <ipxe/fault.h>
+
+/** @file
+ *
+ * Fault injection
+ *
+ */
+
+/**
+ * Inject fault with a specified probability
+ *
+ * @v rate Reciprocal of fault probability (must be non-zero)
+ * @ret rc Return status code
+ */
+int inject_fault_nonzero ( unsigned int rate ) {
+
+ /* Do nothing unless we want to inject a fault now */
+ if ( ( random() % rate ) != 0 )
+ return 0;
+
+ /* Generate error number here so that faults can be injected
+ * into files that don't themselves have error file
+ * identifiers (via errfile.h).
+ */
+ return -EFAULT;
+}
+
+/**
+ * Corrupt data with a specified probability
+ *
+ * @v rate Reciprocal of fault probability (must be non-zero)
+ * @v data Data
+ * @v len Length of data
+ * @ret rc Return status code
+ */
+void inject_corruption_nonzero ( unsigned int rate, const void *data,
+ size_t len ) {
+ uint8_t *writable;
+ size_t offset;
+
+ /* Do nothing if we have no data to corrupt */
+ if ( ! len )
+ return;
+
+ /* Do nothing unless we want to inject a fault now */
+ if ( ! inject_fault_nonzero ( rate ) )
+ return;
+
+ /* Get a writable pointer to the nominally read-only data */
+ writable = ( ( uint8_t * ) data );
+
+ /* Pick a random victim byte and zap it */
+ offset = ( random() % len );
+ writable[offset] ^= random();
+}
diff --git a/qemu/roms/ipxe/src/core/fbcon.c b/qemu/roms/ipxe/src/core/fbcon.c
index 72d6a6789..6d8b0086d 100644
--- a/qemu/roms/ipxe/src/core/fbcon.c
+++ b/qemu/roms/ipxe/src/core/fbcon.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** @file
*
diff --git a/qemu/roms/ipxe/src/core/fnrec.c b/qemu/roms/ipxe/src/core/fnrec.c
index 3453c8b6a..0430817f8 100644
--- a/qemu/roms/ipxe/src/core/fnrec.c
+++ b/qemu/roms/ipxe/src/core/fnrec.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdlib.h>
#include <stdio.h>
diff --git a/qemu/roms/ipxe/src/core/gdbserial.c b/qemu/roms/ipxe/src/core/gdbserial.c
index 6f78c88bf..0983f2557 100644
--- a/qemu/roms/ipxe/src/core/gdbserial.c
+++ b/qemu/roms/ipxe/src/core/gdbserial.c
@@ -15,35 +15,105 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
#include <assert.h>
-#include <ipxe/serial.h>
+#include <ipxe/uart.h>
#include <ipxe/gdbstub.h>
#include <ipxe/gdbserial.h>
+#include <config/serial.h>
+
+/* UART port number */
+#ifdef COMCONSOLE
+#define GDBSERIAL_PORT COMCONSOLE
+#else
+#define GDBSERIAL_PORT 0
+#endif
+
+/* UART baud rate */
+#ifdef COMPRESERVE
+#define GDBSERIAL_BAUD 0
+#else
+#define GDBSERIAL_BAUD COMSPEED
+#endif
+
+/* UART line control register value */
+#ifdef COMPRESERVE
+#define GDBSERIAL_LCR 0
+#else
+#define GDBSERIAL_LCR UART_LCR_WPS ( COMDATA, COMPARITY, COMSTOP )
+#endif
+
+/** GDB serial UART */
+static struct uart gdbserial_uart;
struct gdb_transport serial_gdb_transport __gdb_transport;
static size_t gdbserial_recv ( char *buf, size_t len ) {
+
assert ( len > 0 );
- buf [ 0 ] = serial_getc();
+ while ( ! uart_data_ready ( &gdbserial_uart ) ) {}
+ buf[0] = uart_receive ( &gdbserial_uart );
return 1;
}
static void gdbserial_send ( const char *buf, size_t len ) {
+
while ( len-- > 0 ) {
- serial_putc ( *buf++ );
+ uart_transmit ( &gdbserial_uart, *buf++ );
}
}
+static int gdbserial_init ( int argc, char **argv ) {
+ unsigned int port;
+ char *endp;
+
+ if ( argc == 0 ) {
+ port = GDBSERIAL_PORT;
+ } else if ( argc == 1 ) {
+ port = strtoul ( argv[0], &endp, 10 );
+ if ( *endp ) {
+ printf ( "serial: invalid port\n" );
+ return 1;
+ }
+ } else {
+ printf ( "serial: syntax <port>\n" );
+ return 1;
+ }
+
+ if ( ! gdbserial_configure ( port, GDBSERIAL_BAUD, GDBSERIAL_LCR ) ) {
+ printf ( "serial: unable to configure\n" );
+ return 1;
+ }
+
+ return 0;
+}
+
struct gdb_transport serial_gdb_transport __gdb_transport = {
.name = "serial",
+ .init = gdbserial_init,
.recv = gdbserial_recv,
.send = gdbserial_send,
};
-struct gdb_transport *gdbserial_configure ( void ) {
+struct gdb_transport * gdbserial_configure ( unsigned int port,
+ unsigned int baud, uint8_t lcr ) {
+ int rc;
+
+ if ( ( rc = uart_select ( &gdbserial_uart, port ) ) != 0 )
+ return NULL;
+
+ if ( ( rc = uart_init ( &gdbserial_uart, baud, lcr ) ) != 0 )
+ return NULL;
+
return &serial_gdb_transport;
}
diff --git a/qemu/roms/ipxe/src/core/gdbstub.c b/qemu/roms/ipxe/src/core/gdbstub.c
index af06118b2..6ad52d1a6 100644
--- a/qemu/roms/ipxe/src/core/gdbstub.c
+++ b/qemu/roms/ipxe/src/core/gdbstub.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/**
* @file
diff --git a/qemu/roms/ipxe/src/core/gdbudp.c b/qemu/roms/ipxe/src/core/gdbudp.c
index 5977547c8..e4613d137 100644
--- a/qemu/roms/ipxe/src/core/gdbudp.c
+++ b/qemu/roms/ipxe/src/core/gdbudp.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdio.h>
#include <string.h>
diff --git a/qemu/roms/ipxe/src/core/getkey.c b/qemu/roms/ipxe/src/core/getkey.c
index d69cfb44b..0f0f8b7c3 100644
--- a/qemu/roms/ipxe/src/core/getkey.c
+++ b/qemu/roms/ipxe/src/core/getkey.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ctype.h>
#include <ipxe/console.h>
diff --git a/qemu/roms/ipxe/src/core/getopt.c b/qemu/roms/ipxe/src/core/getopt.c
index abc1edd6c..e6c3948d1 100644
--- a/qemu/roms/ipxe/src/core/getopt.c
+++ b/qemu/roms/ipxe/src/core/getopt.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <string.h>
diff --git a/qemu/roms/ipxe/src/core/image.c b/qemu/roms/ipxe/src/core/image.c
index ec4480238..529e3d72c 100644
--- a/qemu/roms/ipxe/src/core/image.c
+++ b/qemu/roms/ipxe/src/core/image.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stddef.h>
#include <string.h>
@@ -154,6 +158,32 @@ int image_set_cmdline ( struct image *image, const char *cmdline ) {
}
/**
+ * Determine image type
+ *
+ * @v image Executable image
+ * @ret rc Return status code
+ */
+static int image_probe ( struct image *image ) {
+ struct image_type *type;
+ int rc;
+
+ /* Try each type in turn */
+ for_each_table_entry ( type, IMAGE_TYPES ) {
+ if ( ( rc = type->probe ( image ) ) == 0 ) {
+ image->type = type;
+ DBGC ( image, "IMAGE %s is %s\n",
+ image->name, type->name );
+ break;
+ }
+ DBGC ( image, "IMAGE %s is not %s: %s\n", image->name,
+ type->name, strerror ( rc ) );
+ }
+
+ DBGC ( image, "IMAGE %s format not recognised\n", image->name );
+ return -ENOTSUP;
+}
+
+/**
* Register executable image
*
* @v image Executable image
@@ -185,6 +215,14 @@ int register_image ( struct image *image ) {
image->name, user_to_phys ( image->data, 0 ),
user_to_phys ( image->data, image->len ) );
+ /* Try to detect image type, if applicable. Ignore failures,
+ * since we expect to handle some unrecognised images
+ * (e.g. kernel initrds, multiboot modules, random files
+ * provided via our EFI virtual filesystem, etc).
+ */
+ if ( ! image->type )
+ image_probe ( image );
+
return 0;
}
@@ -223,36 +261,6 @@ struct image * find_image ( const char *name ) {
}
/**
- * Determine image type
- *
- * @v image Executable image
- * @ret rc Return status code
- */
-int image_probe ( struct image *image ) {
- struct image_type *type;
- int rc;
-
- /* Succeed if we already have a type */
- if ( image->type )
- return 0;
-
- /* Try each type in turn */
- for_each_table_entry ( type, IMAGE_TYPES ) {
- if ( ( rc = type->probe ( image ) ) == 0 ) {
- image->type = type;
- DBGC ( image, "IMAGE %s is %s\n",
- image->name, type->name );
- return 0;
- }
- DBGC ( image, "IMAGE %s is not %s: %s\n", image->name,
- type->name, strerror ( rc ) );
- }
-
- DBGC ( image, "IMAGE %s format not recognised\n", image->name );
- return -ENOEXEC;
-}
-
-/**
* Execute image
*
* @v image Executable image
@@ -284,9 +292,11 @@ int image_exec ( struct image *image ) {
*/
current_image = image_get ( image );
- /* Check that this image can be selected for execution */
- if ( ( rc = image_select ( image ) ) != 0 )
+ /* Check that this image can be executed */
+ if ( ! ( image->type && image->type->exec ) ) {
+ rc = -ENOEXEC;
goto err;
+ }
/* Check that image is trusted (if applicable) */
if ( require_trusted_images && ! ( image->flags & IMAGE_TRUSTED ) ) {
@@ -378,8 +388,8 @@ int image_replace ( struct image *replacement ) {
}
/* Check that the replacement image can be executed */
- if ( ( rc = image_probe ( replacement ) ) != 0 )
- return rc;
+ if ( ! ( replacement->type && replacement->type->exec ) )
+ return -ENOEXEC;
/* Clear any existing replacement */
image_put ( image->replacement );
@@ -400,16 +410,13 @@ int image_replace ( struct image *replacement ) {
*/
int image_select ( struct image *image ) {
struct image *tmp;
- int rc;
/* Unselect all other images */
for_each_image ( tmp )
tmp->flags &= ~IMAGE_SELECTED;
/* Check that this image can be executed */
- if ( ( rc = image_probe ( image ) ) != 0 )
- return rc;
- if ( ! image->type->exec )
+ if ( ! ( image->type && image->type->exec ) )
return -ENOEXEC;
/* Mark image as selected */
@@ -468,9 +475,7 @@ int image_pixbuf ( struct image *image, struct pixel_buffer **pixbuf ) {
int rc;
/* Check that this image can be used to create a pixel buffer */
- if ( ( rc = image_probe ( image ) ) != 0 )
- return rc;
- if ( ! image->type->pixbuf )
+ if ( ! ( image->type && image->type->pixbuf ) )
return -ENOTSUP;
/* Try creating pixel buffer */
diff --git a/qemu/roms/ipxe/src/core/init.c b/qemu/roms/ipxe/src/core/init.c
index 7ea0730fa..d91e44669 100644
--- a/qemu/roms/ipxe/src/core/init.c
+++ b/qemu/roms/ipxe/src/core/init.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/device.h>
#include <ipxe/console.h>
diff --git a/qemu/roms/ipxe/src/core/interface.c b/qemu/roms/ipxe/src/core/interface.c
index 62f4621db..ba148c13d 100644
--- a/qemu/roms/ipxe/src/core/interface.c
+++ b/qemu/roms/ipxe/src/core/interface.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <string.h>
#include <ipxe/interface.h>
@@ -307,3 +311,28 @@ void intf_restart ( struct interface *intf, int rc ) {
*/
intf->desc = desc;
}
+
+/**
+ * Poke an object interface
+ *
+ * @v intf Object interface
+ * @v type Operation type
+ *
+ * This is a helper function to implement methods which take no
+ * parameters and return nothing.
+ */
+void intf_poke ( struct interface *intf,
+ void ( type ) ( struct interface *intf ) ) {
+ struct interface *dest;
+ intf_poke_TYPE ( void * ) *op =
+ intf_get_dest_op_untyped ( intf, type, &dest );
+ void *object = intf_object ( dest );
+
+ if ( op ) {
+ op ( object );
+ } else {
+ /* Default is to do nothing */
+ }
+
+ intf_put ( dest );
+}
diff --git a/qemu/roms/ipxe/src/core/iobuf.c b/qemu/roms/ipxe/src/core/iobuf.c
index afc91d150..3e52ada4f 100644
--- a/qemu/roms/ipxe/src/core/iobuf.c
+++ b/qemu/roms/ipxe/src/core/iobuf.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <strings.h>
@@ -200,3 +204,33 @@ struct io_buffer * iob_concatenate ( struct list_head *list ) {
return concatenated;
}
+
+/**
+ * Split I/O buffer
+ *
+ * @v iobuf I/O buffer
+ * @v len Length to split into a new I/O buffer
+ * @ret split New I/O buffer, or NULL on allocation failure
+ *
+ * Split the first @c len bytes of the existing I/O buffer into a
+ * separate I/O buffer. The resulting buffers are likely to have no
+ * headroom or tailroom.
+ *
+ * If this call fails, then the original buffer will be unmodified.
+ */
+struct io_buffer * iob_split ( struct io_buffer *iobuf, size_t len ) {
+ struct io_buffer *split;
+
+ /* Sanity checks */
+ assert ( len <= iob_len ( iobuf ) );
+
+ /* Allocate new I/O buffer */
+ split = alloc_iob ( len );
+ if ( ! split )
+ return NULL;
+
+ /* Copy in data */
+ memcpy ( iob_put ( split, len ), iobuf->data, len );
+ iob_pull ( iobuf, len );
+ return split;
+}
diff --git a/qemu/roms/ipxe/src/core/isqrt.c b/qemu/roms/ipxe/src/core/isqrt.c
index 35c918d19..c4d0571e7 100644
--- a/qemu/roms/ipxe/src/core/isqrt.c
+++ b/qemu/roms/ipxe/src/core/isqrt.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** @file
*
diff --git a/qemu/roms/ipxe/src/core/job.c b/qemu/roms/ipxe/src/core/job.c
index 674bec8b5..65df80056 100644
--- a/qemu/roms/ipxe/src/core/job.c
+++ b/qemu/roms/ipxe/src/core/job.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <string.h>
#include <errno.h>
diff --git a/qemu/roms/ipxe/src/core/linebuf.c b/qemu/roms/ipxe/src/core/linebuf.c
index 8fb2f86a7..c197e383c 100644
--- a/qemu/roms/ipxe/src/core/linebuf.c
+++ b/qemu/roms/ipxe/src/core/linebuf.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/**
* @file
@@ -39,7 +43,18 @@ FILE_LICENCE ( GPL2_OR_LATER );
* @ret line Buffered line, or NULL if no line ready to read
*/
char * buffered_line ( struct line_buffer *linebuf ) {
- return ( linebuf->ready ? linebuf->data : NULL );
+ char *line = &linebuf->data[ linebuf->len ];
+
+ /* Fail unless we have a newly completed line to retrieve */
+ if ( ( linebuf->len == 0 ) || ( linebuf->consumed == 0 ) ||
+ ( *(--line) != '\0' ) )
+ return NULL;
+
+ /* Identify start of line */
+ while ( ( line > linebuf->data ) && ( line[-1] != '\0' ) )
+ line--;
+
+ return line;
}
/**
@@ -48,10 +63,11 @@ char * buffered_line ( struct line_buffer *linebuf ) {
* @v linebuf Line buffer
*/
void empty_line_buffer ( struct line_buffer *linebuf ) {
+
free ( linebuf->data );
linebuf->data = NULL;
linebuf->len = 0;
- linebuf->ready = 0;
+ linebuf->consumed = 0;
}
/**
@@ -72,16 +88,13 @@ void empty_line_buffer ( struct line_buffer *linebuf ) {
* should call empty_line_buffer() before freeing a @c struct @c
* line_buffer.
*/
-ssize_t line_buffer ( struct line_buffer *linebuf,
- const char *data, size_t len ) {
+int line_buffer ( struct line_buffer *linebuf, const char *data, size_t len ) {
const char *eol;
size_t consume;
size_t new_len;
char *new_data;
-
- /* Free any completed line from previous iteration */
- if ( linebuf->ready )
- empty_line_buffer ( linebuf );
+ char *lf;
+ char *cr;
/* Search for line terminator */
if ( ( eol = memchr ( data, '\n', len ) ) ) {
@@ -90,6 +103,10 @@ ssize_t line_buffer ( struct line_buffer *linebuf,
consume = len;
}
+ /* Reject any embedded NULs within the data to be consumed */
+ if ( memchr ( data, '\0', consume ) )
+ return -EINVAL;
+
/* Reallocate data buffer and copy in new data */
new_len = ( linebuf->len + consume );
new_data = realloc ( linebuf->data, ( new_len + 1 ) );
@@ -100,13 +117,27 @@ ssize_t line_buffer ( struct line_buffer *linebuf,
linebuf->data = new_data;
linebuf->len = new_len;
- /* If we have reached end of line, trim the line and mark as ready */
+ /* If we have reached end of line, terminate the line */
if ( eol ) {
- linebuf->data[--linebuf->len] = '\0'; /* trim NL */
- if ( linebuf->data[linebuf->len - 1] == '\r' )
- linebuf->data[--linebuf->len] = '\0'; /* trim CR */
- linebuf->ready = 1;
+
+ /* Overwrite trailing LF (which must exist at this point) */
+ assert ( linebuf->len > 0 );
+ lf = &linebuf->data[ linebuf->len - 1 ];
+ assert ( *lf == '\n' );
+ *lf = '\0';
+
+ /* Trim (and overwrite) trailing CR, if present */
+ if ( linebuf->len > 1 ) {
+ cr = ( lf - 1 );
+ if ( *cr == '\r' ) {
+ linebuf->len--;
+ *cr = '\0';
+ }
+ }
}
+ /* Record consumed length */
+ linebuf->consumed = consume;
+
return consume;
}
diff --git a/qemu/roms/ipxe/src/core/lineconsole.c b/qemu/roms/ipxe/src/core/lineconsole.c
index 1b6791cf3..bb3bfafc9 100644
--- a/qemu/roms/ipxe/src/core/lineconsole.c
+++ b/qemu/roms/ipxe/src/core/lineconsole.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** @file
*
diff --git a/qemu/roms/ipxe/src/core/list.c b/qemu/roms/ipxe/src/core/list.c
index 77579d69a..5175c84ec 100644
--- a/qemu/roms/ipxe/src/core/list.c
+++ b/qemu/roms/ipxe/src/core/list.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** @file
*
diff --git a/qemu/roms/ipxe/src/core/log.c b/qemu/roms/ipxe/src/core/log.c
index f160b4fc8..c08e4bb9b 100644
--- a/qemu/roms/ipxe/src/core/log.c
+++ b/qemu/roms/ipxe/src/core/log.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** @file
*
diff --git a/qemu/roms/ipxe/src/core/main.c b/qemu/roms/ipxe/src/core/main.c
index db09e4c39..638dea9cf 100644
--- a/qemu/roms/ipxe/src/core/main.c
+++ b/qemu/roms/ipxe/src/core/main.c
@@ -12,7 +12,7 @@ Literature dealing with the network protocols:
**************************************************************************/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stddef.h>
#include <stdio.h>
@@ -26,6 +26,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
* @ret rc Return status code
*/
__asmcall int main ( void ) {
+ int rc;
/* Perform one-time-only initialisation (e.g. heap) */
initialise();
@@ -35,9 +36,11 @@ __asmcall int main ( void ) {
startup();
printf ( "ok\n" );
- ipxe ( NULL );
+ /* Attempt to boot */
+ if ( ( rc = ipxe ( NULL ) ) != 0 )
+ goto err_ipxe;
+ err_ipxe:
shutdown_exit();
-
- return 0;
+ return rc;
}
diff --git a/qemu/roms/ipxe/src/core/malloc.c b/qemu/roms/ipxe/src/core/malloc.c
index d9c07495d..b120c0325 100644
--- a/qemu/roms/ipxe/src/core/malloc.c
+++ b/qemu/roms/ipxe/src/core/malloc.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stddef.h>
#include <stdint.h>
@@ -106,6 +110,7 @@ static char heap[HEAP_SIZE] __attribute__ (( aligned ( __alignof__(void *) )));
static inline void valgrind_make_blocks_defined ( void ) {
struct memory_block *block;
+ /* Do nothing unless running under Valgrind */
if ( RUNNING_ON_VALGRIND <= 0 )
return;
@@ -147,6 +152,7 @@ static inline void valgrind_make_blocks_noaccess ( void ) {
struct memory_block *block;
struct memory_block *prev = NULL;
+ /* Do nothing unless running under Valgrind */
if ( RUNNING_ON_VALGRIND <= 0 )
return;
@@ -267,24 +273,25 @@ static void discard_all_cache ( void ) {
void * alloc_memblock ( size_t size, size_t align, size_t offset ) {
struct memory_block *block;
size_t align_mask;
+ size_t actual_size;
size_t pre_size;
ssize_t post_size;
struct memory_block *pre;
struct memory_block *post;
- struct memory_block *ptr;
+ void *ptr;
/* Sanity checks */
assert ( size != 0 );
assert ( ( align == 0 ) || ( ( align & ( align - 1 ) ) == 0 ) );
-
valgrind_make_blocks_defined();
check_blocks();
/* Round up size to multiple of MIN_MEMBLOCK_SIZE and
* calculate alignment mask.
*/
- size = ( size + MIN_MEMBLOCK_SIZE - 1 ) & ~( MIN_MEMBLOCK_SIZE - 1 );
- align_mask = ( align - 1 ) | ( MIN_MEMBLOCK_SIZE - 1 );
+ actual_size = ( ( size + MIN_MEMBLOCK_SIZE - 1 ) &
+ ~( MIN_MEMBLOCK_SIZE - 1 ) );
+ align_mask = ( ( align - 1 ) | ( MIN_MEMBLOCK_SIZE - 1 ) );
DBGC2 ( &heap, "Allocating %#zx (aligned %#zx+%zx)\n",
size, align, offset );
@@ -293,7 +300,7 @@ void * alloc_memblock ( size_t size, size_t align, size_t offset ) {
list_for_each_entry ( block, &free_blocks, list ) {
pre_size = ( ( offset - virt_to_phys ( block ) )
& align_mask );
- post_size = ( block->size - pre_size - size );
+ post_size = ( block->size - pre_size - actual_size );
if ( post_size >= 0 ) {
/* Split block into pre-block, block, and
* post-block. After this split, the "pre"
@@ -302,7 +309,7 @@ void * alloc_memblock ( size_t size, size_t align, size_t offset ) {
*/
pre = block;
block = ( ( ( void * ) pre ) + pre_size );
- post = ( ( ( void * ) block ) + size );
+ post = ( ( ( void * ) block ) + actual_size );
DBGC2 ( &heap, "[%p,%p) -> [%p,%p) + [%p,%p)\n",
pre, ( ( ( void * ) pre ) + pre->size ),
pre, block, post,
@@ -313,8 +320,8 @@ void * alloc_memblock ( size_t size, size_t align, size_t offset ) {
* the heap).
*/
if ( (size_t) post_size >= MIN_MEMBLOCK_SIZE ) {
- VALGRIND_MAKE_MEM_DEFINED ( post,
- sizeof ( *post ) );
+ VALGRIND_MAKE_MEM_UNDEFINED
+ ( post, sizeof ( *post ) );
post->size = post_size;
list_add ( &post->list, &pre->list );
}
@@ -328,14 +335,18 @@ void * alloc_memblock ( size_t size, size_t align, size_t offset ) {
* it is too small, which can happen only at
* the very start of the heap.
*/
- if ( pre_size < MIN_MEMBLOCK_SIZE )
+ if ( pre_size < MIN_MEMBLOCK_SIZE ) {
list_del ( &pre->list );
+ VALGRIND_MAKE_MEM_NOACCESS
+ ( pre, sizeof ( *pre ) );
+ }
/* Update total free memory */
- freemem -= size;
+ freemem -= actual_size;
/* Return allocated block */
DBGC2 ( &heap, "Allocated [%p,%p)\n", block,
( ( ( void * ) block ) + size ) );
ptr = block;
+ VALGRIND_MAKE_MEM_UNDEFINED ( ptr, size );
goto done;
}
}
@@ -368,13 +379,16 @@ void free_memblock ( void *ptr, size_t size ) {
struct memory_block *freeing;
struct memory_block *block;
struct memory_block *tmp;
+ size_t actual_size;
ssize_t gap_before;
ssize_t gap_after = -1;
/* Allow for ptr==NULL */
if ( ! ptr )
return;
+ VALGRIND_MAKE_MEM_NOACCESS ( ptr, size );
+ /* Sanity checks */
valgrind_make_blocks_defined();
check_blocks();
@@ -382,9 +396,10 @@ void free_memblock ( void *ptr, size_t size ) {
* would have used.
*/
assert ( size != 0 );
- size = ( size + MIN_MEMBLOCK_SIZE - 1 ) & ~( MIN_MEMBLOCK_SIZE - 1 );
+ actual_size = ( ( size + MIN_MEMBLOCK_SIZE - 1 ) &
+ ~( MIN_MEMBLOCK_SIZE - 1 ) );
freeing = ptr;
- VALGRIND_MAKE_MEM_DEFINED ( freeing, sizeof ( *freeing ) );
+ VALGRIND_MAKE_MEM_UNDEFINED ( freeing, sizeof ( *freeing ) );
DBGC2 ( &heap, "Freeing [%p,%p)\n",
freeing, ( ( ( void * ) freeing ) + size ) );
@@ -392,7 +407,7 @@ void free_memblock ( void *ptr, size_t size ) {
if ( ASSERTING ) {
list_for_each_entry ( block, &free_blocks, list ) {
if ( ( ( ( void * ) block ) <
- ( ( void * ) freeing + size ) ) &&
+ ( ( void * ) freeing + actual_size ) ) &&
( ( void * ) freeing <
( ( void * ) block + block->size ) ) ) {
assert ( 0 );
@@ -407,7 +422,7 @@ void free_memblock ( void *ptr, size_t size ) {
}
/* Insert/merge into free list */
- freeing->size = size;
+ freeing->size = actual_size;
list_for_each_entry_safe ( block, tmp, &free_blocks, list ) {
/* Calculate gaps before and after the "freeing" block */
gap_before = ( ( ( void * ) freeing ) -
@@ -421,8 +436,10 @@ void free_memblock ( void *ptr, size_t size ) {
( ( ( void * ) freeing ) + freeing->size ),
block,
( ( ( void * ) freeing ) + freeing->size ) );
- block->size += size;
+ block->size += actual_size;
list_del ( &block->list );
+ VALGRIND_MAKE_MEM_NOACCESS ( freeing,
+ sizeof ( *freeing ) );
freeing = block;
}
/* Stop processing as soon as we reach a following block */
@@ -444,10 +461,11 @@ void free_memblock ( void *ptr, size_t size ) {
( ( ( void * ) block ) + block->size ) );
freeing->size += block->size;
list_del ( &block->list );
+ VALGRIND_MAKE_MEM_NOACCESS ( block, sizeof ( *block ) );
}
/* Update free memory counter */
- freemem += size;
+ freemem += actual_size;
check_blocks();
valgrind_make_blocks_noaccess();
@@ -490,9 +508,9 @@ void * realloc ( void *old_ptr, size_t new_size ) {
new_block = alloc_memblock ( new_total_size, 1, 0 );
if ( ! new_block )
return NULL;
- VALGRIND_MAKE_MEM_UNDEFINED ( new_block, offsetof ( struct autosized_block, data ) );
new_block->size = new_total_size;
- VALGRIND_MAKE_MEM_NOACCESS ( new_block, offsetof ( struct autosized_block, data ) );
+ VALGRIND_MAKE_MEM_NOACCESS ( &new_block->size,
+ sizeof ( new_block->size ) );
new_ptr = &new_block->data;
VALGRIND_MALLOCLIKE_BLOCK ( new_ptr, new_size, 0, 0 );
}
@@ -505,16 +523,16 @@ void * realloc ( void *old_ptr, size_t new_size ) {
if ( old_ptr && ( old_ptr != NOWHERE ) ) {
old_block = container_of ( old_ptr, struct autosized_block,
data );
- VALGRIND_MAKE_MEM_DEFINED ( old_block, offsetof ( struct autosized_block, data ) );
+ VALGRIND_MAKE_MEM_DEFINED ( &old_block->size,
+ sizeof ( old_block->size ) );
old_total_size = old_block->size;
assert ( old_total_size != 0 );
old_size = ( old_total_size -
offsetof ( struct autosized_block, data ) );
memcpy ( new_ptr, old_ptr,
( ( old_size < new_size ) ? old_size : new_size ) );
- free_memblock ( old_block, old_total_size );
- VALGRIND_MAKE_MEM_NOACCESS ( old_block, offsetof ( struct autosized_block, data ) );
VALGRIND_FREELIKE_BLOCK ( old_ptr, 0 );
+ free_memblock ( old_block, old_total_size );
}
if ( ASSERTED ) {
@@ -611,6 +629,7 @@ void mpopulate ( void *start, size_t len ) {
*/
static void init_heap ( void ) {
VALGRIND_MAKE_MEM_NOACCESS ( heap, sizeof ( heap ) );
+ VALGRIND_MAKE_MEM_NOACCESS ( &free_blocks, sizeof ( free_blocks ) );
mpopulate ( heap, sizeof ( heap ) );
}
diff --git a/qemu/roms/ipxe/src/core/memblock.c b/qemu/roms/ipxe/src/core/memblock.c
index 1fd89b871..aecddc22c 100644
--- a/qemu/roms/ipxe/src/core/memblock.c
+++ b/qemu/roms/ipxe/src/core/memblock.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** @file
*
diff --git a/qemu/roms/ipxe/src/core/memmap_settings.c b/qemu/roms/ipxe/src/core/memmap_settings.c
index 0f6d0abf5..fab3e5f3a 100644
--- a/qemu/roms/ipxe/src/core/memmap_settings.c
+++ b/qemu/roms/ipxe/src/core/memmap_settings.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <string.h>
#include <errno.h>
diff --git a/qemu/roms/ipxe/src/core/menu.c b/qemu/roms/ipxe/src/core/menu.c
index 8d42e1f83..ab5b0c7f5 100644
--- a/qemu/roms/ipxe/src/core/menu.c
+++ b/qemu/roms/ipxe/src/core/menu.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** @file
*
diff --git a/qemu/roms/ipxe/src/core/misc.c b/qemu/roms/ipxe/src/core/misc.c
deleted file mode 100644
index eaceddfea..000000000
--- a/qemu/roms/ipxe/src/core/misc.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/**************************************************************************
-MISC Support Routines
-**************************************************************************/
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include <stdlib.h>
-#include <ctype.h>
-#include <byteswap.h>
-#include <ipxe/in.h>
-#include <ipxe/timer.h>
-
-/**************************************************************************
-INET_ATON - Convert an ascii x.x.x.x to binary form
-**************************************************************************/
-int inet_aton ( const char *cp, struct in_addr *inp ) {
- const char *p = cp;
- const char *digits_start;
- unsigned long ip = 0;
- unsigned long val;
- int j;
- for(j = 0; j <= 3; j++) {
- digits_start = p;
- val = strtoul(p, ( char ** ) &p, 10);
- if ((p == digits_start) || (val > 255)) return 0;
- if ( ( j < 3 ) && ( *(p++) != '.' ) ) return 0;
- ip = (ip << 8) | val;
- }
- if ( *p == '\0' ) {
- inp->s_addr = htonl(ip);
- return 1;
- }
- return 0;
-}
-
-unsigned int strtoul_charval ( unsigned int charval ) {
-
- if ( charval >= 'a' ) {
- charval = ( charval - 'a' + 10 );
- } else if ( charval >= 'A' ) {
- charval = ( charval - 'A' + 10 );
- } else if ( charval <= '9' ) {
- charval = ( charval - '0' );
- }
-
- return charval;
-}
-
-unsigned long strtoul ( const char *p, char **endp, int base ) {
- unsigned long ret = 0;
- int negative = 0;
- unsigned int charval;
-
- while ( isspace ( *p ) )
- p++;
-
- if ( *p == '-' ) {
- negative = 1;
- p++;
- }
-
- base = strtoul_base ( &p, base );
-
- while ( 1 ) {
- charval = strtoul_charval ( *p );
- if ( charval >= ( unsigned int ) base )
- break;
- ret = ( ( ret * base ) + charval );
- p++;
- }
-
- if ( negative )
- ret = -ret;
-
- if ( endp )
- *endp = ( char * ) p;
-
- return ( ret );
-}
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/qemu/roms/ipxe/src/core/monojob.c b/qemu/roms/ipxe/src/core/monojob.c
index 820fa31dc..817f21b2c 100644
--- a/qemu/roms/ipxe/src/core/monojob.c
+++ b/qemu/roms/ipxe/src/core/monojob.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <string.h>
#include <stdio.h>
diff --git a/qemu/roms/ipxe/src/core/null_reboot.c b/qemu/roms/ipxe/src/core/null_reboot.c
index a3d5b2ef8..7be5612a3 100644
--- a/qemu/roms/ipxe/src/core/null_reboot.c
+++ b/qemu/roms/ipxe/src/core/null_reboot.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/**
* @file
diff --git a/qemu/roms/ipxe/src/core/null_sanboot.c b/qemu/roms/ipxe/src/core/null_sanboot.c
index 18c0dea84..2f7522c6c 100644
--- a/qemu/roms/ipxe/src/core/null_sanboot.c
+++ b/qemu/roms/ipxe/src/core/null_sanboot.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <errno.h>
#include <ipxe/sanboot.h>
diff --git a/qemu/roms/ipxe/src/core/null_time.c b/qemu/roms/ipxe/src/core/null_time.c
index 506c70b52..90041a456 100644
--- a/qemu/roms/ipxe/src/core/null_time.c
+++ b/qemu/roms/ipxe/src/core/null_time.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** @file
*
diff --git a/qemu/roms/ipxe/src/core/nvo.c b/qemu/roms/ipxe/src/core/nvo.c
index e135d2b41..d2c9b5e73 100644
--- a/qemu/roms/ipxe/src/core/nvo.c
+++ b/qemu/roms/ipxe/src/core/nvo.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <stdlib.h>
diff --git a/qemu/roms/ipxe/src/core/open.c b/qemu/roms/ipxe/src/core/open.c
index b479c2975..9d665ffda 100644
--- a/qemu/roms/ipxe/src/core/open.c
+++ b/qemu/roms/ipxe/src/core/open.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdarg.h>
#include <string.h>
diff --git a/qemu/roms/ipxe/src/core/params.c b/qemu/roms/ipxe/src/core/params.c
index 93b834419..e1f66acca 100644
--- a/qemu/roms/ipxe/src/core/params.c
+++ b/qemu/roms/ipxe/src/core/params.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** @file
*
diff --git a/qemu/roms/ipxe/src/core/parseopt.c b/qemu/roms/ipxe/src/core/parseopt.c
index d268c0594..66f60158c 100644
--- a/qemu/roms/ipxe/src/core/parseopt.c
+++ b/qemu/roms/ipxe/src/core/parseopt.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stddef.h>
#include <stdint.h>
@@ -32,6 +36,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <ipxe/params.h>
#include <ipxe/timer.h>
#include <ipxe/parseopt.h>
+#include <config/branding.h>
/** @file
*
@@ -343,7 +348,7 @@ void print_usage ( struct command_descriptor *cmd, char **argv ) {
}
if ( cmd->usage )
printf ( " %s", cmd->usage );
- printf ( "\n\nSee http://ipxe.org/cmd/%s for further information\n",
+ printf ( "\n\nSee " PRODUCT_COMMAND_URI " for further information\n",
argv[0] );
}
diff --git a/qemu/roms/ipxe/src/core/pending.c b/qemu/roms/ipxe/src/core/pending.c
index 7bb0c2e00..96d0cf197 100644
--- a/qemu/roms/ipxe/src/core/pending.c
+++ b/qemu/roms/ipxe/src/core/pending.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <errno.h>
#include <ipxe/process.h>
diff --git a/qemu/roms/ipxe/src/core/pinger.c b/qemu/roms/ipxe/src/core/pinger.c
index 31ea2ce1c..0ff7bb9f2 100644
--- a/qemu/roms/ipxe/src/core/pinger.c
+++ b/qemu/roms/ipxe/src/core/pinger.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdlib.h>
#include <string.h>
diff --git a/qemu/roms/ipxe/src/core/pixbuf.c b/qemu/roms/ipxe/src/core/pixbuf.c
index 48f8e9f9a..41e18f8dc 100644
--- a/qemu/roms/ipxe/src/core/pixbuf.c
+++ b/qemu/roms/ipxe/src/core/pixbuf.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** @file
*
diff --git a/qemu/roms/ipxe/src/core/pool.c b/qemu/roms/ipxe/src/core/pool.c
new file mode 100644
index 000000000..0163405f7
--- /dev/null
+++ b/qemu/roms/ipxe/src/core/pool.c
@@ -0,0 +1,114 @@
+/*
+ * 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
+ *
+ * Pooled connections
+ *
+ */
+
+#include <assert.h>
+#include <ipxe/pool.h>
+
+/**
+ * Recycle this connection after closing
+ *
+ * @v intf Data transfer interface
+ */
+void pool_recycle ( struct interface *intf ) {
+
+ intf_poke ( intf, pool_recycle );
+}
+
+/**
+ * Reopen a defunct connection
+ *
+ * @v intf Data transfer interface
+ */
+void pool_reopen ( struct interface *intf ) {
+
+ intf_poke ( intf, pool_reopen );
+}
+
+/**
+ * Add connection to pool
+ *
+ * @v pool Pooled connection
+ * @v list List of pooled connections
+ * @v expiry Expiry time
+ */
+void pool_add ( struct pooled_connection *pool, struct list_head *list,
+ unsigned long expiry ) {
+
+ /* Sanity check */
+ assert ( list_empty ( &pool->list ) );
+ assert ( ! timer_running ( &pool->timer ) );
+
+ /* Add to list of pooled connections */
+ list_add_tail ( &pool->list, list );
+
+ /* Start expiry timer */
+ start_timer_fixed ( &pool->timer, expiry );
+}
+
+/**
+ * Remove connection from pool
+ *
+ * @v pool Pooled connection
+ */
+void pool_del ( struct pooled_connection *pool ) {
+
+ /* Remove from list of pooled connections */
+ list_del ( &pool->list );
+ INIT_LIST_HEAD ( &pool->list );
+
+ /* Stop expiry timer */
+ stop_timer ( &pool->timer );
+
+ /* Mark as a freshly recycled connection */
+ pool->flags = POOL_RECYCLED;
+}
+
+/**
+ * Close expired pooled connection
+ *
+ * @v timer Expiry timer
+ * @v over Failure indicator
+ */
+void pool_expired ( struct retry_timer *timer, int over __unused ) {
+ struct pooled_connection *pool =
+ container_of ( timer, struct pooled_connection, timer );
+
+ /* Sanity check */
+ assert ( ! list_empty ( &pool->list ) );
+
+ /* Remove from connection pool */
+ list_del ( &pool->list );
+ INIT_LIST_HEAD ( &pool->list );
+
+ /* Close expired connection */
+ pool->expired ( pool );
+}
diff --git a/qemu/roms/ipxe/src/core/posix_io.c b/qemu/roms/ipxe/src/core/posix_io.c
index 8460d0f51..35b52beeb 100644
--- a/qemu/roms/ipxe/src/core/posix_io.c
+++ b/qemu/roms/ipxe/src/core/posix_io.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdlib.h>
#include <string.h>
diff --git a/qemu/roms/ipxe/src/core/process.c b/qemu/roms/ipxe/src/core/process.c
index d341a2c37..69852c416 100644
--- a/qemu/roms/ipxe/src/core/process.c
+++ b/qemu/roms/ipxe/src/core/process.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/list.h>
#include <ipxe/init.h>
diff --git a/qemu/roms/ipxe/src/core/profile.c b/qemu/roms/ipxe/src/core/profile.c
index 150e6b273..1075047b9 100644
--- a/qemu/roms/ipxe/src/core/profile.c
+++ b/qemu/roms/ipxe/src/core/profile.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <stdio.h>
diff --git a/qemu/roms/ipxe/src/core/random.c b/qemu/roms/ipxe/src/core/random.c
index 8824dca3a..a74175a79 100644
--- a/qemu/roms/ipxe/src/core/random.c
+++ b/qemu/roms/ipxe/src/core/random.c
@@ -4,7 +4,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdlib.h>
#include <ipxe/timer.h>
diff --git a/qemu/roms/ipxe/src/core/refcnt.c b/qemu/roms/ipxe/src/core/refcnt.c
index 68a86120e..47c975a0b 100644
--- a/qemu/roms/ipxe/src/core/refcnt.c
+++ b/qemu/roms/ipxe/src/core/refcnt.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdlib.h>
#include <ipxe/refcnt.h>
diff --git a/qemu/roms/ipxe/src/core/resolv.c b/qemu/roms/ipxe/src/core/resolv.c
index d59a8c0ad..1e3182b0b 100644
--- a/qemu/roms/ipxe/src/core/resolv.c
+++ b/qemu/roms/ipxe/src/core/resolv.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <stdlib.h>
diff --git a/qemu/roms/ipxe/src/core/serial.c b/qemu/roms/ipxe/src/core/serial.c
index 7e4460ab9..4ce025519 100644
--- a/qemu/roms/ipxe/src/core/serial.c
+++ b/qemu/roms/ipxe/src/core/serial.c
@@ -1,259 +1,184 @@
/*
- * The serial port interface routines implement a simple polled i/o
- * interface to a standard serial port. Due to the space restrictions
- * for the boot blocks, no BIOS support is used (since BIOS requires
- * expensive real/protected mode switches), instead the rudimentary
- * BIOS support is duplicated here.
+ * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
*
- * The base address and speed for the i/o port are passed from the
- * Makefile in the COMCONSOLE and CONSPEED preprocessor macros. The
- * line control parameters are currently hard-coded to 8 bits, no
- * parity, 1 stop bit (8N1). This can be changed in init_serial().
+ * 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+/** @file
+ *
+ * Serial console
+ *
+ */
-#include "stddef.h"
+#include <stddef.h>
#include <ipxe/init.h>
-#include <ipxe/io.h>
-#include <unistd.h>
+#include <ipxe/uart.h>
+#include <ipxe/console.h>
#include <ipxe/serial.h>
-#include "config/serial.h"
-
-/* Set default values if none specified */
+#include <config/console.h>
+#include <config/serial.h>
-#ifndef COMCONSOLE
-#define COMCONSOLE 0x3f8
+/* Set default console usage if applicable */
+#if ! ( defined ( CONSOLE_SERIAL ) && CONSOLE_EXPLICIT ( CONSOLE_SERIAL ) )
+#undef CONSOLE_SERIAL
+#define CONSOLE_SERIAL ( CONSOLE_USAGE_ALL & ~CONSOLE_USAGE_LOG )
#endif
-#ifndef COMSPEED
-#define COMSPEED 9600
-#endif
-
-#ifndef COMDATA
-#define COMDATA 8
+/* UART port number */
+#ifdef COMCONSOLE
+#define CONSOLE_PORT COMCONSOLE
+#else
+#define CONSOLE_PORT 0
#endif
-#ifndef COMPARITY
-#define COMPARITY 0
+/* UART baud rate */
+#ifdef COMPRESERVE
+#define CONSOLE_BAUD 0
+#else
+#define CONSOLE_BAUD COMSPEED
#endif
-#ifndef COMSTOP
-#define COMSTOP 1
+/* UART line control register value */
+#ifdef COMPRESERVE
+#define CONSOLE_LCR 0
+#else
+#define CONSOLE_LCR UART_LCR_WPS ( COMDATA, COMPARITY, COMSTOP )
#endif
-#undef UART_BASE
-#define UART_BASE ( COMCONSOLE )
-
-#undef UART_BAUD
-#define UART_BAUD ( COMSPEED )
+/** Serial console UART */
+struct uart serial_console;
-#if ((115200%UART_BAUD) != 0)
-#error Bad ttys0 baud rate
-#endif
-
-#define COMBRD (115200/UART_BAUD)
+/**
+ * Print a character to serial console
+ *
+ * @v character Character to be printed
+ */
+static void serial_putchar ( int character ) {
-/* Line Control Settings */
-#define UART_LCS ( ( ( (COMDATA) - 5 ) << 0 ) | \
- ( ( (COMPARITY) ) << 3 ) | \
- ( ( (COMSTOP) - 1 ) << 2 ) )
+ /* Do nothing if we have no UART */
+ if ( ! serial_console.base )
+ return;
-/* Data */
-#define UART_RBR 0x00
-#define UART_TBR 0x00
+ /* Transmit character */
+ uart_transmit ( &serial_console, character );
+}
-/* Control */
-#define UART_IER 0x01
-#define UART_IIR 0x02
-#define UART_FCR 0x02
-#define UART_LCR 0x03
-#define UART_MCR 0x04
-#define UART_DLL 0x00
-#define UART_DLM 0x01
+/**
+ * Get character from serial console
+ *
+ * @ret character Character read from console
+ */
+static int serial_getchar ( void ) {
+ uint8_t data;
-/* Status */
-#define UART_LSR 0x05
-#define UART_LSR_TEMPT 0x40 /* Transmitter empty */
-#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
-#define UART_LSR_BI 0x10 /* Break interrupt indicator */
-#define UART_LSR_FE 0x08 /* Frame error indicator */
-#define UART_LSR_PE 0x04 /* Parity error indicator */
-#define UART_LSR_OE 0x02 /* Overrun error indicator */
-#define UART_LSR_DR 0x01 /* Receiver data ready */
+ /* Do nothing if we have no UART */
+ if ( ! serial_console.base )
+ return 0;
-#define UART_MSR 0x06
-#define UART_SCR 0x07
+ /* Wait for data to be ready */
+ while ( ! uart_data_ready ( &serial_console ) ) {}
-#if defined(UART_MEM)
-#define uart_readb(addr) readb((addr))
-#define uart_writeb(val,addr) writeb((val),(addr))
-#else
-#define uart_readb(addr) inb((addr))
-#define uart_writeb(val,addr) outb((val),(addr))
-#endif
+ /* Receive data */
+ data = uart_receive ( &serial_console );
-/* Boolean for the state of serial driver initialization */
-int serial_initialized = 0;
+ /* Strip any high bit and convert DEL to backspace */
+ data &= 0x7f;
+ if ( data == 0x7f )
+ data = 0x08;
-/*
- * void serial_putc(int ch);
- * Write character `ch' to port UART_BASE.
- */
-void serial_putc ( int ch ) {
- int i;
- int status;
- i = 1000; /* timeout */
- while(--i > 0) {
- status = uart_readb(UART_BASE + UART_LSR);
- if (status & UART_LSR_THRE) {
- /* TX buffer emtpy */
- uart_writeb(ch, UART_BASE + UART_TBR);
- break;
- }
- mdelay(2);
- }
+ return data;
}
-/*
- * int serial_getc(void);
- * Read a character from port UART_BASE.
- */
-int serial_getc ( void ) {
- int status;
- int ch;
- do {
- status = uart_readb(UART_BASE + UART_LSR);
- } while((status & 1) == 0);
- ch = uart_readb(UART_BASE + UART_RBR); /* fetch (first) character */
- ch &= 0x7f; /* remove any parity bits we get */
- if (ch == 0x7f) { /* Make DEL... look like BS */
- ch = 0x08;
- }
- return ch;
-}
-
-/*
- * int serial_ischar(void);
- * If there is a character in the input buffer of port UART_BASE,
- * return nonzero; otherwise return 0.
+/**
+ * Check for character ready to read from serial console
+ *
+ * @ret True Character available to read
+ * @ret False No character available to read
*/
-int serial_ischar ( void ) {
- int status;
- status = uart_readb(UART_BASE + UART_LSR); /* line status reg; */
- return status & 1; /* rx char available */
-}
+static int serial_iskey ( void ) {
-/*
- * int serial_init(void);
- * Initialize port UART_BASE to speed COMSPEED, line settings 8N1.
- */
-static void serial_init ( void ) {
- int status;
- int divisor, lcs;
+ /* Do nothing if we have no UART */
+ if ( ! serial_console.base )
+ return 0;
- DBG ( "Serial port %#x initialising\n", UART_BASE );
+ /* Check UART */
+ return uart_data_ready ( &serial_console );
+}
- divisor = COMBRD;
- lcs = UART_LCS;
+/** Serial console */
+struct console_driver serial_console_driver __console_driver = {
+ .putchar = serial_putchar,
+ .getchar = serial_getchar,
+ .iskey = serial_iskey,
+ .usage = CONSOLE_SERIAL,
+};
+/** Initialise serial console */
+static void serial_init ( void ) {
+ int rc;
-#ifdef COMPRESERVE
- lcs = uart_readb(UART_BASE + UART_LCR) & 0x7f;
- uart_writeb(0x80 | lcs, UART_BASE + UART_LCR);
- divisor = (uart_readb(UART_BASE + UART_DLM) << 8) | uart_readb(UART_BASE + UART_DLL);
- uart_writeb(lcs, UART_BASE + UART_LCR);
-#endif
+ /* Do nothing if we have no default port */
+ if ( ! CONSOLE_PORT )
+ return;
- /* Set Baud Rate Divisor to COMSPEED, and test to see if the
- * serial port appears to be present.
- */
- uart_writeb(0x80 | lcs, UART_BASE + UART_LCR);
- uart_writeb(0xaa, UART_BASE + UART_DLL);
- if (uart_readb(UART_BASE + UART_DLL) != 0xaa) {
- DBG ( "Serial port %#x UART_DLL failed\n", UART_BASE );
- goto out;
- }
- uart_writeb(0x55, UART_BASE + UART_DLL);
- if (uart_readb(UART_BASE + UART_DLL) != 0x55) {
- DBG ( "Serial port %#x UART_DLL failed\n", UART_BASE );
- goto out;
+ /* Select UART */
+ if ( ( rc = uart_select ( &serial_console, CONSOLE_PORT ) ) != 0 ) {
+ DBG ( "Could not select UART %d: %s\n",
+ CONSOLE_PORT, strerror ( rc ) );
+ return;
}
- uart_writeb(divisor & 0xff, UART_BASE + UART_DLL);
- if (uart_readb(UART_BASE + UART_DLL) != (divisor & 0xff)) {
- DBG ( "Serial port %#x UART_DLL failed\n", UART_BASE );
- goto out;
- }
- uart_writeb(0xaa, UART_BASE + UART_DLM);
- if (uart_readb(UART_BASE + UART_DLM) != 0xaa) {
- DBG ( "Serial port %#x UART_DLM failed\n", UART_BASE );
- goto out;
- }
- uart_writeb(0x55, UART_BASE + UART_DLM);
- if (uart_readb(UART_BASE + UART_DLM) != 0x55) {
- DBG ( "Serial port %#x UART_DLM failed\n", UART_BASE );
- goto out;
- }
- uart_writeb((divisor >> 8) & 0xff, UART_BASE + UART_DLM);
- if (uart_readb(UART_BASE + UART_DLM) != ((divisor >> 8) & 0xff)) {
- DBG ( "Serial port %#x UART_DLM failed\n", UART_BASE );
- goto out;
- }
- uart_writeb(lcs, UART_BASE + UART_LCR);
-
- /* disable interrupts */
- uart_writeb(0x0, UART_BASE + UART_IER);
- /* enable fifos */
- uart_writeb(0x01, UART_BASE + UART_FCR);
+ /* Initialise UART */
+ if ( ( rc = uart_init ( &serial_console, CONSOLE_BAUD,
+ CONSOLE_LCR ) ) != 0 ) {
+ DBG ( "Could not initialise UART %d baud %d LCR %#02x: %s\n",
+ CONSOLE_PORT, CONSOLE_BAUD, CONSOLE_LCR, strerror ( rc ));
+ return;
+ }
+}
- /* Set clear to send, so flow control works... */
- uart_writeb((1<<1), UART_BASE + UART_MCR);
+/**
+ * Shut down serial console
+ *
+ * @v flags Shutdown flags
+ */
+static void serial_shutdown ( int flags __unused ) {
- /* Flush the input buffer. */
- do {
- /* rx buffer reg
- * throw away (unconditionally the first time)
- */
- (void) uart_readb(UART_BASE + UART_RBR);
- /* line status reg */
- status = uart_readb(UART_BASE + UART_LSR);
- } while(status & UART_LSR_DR);
+ /* Do nothing if we have no UART */
+ if ( ! serial_console.base )
+ return;
- /* Note that serial support has been initialized */
- serial_initialized = 1;
- out:
- return;
-}
+ /* Flush any pending output */
+ uart_flush ( &serial_console );
-/*
- * void serial_fini(void);
- * Cleanup our use of the serial port, in particular flush the
- * output buffer so we don't accidentially lose characters.
- */
-static void serial_fini ( int flags __unused ) {
- int i, status;
- /* Flush the output buffer to avoid dropping characters,
- * if we are reinitializing the serial port.
- */
- i = 10000; /* timeout */
- do {
- status = uart_readb(UART_BASE + UART_LSR);
- } while((--i > 0) && !(status & UART_LSR_TEMPT));
- /* Don't mark it as disabled; it's still usable */
+ /* Leave console enabled; it's still usable */
}
-/**
- * Serial driver initialisation function
- *
- * Initialise serial port early on so that it is available to capture
- * early debug messages.
- */
-struct init_fn serial_init_fn __init_fn ( INIT_SERIAL ) = {
+/** Serial console initialisation function */
+struct init_fn serial_console_init_fn __init_fn ( INIT_CONSOLE ) = {
.initialise = serial_init,
};
-/** Serial driver startup function */
+/** Serial console startup function */
struct startup_fn serial_startup_fn __startup_fn ( STARTUP_EARLY ) = {
- .shutdown = serial_fini,
+ .shutdown = serial_shutdown,
};
diff --git a/qemu/roms/ipxe/src/core/serial_console.c b/qemu/roms/ipxe/src/core/serial_console.c
deleted file mode 100644
index de9b84ca7..000000000
--- a/qemu/roms/ipxe/src/core/serial_console.c
+++ /dev/null
@@ -1,42 +0,0 @@
-#include <ipxe/init.h>
-#include <ipxe/serial.h>
-#include <ipxe/console.h>
-#include <config/console.h>
-
-/** @file
- *
- * Serial console
- *
- */
-
-/* Set default console usage if applicable */
-#if ! ( defined ( CONSOLE_SERIAL ) && CONSOLE_EXPLICIT ( CONSOLE_SERIAL ) )
-#undef CONSOLE_SERIAL
-#define CONSOLE_SERIAL ( CONSOLE_USAGE_ALL & ~CONSOLE_USAGE_LOG )
-#endif
-
-struct console_driver serial_console __console_driver;
-
-static void serial_console_init ( void ) {
- /*
- * Check if serial driver initialization is done.
- * If so, it's time to enable the serial console.
- */
- if ( serial_initialized )
- serial_console.disabled = 0;
-}
-
-struct console_driver serial_console __console_driver = {
- .putchar = serial_putc,
- .getchar = serial_getc,
- .iskey = serial_ischar,
- .disabled = CONSOLE_DISABLED,
- .usage = CONSOLE_SERIAL,
-};
-
-/**
- * Serial console initialisation function
- */
-struct init_fn serial_console_init_fn __init_fn ( INIT_CONSOLE ) = {
- .initialise = serial_console_init,
-};
diff --git a/qemu/roms/ipxe/src/core/settings.c b/qemu/roms/ipxe/src/core/settings.c
index 5e16b27d0..12e6c7d61 100644
--- a/qemu/roms/ipxe/src/core/settings.c
+++ b/qemu/roms/ipxe/src/core/settings.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <stdlib.h>
@@ -35,6 +39,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <ipxe/uuid.h>
#include <ipxe/uri.h>
#include <ipxe/base16.h>
+#include <ipxe/base64.h>
#include <ipxe/pci.h>
#include <ipxe/init.h>
#include <ipxe/version.h>
@@ -337,17 +342,20 @@ struct settings * autovivify_child_settings ( struct settings *parent,
*/
const char * settings_name ( struct settings *settings ) {
static char buf[16];
- char tmp[ sizeof ( buf ) ];
+ char tmp[ 1 /* '.' */ + sizeof ( buf ) ];
/* Find target settings block */
settings = settings_target ( settings );
/* Construct name */
- for ( buf[2] = buf[0] = 0 ; settings ; settings = settings->parent ) {
- memcpy ( tmp, buf, sizeof ( tmp ) );
- snprintf ( buf, sizeof ( buf ), ".%s%s", settings->name, tmp );
+ buf[0] = '\0';
+ tmp[0] = '\0';
+ for ( ; settings->parent ; settings = settings->parent ) {
+ memcpy ( ( tmp + 1 ), buf, ( sizeof ( tmp ) - 1 ) );
+ snprintf ( buf, sizeof ( buf ), "%s%s", settings->name, tmp );
+ tmp[0] = '.';
}
- return ( buf + 2 );
+ return buf;
}
/**
@@ -499,10 +507,10 @@ int register_settings ( struct settings *settings, struct settings *parent,
*/
void unregister_settings ( struct settings *settings ) {
struct settings *child;
- struct settings *tmp;
/* Unregister child settings */
- list_for_each_entry_safe ( child, tmp, &settings->children, siblings ) {
+ while ( ( child = list_first_entry ( &settings->children,
+ struct settings, siblings ) ) ) {
unregister_settings ( child );
}
@@ -1999,32 +2007,6 @@ const struct setting_type setting_type_uint32 __setting_type =
SETTING_TYPE_UINT ( SETTING_TYPE_INT32 );
/**
- * Format hex string setting value
- *
- * @v delimiter Byte delimiter
- * @v raw Raw setting value
- * @v raw_len Length of raw setting value
- * @v buf Buffer to contain formatted value
- * @v len Length of buffer
- * @ret len Length of formatted value, or negative error
- */
-static int format_hex_setting ( const char *delimiter, const void *raw,
- size_t raw_len, char *buf, size_t len ) {
- const uint8_t *bytes = raw;
- int used = 0;
- unsigned int i;
-
- if ( len )
- buf[0] = 0; /* Ensure that a terminating NUL exists */
- for ( i = 0 ; i < raw_len ; i++ ) {
- used += ssnprintf ( ( buf + used ), ( len - used ),
- "%s%02x", ( used ? delimiter : "" ),
- bytes[i] );
- }
- return used;
-}
-
-/**
* Parse hex string setting value (using colon delimiter)
*
* @v type Setting type
@@ -2036,7 +2018,7 @@ static int format_hex_setting ( const char *delimiter, const void *raw,
*/
static int parse_hex_setting ( const struct setting_type *type __unused,
const char *value, void *buf, size_t len ) {
- return hex_decode ( value, ':', buf, len );
+ return hex_decode ( ':', value, buf, len );
}
/**
@@ -2052,7 +2034,7 @@ static int parse_hex_setting ( const struct setting_type *type __unused,
static int format_hex_colon_setting ( const struct setting_type *type __unused,
const void *raw, size_t raw_len,
char *buf, size_t len ) {
- return format_hex_setting ( ":", raw, raw_len, buf, len );
+ return hex_encode ( ':', raw, raw_len, buf, len );
}
/**
@@ -2068,7 +2050,7 @@ static int format_hex_colon_setting ( const struct setting_type *type __unused,
static int parse_hex_hyphen_setting ( const struct setting_type *type __unused,
const char *value, void *buf,
size_t len ) {
- return hex_decode ( value, '-', buf, len );
+ return hex_decode ( '-', value, buf, len );
}
/**
@@ -2084,7 +2066,7 @@ static int parse_hex_hyphen_setting ( const struct setting_type *type __unused,
static int format_hex_hyphen_setting ( const struct setting_type *type __unused,
const void *raw, size_t raw_len,
char *buf, size_t len ) {
- return format_hex_setting ( "-", raw, raw_len, buf, len );
+ return hex_encode ( '-', raw, raw_len, buf, len );
}
/**
@@ -2099,7 +2081,7 @@ static int format_hex_hyphen_setting ( const struct setting_type *type __unused,
*/
static int parse_hex_raw_setting ( const struct setting_type *type __unused,
const char *value, void *buf, size_t len ) {
- return hex_decode ( value, 0, buf, len );
+ return hex_decode ( 0, value, buf, len );
}
/**
@@ -2115,7 +2097,7 @@ static int parse_hex_raw_setting ( const struct setting_type *type __unused,
static int format_hex_raw_setting ( const struct setting_type *type __unused,
const void *raw, size_t raw_len,
char *buf, size_t len ) {
- return format_hex_setting ( "", raw, raw_len, buf, len );
+ return hex_encode ( 0, raw, raw_len, buf, len );
}
/** A hex-string setting (colon-delimited) */
@@ -2140,6 +2122,46 @@ const struct setting_type setting_type_hexraw __setting_type = {
};
/**
+ * Parse Base64-encoded setting value
+ *
+ * @v type Setting type
+ * @v value Formatted setting value
+ * @v buf Buffer to contain raw value
+ * @v len Length of buffer
+ * @v size Integer size, in bytes
+ * @ret len Length of raw value, or negative error
+ */
+static int parse_base64_setting ( const struct setting_type *type __unused,
+ const char *value, void *buf, size_t len ) {
+
+ return base64_decode ( value, buf, len );
+}
+
+/**
+ * Format Base64-encoded setting value
+ *
+ * @v type Setting type
+ * @v raw Raw setting value
+ * @v raw_len Length of raw setting value
+ * @v buf Buffer to contain formatted value
+ * @v len Length of buffer
+ * @ret len Length of formatted value, or negative error
+ */
+static int format_base64_setting ( const struct setting_type *type __unused,
+ const void *raw, size_t raw_len,
+ char *buf, size_t len ) {
+
+ return base64_encode ( raw, raw_len, buf, len );
+}
+
+/** A Base64-encoded setting */
+const struct setting_type setting_type_base64 __setting_type = {
+ .name = "base64",
+ .parse = parse_base64_setting,
+ .format = format_base64_setting,
+};
+
+/**
* Format UUID setting value
*
* @v type Setting type
diff --git a/qemu/roms/ipxe/src/core/string.c b/qemu/roms/ipxe/src/core/string.c
index e53c283c2..3e658e54e 100644
--- a/qemu/roms/ipxe/src/core/string.c
+++ b/qemu/roms/ipxe/src/core/string.c
@@ -1,353 +1,501 @@
/*
- * Copyright (C) 1991, 1992 Linus Torvalds
- * Copyright (C) 2004 Tobias Lorenz
+ * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
*
- * string handling functions
- * based on linux/lib/string.c
+ * 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 free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-FILE_LICENCE ( GPL2_ONLY );
-
-/*
- * stupid library routines.. The optimized versions should generally be found
- * as inline code in <asm-xx/string.h>
+ * 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.
*
- * These are buggy as well..
+ * 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.
*
- * * Fri Jun 25 1999, Ingo Oeser <ioe@informatik.tu-chemnitz.de>
- * - Added strsep() which will replace strtok() soon (because strsep() is
- * reentrant and should be faster). Use only strsep() in new code, please.
+ * 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 <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
-/* *** FROM string.c *** */
+/** @file
+ *
+ * String functions
+ *
+ */
-#ifndef __HAVE_ARCH_STRCPY
/**
- * strcpy - Copy a %NUL terminated string
- * @dest: Where to copy the string to
- * @src: Where to copy the string from
+ * Fill memory region
+ *
+ * @v dest Destination region
+ * @v character Fill character
+ * @v len Length
+ * @ret dest Destination region
*/
-char * strcpy(char * dest,const char *src)
-{
- char *tmp = dest;
+void * generic_memset ( void *dest, int character, size_t len ) {
+ uint8_t *dest_bytes = dest;
- while ((*dest++ = *src++) != '\0')
- /* nothing */;
- return tmp;
+ while ( len-- )
+ *(dest_bytes++) = character;
+ return dest;
}
-#endif
-#ifndef __HAVE_ARCH_STRNCPY
/**
- * strncpy - Copy a length-limited, %NUL-terminated string
- * @dest: Where to copy the string to
- * @src: Where to copy the string from
- * @count: The maximum number of bytes to copy
+ * Copy memory region
*
- * Note that unlike userspace strncpy, this does not %NUL-pad the buffer.
- * However, the result is not %NUL-terminated if the source exceeds
- * @count bytes.
+ * @v dest Destination region
+ * @v src Source region
+ * @v len Length
+ * @ret dest Destination region
*/
-char * strncpy(char * dest,const char *src,size_t count)
-{
- char *tmp = dest;
-
- while (count-- && (*dest++ = *src++) != '\0')
- /* nothing */;
+void * generic_memcpy ( void *dest, const void *src, size_t len ) {
+ const uint8_t *src_bytes = src;
+ uint8_t *dest_bytes = dest;
- return tmp;
+ while ( len-- )
+ *(dest_bytes++) = *(src_bytes++);
+ return dest;
}
-#endif
-#ifndef __HAVE_ARCH_STRCAT
/**
- * strcat - Append one %NUL-terminated string to another
- * @dest: The string to be appended to
- * @src: The string to append to it
+ * Copy (possibly overlapping) memory region
+ *
+ * @v dest Destination region
+ * @v src Source region
+ * @v len Length
+ * @ret dest Destination region
*/
-char * strcat(char * dest, const char * src)
-{
- char *tmp = dest;
-
- while (*dest)
- dest++;
- while ((*dest++ = *src++) != '\0')
- ;
+void * generic_memmove ( void *dest, const void *src, size_t len ) {
+ const uint8_t *src_bytes = ( src + len );
+ uint8_t *dest_bytes = ( dest + len );
+
+ if ( dest < src )
+ return memcpy ( dest, src, len );
+ while ( len-- )
+ *(--dest_bytes) = *(--src_bytes);
+ return dest;
+}
- return tmp;
+/**
+ * Compare memory regions
+ *
+ * @v first First region
+ * @v second Second region
+ * @v len Length
+ * @ret diff Difference
+ */
+int memcmp ( const void *first, const void *second, size_t len ) {
+ const uint8_t *first_bytes = first;
+ const uint8_t *second_bytes = second;
+ int diff;
+
+ while ( len-- ) {
+ diff = ( *(second_bytes++) - *(first_bytes++) );
+ if ( diff )
+ return diff;
+ }
+ return 0;
}
-#endif
-#ifndef __HAVE_ARCH_STRCMP
/**
- * strcmp - Compare two strings
- * @cs: One string
- * @ct: Another string
+ * Find character within a memory region
+ *
+ * @v src Source region
+ * @v character Character to find
+ * @v len Length
+ * @ret found Found character, or NULL if not found
*/
-int strcmp(const char * cs,const char * ct)
-{
- register signed char __res;
+void * memchr ( const void *src, int character, size_t len ) {
+ const uint8_t *src_bytes = src;
- while (1) {
- if ((__res = *cs - *ct++) != 0 || !*cs++)
- break;
+ for ( ; len-- ; src_bytes++ ) {
+ if ( *src_bytes == character )
+ return ( ( void * ) src_bytes );
}
-
- return __res;
+ return NULL;
}
-#endif
-#ifndef __HAVE_ARCH_STRNCMP
/**
- * strncmp - Compare two length-limited strings
- * @cs: One string
- * @ct: Another string
- * @count: The maximum number of bytes to compare
+ * Swap memory regions
+ *
+ * @v first First region
+ * @v second Second region
+ * @v len Length
+ * @ret first First region
*/
-int strncmp(const char * cs,const char * ct,size_t count)
-{
- register signed char __res = 0;
-
- while (count) {
- if ((__res = *cs - *ct++) != 0 || !*cs++)
- break;
- count--;
+void * memswap ( void *first, void *second, size_t len ) {
+ uint8_t *first_bytes = first;
+ uint8_t *second_bytes = second;
+ uint8_t temp;
+
+ for ( ; len-- ; first_bytes++, second_bytes++ ) {
+ temp = *first_bytes;
+ *first_bytes = *second_bytes;
+ *second_bytes = temp;
}
+ return first;
+}
+
+/**
+ * Compare strings
+ *
+ * @v first First string
+ * @v second Second string
+ * @ret diff Difference
+ */
+int strcmp ( const char *first, const char *second ) {
- return __res;
+ return strncmp ( first, second, ~( ( size_t ) 0 ) );
}
-#endif
-#ifndef __HAVE_ARCH_STRCASECMP
-int strcasecmp(const char *a, const char *b)
-{
- while (*a && *b && (*a & ~0x20) == (*b & ~0x20)) {a++; b++; }
- return((*a & ~0x20) - (*b & ~0x20));
+/**
+ * Compare strings
+ *
+ * @v first First string
+ * @v second Second string
+ * @v max Maximum length to compare
+ * @ret diff Difference
+ */
+int strncmp ( const char *first, const char *second, size_t max ) {
+ const uint8_t *first_bytes = ( ( const uint8_t * ) first );
+ const uint8_t *second_bytes = ( ( const uint8_t * ) second );
+ int diff;
+
+ for ( ; max-- ; first_bytes++, second_bytes++ ) {
+ diff = ( *second_bytes - *first_bytes );
+ if ( diff )
+ return diff;
+ if ( ! *first_bytes )
+ return 0;
+ }
+ return 0;
}
-#endif
-#ifndef __HAVE_ARCH_STRCHR
/**
- * strchr - Find the first occurrence of a character in a string
- * @s: The string to be searched
- * @c: The character to search for
+ * Compare case-insensitive strings
+ *
+ * @v first First string
+ * @v second Second string
+ * @ret diff Difference
*/
-char * strchr(const char * s, int c)
-{
- for(; *s != (char) c; ++s)
- if (*s == '\0')
- return NULL;
- return (char *) s;
+int strcasecmp ( const char *first, const char *second ) {
+ const uint8_t *first_bytes = ( ( const uint8_t * ) first );
+ const uint8_t *second_bytes = ( ( const uint8_t * ) second );
+ int diff;
+
+ for ( ; ; first_bytes++, second_bytes++ ) {
+ diff = ( toupper ( *second_bytes ) -
+ toupper ( *first_bytes ) );
+ if ( diff )
+ return diff;
+ if ( ! *first_bytes )
+ return 0;
+ }
}
-#endif
-#ifndef __HAVE_ARCH_STRRCHR
/**
- * strrchr - Find the last occurrence of a character in a string
- * @s: The string to be searched
- * @c: The character to search for
+ * Get length of string
+ *
+ * @v src String
+ * @ret len Length
*/
-char * strrchr(const char * s, int c)
-{
- const char *p = s + strlen(s);
- do {
- if (*p == (char)c)
- return (char *)p;
- } while (--p >= s);
- return NULL;
+size_t strlen ( const char *src ) {
+
+ return strnlen ( src, ~( ( size_t ) 0 ) );
}
-#endif
-#ifndef __HAVE_ARCH_STRLEN
/**
- * strlen - Find the length of a string
- * @s: The string to be sized
+ * Get length of string
+ *
+ * @v src String
+ * @v max Maximum length
+ * @ret len Length
*/
-size_t strlen(const char * s)
-{
- const char *sc;
+size_t strnlen ( const char *src, size_t max ) {
+ const uint8_t *src_bytes = ( ( const uint8_t * ) src );
+ size_t len = 0;
- for (sc = s; *sc != '\0'; ++sc)
- /* nothing */;
- return sc - s;
+ while ( max-- && *(src_bytes++) )
+ len++;
+ return len;
}
-#endif
-#ifndef __HAVE_ARCH_STRNLEN
/**
- * strnlen - Find the length of a length-limited string
- * @s: The string to be sized
- * @count: The maximum number of bytes to search
+ * Find character within a string
+ *
+ * @v src String
+ * @v character Character to find
+ * @ret found Found character, or NULL if not found
*/
-size_t strnlen(const char * s, size_t count)
-{
- const char *sc;
+char * strchr ( const char *src, int character ) {
+ const uint8_t *src_bytes = ( ( const uint8_t * ) src );
- for (sc = s; count-- && *sc != '\0'; ++sc)
- /* nothing */;
- return sc - s;
+ for ( ; ; src_bytes++ ) {
+ if ( *src_bytes == character )
+ return ( ( char * ) src_bytes );
+ if ( ! *src_bytes )
+ return NULL;
+ }
}
-#endif
-#ifndef __HAVE_ARCH_MEMSET
/**
- * memset - Fill a region of memory with the given value
- * @s: Pointer to the start of the area.
- * @c: The byte to fill the area with
- * @count: The size of the area.
+ * Find rightmost character within a string
*
- * Do not use memset() to access IO space, use memset_io() instead.
+ * @v src String
+ * @v character Character to find
+ * @ret found Found character, or NULL if not found
*/
-void * memset(void * s,int c,size_t count)
-{
- char *xs = (char *) s;
+char * strrchr ( const char *src, int character ) {
+ const uint8_t *src_bytes = ( ( const uint8_t * ) src );
+ const uint8_t *start = src_bytes;
+
+ while ( *src_bytes )
+ src_bytes++;
+ for ( src_bytes-- ; src_bytes >= start ; src_bytes-- ) {
+ if ( *src_bytes == character )
+ return ( ( char * ) src_bytes );
+ }
+ return NULL;
+}
- while (count--)
- *xs++ = c;
+/**
+ * Find substring
+ *
+ * @v haystack String
+ * @v needle Substring
+ * @ret found Found substring, or NULL if not found
+ */
+char * strstr ( const char *haystack, const char *needle ) {
+ size_t len = strlen ( needle );
- return s;
+ for ( ; *haystack ; haystack++ ) {
+ if ( memcmp ( haystack, needle, len ) == 0 )
+ return ( ( char * ) haystack );
+ }
+ return NULL;
}
-#endif
-#ifndef __HAVE_ARCH_MEMCPY
/**
- * memcpy - Copy one area of memory to another
- * @dest: Where to copy to
- * @src: Where to copy from
- * @count: The size of the area.
+ * Copy string
*
- * You should not use this function to access IO space, use memcpy_toio()
- * or memcpy_fromio() instead.
+ * @v dest Destination string
+ * @v src Source string
+ * @ret dest Destination string
*/
-void * memcpy(void * dest,const void *src,size_t count)
-{
- char *tmp = (char *) dest, *s = (char *) src;
+char * strcpy ( char *dest, const char *src ) {
+ const uint8_t *src_bytes = ( ( const uint8_t * ) src );
+ uint8_t *dest_bytes = ( ( uint8_t * ) dest );
+
+ /* We cannot use strncpy(), since that would pad the destination */
+ for ( ; ; src_bytes++, dest_bytes++ ) {
+ *dest_bytes = *src_bytes;
+ if ( ! *dest_bytes )
+ break;
+ }
+ return dest;
+}
- while (count--)
- *tmp++ = *s++;
+/**
+ * Copy string
+ *
+ * @v dest Destination string
+ * @v src Source string
+ * @v max Maximum length
+ * @ret dest Destination string
+ */
+char * strncpy ( char *dest, const char *src, size_t max ) {
+ const uint8_t *src_bytes = ( ( const uint8_t * ) src );
+ uint8_t *dest_bytes = ( ( uint8_t * ) dest );
+ for ( ; max ; max--, src_bytes++, dest_bytes++ ) {
+ *dest_bytes = *src_bytes;
+ if ( ! *dest_bytes )
+ break;
+ }
+ while ( max-- )
+ *(dest_bytes++) = '\0';
return dest;
}
-#endif
-#ifndef __HAVE_ARCH_MEMMOVE
/**
- * memmove - Copy one area of memory to another
- * @dest: Where to copy to
- * @src: Where to copy from
- * @count: The size of the area.
+ * Concatenate string
*
- * Unlike memcpy(), memmove() copes with overlapping areas.
+ * @v dest Destination string
+ * @v src Source string
+ * @ret dest Destination string
*/
-void * memmove(void * dest,const void *src,size_t count)
-{
- char *tmp, *s;
-
- if (dest <= src) {
- tmp = (char *) dest;
- s = (char *) src;
- while (count--)
- *tmp++ = *s++;
- }
- else {
- tmp = (char *) dest + count;
- s = (char *) src + count;
- while (count--)
- *--tmp = *--s;
- }
+char * strcat ( char *dest, const char *src ) {
+ strcpy ( ( dest + strlen ( dest ) ), src );
return dest;
}
-#endif
-#ifndef __HAVE_ARCH_MEMCMP
/**
- * memcmp - Compare two areas of memory
- * @cs: One area of memory
- * @ct: Another area of memory
- * @count: The size of the area.
+ * Duplicate string
+ *
+ * @v src Source string
+ * @ret dup Duplicated string, or NULL if allocation failed
*/
-int memcmp(const void * cs,const void * ct,size_t count)
-{
- const unsigned char *su1, *su2;
- int res = 0;
+char * strdup ( const char *src ) {
- for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
- if ((res = *su1 - *su2) != 0)
- break;
- return res;
+ return strndup ( src, ~( ( size_t ) 0 ) );
}
-#endif
-#ifndef __HAVE_ARCH_STRSTR
/**
- * strstr - Find the first substring in a %NUL terminated string
- * @s1: The string to be searched
- * @s2: The string to search for
+ * Duplicate string
+ *
+ * @v src Source string
+ * @v max Maximum length
+ * @ret dup Duplicated string, or NULL if allocation failed
*/
-char * strstr(const char * s1,const char * s2)
-{
- int l1, l2;
-
- l2 = strlen(s2);
- if (!l2)
- return (char *) s1;
- l1 = strlen(s1);
- while (l1 >= l2) {
- l1--;
- if (!memcmp(s1,s2,l2))
- return (char *) s1;
- s1++;
- }
- return NULL;
+char * strndup ( const char *src, size_t max ) {
+ size_t len = strnlen ( src, max );
+ char *dup;
+
+ dup = malloc ( len + 1 /* NUL */ );
+ if ( dup ) {
+ memcpy ( dup, src, len );
+ dup[len] = '\0';
+ }
+ return dup;
+}
+
+/**
+ * Calculate digit value
+ *
+ * @v character Digit character
+ * @ret digit Digit value
+ *
+ * Invalid digits will be returned as a value greater than or equal to
+ * the numeric base.
+ */
+unsigned int digit_value ( unsigned int character ) {
+
+ if ( character >= 'a' )
+ return ( character - ( 'a' - 10 ) );
+ if ( character >= 'A' )
+ return ( character - ( 'A' - 10 ) );
+ if ( character <= '9' )
+ return ( character - '0' );
+ return character;
}
-#endif
-#ifndef __HAVE_ARCH_MEMCHR
/**
- * memchr - Find a character in an area of memory.
- * @s: The memory area
- * @c: The byte to search for
- * @n: The size of the area.
+ * Preprocess string for strtoul() or strtoull()
*
- * returns the address of the first occurrence of @c, or %NULL
- * if @c is not found
+ * @v string String
+ * @v negate Final value should be negated
+ * @v base Numeric base
+ * @ret string Remaining string
*/
-void * memchr(const void *s, int c, size_t n)
-{
- const unsigned char *p = s;
- while (n-- != 0) {
- if ((unsigned char)c == *p++) {
- return (void *)(p-1);
+static const char * strtoul_pre ( const char *string, int *negate, int *base ) {
+
+ /* Skip any leading whitespace */
+ while ( isspace ( *string ) )
+ string++;
+
+ /* Process arithmetic sign, if present */
+ *negate = 0;
+ if ( *string == '-' ) {
+ string++;
+ *negate = 1;
+ } else if ( *string == '+' ) {
+ string++;
+ }
+
+ /* Process base, if present */
+ if ( *base == 0 ) {
+ *base = 10;
+ if ( *string == '0' ) {
+ string++;
+ *base = 8;
+ if ( ( *string & ~0x20 ) == 'X' ) {
+ string++;
+ *base = 16;
+ }
}
}
- return NULL;
+
+ return string;
}
-#endif
+/**
+ * Convert string to numeric value
+ *
+ * @v string String
+ * @v endp End pointer (or NULL)
+ * @v base Numeric base (or zero to autodetect)
+ * @ret value Numeric value
+ */
+unsigned long strtoul ( const char *string, char **endp, int base ) {
+ unsigned long value = 0;
+ unsigned int digit;
+ int negate;
+
+ /* Preprocess string */
+ string = strtoul_pre ( string, &negate, &base );
+
+ /* Process digits */
+ for ( ; ; string++ ) {
+ digit = digit_value ( *string );
+ if ( digit >= ( unsigned int ) base )
+ break;
+ value = ( ( value * base ) + digit );
+ }
+
+ /* Negate value if, applicable */
+ if ( negate )
+ value = -value;
-char * strndup(const char *s, size_t n)
-{
- size_t len = strnlen(s,n);
- char *new;
+ /* Fill in end pointer, if applicable */
+ if ( endp )
+ *endp = ( ( char * ) string );
- new = malloc(len+1);
- if (new) {
- new[len] = '\0';
- memcpy(new,s,len);
- }
- return new;
+ return value;
}
-char * strdup(const char *s) {
- return strndup(s, ~((size_t)0));
+/**
+ * Convert string to numeric value
+ *
+ * @v string String
+ * @v endp End pointer (or NULL)
+ * @v base Numeric base (or zero to autodetect)
+ * @ret value Numeric value
+ */
+unsigned long long strtoull ( const char *string, char **endp, int base ) {
+ unsigned long long value = 0;
+ unsigned int digit;
+ int negate;
+
+ /* Preprocess string */
+ string = strtoul_pre ( string, &negate, &base );
+
+ /* Process digits */
+ for ( ; ; string++ ) {
+ digit = digit_value ( *string );
+ if ( digit >= ( unsigned int ) base )
+ break;
+ value = ( ( value * base ) + digit );
+ }
+
+ /* Negate value if, applicable */
+ if ( negate )
+ value = -value;
+
+ /* Fill in end pointer, if applicable */
+ if ( endp )
+ *endp = ( ( char * ) string );
+
+ return value;
}
diff --git a/qemu/roms/ipxe/src/core/stringextra.c b/qemu/roms/ipxe/src/core/stringextra.c
index 0a509852e..18ffc6301 100644
--- a/qemu/roms/ipxe/src/core/stringextra.c
+++ b/qemu/roms/ipxe/src/core/stringextra.c
@@ -38,122 +38,6 @@ FILE_LICENCE ( GPL2_ONLY );
/* *** FROM string.c *** */
-#ifndef __HAVE_ARCH_STRNICMP
-/**
- * strnicmp - Case insensitive, length-limited string comparison
- * @s1: One string
- * @s2: The other string
- * @len: the maximum number of characters to compare
- */
-int strnicmp(const char *s1, const char *s2, size_t len)
-{
- /* Yes, Virginia, it had better be unsigned */
- unsigned char c1, c2;
-
- c1 = 0; c2 = 0;
- if (len) {
- do {
- c1 = *s1; c2 = *s2;
- s1++; s2++;
- if (!c1)
- break;
- if (!c2)
- break;
- if (c1 == c2)
- continue;
- c1 = tolower(c1);
- c2 = tolower(c2);
- if (c1 != c2)
- break;
- } while (--len);
- }
- return (int)c1 - (int)c2;
-}
-#endif
-
-char * ___strtok;
-
-#ifndef __HAVE_ARCH_STRNCAT
-/**
- * strncat - Append a length-limited, %NUL-terminated string to another
- * @dest: The string to be appended to
- * @src: The string to append to it
- * @count: The maximum numbers of bytes to copy
- *
- * Note that in contrast to strncpy, strncat ensures the result is
- * terminated.
- */
-char * strncat(char *dest, const char *src, size_t count)
-{
- char *tmp = dest;
-
- if (count) {
- while (*dest)
- dest++;
- while ((*dest++ = *src++)) {
- if (--count == 0) {
- *dest = '\0';
- break;
- }
- }
- }
-
- return tmp;
-}
-#endif
-
-#ifndef __HAVE_ARCH_STRSPN
-/**
- * strspn - Calculate the length of the initial substring of @s which only
- * contain letters in @accept
- * @s: The string to be searched
- * @accept: The string to search for
- */
-size_t strspn(const char *s, const char *accept)
-{
- const char *p;
- const char *a;
- size_t count = 0;
-
- for (p = s; *p != '\0'; ++p) {
- for (a = accept; *a != '\0'; ++a) {
- if (*p == *a)
- break;
- }
- if (*a == '\0')
- return count;
- ++count;
- }
-
- return count;
-}
-#endif
-
-#ifndef __HAVE_ARCH_STRCSPN
-/**
- * strcspn - Calculate the length of the initial substring of @s which only
- * contain letters not in @reject
- * @s: The string to be searched
- * @accept: The string to search for
- */
-size_t strcspn(const char *s, const char *reject)
-{
- const char *p;
- const char *r;
- size_t count = 0;
-
- for (p = s; *p != '\0'; ++p) {
- for (r = reject; *r != '\0'; ++r) {
- if (*p == *r)
- return count;
- }
- ++count;
- }
-
- return count;
-}
-#endif
-
#ifndef __HAVE_ARCH_STRPBRK
/**
* strpbrk - Find the first occurrence of a set of characters
@@ -174,35 +58,6 @@ char * strpbrk(const char * cs,const char * ct)
}
#endif
-#ifndef __HAVE_ARCH_STRTOK
-/**
- * strtok - Split a string into tokens
- * @s: The string to be searched
- * @ct: The characters to search for
- *
- * WARNING: strtok is deprecated, use strsep instead.
- */
-char * strtok(char * s,const char * ct)
-{
- char *sbegin, *send;
-
- sbegin = s ? s : ___strtok;
- if (!sbegin) {
- return NULL;
- }
- sbegin += strspn(sbegin,ct);
- if (*sbegin == '\0') {
- ___strtok = NULL;
- return( NULL );
- }
- send = strpbrk( sbegin, ct);
- if (send && *send != '\0')
- *send++ = '\0';
- ___strtok = send;
- return (sbegin);
-}
-#endif
-
#ifndef __HAVE_ARCH_STRSEP
/**
* strsep - Split a string into tokens
@@ -230,46 +85,3 @@ char * strsep(char **s, const char *ct)
return sbegin;
}
#endif
-
-#ifndef __HAVE_ARCH_BCOPY
-/**
- * bcopy - Copy one area of memory to another
- * @src: Where to copy from
- * @dest: Where to copy to
- * @count: The size of the area.
- *
- * Note that this is the same as memcpy(), with the arguments reversed.
- * memcpy() is the standard, bcopy() is a legacy BSD function.
- *
- * You should not use this function to access IO space, use memcpy_toio()
- * or memcpy_fromio() instead.
- */
-char * bcopy(const char * src, char * dest, int count)
-{
- return memmove(dest,src,count);
-}
-#endif
-
-#ifndef __HAVE_ARCH_MEMSCAN
-/**
- * memscan - Find a character in an area of memory.
- * @addr: The memory area
- * @c: The byte to search for
- * @size: The size of the area.
- *
- * returns the address of the first occurrence of @c, or 1 byte past
- * the area if @c is not found
- */
-void * memscan(const void * addr, int c, size_t size)
-{
- unsigned char * p = (unsigned char *) addr;
-
- while (size) {
- if (*p == c)
- return (void *) p;
- p++;
- size--;
- }
- return (void *) p;
-}
-#endif
diff --git a/qemu/roms/ipxe/src/core/strtoull.c b/qemu/roms/ipxe/src/core/strtoull.c
deleted file mode 100644
index 00986eef0..000000000
--- a/qemu/roms/ipxe/src/core/strtoull.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>
- * 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 <stdlib.h>
-#include <ctype.h>
-
-/*
- * Despite being exactly the same as strtoul() except the long long instead of
- * long it ends up being much bigger so provide a separate implementation in a
- * separate object so that it won't be linked in if not used.
- */
-unsigned long long strtoull ( const char *p, char **endp, int base ) {
- unsigned long long ret = 0;
- int negative = 0;
- unsigned int charval;
-
- while ( isspace ( *p ) )
- p++;
-
- if ( *p == '-' ) {
- negative = 1;
- p++;
- }
-
- base = strtoul_base ( &p, base );
-
- while ( 1 ) {
- charval = strtoul_charval ( *p );
- if ( charval >= ( unsigned int ) base )
- break;
- ret = ( ( ret * base ) + charval );
- p++;
- }
-
- if ( negative )
- ret = -ret;
-
- if ( endp )
- *endp = ( char * ) p;
-
- return ( ret );
-}
diff --git a/qemu/roms/ipxe/src/core/time.c b/qemu/roms/ipxe/src/core/time.c
index f70e1981d..29a924ebe 100644
--- a/qemu/roms/ipxe/src/core/time.c
+++ b/qemu/roms/ipxe/src/core/time.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <time.h>
diff --git a/qemu/roms/ipxe/src/core/timer.c b/qemu/roms/ipxe/src/core/timer.c
index 18c2b2849..dbd89f12b 100644
--- a/qemu/roms/ipxe/src/core/timer.c
+++ b/qemu/roms/ipxe/src/core/timer.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <unistd.h>
diff --git a/qemu/roms/ipxe/src/core/uart.c b/qemu/roms/ipxe/src/core/uart.c
new file mode 100644
index 000000000..b85fe0767
--- /dev/null
+++ b/qemu/roms/ipxe/src/core/uart.c
@@ -0,0 +1,153 @@
+/*
+ * 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
+ *
+ * 16550-compatible UART
+ *
+ */
+
+#include <unistd.h>
+#include <errno.h>
+#include <ipxe/uart.h>
+
+/** Timeout for transmit holding register to become empty */
+#define UART_THRE_TIMEOUT_MS 100
+
+/** Timeout for transmitter to become empty */
+#define UART_TEMT_TIMEOUT_MS 1000
+
+/**
+ * Transmit data
+ *
+ * @v uart UART
+ * @v data Data
+ */
+void uart_transmit ( struct uart *uart, uint8_t data ) {
+ unsigned int i;
+ uint8_t lsr;
+
+ /* Wait for transmitter holding register to become empty */
+ for ( i = 0 ; i < UART_THRE_TIMEOUT_MS ; i++ ) {
+ lsr = uart_read ( uart, UART_LSR );
+ if ( lsr & UART_LSR_THRE )
+ break;
+ mdelay ( 1 );
+ }
+
+ /* Transmit data (even if we timed out) */
+ uart_write ( uart, UART_THR, data );
+}
+
+/**
+ * Flush data
+ *
+ * @v uart UART
+ */
+void uart_flush ( struct uart *uart ) {
+ unsigned int i;
+ uint8_t lsr;
+
+ /* Wait for transmitter and receiver to become empty */
+ for ( i = 0 ; i < UART_TEMT_TIMEOUT_MS ; i++ ) {
+ uart_read ( uart, UART_RBR );
+ lsr = uart_read ( uart, UART_LSR );
+ if ( ( lsr & UART_LSR_TEMT ) && ! ( lsr & UART_LSR_DR ) )
+ break;
+ }
+}
+
+/**
+ * Check for existence of UART
+ *
+ * @v uart UART
+ * @ret rc Return status code
+ */
+int uart_exists ( struct uart *uart ) {
+
+ /* Fail if no UART port is defined */
+ if ( ! uart->base )
+ return -ENODEV;
+
+ /* Fail if UART scratch register seems not to be present */
+ uart_write ( uart, UART_SCR, 0x18 );
+ if ( uart_read ( uart, UART_SCR ) != 0x18 )
+ return -ENODEV;
+ uart_write ( uart, UART_SCR, 0xae );
+ if ( uart_read ( uart, UART_SCR ) != 0xae )
+ return -ENODEV;
+
+ return 0;
+}
+
+/**
+ * Initialise UART
+ *
+ * @v uart UART
+ * @v baud Baud rate, or zero to leave unchanged
+ * @v lcr Line control register value, or zero to leave unchanged
+ * @ret rc Return status code
+ */
+int uart_init ( struct uart *uart, unsigned int baud, uint8_t lcr ) {
+ uint8_t dlm;
+ uint8_t dll;
+ int rc;
+
+ /* Check for existence of UART */
+ if ( ( rc = uart_exists ( uart ) ) != 0 )
+ return rc;
+
+ /* Configure divisor and line control register, if applicable */
+ if ( ! lcr )
+ lcr = uart_read ( uart, UART_LCR );
+ uart->lcr = lcr;
+ uart_write ( uart, UART_LCR, ( lcr | UART_LCR_DLAB ) );
+ if ( baud ) {
+ uart->divisor = ( UART_MAX_BAUD / baud );
+ dlm = ( ( uart->divisor >> 8 ) & 0xff );
+ dll = ( ( uart->divisor >> 0 ) & 0xff );
+ uart_write ( uart, UART_DLM, dlm );
+ uart_write ( uart, UART_DLL, dll );
+ } else {
+ dlm = uart_read ( uart, UART_DLM );
+ dll = uart_read ( uart, UART_DLL );
+ uart->divisor = ( ( dlm << 8 ) | dll );
+ }
+ uart_write ( uart, UART_LCR, ( lcr & ~UART_LCR_DLAB ) );
+
+ /* Disable interrupts */
+ uart_write ( uart, UART_IER, 0 );
+
+ /* Enable FIFOs */
+ uart_write ( uart, UART_FCR, UART_FCR_FE );
+
+ /* Assert DTR and RTS */
+ uart_write ( uart, UART_MCR, ( UART_MCR_DTR | UART_MCR_RTS ) );
+
+ /* Flush any stale data */
+ uart_flush ( uart );
+
+ return 0;
+}
diff --git a/qemu/roms/ipxe/src/core/uri.c b/qemu/roms/ipxe/src/core/uri.c
index 9ec21cee4..3b5f270fe 100644
--- a/qemu/roms/ipxe/src/core/uri.c
+++ b/qemu/roms/ipxe/src/core/uri.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** @file
*
@@ -661,6 +665,7 @@ struct uri * resolve_uri ( const struct uri *base_uri,
* Construct TFTP URI from next-server and filename
*
* @v next_server Next-server address
+ * @v port Port number, or zero to use the default port
* @v filename Filename
* @ret uri URI, or NULL on failure
*
@@ -669,12 +674,18 @@ struct uri * resolve_uri ( const struct uri *base_uri,
* generic URI parser. We provide a mechanism for directly
* constructing a TFTP URI from the next-server and filename.
*/
-struct uri * tftp_uri ( struct in_addr next_server, const char *filename ) {
+struct uri * tftp_uri ( struct in_addr next_server, unsigned int port,
+ const char *filename ) {
+ char buf[ 6 /* "65535" + NUL */ ];
struct uri uri;
memset ( &uri, 0, sizeof ( uri ) );
uri.scheme = "tftp";
uri.host = inet_ntoa ( next_server );
+ if ( port ) {
+ snprintf ( buf, sizeof ( buf ), "%d", port );
+ uri.port = buf;
+ }
uri.path = filename;
return uri_dup ( &uri );
}
diff --git a/qemu/roms/ipxe/src/core/uuid.c b/qemu/roms/ipxe/src/core/uuid.c
index 27a249da8..b8d21de17 100644
--- a/qemu/roms/ipxe/src/core/uuid.c
+++ b/qemu/roms/ipxe/src/core/uuid.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <stdio.h>
diff --git a/qemu/roms/ipxe/src/core/version.c b/qemu/roms/ipxe/src/core/version.c
index 1e1e9daca..c984335c2 100644
--- a/qemu/roms/ipxe/src/core/version.c
+++ b/qemu/roms/ipxe/src/core/version.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** @file
*
@@ -29,6 +33,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <ipxe/features.h>
#include <ipxe/version.h>
#include <config/general.h>
+#include <config/branding.h>
/**
* Create wide-character version of string
diff --git a/qemu/roms/ipxe/src/core/vsprintf.c b/qemu/roms/ipxe/src/core/vsprintf.c
index 54811b11b..cb3bec5dd 100644
--- a/qemu/roms/ipxe/src/core/vsprintf.c
+++ b/qemu/roms/ipxe/src/core/vsprintf.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stddef.h>
#include <stdarg.h>
diff --git a/qemu/roms/ipxe/src/core/wchar.c b/qemu/roms/ipxe/src/core/wchar.c
index 7fabca470..860322820 100644
--- a/qemu/roms/ipxe/src/core/wchar.c
+++ b/qemu/roms/ipxe/src/core/wchar.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/**
* @file
diff --git a/qemu/roms/ipxe/src/core/xfer.c b/qemu/roms/ipxe/src/core/xfer.c
index 8d4bc9f53..112fee1bf 100644
--- a/qemu/roms/ipxe/src/core/xfer.c
+++ b/qemu/roms/ipxe/src/core/xfer.c
@@ -15,9 +15,13 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <string.h>
#include <stdlib.h>
@@ -134,18 +138,8 @@ size_t xfer_window ( struct interface *intf ) {
* generating an xfer_window_changed() message.
*/
void xfer_window_changed ( struct interface *intf ) {
- struct interface *dest;
- xfer_window_changed_TYPE ( void * ) *op =
- intf_get_dest_op ( intf, xfer_window_changed, &dest );
- void *object = intf_object ( dest );
- if ( op ) {
- op ( object );
- } else {
- /* Default is to do nothing */
- }
-
- intf_put ( dest );
+ intf_poke ( intf, xfer_window_changed );
}
/**
@@ -365,3 +359,34 @@ int xfer_seek ( struct interface *intf, off_t offset ) {
return xfer_deliver ( intf, iobuf, &meta );
}
+
+/**
+ * Check that data is delivered strictly in order
+ *
+ * @v meta Data transfer metadata
+ * @v pos Current position
+ * @v len Length of data
+ * @ret rc Return status code
+ */
+int xfer_check_order ( struct xfer_metadata *meta, size_t *pos, size_t len ) {
+ size_t new_pos;
+
+ /* Allow out-of-order zero-length packets (as used by xfer_seek()) */
+ if ( len == 0 )
+ return 0;
+
+ /* Calculate position of this delivery */
+ new_pos = *pos;
+ if ( meta->flags & XFER_FL_ABS_OFFSET )
+ new_pos = 0;
+ new_pos += meta->offset;
+
+ /* Fail if delivery position is not equal to current position */
+ if ( new_pos != *pos )
+ return -EPROTO;
+
+ /* Update current position */
+ *pos += len;
+
+ return 0;
+}
diff --git a/qemu/roms/ipxe/src/core/xferbuf.c b/qemu/roms/ipxe/src/core/xferbuf.c
index a0457feee..240118557 100644
--- a/qemu/roms/ipxe/src/core/xferbuf.c
+++ b/qemu/roms/ipxe/src/core/xferbuf.c
@@ -15,15 +15,21 @@
* 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 );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ipxe/xfer.h>
#include <ipxe/iobuf.h>
+#include <ipxe/umalloc.h>
+#include <ipxe/profile.h>
#include <ipxe/xferbuf.h>
/** @file
@@ -32,14 +38,26 @@ FILE_LICENCE ( GPL2_OR_LATER );
*
*/
+/** Data delivery profiler */
+static struct profiler xferbuf_deliver_profiler __profiler =
+ { .name = "xferbuf.deliver" };
+
+/** Data write profiler */
+static struct profiler xferbuf_write_profiler __profiler =
+ { .name = "xferbuf.write" };
+
+/** Data read profiler */
+static struct profiler xferbuf_read_profiler __profiler =
+ { .name = "xferbuf.read" };
+
/**
- * Finish using data transfer buffer
+ * Free data transfer buffer
*
* @v xferbuf Data transfer buffer
*/
-void xferbuf_done ( struct xfer_buffer *xferbuf ) {
- free ( xferbuf->data );
- xferbuf->data = NULL;
+void xferbuf_free ( struct xfer_buffer *xferbuf ) {
+
+ xferbuf->op->realloc ( xferbuf, 0 );
xferbuf->len = 0;
xferbuf->pos = 0;
}
@@ -52,26 +70,78 @@ void xferbuf_done ( struct xfer_buffer *xferbuf ) {
* @ret rc Return status code
*/
static int xferbuf_ensure_size ( struct xfer_buffer *xferbuf, size_t len ) {
- void *new_data;
+ int rc;
/* If buffer is already large enough, do nothing */
if ( len <= xferbuf->len )
return 0;
/* Extend buffer */
- new_data = realloc ( xferbuf->data, len );
- if ( ! new_data ) {
+ if ( ( rc = xferbuf->op->realloc ( xferbuf, len ) ) != 0 ) {
DBGC ( xferbuf, "XFERBUF %p could not extend buffer to "
- "%zd bytes\n", xferbuf, len );
- return -ENOSPC;
+ "%zd bytes: %s\n", xferbuf, len, strerror ( rc ) );
+ return rc;
}
- xferbuf->data = new_data;
xferbuf->len = len;
return 0;
}
/**
+ * Write to data transfer buffer
+ *
+ * @v xferbuf Data transfer buffer
+ * @v offset Starting offset
+ * @v data Data to write
+ * @v len Length of data
+ */
+int xferbuf_write ( struct xfer_buffer *xferbuf, size_t offset,
+ const void *data, size_t len ) {
+ size_t max_len;
+ int rc;
+
+ /* Check for overflow */
+ max_len = ( offset + len );
+ if ( max_len < offset )
+ return -EOVERFLOW;
+
+ /* Ensure buffer is large enough to contain this write */
+ if ( ( rc = xferbuf_ensure_size ( xferbuf, max_len ) ) != 0 )
+ return rc;
+
+ /* Copy data to buffer */
+ profile_start ( &xferbuf_write_profiler );
+ xferbuf->op->write ( xferbuf, offset, data, len );
+ profile_stop ( &xferbuf_write_profiler );
+
+ return 0;
+}
+
+/**
+ * Read from data transfer buffer
+ *
+ * @v xferbuf Data transfer buffer
+ * @v offset Starting offset
+ * @v data Data to write
+ * @v len Length of data
+ */
+int xferbuf_read ( struct xfer_buffer *xferbuf, size_t offset,
+ void *data, size_t len ) {
+
+ /* Check that read is within buffer range */
+ if ( ( offset > xferbuf->len ) ||
+ ( len > ( xferbuf->len - offset ) ) )
+ return -ENOENT;
+
+ /* Copy data from buffer */
+ profile_start ( &xferbuf_read_profiler );
+ xferbuf->op->read ( xferbuf, offset, data, len );
+ profile_stop ( &xferbuf_read_profiler );
+
+ return 0;
+}
+
+/**
* Add received data to data transfer buffer
*
* @v xferbuf Data transfer buffer
@@ -81,28 +151,174 @@ static int xferbuf_ensure_size ( struct xfer_buffer *xferbuf, size_t len ) {
*/
int xferbuf_deliver ( struct xfer_buffer *xferbuf, struct io_buffer *iobuf,
struct xfer_metadata *meta ) {
- size_t len;
- size_t max;
+ size_t len = iob_len ( iobuf );
+ size_t pos;
int rc;
+ /* Start profiling */
+ profile_start ( &xferbuf_deliver_profiler );
+
/* Calculate new buffer position */
+ pos = xferbuf->pos;
if ( meta->flags & XFER_FL_ABS_OFFSET )
- xferbuf->pos = 0;
- xferbuf->pos += meta->offset;
+ pos = 0;
+ pos += meta->offset;
- /* Ensure that we have enough buffer space for this data */
- len = iob_len ( iobuf );
- max = ( xferbuf->pos + len );
- if ( ( rc = xferbuf_ensure_size ( xferbuf, max ) ) != 0 )
+ /* Write data to buffer */
+ if ( ( rc = xferbuf_write ( xferbuf, pos, iobuf->data, len ) ) != 0 )
goto done;
- /* Copy data to buffer */
- memcpy ( ( xferbuf->data + xferbuf->pos ), iobuf->data, len );
-
/* Update current buffer position */
- xferbuf->pos += len;
+ xferbuf->pos = ( pos + len );
done:
free_iob ( iobuf );
+ profile_stop ( &xferbuf_deliver_profiler );
return rc;
}
+
+/**
+ * Reallocate malloc()-based data buffer
+ *
+ * @v xferbuf Data transfer buffer
+ * @v len New length (or zero to free buffer)
+ * @ret rc Return status code
+ */
+static int xferbuf_malloc_realloc ( struct xfer_buffer *xferbuf, size_t len ) {
+ void *new_data;
+
+ new_data = realloc ( xferbuf->data, len );
+ if ( ! new_data )
+ return -ENOSPC;
+ xferbuf->data = new_data;
+ return 0;
+}
+
+/**
+ * Write data to malloc()-based data buffer
+ *
+ * @v xferbuf Data transfer buffer
+ * @v offset Starting offset
+ * @v data Data to copy
+ * @v len Length of data
+ */
+static void xferbuf_malloc_write ( struct xfer_buffer *xferbuf, size_t offset,
+ const void *data, size_t len ) {
+
+ memcpy ( ( xferbuf->data + offset ), data, len );
+}
+
+/**
+ * Read data from malloc()-based data buffer
+ *
+ * @v xferbuf Data transfer buffer
+ * @v offset Starting offset
+ * @v data Data to read
+ * @v len Length of data
+ */
+static void xferbuf_malloc_read ( struct xfer_buffer *xferbuf, size_t offset,
+ void *data, size_t len ) {
+
+ memcpy ( data, ( xferbuf->data + offset ), len );
+}
+
+/** malloc()-based data buffer operations */
+struct xfer_buffer_operations xferbuf_malloc_operations = {
+ .realloc = xferbuf_malloc_realloc,
+ .write = xferbuf_malloc_write,
+ .read = xferbuf_malloc_read,
+};
+
+/**
+ * Reallocate umalloc()-based data buffer
+ *
+ * @v xferbuf Data transfer buffer
+ * @v len New length (or zero to free buffer)
+ * @ret rc Return status code
+ */
+static int xferbuf_umalloc_realloc ( struct xfer_buffer *xferbuf, size_t len ) {
+ userptr_t *udata = xferbuf->data;
+ userptr_t new_udata;
+
+ new_udata = urealloc ( *udata, len );
+ if ( ! new_udata )
+ return -ENOSPC;
+ *udata = new_udata;
+ return 0;
+}
+
+/**
+ * Write data to umalloc()-based data buffer
+ *
+ * @v xferbuf Data transfer buffer
+ * @v offset Starting offset
+ * @v data Data to copy
+ * @v len Length of data
+ */
+static void xferbuf_umalloc_write ( struct xfer_buffer *xferbuf, size_t offset,
+ const void *data, size_t len ) {
+ userptr_t *udata = xferbuf->data;
+
+ copy_to_user ( *udata, offset, data, len );
+}
+
+/**
+ * Read data from umalloc()-based data buffer
+ *
+ * @v xferbuf Data transfer buffer
+ * @v offset Starting offset
+ * @v data Data to read
+ * @v len Length of data
+ */
+static void xferbuf_umalloc_read ( struct xfer_buffer *xferbuf, size_t offset,
+ void *data, size_t len ) {
+ userptr_t *udata = xferbuf->data;
+
+ copy_from_user ( data, *udata, offset, len );
+}
+
+/** umalloc()-based data buffer operations */
+struct xfer_buffer_operations xferbuf_umalloc_operations = {
+ .realloc = xferbuf_umalloc_realloc,
+ .write = xferbuf_umalloc_write,
+ .read = xferbuf_umalloc_read,
+};
+
+/**
+ * Get underlying data transfer buffer
+ *
+ * @v interface Data transfer interface
+ * @ret xferbuf Data transfer buffer, or NULL on error
+ *
+ * This call will check that the xfer_buffer() handler belongs to the
+ * destination interface which also provides xfer_deliver() for this
+ * interface.
+ *
+ * This is done to prevent accidental accesses to a data transfer
+ * buffer which may be located behind a non-transparent datapath via a
+ * series of pass-through interfaces.
+ */
+struct xfer_buffer * xfer_buffer ( struct interface *intf ) {
+ struct interface *dest;
+ xfer_buffer_TYPE ( void * ) *op =
+ intf_get_dest_op ( intf, xfer_buffer, &dest );
+ void *object = intf_object ( dest );
+ struct interface *xfer_deliver_dest;
+ struct xfer_buffer *xferbuf;
+
+ /* Check that this operation is provided by the same interface
+ * which handles xfer_deliver().
+ */
+ ( void ) intf_get_dest_op ( intf, xfer_deliver, &xfer_deliver_dest );
+
+ if ( op && ( dest == xfer_deliver_dest ) ) {
+ xferbuf = op ( object );
+ } else {
+ /* Default is to not have a data transfer buffer */
+ xferbuf = NULL;
+ }
+
+ intf_put ( xfer_deliver_dest );
+ intf_put ( dest );
+ return xferbuf;
+}