diff options
author | RajithaY <rajithax.yerrumsetty@intel.com> | 2017-04-25 03:31:15 -0700 |
---|---|---|
committer | Rajitha Yerrumchetty <rajithax.yerrumsetty@intel.com> | 2017-05-22 06:48:08 +0000 |
commit | bb756eebdac6fd24e8919e2c43f7d2c8c4091f59 (patch) | |
tree | ca11e03542edf2d8f631efeca5e1626d211107e3 /qemu/roms/ipxe/src/core | |
parent | a14b48d18a9ed03ec191cf16b162206998a895ce (diff) |
Adding qemu as a submodule of KVMFORNFV
This Patch includes the changes to add qemu as a submodule to
kvmfornfv repo and make use of the updated latest qemu for the
execution of all testcase
Change-Id: I1280af507a857675c7f81d30c95255635667bdd7
Signed-off-by:RajithaY<rajithax.yerrumsetty@intel.com>
Diffstat (limited to 'qemu/roms/ipxe/src/core')
83 files changed, 0 insertions, 18426 deletions
diff --git a/qemu/roms/ipxe/src/core/acpi.c b/qemu/roms/ipxe/src/core/acpi.c deleted file mode 100644 index b0ccfa78d..000000000 --- a/qemu/roms/ipxe/src/core/acpi.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <errno.h> -#include <ipxe/acpi.h> -#include <ipxe/interface.h> - -/** @file - * - * ACPI support functions - * - */ - -/****************************************************************************** - * - * Utility functions - * - ****************************************************************************** - */ - -/** - * Fix up ACPI table checksum - * - * @v acpi ACPI table header - */ -void acpi_fix_checksum ( struct acpi_description_header *acpi ) { - unsigned int i = 0; - uint8_t sum = 0; - - for ( i = 0 ; i < acpi->length ; i++ ) { - sum += *( ( ( uint8_t * ) acpi ) + i ); - } - acpi->checksum -= sum; -} - -/****************************************************************************** - * - * Interface methods - * - ****************************************************************************** - */ - -/** - * Describe object in an ACPI table - * - * @v intf Interface - * @v acpi ACPI table - * @v len Length of ACPI table - * @ret rc Return status code - */ -int acpi_describe ( struct interface *intf, - struct acpi_description_header *acpi, size_t len ) { - struct interface *dest; - acpi_describe_TYPE ( void * ) *op = - intf_get_dest_op ( intf, acpi_describe, &dest ); - void *object = intf_object ( dest ); - int rc; - - if ( op ) { - rc = op ( object, acpi, len ); - } else { - /* Default is to fail to describe */ - rc = -EOPNOTSUPP; - } - - intf_put ( dest ); - return rc; -} diff --git a/qemu/roms/ipxe/src/core/ansicol.c b/qemu/roms/ipxe/src/core/ansicol.c deleted file mode 100644 index ddf9ba77c..000000000 --- a/qemu/roms/ipxe/src/core/ansicol.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (C) 2013 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdio.h> -#include <errno.h> -#include <assert.h> -#include <ipxe/ansiesc.h> -#include <ipxe/ansicol.h> -#include <config/colour.h> - -/** @file - * - * ANSI colours - * - */ - -/** ANSI colour pair definitions */ -static struct ansicol_pair ansicol_pairs[] = { - [CPAIR_DEFAULT] = { COLOR_DEFAULT, COLOR_DEFAULT }, - [CPAIR_NORMAL] = { COLOR_NORMAL_FG, COLOR_NORMAL_BG }, - [CPAIR_SELECT] = { COLOR_SELECT_FG, COLOR_SELECT_BG }, - [CPAIR_SEPARATOR] = { COLOR_SEPARATOR_FG, COLOR_SEPARATOR_BG }, - [CPAIR_EDIT] = { COLOR_EDIT_FG, COLOR_EDIT_BG }, - [CPAIR_ALERT] = { COLOR_ALERT_FG, COLOR_ALERT_BG }, - [CPAIR_URL] = { COLOR_URL_FG, COLOR_URL_BG }, - [CPAIR_PXE] = { COLOR_PXE_FG, COLOR_PXE_BG }, -}; - -/** - * Set ANSI colour (when no colour definition support is present) - * - * @v colour Colour index - * @v which Foreground/background selector - */ -__weak void ansicol_set ( unsigned int colour, unsigned int which ) { - - /* Colour indices are hardcoded and should never be out of range */ - assert ( colour < 10 ); - - /* Set basic colour */ - printf ( CSI "%c%dm", which, colour ); -} - -/** - * Set ANSI foreground colour - * - * @v colour Colour index - */ -static void ansicol_foreground ( unsigned int colour ) { - ansicol_set ( colour, '3' ); -} - -/** - * Set ANSI background colour - * - * @v colour Colour index - */ -static void ansicol_background ( unsigned int colour ) { - ansicol_set ( colour, '4' ); -} - -/** - * Set ANSI foreground and background colour - * - * @v cpair Colour pair index - */ -void ansicol_set_pair ( unsigned int cpair ) { - struct ansicol_pair *pair; - - /* Colour pair indices are hardcoded and should never be out of range */ - assert ( cpair < ( sizeof ( ansicol_pairs ) / - sizeof ( ansicol_pairs[0] ) ) ); - - /* Set both foreground and background colours */ - pair = &ansicol_pairs[cpair]; - ansicol_foreground ( pair->foreground ); - ansicol_background ( pair->background ); -} - -/** - * Define ANSI colour pair - * - * @v cpair Colour pair index - * @v foreground Foreground colour index - * @v background Background colour index - * @ret rc Return status code - */ -int ansicol_define_pair ( unsigned int cpair, unsigned int foreground, - unsigned int background ) { - struct ansicol_pair *pair; - - /* Fail if colour index is out of range */ - if ( cpair >= ( sizeof ( ansicol_pairs ) / sizeof ( ansicol_pairs[0] ))) - return -EINVAL; - - /* Update colour pair definition */ - pair = &ansicol_pairs[cpair]; - pair->foreground = foreground; - pair->background = background; - DBGC ( &ansicol_pairs[0], "ANSICOL redefined colour pair %d as " - "foreground %d background %d\n", cpair, foreground, background ); - - return 0; -} diff --git a/qemu/roms/ipxe/src/core/ansicoldef.c b/qemu/roms/ipxe/src/core/ansicoldef.c deleted file mode 100644 index 6d8598e11..000000000 --- a/qemu/roms/ipxe/src/core/ansicoldef.c +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright (C) 2013 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdio.h> -#include <errno.h> -#include <ipxe/ansiesc.h> -#include <ipxe/ansicol.h> -#include <config/colour.h> - -/** @file - * - * ANSI colour definitions - * - */ - -/** - * Construct ANSI colour definition - * - * @v basic Basic colour - * @v rgb 24-bit RGB value (or ANSICOL_NO_RGB) - * @ret ansicol ANSI colour definition - */ -#define ANSICOL_DEFINE( basic, rgb ) ( ( (basic) << 28 ) | (rgb) ) - -/** - * Extract basic colour from ANSI colour definition - * - * @v ansicol ANSI colour definition - * @ret basic Basic colour - */ -#define ANSICOL_BASIC( ansicol ) ( (ansicol) >> 28 ) - -/** - * Extract 24-bit RGB value from ANSI colour definition - * - * @v ansicol ANSI colour definition - * @ret rgb 24-bit RGB value - */ -#define ANSICOL_RGB( ansicol ) ( ( (ansicol) >> 0 ) & 0xffffffUL ) - -/** - * Extract 24-bit RGB value red component from ANSI colour definition - * - * @v ansicol ANSI colour definition - * @ret red Red component - */ -#define ANSICOL_RED( ansicol ) ( ( (ansicol) >> 16 ) & 0xff ) - -/** - * Extract 24-bit RGB value green component from ANSI colour definition - * - * @v ansicol ANSI colour definition - * @ret green Green component - */ -#define ANSICOL_GREEN( ansicol ) ( ( (ansicol) >> 8 ) & 0xff ) - -/** - * Extract 24-bit RGB value blue component from ANSI colour definition - * - * @v ansicol ANSI colour definition - * @ret blue Blue component - */ -#define ANSICOL_BLUE( ansicol ) ( ( (ansicol) >> 0 ) & 0xff ) - -/** - * Construct default ANSI colour definition - * - * @v basic Basic colour - * @ret ansicol ANSI colour definition - * - * Colours default to being just a basic colour. If the colour - * matches the normal UI text background colour, then its basic colour - * value is set to @c ANSICOL_MAGIC. - */ -#define ANSICOL_DEFAULT( basic ) \ - ANSICOL_DEFINE ( ( ( (basic) == COLOR_NORMAL_BG ) ? \ - ANSICOL_MAGIC : (basic) ), \ - ANSICOL_NO_RGB ) - -/** ANSI colour definitions */ -static uint32_t ansicols[] = { - [COLOR_BLACK] = ANSICOL_DEFAULT ( COLOR_BLACK ), - [COLOR_RED] = ANSICOL_DEFAULT ( COLOR_RED ), - [COLOR_GREEN] = ANSICOL_DEFAULT ( COLOR_GREEN ), - [COLOR_YELLOW] = ANSICOL_DEFAULT ( COLOR_YELLOW ), - [COLOR_BLUE] = ANSICOL_DEFAULT ( COLOR_BLUE ), - [COLOR_MAGENTA] = ANSICOL_DEFAULT ( COLOR_MAGENTA ), - [COLOR_CYAN] = ANSICOL_DEFAULT ( COLOR_CYAN ), - [COLOR_WHITE] = ANSICOL_DEFAULT ( COLOR_WHITE ), -}; - -/** Magic basic colour */ -static uint8_t ansicol_magic = COLOR_NORMAL_BG; - -/** - * Define ANSI colour - * - * @v colour Colour index - * @v basic Basic colour - * @v rgb 24-bit RGB value (or ANSICOL_NO_RGB) - * @ret rc Return status code - */ -int ansicol_define ( unsigned int colour, unsigned int basic, uint32_t rgb ) { - uint32_t ansicol; - - /* Fail if colour index is out of range */ - if ( colour >= ( sizeof ( ansicols ) / sizeof ( ansicols[0] ) ) ) - return -EINVAL; - - /* Update colour definition */ - ansicol = ANSICOL_DEFINE ( basic, rgb ); - ansicols[colour] = ansicol; - DBGC ( &ansicols[0], "ANSICOL redefined colour %d as basic %d RGB " - "%#06lx%s\n", colour, ANSICOL_BASIC ( ansicol ), - ANSICOL_RGB ( ansicol ), - ( ( ansicol & ANSICOL_NO_RGB ) ? " [norgb]" : "" ) ); - - return 0; -} - -/** - * Set ANSI colour (using colour definitions) - * - * @v colour Colour index - * @v which Foreground/background selector - */ -void ansicol_set ( unsigned int colour, unsigned int which ) { - uint32_t ansicol; - unsigned int basic; - - /* Use default colour if colour index is out of range */ - if ( colour < ( sizeof ( ansicols ) / sizeof ( ansicols[0] ) ) ) { - ansicol = ansicols[colour]; - } else { - ansicol = ANSICOL_DEFINE ( COLOUR_DEFAULT, ANSICOL_NO_RGB ); - } - - /* If basic colour is out of range, use the magic colour */ - basic = ANSICOL_BASIC ( ansicol ); - if ( basic >= 10 ) - basic = ansicol_magic; - - /* Set basic colour first */ - printf ( CSI "%c%dm", which, basic ); - - /* Set 24-bit RGB colour, if applicable */ - if ( ! ( ansicol & ANSICOL_NO_RGB ) ) { - printf ( CSI "%c8;2;%d;%d;%dm", which, ANSICOL_RED ( ansicol ), - ANSICOL_GREEN ( ansicol ), ANSICOL_BLUE ( ansicol ) ); - } -} - -/** - * Reset magic colour - * - */ -void ansicol_reset_magic ( void ) { - - /* Set to the compile-time default background colour */ - ansicol_magic = COLOR_NORMAL_BG; -} - -/** - * Set magic colour to transparent - * - */ -void ansicol_set_magic_transparent ( void ) { - - /* Set to the console default colour (which will give a - * transparent background on the framebuffer console). - */ - ansicol_magic = COLOR_DEFAULT; -} diff --git a/qemu/roms/ipxe/src/core/ansiesc.c b/qemu/roms/ipxe/src/core/ansiesc.c deleted file mode 100644 index 7f545db0e..000000000 --- a/qemu/roms/ipxe/src/core/ansiesc.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <string.h> -#include <assert.h> -#include <ipxe/ansiesc.h> - -/** @file - * - * ANSI escape sequences - * - */ - -/** - * Call ANSI escape sequence handler - * - * @v ctx ANSI escape sequence context - * @v function Control function identifier - * @v count Parameter count - * @v params Parameter list - */ -static void ansiesc_call_handler ( struct ansiesc_context *ctx, - unsigned int function, int count, - int params[] ) { - struct ansiesc_handler *handlers = ctx->handlers; - struct ansiesc_handler *handler; - - for ( handler = handlers ; handler->function ; handler++ ) { - if ( handler->function == function ) { - handler->handle ( ctx, count, params ); - break; - } - } -} - -/** - * Process character that may be part of ANSI escape sequence - * - * @v ctx ANSI escape sequence context - * @v c Character - * @ret c Original character if not part of escape sequence - * @ret <0 Character was part of escape sequence - * - * ANSI escape sequences will be plucked out of the character stream - * and interpreted; once complete they will be passed to the - * appropriate handler if one exists in this ANSI escape sequence - * context. - * - * In the interests of code size, we are rather liberal about the - * sequences we are prepared to accept as valid. - */ -int ansiesc_process ( struct ansiesc_context *ctx, int c ) { - - if ( ctx->count == 0 ) { - if ( c == ESC ) { - /* First byte of CSI : begin escape sequence */ - ctx->count = 1; - memset ( ctx->params, 0xff, sizeof ( ctx->params ) ); - ctx->function = 0; - return -1; - } else { - /* Normal character */ - return c; - } - } else { - if ( c == '[' ) { - /* Second byte of CSI : do nothing */ - } else if ( ( c >= '0' ) && ( c <= '9' ) ) { - /* Parameter Byte : part of a parameter value */ - int *param = &ctx->params[ctx->count - 1]; - if ( *param < 0 ) - *param = 0; - *param = ( ( *param * 10 ) + ( c - '0' ) ); - } else if ( c == ';' ) { - /* Parameter Byte : parameter delimiter */ - ctx->count++; - if ( ctx->count > ( sizeof ( ctx->params ) / - sizeof ( ctx->params[0] ) ) ) { - /* Excessive parameters : abort sequence */ - ctx->count = 0; - DBG ( "Too many parameters in ANSI escape " - "sequence\n" ); - } - } else if ( ( ( c >= 0x20 ) && ( c <= 0x2f ) ) || - ( c == '?' ) ) { - /* Intermediate Byte */ - ctx->function <<= 8; - ctx->function |= c; - } else { - /* Treat as Final Byte. Zero ctx->count before - * calling handler to avoid potential infinite loops. - */ - int count = ctx->count; - ctx->count = 0; - ctx->function <<= 8; - ctx->function |= c; - ansiesc_call_handler ( ctx, ctx->function, - count, ctx->params ); - } - return -1; - } -} diff --git a/qemu/roms/ipxe/src/core/asprintf.c b/qemu/roms/ipxe/src/core/asprintf.c deleted file mode 100644 index 00edf8e11..000000000 --- a/qemu/roms/ipxe/src/core/asprintf.c +++ /dev/null @@ -1,49 +0,0 @@ -#include <stdint.h> -#include <stddef.h> -#include <stdlib.h> -#include <stdio.h> -#include <errno.h> - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/** - * Write a formatted string to newly allocated memory. - * - * @v strp Pointer to hold allocated string - * @v fmt Format string - * @v args Arguments corresponding to the format string - * @ret len Length of formatted string - */ -int vasprintf ( char **strp, const char *fmt, va_list args ) { - size_t len; - va_list args_tmp; - - /* Calculate length needed for string */ - va_copy ( args_tmp, args ); - len = ( vsnprintf ( NULL, 0, fmt, args_tmp ) + 1 ); - va_end ( args_tmp ); - - /* Allocate and fill string */ - *strp = malloc ( len ); - if ( ! *strp ) - return -ENOMEM; - return vsnprintf ( *strp, len, fmt, args ); -} - -/** - * Write a formatted string to newly allocated memory. - * - * @v strp Pointer to hold allocated string - * @v fmt Format string - * @v ... Arguments corresponding to the format string - * @ret len Length of formatted string - */ -int asprintf ( char **strp, const char *fmt, ... ) { - va_list args; - int len; - - va_start ( args, fmt ); - len = vasprintf ( strp, fmt, args ); - va_end ( args ); - return len; -} diff --git a/qemu/roms/ipxe/src/core/assert.c b/qemu/roms/ipxe/src/core/assert.c deleted file mode 100644 index 294e766be..000000000 --- a/qemu/roms/ipxe/src/core/assert.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2011 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/** @file - * - * Assertions - * - */ - -#include <assert.h> - -/** Number of assertion failures triggered */ -unsigned int assertion_failures = 0; diff --git a/qemu/roms/ipxe/src/core/base16.c b/qemu/roms/ipxe/src/core/base16.c deleted file mode 100644 index f9e0f3364..000000000 --- a/qemu/roms/ipxe/src/core/base16.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) 2010 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdint.h> -#include <stdio.h> -#include <errno.h> -#include <assert.h> -#include <ipxe/string.h> -#include <ipxe/vsprintf.h> -#include <ipxe/base16.h> - -/** @file - * - * Base16 encoding - * - */ - -/** - * Encode hexadecimal string (with optional byte separator character) - * - * @v separator Byte separator character, or 0 for no separator - * @v raw Raw data - * @v raw_len Length of raw data - * @v data Buffer - * @v len Length of buffer - * @ret len Encoded length - */ -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] ); - } - return used; -} - -/** - * Decode hexadecimal string (with optional byte separator character) - * - * @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 ( char separator, const char *encoded, void *data, size_t len ) { - uint8_t *out = data; - unsigned int count = 0; - unsigned int sixteens; - unsigned int units; - - while ( *encoded ) { - - /* Check separator, if applicable */ - if ( count && separator && ( ( *(encoded++) != separator ) ) ) - return -EINVAL; - - /* Extract digits. Note that either digit may be NUL, - * which would be interpreted as an invalid value by - * digit_value(); there is therefore no need for an - * explicit end-of-string check. - */ - sixteens = digit_value ( *(encoded++) ); - if ( sixteens >= 16 ) - return -EINVAL; - units = digit_value ( *(encoded++) ); - if ( units >= 16 ) - return -EINVAL; - - /* Store result */ - if ( count < len ) - out[count] = ( ( sixteens << 4 ) | units ); - count++; - - } - return count; -} diff --git a/qemu/roms/ipxe/src/core/base64.c b/qemu/roms/ipxe/src/core/base64.c deleted file mode 100644 index e452f7d41..000000000 --- a/qemu/roms/ipxe/src/core/base64.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (C) 2009 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdint.h> -#include <string.h> -#include <ctype.h> -#include <errno.h> -#include <assert.h> -#include <ipxe/base64.h> - -/** @file - * - * Base64 encoding - * - */ - -static const char base64[64] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -/** - * Base64-encode data - * - * @v raw Raw data - * @v raw_len Length of raw data - * @v data Buffer - * @v len Length of buffer - * @ret len Encoded length - */ -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 ); - 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, used++ ) { - byte = ( bit / 8 ); - shift = ( bit % 8 ); - tmp = ( raw_bytes[byte] << shift ); - if ( ( byte + 1 ) < raw_len ) - tmp |= ( raw_bytes[ byte + 1 ] >> ( 8 - shift ) ); - tmp = ( ( tmp >> 2 ) & 0x3f ); - if ( used < len ) - data[used] = base64[tmp]; - } - for ( ; ( bit % 8 ) != 0 ; bit += 6, used++ ) { - if ( used < len ) - data[used] = '='; - } - if ( used < len ) - data[used] = '\0'; - if ( len ) - data[ len - 1 ] = '\0'; /* Ensure terminator exists */ - - return used; -} - -/** - * Base64-decode string - * - * @v encoded Encoded string - * @v data Buffer - * @v len Length of buffer - * @ret len Length of data, or negative error - */ -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 in_bits; - unsigned int bit = 0; - unsigned int pad_count = 0; - size_t offset; - - /* Zero the output buffer */ - memset ( data, 0, len ); - - /* Decode string */ - while ( ( in_char = *(in++) ) ) { - - /* Ignore whitespace characters */ - if ( isspace ( in_char ) ) - continue; - - /* Process pad characters */ - if ( in_char == '=' ) { - if ( pad_count >= 2 ) { - DBG ( "Base64-encoded string \"%s\" has too " - "many pad characters\n", encoded ); - return -EINVAL; - } - pad_count++; - bit -= 2; /* unused_bits = ( 2 * pad_count ) */ - continue; - } - if ( pad_count ) { - DBG ( "Base64-encoded string \"%s\" has invalid pad " - "sequence\n", encoded ); - return -EINVAL; - } - - /* Process normal characters */ - match = strchr ( base64, in_char ); - if ( ! match ) { - DBG ( "Base64-encoded string \"%s\" contains invalid " - "character '%c'\n", encoded, in_char ); - return -EINVAL; - } - in_bits = ( match - base64 ); - - /* Add to raw data */ - 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; - } - - /* Check that we decoded a whole number of bytes */ - if ( ( bit % 8 ) != 0 ) { - DBG ( "Base64-encoded string \"%s\" has invalid bit length " - "%d\n", encoded, bit ); - return -EINVAL; - } - - /* Return length in bytes */ - return ( bit / 8 ); -} diff --git a/qemu/roms/ipxe/src/core/basename.c b/qemu/roms/ipxe/src/core/basename.c deleted file mode 100644 index f4f929517..000000000 --- a/qemu/roms/ipxe/src/core/basename.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/** - * @file - * - * Get base name of path - * - */ - -#include <string.h> -#include <libgen.h> - -/** - * Return base name from path - * - * @v path Full path - * @ret basename Base name - */ -char * basename ( char *path ) { - char *basename; - - basename = strrchr ( path, '/' ); - return ( basename ? ( basename + 1 ) : path ); -} - -/** - * Return directory name from path - * - * @v path Full path - * @ret dirname Directory name - * - * Note that this function may modify its argument. - */ -char * dirname ( char *path ) { - char *separator; - - separator = strrchr ( path, '/' ); - if ( separator == path ) { - return "/"; - } else if ( separator ) { - *separator = 0; - return path; - } else { - return "."; - } -} diff --git a/qemu/roms/ipxe/src/core/bitmap.c b/qemu/roms/ipxe/src/core/bitmap.c deleted file mode 100644 index 2aac33870..000000000 --- a/qemu/roms/ipxe/src/core/bitmap.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <errno.h> -#include <ipxe/bitmap.h> - -/** @file - * - * Bitmaps for multicast downloads - * - */ - -/** - * Resize bitmap - * - * @v bitmap Bitmap - * @v new_length New length of bitmap, in bits - * @ret rc Return status code - */ -int bitmap_resize ( struct bitmap *bitmap, unsigned int new_length ) { - unsigned int old_num_blocks; - unsigned int new_num_blocks; - size_t new_size; - bitmap_block_t *new_blocks; - - old_num_blocks = BITMAP_INDEX ( bitmap->length + BITMAP_BLKSIZE - 1 ); - new_num_blocks = BITMAP_INDEX ( new_length + BITMAP_BLKSIZE - 1 ); - - if ( old_num_blocks != new_num_blocks ) { - new_size = ( new_num_blocks * sizeof ( bitmap->blocks[0] ) ); - new_blocks = realloc ( bitmap->blocks, new_size ); - if ( ! new_blocks ) { - DBGC ( bitmap, "Bitmap %p could not resize to %d " - "bits\n", bitmap, new_length ); - return -ENOMEM; - } - bitmap->blocks = new_blocks; - } - bitmap->length = new_length; - - while ( old_num_blocks < new_num_blocks ) { - bitmap->blocks[old_num_blocks++] = 0; - } - - DBGC ( bitmap, "Bitmap %p resized to %d bits\n", bitmap, new_length ); - return 0; -} - -/** - * Test bit in bitmap - * - * @v bitmap Bitmap - * @v bit Bit index - * @ret is_set Bit is set - */ -int bitmap_test ( struct bitmap *bitmap, unsigned int bit ) { - unsigned int index = BITMAP_INDEX ( bit ); - bitmap_block_t mask = BITMAP_MASK ( bit ); - - if ( bit >= bitmap->length ) - return 0; - return ( ( bitmap->blocks[index] & mask ) != 0 ); -} - -/** - * Set bit in bitmap - * - * @v bitmap Bitmap - * @v bit Bit index - */ -void bitmap_set ( struct bitmap *bitmap, unsigned int bit ) { - unsigned int index = BITMAP_INDEX ( bit ); - bitmap_block_t mask = BITMAP_MASK ( bit ); - - DBGC ( bitmap, "Bitmap %p setting bit %d\n", bitmap, bit ); - - /* Update bitmap */ - bitmap->blocks[index] |= mask; - - /* Update first gap counter */ - while ( bitmap_test ( bitmap, bitmap->first_gap ) ) { - bitmap->first_gap++; - } -} diff --git a/qemu/roms/ipxe/src/core/blockdev.c b/qemu/roms/ipxe/src/core/blockdev.c deleted file mode 100644 index c219d9673..000000000 --- a/qemu/roms/ipxe/src/core/blockdev.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2010 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <errno.h> -#include <ipxe/interface.h> -#include <ipxe/blockdev.h> - -/** @file - * - * Block devices - * - */ - -/** - * Read from block device - * - * @v control Control interface - * @v data Data interface - * @v lba Starting logical block address - * @v count Number of logical blocks - * @v buffer Data buffer - * @v len Length of data buffer - * @ret rc Return status code - */ -int block_read ( struct interface *control, struct interface *data, - uint64_t lba, unsigned int count, - userptr_t buffer, size_t len ) { - struct interface *dest; - block_read_TYPE ( void * ) *op = - intf_get_dest_op ( control, block_read, &dest ); - void *object = intf_object ( dest ); - int rc; - - if ( op ) { - rc = op ( object, data, lba, count, buffer, len ); - } else { - /* Default is to fail to issue the command */ - rc = -EOPNOTSUPP; - } - - intf_put ( dest ); - return rc; -} - -/** - * Write to block device - * - * @v control Control interface - * @v data Data interface - * @v lba Starting logical block address - * @v count Number of logical blocks - * @v buffer Data buffer - * @v len Length of data buffer - * @ret rc Return status code - */ -int block_write ( struct interface *control, struct interface *data, - uint64_t lba, unsigned int count, - userptr_t buffer, size_t len ) { - struct interface *dest; - block_write_TYPE ( void * ) *op = - intf_get_dest_op ( control, block_write, &dest ); - void *object = intf_object ( dest ); - int rc; - - if ( op ) { - rc = op ( object, data, lba, count, buffer, len ); - } else { - /* Default is to fail to issue the command */ - rc = -EOPNOTSUPP; - } - - intf_put ( dest ); - return rc; -} - -/** - * Read block device capacity - * - * @v control Control interface - * @v data Data interface - * @ret rc Return status code - */ -int block_read_capacity ( struct interface *control, struct interface *data ) { - struct interface *dest; - block_read_capacity_TYPE ( void * ) *op = - intf_get_dest_op ( control, block_read_capacity, &dest ); - void *object = intf_object ( dest ); - int rc; - - if ( op ) { - rc = op ( object, data ); - } else { - /* Default is to fail to issue the command */ - rc = -EOPNOTSUPP; - } - - intf_put ( dest ); - return rc; -} - -/** - * Report block device capacity - * - * @v intf Interface - * @v capacity Block device capacity - */ -void block_capacity ( struct interface *intf, - struct block_device_capacity *capacity ) { - struct interface *dest; - block_capacity_TYPE ( void * ) *op = - intf_get_dest_op ( intf, block_capacity, &dest ); - void *object = intf_object ( dest ); - - if ( op ) { - op ( object, capacity ); - } else { - /* Default is to do nothing */ - } - - intf_put ( dest ); -} diff --git a/qemu/roms/ipxe/src/core/blocktrans.c b/qemu/roms/ipxe/src/core/blocktrans.c deleted file mode 100644 index 3f32f9cf8..000000000 --- a/qemu/roms/ipxe/src/core/blocktrans.c +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/** - * @file - * - * 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 deleted file mode 100644 index 7fd00036f..000000000 --- a/qemu/roms/ipxe/src/core/console.c +++ /dev/null @@ -1,164 +0,0 @@ -#include "stddef.h" -#include <ipxe/console.h> -#include <ipxe/process.h> -#include <ipxe/nap.h> - -/** @file */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/** Current console usage */ -int console_usage = CONSOLE_USAGE_STDOUT; - -/** Console width */ -unsigned int console_width = CONSOLE_DEFAULT_WIDTH; - -/** Console height */ -unsigned int console_height = CONSOLE_DEFAULT_HEIGHT; - -/** - * Write a single character to each console device - * - * @v character Character to be written - * - * The character is written out to all enabled console devices, using - * each device's console_driver::putchar() method. - */ -void putchar ( int character ) { - struct console_driver *console; - - /* Automatic LF -> CR,LF translation */ - if ( character == '\n' ) - putchar ( '\r' ); - - for_each_table_entry ( console, CONSOLES ) { - if ( ( ! ( console->disabled & CONSOLE_DISABLED_OUTPUT ) ) && - ( console_usage & console->usage ) && - console->putchar ) - console->putchar ( character ); - } -} - -/** - * Check to see if any input is available on any console - * - * @ret console Console device that has input available, or NULL - * - * All enabled console devices are checked once for available input - * using each device's console_driver::iskey() method. The first - * console device that has available input will be returned, if any. - */ -static struct console_driver * has_input ( void ) { - struct console_driver *console; - - for_each_table_entry ( console, CONSOLES ) { - if ( ( ! ( console->disabled & CONSOLE_DISABLED_INPUT ) ) && - console->iskey ) { - if ( console->iskey () ) - return console; - } - } - return NULL; -} - -/** - * Read a single character from any console - * - * @ret character Character read from a console. - * - * A character will be read from the first enabled console device that - * has input available using that console's console_driver::getchar() - * method. If no console has input available to be read, this method - * will block. To perform a non-blocking read, use something like - * - * @code - * - * int key = iskey() ? getchar() : -1; - * - * @endcode - * - * The character read will not be echoed back to any console. - */ -int getchar ( void ) { - struct console_driver *console; - int character; - - while ( 1 ) { - console = has_input(); - if ( console && console->getchar ) { - character = console->getchar (); - break; - } - - /* Doze for a while (until the next interrupt). This works - * fine, because the keyboard is interrupt-driven, and the - * timer interrupt (approx. every 50msec) takes care of the - * serial port, which is read by polling. This reduces the - * power dissipation of a modern CPU considerably, and also - * makes Etherboot waiting for user interaction waste a lot - * less CPU time in a VMware session. - */ - cpu_nap(); - - /* Keep processing background tasks while we wait for - * input. - */ - step(); - } - - /* CR -> LF translation */ - if ( character == '\r' ) - character = '\n'; - - return character; -} - -/** - * Check for available input on any console - * - * @ret is_available Input is available on a console - * - * All enabled console devices are checked once for available input - * using each device's console_driver::iskey() method. If any console - * device has input available, this call will return true. If this - * call returns true, you can then safely call getchar() without - * blocking. - */ -int iskey ( void ) { - return has_input() ? 1 : 0; -} - -/** - * Configure console - * - * @v config Console configuration - * @ret rc Return status code - * - * The configuration is passed to all configurable consoles, including - * those which are currently disabled. Consoles may choose to enable - * or disable themselves depending upon the configuration. - * - * If configuration fails, then all consoles will be reset. - */ -int console_configure ( struct console_configuration *config ) { - struct console_driver *console; - int rc; - - /* Reset console width and height */ - console_set_size ( CONSOLE_DEFAULT_WIDTH, CONSOLE_DEFAULT_HEIGHT ); - - /* Try to configure each console */ - for_each_table_entry ( console, CONSOLES ) { - if ( ( console->configure ) && - ( ( rc = console->configure ( config ) ) != 0 ) ) - goto err; - } - - return 0; - - err: - /* Reset all consoles, avoiding a potential infinite loop */ - if ( config ) - console_reset(); - return rc; -} diff --git a/qemu/roms/ipxe/src/core/cpio.c b/qemu/roms/ipxe/src/core/cpio.c deleted file mode 100644 index 080c72daf..000000000 --- a/qemu/roms/ipxe/src/core/cpio.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/** @file - * - * CPIO archives - * - */ - -#include <stdio.h> -#include <string.h> -#include <ipxe/cpio.h> - -/** - * Set field within a CPIO header - * - * @v field Field within CPIO header - * @v value Value to set - */ -void cpio_set_field ( char *field, unsigned long value ) { - char buf[9]; - - snprintf ( buf, sizeof ( buf ), "%08lx", value ); - memcpy ( field, buf, 8 ); -} diff --git a/qemu/roms/ipxe/src/core/ctype.c b/qemu/roms/ipxe/src/core/ctype.c deleted file mode 100644 index 891af71ea..000000000 --- a/qemu/roms/ipxe/src/core/ctype.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2009 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 - * - * Character types - * - */ - -#include <ctype.h> - -/** - * Check to see if character is a space - * - * @v character Character - * @ret isspace Character is a space - */ -int isspace ( int character ) { - - switch ( character ) { - case ' ' : - case '\f' : - case '\n' : - case '\r' : - case '\t' : - case '\v' : - return 1; - default: - return 0; - } -} diff --git a/qemu/roms/ipxe/src/core/cwuri.c b/qemu/roms/ipxe/src/core/cwuri.c deleted file mode 100644 index 612f0b179..000000000 --- a/qemu/roms/ipxe/src/core/cwuri.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stddef.h> -#include <ipxe/uri.h> - -/** @file - * - * Current working URI - * - * Somewhat analogous to the current working directory in a POSIX - * system. - */ - -/** Current working URI */ -struct uri *cwuri = NULL; - -/** - * Change working URI - * - * @v uri New working URI, or NULL - */ -void churi ( struct uri *uri ) { - struct uri *new_uri = NULL; - - if ( uri ) - new_uri = resolve_uri ( cwuri, uri ); - - uri_put ( cwuri ); - cwuri = new_uri; -} diff --git a/qemu/roms/ipxe/src/core/debug.c b/qemu/roms/ipxe/src/core/debug.c deleted file mode 100644 index def5d8b09..000000000 --- a/qemu/roms/ipxe/src/core/debug.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdio.h> -#include <stdint.h> -#include <stdarg.h> -#include <ctype.h> -#include <ipxe/console.h> - -/** - * Print debug message - * - * @v fmt Format string - * @v ... Arguments - */ -void dbg_printf ( const char *fmt, ... ) { - int saved_usage; - va_list args; - - /* Mark console as in use for debugging messages */ - saved_usage = console_set_usage ( CONSOLE_USAGE_DEBUG ); - - /* Print message */ - va_start ( args, fmt ); - vprintf ( fmt, args ); - va_end ( args ); - - /* Restore console usage */ - console_set_usage ( saved_usage ); -} - -/** - * Pause until a key is pressed - * - */ -void dbg_pause ( void ) { - dbg_printf ( "\nPress a key..." ); - getchar(); - dbg_printf ( "\r \r" ); -} - -/** - * Indicate more data to follow and pause until a key is pressed - * - */ -void dbg_more ( void ) { - dbg_printf ( "---more---" ); - getchar(); - dbg_printf ( "\r \r" ); -} - -/** - * Print row of a hex dump with specified display address - * - * @v dispaddr Display address - * @v data Data to print - * @v len Length of data - * @v offset Starting offset within data - */ -static void dbg_hex_dump_da_row ( unsigned long dispaddr, const void *data, - unsigned long len, unsigned int offset ) { - const uint8_t *bytes = data; - unsigned int i; - uint8_t byte; - - dbg_printf ( "%08lx :", ( dispaddr + offset ) ); - for ( i = offset ; i < ( offset + 16 ) ; i++ ) { - if ( i >= len ) { - dbg_printf ( " " ); - continue; - } - dbg_printf ( "%c%02x", - ( ( ( i % 16 ) == 8 ) ? '-' : ' ' ), bytes[i] ); - } - dbg_printf ( " : " ); - for ( i = offset ; i < ( offset + 16 ) ; i++ ) { - if ( i >= len ) { - dbg_printf ( " " ); - continue; - } - byte = bytes[i]; - dbg_printf ( "%c", ( isprint ( byte ) ? byte : '.' ) ); - } - dbg_printf ( "\n" ); -} - -/** - * Print hex dump with specified display address - * - * @v dispaddr Display address - * @v data Data to print - * @v len Length of data - */ -void dbg_hex_dump_da ( unsigned long dispaddr, const void *data, - unsigned long len ) { - unsigned int offset; - - for ( offset = 0 ; offset < len ; offset += 16 ) { - dbg_hex_dump_da_row ( dispaddr, data, len, offset ); - } -} - -/** - * Base message stream colour - * - * We default to using 31 (red foreground) as the base colour. - */ -#ifndef DBGCOL_MIN -#define DBGCOL_MIN 31 -#endif - -/** - * Maximum number of separately coloured message streams - * - * Six is the realistic maximum; there are 8 basic ANSI colours, one - * of which will be the terminal default and one of which will be - * invisible on the terminal because it matches the background colour. - */ -#ifndef DBGCOL_MAX -#define DBGCOL_MAX ( DBGCOL_MIN + 6 - 1 ) -#endif - -/** A colour assigned to an autocolourised debug message stream */ -struct autocolour { - /** Message stream ID */ - unsigned long stream; - /** Last recorded usage */ - unsigned long last_used; -}; - -/** - * Choose colour index for debug autocolourisation - * - * @v stream Message stream ID - * @ret colour Colour ID - */ -static int dbg_autocolour ( unsigned long stream ) { - static struct autocolour acs[ DBGCOL_MAX - DBGCOL_MIN + 1 ]; - static unsigned long use; - unsigned int i; - unsigned int oldest; - unsigned int oldest_last_used; - - /* Increment usage iteration counter */ - use++; - - /* Scan through list for a currently assigned colour */ - for ( i = 0 ; i < ( sizeof ( acs ) / sizeof ( acs[0] ) ) ; i++ ) { - if ( acs[i].stream == stream ) { - acs[i].last_used = use; - return i; - } - } - - /* No colour found; evict the oldest from the list */ - oldest = 0; - oldest_last_used = use; - for ( i = 0 ; i < ( sizeof ( acs ) / sizeof ( acs[0] ) ) ; i++ ) { - if ( acs[i].last_used < oldest_last_used ) { - oldest_last_used = acs[i].last_used; - oldest = i; - } - } - acs[oldest].stream = stream; - acs[oldest].last_used = use; - return oldest; -} - -/** - * Select automatic colour for debug messages - * - * @v stream Message stream ID - */ -void dbg_autocolourise ( unsigned long stream ) { - dbg_printf ( "\033[%dm", - ( stream ? ( DBGCOL_MIN + dbg_autocolour ( stream ) ) :0)); -} - -/** - * Revert to normal colour - * - */ -void dbg_decolourise ( void ) { - dbg_printf ( "\033[0m" ); -} diff --git a/qemu/roms/ipxe/src/core/debug_md5.c b/qemu/roms/ipxe/src/core/debug_md5.c deleted file mode 100644 index d0dbad9ed..000000000 --- a/qemu/roms/ipxe/src/core/debug_md5.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdio.h> -#include <stdint.h> -#include <ipxe/crypto.h> -#include <ipxe/md5.h> - -/** - * Print an MD5 checksum with specified display address - * - * @v dispaddr Display address - * @v data Data to checksum - * @v len Length of data - */ -void dbg_md5_da ( unsigned long dispaddr, const void *data, - unsigned long len ) { - struct digest_algorithm *digest = &md5_algorithm; - uint8_t digest_ctx[digest->ctxsize]; - uint8_t digest_out[digest->digestsize]; - unsigned int i; - - printf ( "md5sum ( %#08lx, %#lx ) = ", dispaddr, len ); - digest_init ( digest, digest_ctx ); - digest_update ( digest, digest_ctx, data, len ); - digest_final ( digest, digest_ctx, digest_out ); - for ( i = 0 ; i < sizeof ( digest_out ) ; i++ ) - printf ( "%02x", digest_out[i] ); - printf ( "\n" ); -} diff --git a/qemu/roms/ipxe/src/core/device.c b/qemu/roms/ipxe/src/core/device.c deleted file mode 100644 index 77d7b719b..000000000 --- a/qemu/roms/ipxe/src/core/device.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <string.h> -#include <ipxe/list.h> -#include <ipxe/tables.h> -#include <ipxe/init.h> -#include <ipxe/interface.h> -#include <ipxe/device.h> - -/** - * @file - * - * Device model - * - */ - -/** Registered root devices */ -static LIST_HEAD ( devices ); - -/** Device removal inhibition counter */ -int device_keep_count = 0; - -/** - * Probe a root device - * - * @v rootdev Root device - * @ret rc Return status code - */ -static int rootdev_probe ( struct root_device *rootdev ) { - int rc; - - DBG ( "Adding %s root bus\n", rootdev->dev.name ); - if ( ( rc = rootdev->driver->probe ( rootdev ) ) != 0 ) { - DBG ( "Failed to add %s root bus: %s\n", - rootdev->dev.name, strerror ( rc ) ); - return rc; - } - - return 0; -} - -/** - * Remove a root device - * - * @v rootdev Root device - */ -static void rootdev_remove ( struct root_device *rootdev ) { - rootdev->driver->remove ( rootdev ); - DBG ( "Removed %s root bus\n", rootdev->dev.name ); -} - -/** - * Probe all devices - * - * This initiates probing for all devices in the system. After this - * call, the device hierarchy will be populated, and all hardware - * should be ready to use. - */ -static void probe_devices ( void ) { - struct root_device *rootdev; - int rc; - - for_each_table_entry ( rootdev, ROOT_DEVICES ) { - list_add ( &rootdev->dev.siblings, &devices ); - INIT_LIST_HEAD ( &rootdev->dev.children ); - if ( ( rc = rootdev_probe ( rootdev ) ) != 0 ) - list_del ( &rootdev->dev.siblings ); - } -} - -/** - * Remove all devices - * - */ -static void remove_devices ( int booting __unused ) { - struct root_device *rootdev; - struct root_device *tmp; - - if ( device_keep_count != 0 ) { - DBG ( "Refusing to remove devices on shutdown\n" ); - return; - } - - list_for_each_entry_safe ( rootdev, tmp, &devices, dev.siblings ) { - rootdev_remove ( rootdev ); - list_del ( &rootdev->dev.siblings ); - } -} - -struct startup_fn startup_devices __startup_fn ( STARTUP_NORMAL ) = { - .startup = probe_devices, - .shutdown = remove_devices, -}; - -/** - * Identify a device behind an interface - * - * @v intf Interface - * @ret device Device, or NULL - */ -struct device * identify_device ( struct interface *intf ) { - struct interface *dest; - identify_device_TYPE ( void * ) *op = - intf_get_dest_op ( intf, identify_device, &dest ); - void *object = intf_object ( dest ); - void *device; - - if ( op ) { - device = op ( object ); - } else { - /* Default is to return NULL */ - device = NULL; - } - - intf_put ( dest ); - return device; -} diff --git a/qemu/roms/ipxe/src/core/downloader.c b/qemu/roms/ipxe/src/core/downloader.c deleted file mode 100644 index d745f3617..000000000 --- a/qemu/roms/ipxe/src/core/downloader.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdlib.h> -#include <errno.h> -#include <syslog.h> -#include <ipxe/iobuf.h> -#include <ipxe/xfer.h> -#include <ipxe/open.h> -#include <ipxe/job.h> -#include <ipxe/uaccess.h> -#include <ipxe/umalloc.h> -#include <ipxe/image.h> -#include <ipxe/xferbuf.h> -#include <ipxe/downloader.h> - -/** @file - * - * Image downloader - * - */ - -/** A downloader */ -struct downloader { - /** Reference count for this object */ - struct refcnt refcnt; - - /** Job control interface */ - struct interface job; - /** Data transfer interface */ - struct interface xfer; - - /** Image to contain downloaded file */ - struct image *image; - /** Data transfer buffer */ - struct xfer_buffer buffer; -}; - -/** - * Free downloader object - * - * @v refcnt Downloader reference counter - */ -static void downloader_free ( struct refcnt *refcnt ) { - struct downloader *downloader = - container_of ( refcnt, struct downloader, refcnt ); - - image_put ( downloader->image ); - free ( downloader ); -} - -/** - * Terminate download - * - * @v downloader Downloader - * @v rc Reason for termination - */ -static void downloader_finished ( struct downloader *downloader, int rc ) { - - /* Log download status */ - if ( rc == 0 ) { - syslog ( LOG_NOTICE, "Downloaded \"%s\"\n", - downloader->image->name ); - } else { - syslog ( LOG_ERR, "Download of \"%s\" failed: %s\n", - 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 ); -} - -/**************************************************************************** - * - * Job control interface - * - */ - -/** - * Report progress of download job - * - * @v downloader Downloader - * @v progress Progress report to fill in - * @ret ongoing_rc Ongoing job status code (if known) - */ -static int downloader_progress ( struct downloader *downloader, - struct job_progress *progress ) { - - /* This is not entirely accurate, since downloaded data may - * arrive out of order (e.g. with multicast protocols), but - * it's a reasonable first approximation. - */ - progress->completed = downloader->buffer.pos; - progress->total = downloader->buffer.len; - - return 0; -} - -/**************************************************************************** - * - * Data transfer interface - * - */ - -/** - * Handle received data - * - * @v downloader Downloader - * @v iobuf Datagram I/O buffer - * @v meta Data transfer metadata - * @ret rc Return status code - */ -static int downloader_xfer_deliver ( struct downloader *downloader, - struct io_buffer *iobuf, - struct xfer_metadata *meta ) { - int rc; - - /* 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 ), -}; - -/** Downloader data transfer interface descriptor */ -static struct interface_descriptor downloader_xfer_desc = - INTF_DESC ( struct downloader, xfer, downloader_xfer_operations ); - -/**************************************************************************** - * - * Job control interface - * - */ - -/** Downloader job control interface operations */ -static struct interface_operation downloader_job_op[] = { - INTF_OP ( job_progress, struct downloader *, downloader_progress ), - INTF_OP ( intf_close, struct downloader *, downloader_finished ), -}; - -/** Downloader job control interface descriptor */ -static struct interface_descriptor downloader_job_desc = - INTF_DESC ( struct downloader, job, downloader_job_op ); - -/**************************************************************************** - * - * Instantiator - * - */ - -/** - * Instantiate a downloader - * - * @v job Job control interface - * @v image Image to fill with downloaded file - * @ret rc Return status code - * - * Instantiates a downloader object to download the content of the - * specified image from its URI. - */ -int create_downloader ( struct interface *job, struct image *image ) { - struct downloader *downloader; - int rc; - - /* Allocate and initialise structure */ - downloader = zalloc ( sizeof ( *downloader ) ); - if ( ! downloader ) - return -ENOMEM; - ref_init ( &downloader->refcnt, downloader_free ); - intf_init ( &downloader->job, &downloader_job_desc, - &downloader->refcnt ); - 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 ) - goto err; - - /* Attach parent interface, mortalise self, and return */ - intf_plug_plug ( &downloader->job, job ); - ref_put ( &downloader->refcnt ); - return 0; - - err: - downloader_finished ( downloader, rc ); - ref_put ( &downloader->refcnt ); - return rc; -} diff --git a/qemu/roms/ipxe/src/core/edd.c b/qemu/roms/ipxe/src/core/edd.c deleted file mode 100644 index a50b74ab1..000000000 --- a/qemu/roms/ipxe/src/core/edd.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2010 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <errno.h> -#include <ipxe/interface.h> -#include <ipxe/edd.h> - -/** @file - * - * Enhanced Disk Drive specification - * - */ - -/** - * Describe a disk device using EDD - * - * @v intf Interface - * @v type EDD interface type - * @v path EDD device path - * @ret rc Return status code - */ -int edd_describe ( struct interface *intf, struct edd_interface_type *type, - union edd_device_path *path ) { - struct interface *dest; - edd_describe_TYPE ( void * ) *op = - intf_get_dest_op ( intf, edd_describe, &dest ); - void *object = intf_object ( dest ); - int rc; - - if ( op ) { - rc = op ( object, type, path ); - } else { - /* Default is to not support this operation */ - rc = -ENOTSUP; - } - - intf_put ( dest ); - return rc; -} diff --git a/qemu/roms/ipxe/src/core/errno.c b/qemu/roms/ipxe/src/core/errno.c deleted file mode 100644 index 5de15bb92..000000000 --- a/qemu/roms/ipxe/src/core/errno.c +++ /dev/null @@ -1,20 +0,0 @@ -#include <errno.h> - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/** @file - * - * Error codes - * - * This file provides the global variable #errno. - * - */ - -/** - * Global "last error" number. - * - * This is valid only when a function has just returned indicating a - * failure. - * - */ -int errno; diff --git a/qemu/roms/ipxe/src/core/exec.c b/qemu/roms/ipxe/src/core/exec.c deleted file mode 100644 index 2c2ade0a5..000000000 --- a/qemu/roms/ipxe/src/core/exec.c +++ /dev/null @@ -1,605 +0,0 @@ -/* - * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdint.h> -#include <string.h> -#include <stdlib.h> -#include <stdio.h> -#include <ctype.h> -#include <unistd.h> -#include <getopt.h> -#include <errno.h> -#include <assert.h> -#include <ipxe/tables.h> -#include <ipxe/command.h> -#include <ipxe/parseopt.h> -#include <ipxe/settings.h> -#include <ipxe/console.h> -#include <ipxe/keys.h> -#include <ipxe/process.h> -#include <ipxe/nap.h> -#include <ipxe/shell.h> - -/** @file - * - * Command execution - * - */ - -/** Shell stop state */ -static int stop_state; - -/** - * Execute command - * - * @v command Command name - * @v argv Argument list - * @ret rc Return status code - * - * Execute the named command. Unlike a traditional POSIX execv(), - * this function returns the exit status of the command. - */ -int execv ( const char *command, char * const argv[] ) { - struct command *cmd; - int argc; - int rc; - - /* Count number of arguments */ - for ( argc = 0 ; argv[argc] ; argc++ ) {} - - /* An empty command is deemed to do nothing, successfully */ - if ( command == NULL ) { - rc = 0; - goto done; - } - - /* Sanity checks */ - if ( argc == 0 ) { - DBG ( "%s: empty argument list\n", command ); - rc = -EINVAL; - goto done; - } - - /* Reset getopt() library ready for use by the command. This - * is an artefact of the POSIX getopt() API within the context - * of Etherboot; see the documentation for reset_getopt() for - * details. - */ - reset_getopt(); - - /* Hand off to command implementation */ - for_each_table_entry ( cmd, COMMANDS ) { - if ( strcmp ( command, cmd->name ) == 0 ) { - rc = cmd->exec ( argc, ( char ** ) argv ); - goto done; - } - } - - printf ( "%s: command not found\n", command ); - rc = -ENOEXEC; - - done: - /* Store error number, if an error occurred */ - if ( rc ) { - errno = rc; - if ( errno < 0 ) - errno = -errno; - } - - return rc; -} - -/** - * Split command line into tokens - * - * @v command Command line - * @v tokens Token list to populate, or NULL - * @ret count Number of tokens - * - * Splits the command line into whitespace-delimited tokens. If @c - * tokens is non-NULL, any whitespace in the command line will be - * replaced with NULs. - */ -static int split_command ( char *command, char **tokens ) { - int count = 0; - - while ( 1 ) { - /* Skip over any whitespace / convert to NUL */ - while ( isspace ( *command ) ) { - if ( tokens ) - *command = '\0'; - command++; - } - /* Check for end of line */ - if ( ! *command ) - break; - /* We have found the start of the next argument */ - if ( tokens ) - tokens[count] = command; - count++; - /* Skip to start of next whitespace, if any */ - while ( *command && ! isspace ( *command ) ) { - command++; - } - } - return count; -} - -/** - * Process next command only if previous command succeeded - * - * @v rc Status of previous command - * @ret process Process next command - */ -static int process_on_success ( int rc ) { - return ( rc == 0 ); -} - -/** - * Process next command only if previous command failed - * - * @v rc Status of previous command - * @ret process Process next command - */ -static int process_on_failure ( int rc ) { - return ( rc != 0 ); -} - -/** - * Process next command regardless of status from previous command - * - * @v rc Status of previous command - * @ret process Process next command - */ -static int process_always ( int rc __unused ) { - return 1; -} - -/** - * Find command terminator - * - * @v tokens Token list - * @ret process_next "Should next command be processed?" function - * @ret argc Argument count - */ -static int command_terminator ( char **tokens, - int ( **process_next ) ( int rc ) ) { - unsigned int i; - - /* Find first terminating token */ - for ( i = 0 ; tokens[i] ; i++ ) { - if ( tokens[i][0] == '#' ) { - /* Start of a comment */ - break; - } else if ( strcmp ( tokens[i], "||" ) == 0 ) { - /* Short-circuit logical OR */ - *process_next = process_on_failure; - return i; - } else if ( strcmp ( tokens[i], "&&" ) == 0 ) { - /* Short-circuit logical AND */ - *process_next = process_on_success; - return i; - } else if ( strcmp ( tokens[i], ";" ) == 0 ) { - /* Process next command unconditionally */ - *process_next = process_always; - return i; - } - } - - /* End of token list */ - *process_next = NULL; - return i; -} - -/** - * Set shell stop state - * - * @v stop Shell stop state - */ -void shell_stop ( int stop ) { - stop_state = stop; -} - -/** - * Test and consume shell stop state - * - * @v stop Shell stop state to consume - * @v stopped Shell had been stopped - */ -int shell_stopped ( int stop ) { - int stopped; - - /* Test to see if we need to stop */ - stopped = ( stop_state >= stop ); - - /* Consume stop state */ - if ( stop_state <= stop ) - stop_state = 0; - - return stopped; -} - -/** - * Expand settings within a token list - * - * @v argc Argument count - * @v tokens Token list - * @v argv Argument list to fill in - * @ret rc Return status code - */ -static int expand_tokens ( int argc, char **tokens, char **argv ) { - int i; - - /* Expand each token in turn */ - for ( i = 0 ; i < argc ; i++ ) { - argv[i] = expand_settings ( tokens[i] ); - if ( ! argv[i] ) - goto err_expand_settings; - } - - return 0; - - err_expand_settings: - assert ( argv[i] == NULL ); - for ( ; i >= 0 ; i-- ) - free ( argv[i] ); - return -ENOMEM; -} - -/** - * Free an expanded token list - * - * @v argv Argument list - */ -static void free_tokens ( char **argv ) { - - /* Free each expanded argument */ - while ( *argv ) - free ( *(argv++) ); -} - -/** - * Execute command line - * - * @v command Command line - * @ret rc Return status code - * - * Execute the named command and arguments. - */ -int system ( const char *command ) { - int count = split_command ( ( char * ) command, NULL ); - char *all_tokens[ count + 1 ]; - int ( * process_next ) ( int rc ); - char *command_copy; - char **tokens; - int argc; - int process; - int rc = 0; - - /* Create modifiable copy of command */ - command_copy = strdup ( command ); - if ( ! command_copy ) - return -ENOMEM; - - /* Split command into tokens */ - split_command ( command_copy, all_tokens ); - all_tokens[count] = NULL; - - /* Process individual commands */ - process = 1; - for ( tokens = all_tokens ; ; tokens += ( argc + 1 ) ) { - - /* Find command terminator */ - argc = command_terminator ( tokens, &process_next ); - - /* Expand tokens and execute command */ - if ( process ) { - char *argv[ argc + 1 ]; - - /* Expand tokens */ - if ( ( rc = expand_tokens ( argc, tokens, argv ) ) != 0) - break; - argv[argc] = NULL; - - /* Execute command */ - rc = execv ( argv[0], argv ); - - /* Free tokens */ - free_tokens ( argv ); - } - - /* Stop processing, if applicable */ - if ( shell_stopped ( SHELL_STOP_COMMAND ) ) - break; - - /* Stop processing if we have reached the end of the - * command. - */ - if ( ! process_next ) - break; - - /* Determine whether or not to process next command */ - process = process_next ( rc ); - } - - /* Free modified copy of command */ - free ( command_copy ); - - return rc; -} - -/** - * Concatenate arguments - * - * @v args Argument list (NULL-terminated) - * @ret string Concatenated arguments - * - * The returned string is allocated with malloc(). The caller is - * responsible for eventually free()ing this string. - */ -char * concat_args ( char **args ) { - char **arg; - size_t len; - char *string; - char *ptr; - - /* Calculate total string length */ - len = 1 /* NUL */; - for ( arg = args ; *arg ; arg++ ) - len += ( 1 /* possible space */ + strlen ( *arg ) ); - - /* Allocate string */ - string = zalloc ( len ); - if ( ! string ) - return NULL; - - /* Populate string */ - ptr = string; - for ( arg = args ; *arg ; arg++ ) { - ptr += sprintf ( ptr, "%s%s", - ( ( arg == args ) ? "" : " " ), *arg ); - } - assert ( ptr < ( string + len ) ); - - return string; -} - -/** "echo" options */ -struct echo_options { - /** Do not print trailing newline */ - int no_newline; -}; - -/** "echo" option list */ -static struct option_descriptor echo_opts[] = { - OPTION_DESC ( "n", 'n', no_argument, - struct echo_options, no_newline, parse_flag ), -}; - -/** "echo" command descriptor */ -static struct command_descriptor echo_cmd = - COMMAND_DESC ( struct echo_options, echo_opts, 0, MAX_ARGUMENTS, - "[...]" ); - -/** - * "echo" command - * - * @v argc Argument count - * @v argv Argument list - * @ret rc Return status code - */ -static int echo_exec ( int argc, char **argv ) { - struct echo_options opts; - char *text; - int rc; - - /* Parse options */ - if ( ( rc = parse_options ( argc, argv, &echo_cmd, &opts ) ) != 0 ) - return rc; - - /* Parse text */ - text = concat_args ( &argv[optind] ); - if ( ! text ) - return -ENOMEM; - - /* Print text */ - printf ( "%s%s", text, ( opts.no_newline ? "" : "\n" ) ); - - free ( text ); - return 0; -} - -/** "echo" command */ -struct command echo_command __command = { - .name = "echo", - .exec = echo_exec, -}; - -/** "exit" options */ -struct exit_options {}; - -/** "exit" option list */ -static struct option_descriptor exit_opts[] = {}; - -/** "exit" command descriptor */ -static struct command_descriptor exit_cmd = - COMMAND_DESC ( struct exit_options, exit_opts, 0, 1, "[<status>]" ); - -/** - * "exit" command - * - * @v argc Argument count - * @v argv Argument list - * @ret rc Return status code - */ -static int exit_exec ( int argc, char **argv ) { - struct exit_options opts; - unsigned int exit_code = 0; - int rc; - - /* Parse options */ - if ( ( rc = parse_options ( argc, argv, &exit_cmd, &opts ) ) != 0 ) - return rc; - - /* Parse exit status, if present */ - if ( optind != argc ) { - if ( ( rc = parse_integer ( argv[optind], &exit_code ) ) != 0 ) - return rc; - } - - /* Stop shell processing */ - shell_stop ( SHELL_STOP_COMMAND_SEQUENCE ); - - return exit_code; -} - -/** "exit" command */ -struct command exit_command __command = { - .name = "exit", - .exec = exit_exec, -}; - -/** "isset" options */ -struct isset_options {}; - -/** "isset" option list */ -static struct option_descriptor isset_opts[] = {}; - -/** "isset" command descriptor */ -static struct command_descriptor isset_cmd = - COMMAND_DESC ( struct isset_options, isset_opts, 1, 1, "<value>" ); - -/** - * "isset" command - * - * @v argc Argument count - * @v argv Argument list - * @ret rc Return status code - */ -static int isset_exec ( int argc, char **argv ) { - struct isset_options opts; - int rc; - - /* Parse options */ - if ( ( rc = parse_options ( argc, argv, &isset_cmd, &opts ) ) != 0 ) - return rc; - - /* Return success iff argument is non-empty */ - return ( argv[optind][0] ? 0 : -ENOENT ); -} - -/** "isset" command */ -struct command isset_command __command = { - .name = "isset", - .exec = isset_exec, -}; - -/** "iseq" options */ -struct iseq_options {}; - -/** "iseq" option list */ -static struct option_descriptor iseq_opts[] = {}; - -/** "iseq" command descriptor */ -static struct command_descriptor iseq_cmd = - COMMAND_DESC ( struct iseq_options, iseq_opts, 2, 2, - "<value1> <value2>" ); - -/** - * "iseq" command - * - * @v argc Argument count - * @v argv Argument list - * @ret rc Return status code - */ -static int iseq_exec ( int argc, char **argv ) { - struct iseq_options opts; - int rc; - - /* Parse options */ - if ( ( rc = parse_options ( argc, argv, &iseq_cmd, &opts ) ) != 0 ) - return rc; - - /* Return success iff arguments are equal */ - return ( ( strcmp ( argv[optind], argv[ optind + 1 ] ) == 0 ) ? - 0 : -ERANGE ); -} - -/** "iseq" command */ -struct command iseq_command __command = { - .name = "iseq", - .exec = iseq_exec, -}; - -/** "sleep" options */ -struct sleep_options {}; - -/** "sleep" option list */ -static struct option_descriptor sleep_opts[] = {}; - -/** "sleep" command descriptor */ -static struct command_descriptor sleep_cmd = - COMMAND_DESC ( struct sleep_options, sleep_opts, 1, 1, "<seconds>" ); - -/** - * "sleep" command - * - * @v argc Argument count - * @v argv Argument list - * @ret rc Return status code - */ -static int sleep_exec ( int argc, char **argv ) { - struct sleep_options opts; - unsigned int seconds; - unsigned long start; - unsigned long delay; - int rc; - - /* Parse options */ - if ( ( rc = parse_options ( argc, argv, &sleep_cmd, &opts ) ) != 0 ) - return rc; - - /* Parse number of seconds */ - if ( ( rc = parse_integer ( argv[optind], &seconds ) ) != 0 ) - return rc; - - /* Delay for specified number of seconds */ - start = currticks(); - delay = ( seconds * TICKS_PER_SEC ); - while ( ( currticks() - start ) <= delay ) { - step(); - if ( iskey() && ( getchar() == CTRL_C ) ) - return -ECANCELED; - cpu_nap(); - } - - return 0; -} - -/** "sleep" command */ -struct command sleep_command __command = { - .name = "sleep", - .exec = sleep_exec, -}; diff --git a/qemu/roms/ipxe/src/core/fault.c b/qemu/roms/ipxe/src/core/fault.c deleted file mode 100644 index 63d3ccacf..000000000 --- a/qemu/roms/ipxe/src/core/fault.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (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 deleted file mode 100644 index 6d8b0086d..000000000 --- a/qemu/roms/ipxe/src/core/fbcon.c +++ /dev/null @@ -1,696 +0,0 @@ -/* - * Copyright (C) 2013 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/** @file - * - * Frame buffer console - * - */ - -#include <string.h> -#include <errno.h> -#include <assert.h> -#include <byteswap.h> -#include <ipxe/ansiesc.h> -#include <ipxe/image.h> -#include <ipxe/pixbuf.h> -#include <ipxe/umalloc.h> -#include <ipxe/console.h> -#include <ipxe/fbcon.h> - -/** - * Calculate raw colour value - * - * @v fbcon Frame buffer console - * @v rgb 24-bit RGB value - * @ret raw Raw colour - */ -static uint32_t fbcon_colour ( struct fbcon *fbcon, uint32_t rgb ) { - struct fbcon_colour_map *map = fbcon->map; - uint8_t red = ( rgb >> 16 ); - uint8_t green = ( rgb >> 8 ); - uint8_t blue = ( rgb >> 0 ); - uint32_t mapped; - - mapped = ( ( ( red >> map->red_scale ) << map->red_lsb ) | - ( ( green >> map->green_scale ) << map->green_lsb ) | - ( ( blue >> map->blue_scale ) << map->blue_lsb ) ); - return cpu_to_le32 ( mapped ); -} - -/** - * Calculate ANSI font colour - * - * @v fbcon Frame buffer console - * @v ansicol ANSI colour value (0-based) - * @ret colour Raw colour - */ -static uint32_t fbcon_ansi_colour ( struct fbcon *fbcon, - unsigned int ansicol ) { - uint32_t rgb; - - /* Treat ansicol as 3-bit BGR with intensity 0xaa */ - rgb = ( ( ( ansicol & ( 1 << 0 ) ) ? 0xaa0000 : 0 ) | - ( ( ansicol & ( 1 << 1 ) ) ? 0x00aa00 : 0 ) | - ( ( ansicol & ( 1 << 2 ) ) ? 0x0000aa : 0 ) ); - - return fbcon_colour ( fbcon, rgb ); -} - -/** - * Set default foreground colour - * - * @v fbcon Frame buffer console - */ -static void fbcon_set_default_foreground ( struct fbcon *fbcon ) { - - /* Default to non-bold white foreground */ - fbcon->foreground = fbcon_ansi_colour ( fbcon, 0x7 ); - fbcon->bold = 0; -} - -/** - * Set default background colour - * - * @v fbcon Frame buffer console - */ -static void fbcon_set_default_background ( struct fbcon *fbcon ) { - - /* Default to transparent background */ - fbcon->background = FBCON_TRANSPARENT; -} - -/** - * Clear rows of characters - * - * @v fbcon Frame buffer console - * @v ypos Starting Y position - */ -static void fbcon_clear ( struct fbcon *fbcon, unsigned int ypos ) { - struct fbcon_text_cell cell = { - .foreground = fbcon->foreground, - .background = fbcon->background, - .character = ' ', - }; - size_t offset; - unsigned int xpos; - - /* Clear stored character array */ - for ( ; ypos < fbcon->character.height ; ypos++ ) { - offset = ( ypos * fbcon->character.width * sizeof ( cell ) ); - for ( xpos = 0 ; xpos < fbcon->character.width ; xpos++ ) { - copy_to_user ( fbcon->text.start, offset, &cell, - sizeof ( cell ) ); - offset += sizeof ( cell ); - } - } -} - -/** - * Store character at specified position - * - * @v fbcon Frame buffer console - * @v cell Text cell - * @v xpos X position - * @v ypos Y position - */ -static void fbcon_store ( struct fbcon *fbcon, struct fbcon_text_cell *cell, - unsigned int xpos, unsigned int ypos ) { - size_t offset; - - /* Store cell */ - offset = ( ( ( ypos * fbcon->character.width ) + xpos ) * - sizeof ( *cell ) ); - copy_to_user ( fbcon->text.start, offset, cell, sizeof ( *cell ) ); -} - -/** - * Draw character at specified position - * - * @v fbcon Frame buffer console - * @v cell Text cell - * @v xpos X position - * @v ypos Y position - */ -static void fbcon_draw ( struct fbcon *fbcon, struct fbcon_text_cell *cell, - unsigned int xpos, unsigned int ypos ) { - struct fbcon_font_glyph glyph; - size_t offset; - size_t pixel_len; - size_t skip_len; - unsigned int row; - unsigned int column; - uint8_t bitmask; - int transparent; - void *src; - - /* Get font character */ - copy_from_user ( &glyph, fbcon->font->start, - ( cell->character * sizeof ( glyph ) ), - sizeof ( glyph ) ); - - /* Calculate pixel geometry */ - offset = ( fbcon->indent + - ( ypos * fbcon->character.stride ) + - ( xpos * fbcon->character.len ) ); - pixel_len = fbcon->pixel->len; - skip_len = ( fbcon->pixel->stride - fbcon->character.len ); - - /* Check for transparent background colour */ - transparent = ( cell->background == FBCON_TRANSPARENT ); - - /* Draw character rows */ - for ( row = 0 ; row < FBCON_CHAR_HEIGHT ; row++ ) { - - /* Draw background picture, if applicable */ - if ( transparent ) { - if ( fbcon->picture.start ) { - memcpy_user ( fbcon->start, offset, - fbcon->picture.start, offset, - fbcon->character.len ); - } else { - memset_user ( fbcon->start, offset, 0, - fbcon->character.len ); - } - } - - /* Draw character row */ - for ( column = FBCON_CHAR_WIDTH, bitmask = glyph.bitmask[row] ; - column ; column--, bitmask <<= 1, offset += pixel_len ) { - if ( bitmask & 0x80 ) { - src = &cell->foreground; - } else if ( ! transparent ) { - src = &cell->background; - } else { - continue; - } - copy_to_user ( fbcon->start, offset, src, pixel_len ); - } - - /* Move to next row */ - offset += skip_len; - } -} - -/** - * Redraw all characters - * - * @v fbcon Frame buffer console - */ -static void fbcon_redraw ( struct fbcon *fbcon ) { - struct fbcon_text_cell cell; - size_t offset = 0; - unsigned int xpos; - unsigned int ypos; - - /* Redraw characters */ - for ( ypos = 0 ; ypos < fbcon->character.height ; ypos++ ) { - for ( xpos = 0 ; xpos < fbcon->character.width ; xpos++ ) { - copy_from_user ( &cell, fbcon->text.start, offset, - sizeof ( cell ) ); - fbcon_draw ( fbcon, &cell, xpos, ypos ); - offset += sizeof ( cell ); - } - } -} - -/** - * Scroll screen - * - * @v fbcon Frame buffer console - */ -static void fbcon_scroll ( struct fbcon *fbcon ) { - size_t row_len; - - /* Sanity check */ - assert ( fbcon->ypos == fbcon->character.height ); - - /* Scroll up character array */ - row_len = ( fbcon->character.width * sizeof ( struct fbcon_text_cell )); - memmove_user ( fbcon->text.start, 0, fbcon->text.start, row_len, - ( row_len * ( fbcon->character.height - 1 ) ) ); - fbcon_clear ( fbcon, ( fbcon->character.height - 1 ) ); - - /* Update cursor position */ - fbcon->ypos--; - - /* Redraw all characters */ - fbcon_redraw ( fbcon ); -} - -/** - * Draw character at cursor position - * - * @v fbcon Frame buffer console - * @v show_cursor Show cursor - */ -static void fbcon_draw_cursor ( struct fbcon *fbcon, int show_cursor ) { - struct fbcon_text_cell cell; - size_t offset; - - offset = ( ( ( fbcon->ypos * fbcon->character.width ) + fbcon->xpos ) * - sizeof ( cell ) ); - copy_from_user ( &cell, fbcon->text.start, offset, sizeof ( cell ) ); - if ( show_cursor ) { - cell.background = fbcon->foreground; - cell.foreground = ( ( fbcon->background == FBCON_TRANSPARENT ) ? - 0 : fbcon->background ); - } - fbcon_draw ( fbcon, &cell, fbcon->xpos, fbcon->ypos ); -} - -/** - * Handle ANSI CUP (cursor position) - * - * @v ctx ANSI escape sequence context - * @v count Parameter count - * @v params[0] Row (1 is top) - * @v params[1] Column (1 is left) - */ -static void fbcon_handle_cup ( struct ansiesc_context *ctx, - unsigned int count __unused, int params[] ) { - struct fbcon *fbcon = container_of ( ctx, struct fbcon, ctx ); - int cx = ( params[1] - 1 ); - int cy = ( params[0] - 1 ); - - fbcon_draw_cursor ( fbcon, 0 ); - fbcon->xpos = cx; - if ( fbcon->xpos >= fbcon->character.width ) - fbcon->xpos = 0; - fbcon->ypos = cy; - if ( fbcon->ypos >= fbcon->character.height ) - fbcon->ypos = 0; - fbcon_draw_cursor ( fbcon, fbcon->show_cursor ); -} - -/** - * Handle ANSI ED (erase in page) - * - * @v ctx ANSI escape sequence context - * @v count Parameter count - * @v params[0] Region to erase - */ -static void fbcon_handle_ed ( struct ansiesc_context *ctx, - unsigned int count __unused, - int params[] __unused ) { - struct fbcon *fbcon = container_of ( ctx, struct fbcon, ctx ); - - /* We assume that we always clear the whole screen */ - assert ( params[0] == ANSIESC_ED_ALL ); - - /* Clear character array */ - fbcon_clear ( fbcon, 0 ); - - /* Redraw all characters */ - fbcon_redraw ( fbcon ); - - /* Reset cursor position */ - fbcon->xpos = 0; - fbcon->ypos = 0; - fbcon_draw_cursor ( fbcon, fbcon->show_cursor ); -} - -/** - * Handle ANSI SGR (set graphics rendition) - * - * @v ctx ANSI escape sequence context - * @v count Parameter count - * @v params List of graphic rendition aspects - */ -static void fbcon_handle_sgr ( struct ansiesc_context *ctx, unsigned int count, - int params[] ) { - struct fbcon *fbcon = container_of ( ctx, struct fbcon, ctx ); - uint32_t *custom = NULL; - uint32_t rgb; - unsigned int end; - unsigned int i; - int aspect; - - for ( i = 0 ; i < count ; i++ ) { - - /* Process aspect */ - aspect = params[i]; - if ( aspect == 0 ) { - fbcon_set_default_foreground ( fbcon ); - fbcon_set_default_background ( fbcon ); - } else if ( aspect == 1 ) { - fbcon->bold = fbcon_colour ( fbcon, FBCON_BOLD ); - } else if ( aspect == 22 ) { - fbcon->bold = 0; - } else if ( ( aspect >= 30 ) && ( aspect <= 37 ) ) { - fbcon->foreground = - fbcon_ansi_colour ( fbcon, aspect - 30 ); - } else if ( aspect == 38 ) { - custom = &fbcon->foreground; - } else if ( aspect == 39 ) { - fbcon_set_default_foreground ( fbcon ); - } else if ( ( aspect >= 40 ) && ( aspect <= 47 ) ) { - fbcon->background = - fbcon_ansi_colour ( fbcon, aspect - 40 ); - } else if ( aspect == 48 ) { - custom = &fbcon->background; - } else if ( aspect == 49 ) { - fbcon_set_default_background ( fbcon ); - } - - /* Process custom RGB colour, if applicable - * - * We support the xterm-compatible - * "<ESC>[38;2;<red>;<green>;<blue>m" and - * "<ESC>[48;2;<red>;<green>;<blue>m" sequences. - */ - if ( custom ) { - rgb = 0; - end = ( i + 5 ); - for ( ; ( i < count ) && ( i < end ) ; i++ ) - rgb = ( ( rgb << 8 ) | params[i] ); - *custom = fbcon_colour ( fbcon, rgb ); - custom = NULL; - } - } -} - -/** - * Handle ANSI DECTCEM set (show cursor) - * - * @v ctx ANSI escape sequence context - * @v count Parameter count - * @v params List of graphic rendition aspects - */ -static void fbcon_handle_dectcem_set ( struct ansiesc_context *ctx, - unsigned int count __unused, - int params[] __unused ) { - struct fbcon *fbcon = container_of ( ctx, struct fbcon, ctx ); - - fbcon->show_cursor = 1; - fbcon_draw_cursor ( fbcon, 1 ); -} - -/** - * Handle ANSI DECTCEM reset (hide cursor) - * - * @v ctx ANSI escape sequence context - * @v count Parameter count - * @v params List of graphic rendition aspects - */ -static void fbcon_handle_dectcem_reset ( struct ansiesc_context *ctx, - unsigned int count __unused, - int params[] __unused ) { - struct fbcon *fbcon = container_of ( ctx, struct fbcon, ctx ); - - fbcon->show_cursor = 0; - fbcon_draw_cursor ( fbcon, 0 ); -} - -/** ANSI escape sequence handlers */ -static struct ansiesc_handler fbcon_ansiesc_handlers[] = { - { ANSIESC_CUP, fbcon_handle_cup }, - { ANSIESC_ED, fbcon_handle_ed }, - { ANSIESC_SGR, fbcon_handle_sgr }, - { ANSIESC_DECTCEM_SET, fbcon_handle_dectcem_set }, - { ANSIESC_DECTCEM_RESET, fbcon_handle_dectcem_reset }, - { 0, NULL } -}; - -/** - * Print a character to current cursor position - * - * @v fbcon Frame buffer console - * @v character Character - */ -void fbcon_putchar ( struct fbcon *fbcon, int character ) { - struct fbcon_text_cell cell; - - /* Intercept ANSI escape sequences */ - character = ansiesc_process ( &fbcon->ctx, character ); - if ( character < 0 ) - return; - - /* Handle control characters */ - switch ( character ) { - case '\r': - fbcon_draw_cursor ( fbcon, 0 ); - fbcon->xpos = 0; - break; - case '\n': - fbcon_draw_cursor ( fbcon, 0 ); - fbcon->xpos = 0; - fbcon->ypos++; - break; - case '\b': - fbcon_draw_cursor ( fbcon, 0 ); - if ( fbcon->xpos ) { - fbcon->xpos--; - } else if ( fbcon->ypos ) { - fbcon->xpos = ( fbcon->character.width - 1 ); - fbcon->ypos--; - } - break; - default: - /* Print character at current cursor position */ - cell.foreground = ( fbcon->foreground | fbcon->bold ); - cell.background = fbcon->background; - cell.character = character; - fbcon_store ( fbcon, &cell, fbcon->xpos, fbcon->ypos ); - fbcon_draw ( fbcon, &cell, fbcon->xpos, fbcon->ypos ); - - /* Advance cursor */ - fbcon->xpos++; - if ( fbcon->xpos >= fbcon->character.width ) { - fbcon->xpos = 0; - fbcon->ypos++; - } - break; - } - - /* Scroll screen if necessary */ - if ( fbcon->ypos >= fbcon->character.height ) - fbcon_scroll ( fbcon ); - - /* Show cursor */ - fbcon_draw_cursor ( fbcon, fbcon->show_cursor ); -} - -/** - * Initialise background picture - * - * @v fbcon Frame buffer console - * @v pixbuf Background picture - * @ret rc Return status code - */ -static int fbcon_picture_init ( struct fbcon *fbcon, - struct pixel_buffer *pixbuf ) { - struct fbcon_geometry *pixel = fbcon->pixel; - struct fbcon_picture *picture = &fbcon->picture; - size_t len; - size_t pixbuf_stride; - size_t indent; - size_t pixbuf_indent; - size_t offset; - size_t pixbuf_offset; - uint32_t rgb; - uint32_t raw; - unsigned int x; - unsigned int y; - unsigned int width; - unsigned int height; - int xgap; - int ygap; - int rc; - - /* Allocate buffer */ - len = ( pixel->height * pixel->stride ); - picture->start = umalloc ( len ); - if ( ! picture->start ) { - DBGC ( fbcon, "FBCON %p could not allocate %zd bytes for " - "picture\n", fbcon, len ); - rc = -ENOMEM; - goto err_umalloc; - } - - /* Centre picture on console */ - pixbuf_stride = ( pixbuf->width * sizeof ( rgb ) ); - xgap = ( ( ( int ) ( pixel->width - pixbuf->width ) ) / 2 ); - ygap = ( ( ( int ) ( pixel->height - pixbuf->height ) ) / 2 ); - indent = ( ( ( ( ygap >= 0 ) ? ygap : 0 ) * pixel->stride ) + - ( ( ( xgap >= 0 ) ? xgap : 0 ) * pixel->len ) ); - pixbuf_indent = ( ( ( ( ygap < 0 ) ? -ygap : 0 ) * pixbuf_stride ) + - ( ( ( xgap < 0 ) ? -xgap : 0 ) * sizeof ( rgb ) ) ); - width = pixbuf->width; - if ( width > pixel->width ) - width = pixel->width; - height = pixbuf->height; - if ( height > pixel->height ) - height = pixel->height; - DBGC ( fbcon, "FBCON %p picture is pixel %dx%d at [%d,%d),[%d,%d)\n", - fbcon, width, height, xgap, ( xgap + pixbuf->width ), ygap, - ( ygap + pixbuf->height ) ); - - /* Convert to frame buffer raw format */ - memset_user ( picture->start, 0, 0, len ); - for ( y = 0 ; y < height ; y++ ) { - offset = ( indent + ( y * pixel->stride ) ); - pixbuf_offset = ( pixbuf_indent + ( y * pixbuf_stride ) ); - for ( x = 0 ; x < width ; x++ ) { - copy_from_user ( &rgb, pixbuf->data, pixbuf_offset, - sizeof ( rgb ) ); - raw = fbcon_colour ( fbcon, rgb ); - copy_to_user ( picture->start, offset, &raw, - pixel->len ); - offset += pixel->len; - pixbuf_offset += sizeof ( rgb ); - } - } - - return 0; - - ufree ( picture->start ); - err_umalloc: - return rc; -} - -/** - * Initialise frame buffer console - * - * @v fbcon Frame buffer console - * @v start Start address - * @v pixel Pixel geometry - * @v margin Minimum margin - * @v map Colour mapping - * @v font Font definition - * @v pixbuf Background picture (if any) - * @ret rc Return status code - */ -int fbcon_init ( struct fbcon *fbcon, userptr_t start, - struct fbcon_geometry *pixel, - struct fbcon_margin *margin, - struct fbcon_colour_map *map, - struct fbcon_font *font, - struct pixel_buffer *pixbuf ) { - int width; - int height; - unsigned int xgap; - unsigned int ygap; - int rc; - - /* Initialise data structure */ - memset ( fbcon, 0, sizeof ( *fbcon ) ); - fbcon->start = start; - fbcon->pixel = pixel; - assert ( pixel->len <= sizeof ( uint32_t ) ); - fbcon->map = map; - fbcon->font = font; - fbcon->ctx.handlers = fbcon_ansiesc_handlers; - fbcon->show_cursor = 1; - - /* Derive overall length */ - fbcon->len = ( pixel->height * pixel->stride ); - DBGC ( fbcon, "FBCON %p at [%08lx,%08lx)\n", fbcon, - user_to_phys ( fbcon->start, 0 ), - user_to_phys ( fbcon->start, fbcon->len ) ); - - /* Expand margin to accommodate whole characters */ - width = ( pixel->width - margin->left - margin->right ); - height = ( pixel->height - margin->top - margin->bottom ); - if ( ( width < FBCON_CHAR_WIDTH ) || ( height < FBCON_CHAR_HEIGHT ) ) { - DBGC ( fbcon, "FBCON %p has unusable character area " - "[%d-%d),[%d-%d)\n", fbcon, - margin->left, ( pixel->width - margin->right ), - margin->top, ( pixel->height - margin->bottom ) ); - rc = -EINVAL; - goto err_margin; - } - xgap = ( width % FBCON_CHAR_WIDTH ); - ygap = ( height % FBCON_CHAR_HEIGHT ); - fbcon->margin.left = ( margin->left + ( xgap / 2 ) ); - fbcon->margin.top = ( margin->top + ( ygap / 2 ) ); - fbcon->margin.right = ( margin->right + ( xgap - ( xgap / 2 ) ) ); - fbcon->margin.bottom = ( margin->bottom + ( ygap - ( ygap / 2 ) ) ); - fbcon->indent = ( ( fbcon->margin.top * pixel->stride ) + - ( fbcon->margin.left * pixel->len ) ); - - /* Derive character geometry from pixel geometry */ - fbcon->character.width = ( width / FBCON_CHAR_WIDTH ); - fbcon->character.height = ( height / FBCON_CHAR_HEIGHT ); - fbcon->character.len = ( pixel->len * FBCON_CHAR_WIDTH ); - fbcon->character.stride = ( pixel->stride * FBCON_CHAR_HEIGHT ); - DBGC ( fbcon, "FBCON %p is pixel %dx%d, char %dx%d at " - "[%d-%d),[%d-%d)\n", fbcon, fbcon->pixel->width, - fbcon->pixel->height, fbcon->character.width, - fbcon->character.height, fbcon->margin.left, - ( fbcon->pixel->width - fbcon->margin.right ), - fbcon->margin.top, - ( fbcon->pixel->height - fbcon->margin.bottom ) ); - - /* Set default colours */ - fbcon_set_default_foreground ( fbcon ); - fbcon_set_default_background ( fbcon ); - - /* Allocate and initialise stored character array */ - fbcon->text.start = umalloc ( fbcon->character.width * - fbcon->character.height * - sizeof ( struct fbcon_text_cell ) ); - if ( ! fbcon->text.start ) { - rc = -ENOMEM; - goto err_text; - } - fbcon_clear ( fbcon, 0 ); - - /* Set framebuffer to all black (including margins) */ - memset_user ( fbcon->start, 0, 0, fbcon->len ); - - /* Generate pixel buffer from background image, if applicable */ - if ( pixbuf && ( ( rc = fbcon_picture_init ( fbcon, pixbuf ) ) != 0 ) ) - goto err_picture; - - /* Draw background picture (including margins), if applicable */ - if ( fbcon->picture.start ) { - memcpy_user ( fbcon->start, 0, fbcon->picture.start, 0, - fbcon->len ); - } - - /* Update console width and height */ - console_set_size ( fbcon->character.width, fbcon->character.height ); - - return 0; - - ufree ( fbcon->picture.start ); - err_picture: - ufree ( fbcon->text.start ); - err_text: - err_margin: - return rc; -} - -/** - * Finalise frame buffer console - * - * @v fbcon Frame buffer console - */ -void fbcon_fini ( struct fbcon *fbcon ) { - - ufree ( fbcon->text.start ); - ufree ( fbcon->picture.start ); -} diff --git a/qemu/roms/ipxe/src/core/fnrec.c b/qemu/roms/ipxe/src/core/fnrec.c deleted file mode 100644 index 0430817f8..000000000 --- a/qemu/roms/ipxe/src/core/fnrec.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright (C) 2010 Stefan Hajnoczi <stefanha@gmail.com>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <ipxe/init.h> -#include <ipxe/uaccess.h> -#include <ipxe/io.h> - -/** @file - * - * Function trace recorder for crash and hang debugging - * - */ - -/** Constant for identifying valid trace buffers */ -#define FNREC_MAGIC ( 'f' << 24 | 'n' << 16 | 'r' << 8 | 'e' ) - -/** Number of trace buffer entries */ -#define FNREC_NUM_ENTRIES 4096 - -/** Trace buffer physical address - * - * Fixed at 17MB - */ -#define FNREC_PHYS_ADDRESS ( 17 * 1024 * 1024 ) - -/** A trace buffer entry */ -struct fnrec_entry { - /** Called function address */ - void *called_fn; - /** Call site */ - void *call_site; - /** Entry count */ - uint16_t entry_count; - /** Exit count */ - uint16_t exit_count; - /** Checksum */ - unsigned long checksum; -}; - -/** A trace buffer */ -struct fnrec_buffer { - /** Constant for identifying valid trace buffers */ - uint32_t magic; - - /** Next trace buffer entry to fill */ - unsigned int idx; - - /** Trace buffer */ - struct fnrec_entry data[FNREC_NUM_ENTRIES] - __attribute__ (( aligned ( 64 ) )); -}; - -/** The trace buffer */ -static struct fnrec_buffer *fnrec_buffer; - -/** - * Test whether the trace buffer is valid - * - * @ret is_valid Buffer is valid - */ -static int fnrec_is_valid ( void ) { - return ( fnrec_buffer && ( fnrec_buffer->magic == FNREC_MAGIC ) ); -} - -/** - * Invalidate the trace buffer - * - */ -static void fnrec_invalidate ( void ) { - fnrec_buffer->magic = 0; -} - -/** - * Reset the trace buffer and clear entries - */ -static void fnrec_reset ( void ) { - memset ( fnrec_buffer, 0, sizeof ( *fnrec_buffer ) ); - fnrec_buffer->magic = FNREC_MAGIC; -} - -/** - * Append an entry to the trace buffer - * - * @v called_fn Called function - * @v call_site Call site - * @ret entry Trace buffer entry - */ -static struct fnrec_entry * fnrec_append ( void *called_fn, void *call_site ) { - struct fnrec_entry *entry; - - /* Re-use existing entry, if possible */ - entry = &fnrec_buffer->data[ fnrec_buffer->idx ]; - if ( ( entry->called_fn == called_fn ) && - ( entry->call_site == call_site ) && - ( entry->entry_count >= entry->exit_count ) ) { - return entry; - } - - /* Otherwise, create a new entry */ - fnrec_buffer->idx = ( ( fnrec_buffer->idx + 1 ) % FNREC_NUM_ENTRIES ); - entry = &fnrec_buffer->data[ fnrec_buffer->idx ]; - entry->called_fn = called_fn; - entry->call_site = call_site; - entry->entry_count = 0; - entry->exit_count = 0; - entry->checksum = ( ( ( unsigned long ) called_fn ) ^ - ( ( unsigned long ) call_site ) ); - return entry; -} - -/** - * Print the contents of the trace buffer in chronological order - */ -static void fnrec_dump ( void ) { - struct fnrec_entry *entry; - unsigned int i; - unsigned int idx; - unsigned long checksum; - - printf ( "fnrec buffer dump:\n" ); - for ( i = 1 ; i <= FNREC_NUM_ENTRIES ; i++ ) { - idx = ( ( fnrec_buffer->idx + i ) % FNREC_NUM_ENTRIES ); - entry = &fnrec_buffer->data[idx]; - if ( ( entry->entry_count == 0 ) && ( entry->exit_count == 0 ) ) - continue; - checksum = ( ( ( ( unsigned long ) entry->called_fn ) ^ - ( ( unsigned long ) entry->call_site ) ) + - entry->entry_count + entry->exit_count ); - printf ( "%p %p %d %d", entry->called_fn, entry->call_site, - entry->entry_count, entry->exit_count ); - if ( entry->checksum != checksum ) { - printf ( " (checksum wrong at phys %08lx)", - virt_to_phys ( entry ) ); - } - printf ( "\n"); - } -} - -/** - * Function tracer initialisation function - */ -static void fnrec_init ( void ) { - - fnrec_buffer = phys_to_virt ( FNREC_PHYS_ADDRESS ); - if ( fnrec_is_valid() ) { - fnrec_invalidate(); - fnrec_dump(); - } else { - printf ( "fnrec buffer not found\n" ); - } - fnrec_reset(); -} - -struct init_fn fnrec_init_fn __init_fn ( INIT_NORMAL ) = { - .initialise = fnrec_init, -}; - -/* - * These functions are called from every C function. The compiler inserts - * these calls when -finstrument-functions is used. - */ -void __cyg_profile_func_enter ( void *called_fn, void *call_site ) { - struct fnrec_entry *entry; - - if ( fnrec_is_valid() ) { - entry = fnrec_append ( called_fn, call_site ); - entry->entry_count++; - entry->checksum++; - mb(); - } -} - -void __cyg_profile_func_exit ( void *called_fn, void *call_site ) { - struct fnrec_entry *entry; - - if ( fnrec_is_valid() ) { - entry = fnrec_append ( called_fn, call_site ); - entry->exit_count++; - entry->checksum++; - mb(); - } -} diff --git a/qemu/roms/ipxe/src/core/gdbserial.c b/qemu/roms/ipxe/src/core/gdbserial.c deleted file mode 100644 index 0983f2557..000000000 --- a/qemu/roms/ipxe/src/core/gdbserial.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (C) 2008 Stefan Hajnoczi <stefanha@gmail.com>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stddef.h> -#include <stdio.h> -#include <stdlib.h> -#include <assert.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 ); - 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 ) { - 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 ( 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 deleted file mode 100644 index 6ad52d1a6..000000000 --- a/qemu/roms/ipxe/src/core/gdbstub.c +++ /dev/null @@ -1,405 +0,0 @@ -/* - * Copyright (C) 2008 Stefan Hajnoczi <stefanha@gmail.com>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/** - * @file - * - * GDB stub for remote debugging - * - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <ctype.h> -#include <byteswap.h> -#include <ipxe/gdbstub.h> -#include "gdbmach.h" - -enum { - POSIX_EINVAL = 0x1c, /* used to report bad arguments to GDB */ - SIZEOF_PAYLOAD = 256, /* buffer size of GDB payload data */ -}; - -struct gdbstub { - struct gdb_transport *trans; - int exit_handler; /* leave interrupt handler */ - - int signo; - gdbreg_t *regs; - - void ( * parse ) ( struct gdbstub *stub, char ch ); - uint8_t cksum1; - - /* Buffer for payload data when parsing a packet. Once the - * packet has been received, this buffer is used to hold - * the reply payload. */ - char buf [ SIZEOF_PAYLOAD + 4 ]; /* $...PAYLOAD...#XX */ - char *payload; /* start of payload */ - int len; /* length of payload */ -}; - -/* Packet parser states */ -static void gdbstub_state_new ( struct gdbstub *stub, char ch ); -static void gdbstub_state_data ( struct gdbstub *stub, char ch ); -static void gdbstub_state_cksum1 ( struct gdbstub *stub, char ch ); -static void gdbstub_state_cksum2 ( struct gdbstub *stub, char ch ); -static void gdbstub_state_wait_ack ( struct gdbstub *stub, char ch ); - -static uint8_t gdbstub_from_hex_digit ( char ch ) { - return ( isdigit ( ch ) ? ch - '0' : tolower ( ch ) - 'a' + 0xa ) & 0xf; -} - -static uint8_t gdbstub_to_hex_digit ( uint8_t b ) { - b &= 0xf; - return ( b < 0xa ? '0' : 'a' - 0xa ) + b; -} - -/* - * To make reading/writing device memory atomic, we check for - * 2- or 4-byte aligned operations and handle them specially. - */ - -static void gdbstub_from_hex_buf ( char *dst, char *src, int lenbytes ) { - if ( lenbytes == 2 && ( ( unsigned long ) dst & 0x1 ) == 0 ) { - uint16_t i = gdbstub_from_hex_digit ( src [ 2 ] ) << 12 | - gdbstub_from_hex_digit ( src [ 3 ] ) << 8 | - gdbstub_from_hex_digit ( src [ 0 ] ) << 4 | - gdbstub_from_hex_digit ( src [ 1 ] ); - * ( uint16_t * ) dst = cpu_to_le16 ( i ); - } else if ( lenbytes == 4 && ( ( unsigned long ) dst & 0x3 ) == 0 ) { - uint32_t i = gdbstub_from_hex_digit ( src [ 6 ] ) << 28 | - gdbstub_from_hex_digit ( src [ 7 ] ) << 24 | - gdbstub_from_hex_digit ( src [ 4 ] ) << 20 | - gdbstub_from_hex_digit ( src [ 5 ] ) << 16 | - gdbstub_from_hex_digit ( src [ 2 ] ) << 12 | - gdbstub_from_hex_digit ( src [ 3 ] ) << 8 | - gdbstub_from_hex_digit ( src [ 0 ] ) << 4 | - gdbstub_from_hex_digit ( src [ 1 ] ); - * ( uint32_t * ) dst = cpu_to_le32 ( i ); - } else { - while ( lenbytes-- > 0 ) { - *dst++ = gdbstub_from_hex_digit ( src [ 0 ] ) << 4 | - gdbstub_from_hex_digit ( src [ 1 ] ); - src += 2; - } - } -} - -static void gdbstub_to_hex_buf ( char *dst, char *src, int lenbytes ) { - if ( lenbytes == 2 && ( ( unsigned long ) src & 0x1 ) == 0 ) { - uint16_t i = cpu_to_le16 ( * ( uint16_t * ) src ); - dst [ 0 ] = gdbstub_to_hex_digit ( i >> 4 ); - dst [ 1 ] = gdbstub_to_hex_digit ( i ); - dst [ 2 ] = gdbstub_to_hex_digit ( i >> 12 ); - dst [ 3 ] = gdbstub_to_hex_digit ( i >> 8 ); - } else if ( lenbytes == 4 && ( ( unsigned long ) src & 0x3 ) == 0 ) { - uint32_t i = cpu_to_le32 ( * ( uint32_t * ) src ); - dst [ 0 ] = gdbstub_to_hex_digit ( i >> 4 ); - dst [ 1 ] = gdbstub_to_hex_digit ( i ); - dst [ 2 ] = gdbstub_to_hex_digit ( i >> 12 ); - dst [ 3 ] = gdbstub_to_hex_digit ( i >> 8 ); - dst [ 4 ] = gdbstub_to_hex_digit ( i >> 20 ); - dst [ 5 ] = gdbstub_to_hex_digit ( i >> 16); - dst [ 6 ] = gdbstub_to_hex_digit ( i >> 28 ); - dst [ 7 ] = gdbstub_to_hex_digit ( i >> 24 ); - } else { - while ( lenbytes-- > 0 ) { - *dst++ = gdbstub_to_hex_digit ( *src >> 4 ); - *dst++ = gdbstub_to_hex_digit ( *src ); - src++; - } - } -} - -static uint8_t gdbstub_cksum ( char *data, int len ) { - uint8_t cksum = 0; - while ( len-- > 0 ) { - cksum += ( uint8_t ) *data++; - } - return cksum; -} - -static void gdbstub_tx_packet ( struct gdbstub *stub ) { - uint8_t cksum = gdbstub_cksum ( stub->payload, stub->len ); - stub->buf [ 0 ] = '$'; - stub->buf [ stub->len + 1 ] = '#'; - stub->buf [ stub->len + 2 ] = gdbstub_to_hex_digit ( cksum >> 4 ); - stub->buf [ stub->len + 3 ] = gdbstub_to_hex_digit ( cksum ); - stub->trans->send ( stub->buf, stub->len + 4 ); - stub->parse = gdbstub_state_wait_ack; -} - -/* GDB commands */ -static void gdbstub_send_ok ( struct gdbstub *stub ) { - stub->payload [ 0 ] = 'O'; - stub->payload [ 1 ] = 'K'; - stub->len = 2; - gdbstub_tx_packet ( stub ); -} - -static void gdbstub_send_num_packet ( struct gdbstub *stub, char reply, int num ) { - stub->payload [ 0 ] = reply; - stub->payload [ 1 ] = gdbstub_to_hex_digit ( ( char ) num >> 4 ); - stub->payload [ 2 ] = gdbstub_to_hex_digit ( ( char ) num ); - stub->len = 3; - gdbstub_tx_packet ( stub ); -} - -/* Format is arg1,arg2,...,argn:data where argn are hex integers and data is not an argument */ -static int gdbstub_get_packet_args ( struct gdbstub *stub, unsigned long *args, int nargs, int *stop_idx ) { - int i; - char ch = 0; - int argc = 0; - unsigned long val = 0; - for ( i = 1; i < stub->len && argc < nargs; i++ ) { - ch = stub->payload [ i ]; - if ( ch == ':' ) { - break; - } else if ( ch == ',' ) { - args [ argc++ ] = val; - val = 0; - } else { - val = ( val << 4 ) | gdbstub_from_hex_digit ( ch ); - } - } - if ( stop_idx ) { - *stop_idx = i; - } - if ( argc < nargs ) { - args [ argc++ ] = val; - } - return ( ( i == stub->len || ch == ':' ) && argc == nargs ); -} - -static void gdbstub_send_errno ( struct gdbstub *stub, int errno ) { - gdbstub_send_num_packet ( stub, 'E', errno ); -} - -static void gdbstub_report_signal ( struct gdbstub *stub ) { - gdbstub_send_num_packet ( stub, 'S', stub->signo ); -} - -static void gdbstub_read_regs ( struct gdbstub *stub ) { - gdbstub_to_hex_buf ( stub->payload, ( char * ) stub->regs, GDBMACH_SIZEOF_REGS ); - stub->len = GDBMACH_SIZEOF_REGS * 2; - gdbstub_tx_packet ( stub ); -} - -static void gdbstub_write_regs ( struct gdbstub *stub ) { - if ( stub->len != 1 + GDBMACH_SIZEOF_REGS * 2 ) { - gdbstub_send_errno ( stub, POSIX_EINVAL ); - return; - } - gdbstub_from_hex_buf ( ( char * ) stub->regs, &stub->payload [ 1 ], GDBMACH_SIZEOF_REGS ); - gdbstub_send_ok ( stub ); -} - -static void gdbstub_read_mem ( struct gdbstub *stub ) { - unsigned long args [ 2 ]; - if ( !gdbstub_get_packet_args ( stub, args, sizeof args / sizeof args [ 0 ], NULL ) ) { - gdbstub_send_errno ( stub, POSIX_EINVAL ); - return; - } - args [ 1 ] = ( args [ 1 ] < SIZEOF_PAYLOAD / 2 ) ? args [ 1 ] : SIZEOF_PAYLOAD / 2; - gdbstub_to_hex_buf ( stub->payload, ( char * ) args [ 0 ], args [ 1 ] ); - stub->len = args [ 1 ] * 2; - gdbstub_tx_packet ( stub ); -} - -static void gdbstub_write_mem ( struct gdbstub *stub ) { - unsigned long args [ 2 ]; - int colon; - if ( !gdbstub_get_packet_args ( stub, args, sizeof args / sizeof args [ 0 ], &colon ) || - colon >= stub->len || stub->payload [ colon ] != ':' || - ( stub->len - colon - 1 ) % 2 != 0 ) { - gdbstub_send_errno ( stub, POSIX_EINVAL ); - return; - } - gdbstub_from_hex_buf ( ( char * ) args [ 0 ], &stub->payload [ colon + 1 ], ( stub->len - colon - 1 ) / 2 ); - gdbstub_send_ok ( stub ); -} - -static void gdbstub_continue ( struct gdbstub *stub, int single_step ) { - gdbreg_t pc; - if ( stub->len > 1 && gdbstub_get_packet_args ( stub, &pc, 1, NULL ) ) { - gdbmach_set_pc ( stub->regs, pc ); - } - gdbmach_set_single_step ( stub->regs, single_step ); - stub->exit_handler = 1; - /* Reply will be sent when we hit the next breakpoint or interrupt */ -} - -static void gdbstub_breakpoint ( struct gdbstub *stub ) { - unsigned long args [ 3 ]; - int enable = stub->payload [ 0 ] == 'Z' ? 1 : 0; - if ( !gdbstub_get_packet_args ( stub, args, sizeof args / sizeof args [ 0 ], NULL ) ) { - gdbstub_send_errno ( stub, POSIX_EINVAL ); - return; - } - if ( gdbmach_set_breakpoint ( args [ 0 ], args [ 1 ], args [ 2 ], enable ) ) { - gdbstub_send_ok ( stub ); - } else { - /* Not supported */ - stub->len = 0; - gdbstub_tx_packet ( stub ); - } -} - -static void gdbstub_rx_packet ( struct gdbstub *stub ) { - switch ( stub->payload [ 0 ] ) { - case '?': - gdbstub_report_signal ( stub ); - break; - case 'g': - gdbstub_read_regs ( stub ); - break; - case 'G': - gdbstub_write_regs ( stub ); - break; - case 'm': - gdbstub_read_mem ( stub ); - break; - case 'M': - gdbstub_write_mem ( stub ); - break; - case 'c': /* Continue */ - case 'k': /* Kill */ - case 's': /* Step */ - case 'D': /* Detach */ - gdbstub_continue ( stub, stub->payload [ 0 ] == 's' ); - if ( stub->payload [ 0 ] == 'D' ) { - gdbstub_send_ok ( stub ); - } - break; - case 'Z': /* Insert breakpoint */ - case 'z': /* Remove breakpoint */ - gdbstub_breakpoint ( stub ); - break; - default: - stub->len = 0; - gdbstub_tx_packet ( stub ); - break; - } -} - -/* GDB packet parser */ -static void gdbstub_state_new ( struct gdbstub *stub, char ch ) { - if ( ch == '$' ) { - stub->len = 0; - stub->parse = gdbstub_state_data; - } -} - -static void gdbstub_state_data ( struct gdbstub *stub, char ch ) { - if ( ch == '#' ) { - stub->parse = gdbstub_state_cksum1; - } else if ( ch == '$' ) { - stub->len = 0; /* retry new packet */ - } else { - /* If the length exceeds our buffer, let the checksum fail */ - if ( stub->len < SIZEOF_PAYLOAD ) { - stub->payload [ stub->len++ ] = ch; - } - } -} - -static void gdbstub_state_cksum1 ( struct gdbstub *stub, char ch ) { - stub->cksum1 = gdbstub_from_hex_digit ( ch ) << 4; - stub->parse = gdbstub_state_cksum2; -} - -static void gdbstub_state_cksum2 ( struct gdbstub *stub, char ch ) { - uint8_t their_cksum; - uint8_t our_cksum; - - stub->parse = gdbstub_state_new; - their_cksum = stub->cksum1 + gdbstub_from_hex_digit ( ch ); - our_cksum = gdbstub_cksum ( stub->payload, stub->len ); - if ( their_cksum == our_cksum ) { - stub->trans->send ( "+", 1 ); - if ( stub->len > 0 ) { - gdbstub_rx_packet ( stub ); - } - } else { - stub->trans->send ( "-", 1 ); - } -} - -static void gdbstub_state_wait_ack ( struct gdbstub *stub, char ch ) { - if ( ch == '+' ) { - stub->parse = gdbstub_state_new; - } else { - /* This retransmit is very aggressive but necessary to keep - * in sync with GDB. */ - gdbstub_tx_packet ( stub ); - } -} - -static void gdbstub_parse ( struct gdbstub *stub, char ch ) { - stub->parse ( stub, ch ); -} - -static struct gdbstub stub = { - .parse = gdbstub_state_new -}; - -void gdbstub_handler ( int signo, gdbreg_t *regs ) { - char packet [ SIZEOF_PAYLOAD + 4 ]; - size_t len, i; - - /* A transport must be set up */ - if ( !stub.trans ) { - return; - } - - stub.signo = signo; - stub.regs = regs; - stub.exit_handler = 0; - gdbstub_report_signal ( &stub ); - while ( !stub.exit_handler && ( len = stub.trans->recv ( packet, sizeof ( packet ) ) ) > 0 ) { - for ( i = 0; i < len; i++ ) { - gdbstub_parse ( &stub, packet [ i ] ); - } - } -} - -struct gdb_transport *find_gdb_transport ( const char *name ) { - struct gdb_transport *trans; - - for_each_table_entry ( trans, GDB_TRANSPORTS ) { - if ( strcmp ( trans->name, name ) == 0 ) { - return trans; - } - } - return NULL; -} - -void gdbstub_start ( struct gdb_transport *trans ) { - stub.trans = trans; - stub.payload = &stub.buf [ 1 ]; - gdbmach_init(); - gdbmach_breakpoint(); -} diff --git a/qemu/roms/ipxe/src/core/gdbudp.c b/qemu/roms/ipxe/src/core/gdbudp.c deleted file mode 100644 index e4613d137..000000000 --- a/qemu/roms/ipxe/src/core/gdbudp.c +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright (C) 2008 Stefan Hajnoczi <stefanha@gmail.com>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdio.h> -#include <string.h> -#include <byteswap.h> -#include <ipxe/iobuf.h> -#include <ipxe/in.h> -#include <ipxe/if_arp.h> -#include <ipxe/if_ether.h> -#include <ipxe/ip.h> -#include <ipxe/udp.h> -#include <ipxe/netdevice.h> -#include <ipxe/nap.h> -#include <ipxe/gdbstub.h> -#include <ipxe/gdbudp.h> - -/** @file - * - * GDB over UDP transport - * - */ - -enum { - DEFAULT_PORT = 43770, /* UDP listen port */ -}; - -struct gdb_transport udp_gdb_transport __gdb_transport; - -static struct net_device *netdev; -static uint8_t dest_eth[ETH_ALEN]; -static struct sockaddr_in dest_addr; -static struct sockaddr_in source_addr; - -static void gdbudp_ensure_netdev_open ( struct net_device *netdev ) { - /* The device may have been closed between breakpoints */ - assert ( netdev ); - netdev_open ( netdev ); - - /* Strictly speaking, we may need to close the device when leaving the interrupt handler */ -} - -static size_t gdbudp_recv ( char *buf, size_t len ) { - struct io_buffer *iob; - struct ethhdr *ethhdr; - struct arphdr *arphdr; - struct iphdr *iphdr; - struct udp_header *udphdr; - size_t payload_len; - - gdbudp_ensure_netdev_open ( netdev ); - - for ( ; ; ) { - netdev_poll ( netdev ); - while ( ( iob = netdev_rx_dequeue ( netdev ) ) != NULL ) { - /* Ethernet header */ - if ( iob_len ( iob ) < sizeof ( *ethhdr ) ) { - goto bad_packet; - } - ethhdr = iob->data; - iob_pull ( iob, sizeof ( *ethhdr ) ); - - /* Handle ARP requests so the client can find our MAC */ - if ( ethhdr->h_protocol == htons ( ETH_P_ARP ) ) { - arphdr = iob->data; - if ( iob_len ( iob ) < sizeof ( *arphdr ) + 2 * ( ETH_ALEN + sizeof ( struct in_addr ) ) || - arphdr->ar_hrd != htons ( ARPHRD_ETHER ) || - arphdr->ar_pro != htons ( ETH_P_IP ) || - arphdr->ar_hln != ETH_ALEN || - arphdr->ar_pln != sizeof ( struct in_addr ) || - arphdr->ar_op != htons ( ARPOP_REQUEST ) || - * ( uint32_t * ) arp_target_pa ( arphdr ) != source_addr.sin_addr.s_addr ) { - goto bad_packet; - } - - /* Generate an ARP reply */ - arphdr->ar_op = htons ( ARPOP_REPLY ); - memswap ( arp_sender_pa ( arphdr ), arp_target_pa ( arphdr ), sizeof ( struct in_addr ) ); - memcpy ( arp_target_ha ( arphdr ), arp_sender_ha ( arphdr ), ETH_ALEN ); - memcpy ( arp_sender_ha ( arphdr ), netdev->ll_addr, ETH_ALEN ); - - /* Fix up ethernet header */ - ethhdr = iob_push ( iob, sizeof ( *ethhdr ) ); - memcpy ( ethhdr->h_dest, ethhdr->h_source, ETH_ALEN ); - memcpy ( ethhdr->h_source, netdev->ll_addr, ETH_ALEN ); - - netdev_tx ( netdev, iob ); - continue; /* no need to free iob */ - } - - if ( ethhdr->h_protocol != htons ( ETH_P_IP ) ) { - goto bad_packet; - } - - /* IP header */ - if ( iob_len ( iob ) < sizeof ( *iphdr ) ) { - goto bad_packet; - } - iphdr = iob->data; - iob_pull ( iob, sizeof ( *iphdr ) ); - if ( iphdr->protocol != IP_UDP || iphdr->dest.s_addr != source_addr.sin_addr.s_addr ) { - goto bad_packet; - } - - /* UDP header */ - if ( iob_len ( iob ) < sizeof ( *udphdr ) ) { - goto bad_packet; - } - udphdr = iob->data; - if ( udphdr->dest != source_addr.sin_port ) { - goto bad_packet; - } - - /* Learn the remote connection details */ - memcpy ( dest_eth, ethhdr->h_source, ETH_ALEN ); - dest_addr.sin_addr.s_addr = iphdr->src.s_addr; - dest_addr.sin_port = udphdr->src; - - /* Payload */ - payload_len = ntohs ( udphdr->len ); - if ( payload_len < sizeof ( *udphdr ) || payload_len > iob_len ( iob ) ) { - goto bad_packet; - } - payload_len -= sizeof ( *udphdr ); - iob_pull ( iob, sizeof ( *udphdr ) ); - if ( payload_len > len ) { - goto bad_packet; - } - memcpy ( buf, iob->data, payload_len ); - - free_iob ( iob ); - return payload_len; - -bad_packet: - free_iob ( iob ); - } - cpu_nap(); - } -} - -static void gdbudp_send ( const char *buf, size_t len ) { - struct io_buffer *iob; - struct ethhdr *ethhdr; - struct iphdr *iphdr; - struct udp_header *udphdr; - - /* Check that we are connected */ - if ( dest_addr.sin_port == 0 ) { - return; - } - - gdbudp_ensure_netdev_open ( netdev ); - - iob = alloc_iob ( sizeof ( *ethhdr ) + sizeof ( *iphdr ) + sizeof ( *udphdr ) + len ); - if ( !iob ) { - return; - } - - /* Payload */ - iob_reserve ( iob, sizeof ( *ethhdr ) + sizeof ( *iphdr ) + sizeof ( *udphdr ) ); - memcpy ( iob_put ( iob, len ), buf, len ); - - /* UDP header */ - udphdr = iob_push ( iob, sizeof ( *udphdr ) ); - udphdr->src = source_addr.sin_port; - udphdr->dest = dest_addr.sin_port; - udphdr->len = htons ( iob_len ( iob ) ); - udphdr->chksum = 0; /* optional and we are not using it */ - - /* IP header */ - iphdr = iob_push ( iob, sizeof ( *iphdr ) ); - memset ( iphdr, 0, sizeof ( *iphdr ) ); - iphdr->verhdrlen = ( IP_VER | ( sizeof ( *iphdr ) / 4 ) ); - iphdr->service = IP_TOS; - iphdr->len = htons ( iob_len ( iob ) ); - iphdr->ttl = IP_TTL; - iphdr->protocol = IP_UDP; - iphdr->dest.s_addr = dest_addr.sin_addr.s_addr; - iphdr->src.s_addr = source_addr.sin_addr.s_addr; - iphdr->chksum = tcpip_chksum ( iphdr, sizeof ( *iphdr ) ); - - /* Ethernet header */ - ethhdr = iob_push ( iob, sizeof ( *ethhdr ) ); - memcpy ( ethhdr->h_dest, dest_eth, ETH_ALEN ); - memcpy ( ethhdr->h_source, netdev->ll_addr, ETH_ALEN ); - ethhdr->h_protocol = htons ( ETH_P_IP ); - - netdev_tx ( netdev, iob ); -} - -struct gdb_transport *gdbudp_configure ( const char *name, struct sockaddr_in *addr ) { - struct settings *settings; - - /* Release old network device */ - netdev_put ( netdev ); - - netdev = find_netdev ( name ); - if ( !netdev ) { - return NULL; - } - - /* Hold network device */ - netdev_get ( netdev ); - - /* Source UDP port */ - source_addr.sin_port = ( addr && addr->sin_port ) ? addr->sin_port : htons ( DEFAULT_PORT ); - - /* Source IP address */ - if ( addr && addr->sin_addr.s_addr ) { - source_addr.sin_addr.s_addr = addr->sin_addr.s_addr; - } else { - settings = netdev_settings ( netdev ); - fetch_ipv4_setting ( settings, &ip_setting, &source_addr.sin_addr ); - if ( source_addr.sin_addr.s_addr == 0 ) { - netdev_put ( netdev ); - netdev = NULL; - return NULL; - } - } - - return &udp_gdb_transport; -} - -static int gdbudp_init ( int argc, char **argv ) { - if ( argc != 1 ) { - printf ( "udp: missing <interface> argument\n" ); - return 1; - } - - if ( !gdbudp_configure ( argv[0], NULL ) ) { - printf ( "%s: device does not exist or has no IP address\n", argv[0] ); - return 1; - } - return 0; -} - -struct gdb_transport udp_gdb_transport __gdb_transport = { - .name = "udp", - .init = gdbudp_init, - .send = gdbudp_send, - .recv = gdbudp_recv, -}; diff --git a/qemu/roms/ipxe/src/core/getkey.c b/qemu/roms/ipxe/src/core/getkey.c deleted file mode 100644 index 0f0f8b7c3..000000000 --- a/qemu/roms/ipxe/src/core/getkey.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <ctype.h> -#include <ipxe/console.h> -#include <ipxe/process.h> -#include <ipxe/keys.h> -#include <ipxe/timer.h> -#include <ipxe/nap.h> - -/** @file - * - * Special key interpretation - * - */ - -#define GETKEY_TIMEOUT ( TICKS_PER_SEC / 4 ) - -/** - * Read character from console if available within timeout period - * - * @v timeout Timeout period, in ticks (0=indefinite) - * @ret character Character read from console - */ -static int getchar_timeout ( unsigned long timeout ) { - unsigned long start = currticks(); - - while ( ( timeout == 0 ) || ( ( currticks() - start ) < timeout ) ) { - step(); - if ( iskey() ) - return getchar(); - cpu_nap(); - } - - return -1; -} - -/** - * Get single keypress - * - * @v timeout Timeout period, in ticks (0=indefinite) - * @ret key Key pressed - * - * The returned key will be an ASCII value or a KEY_XXX special - * constant. This function differs from getchar() in that getchar() - * will return "special" keys (e.g. cursor keys) as a series of - * characters forming an ANSI escape sequence. - */ -int getkey ( unsigned long timeout ) { - int character; - unsigned int n = 0; - - character = getchar_timeout ( timeout ); - if ( character != ESC ) - return character; - - while ( ( character = getchar_timeout ( GETKEY_TIMEOUT ) ) >= 0 ) { - if ( character == '[' ) - continue; - if ( isdigit ( character ) ) { - n = ( ( n * 10 ) + ( character - '0' ) ); - continue; - } - if ( character >= 0x40 ) - return KEY_ANSI ( n, character ); - } - - return ESC; -} diff --git a/qemu/roms/ipxe/src/core/getopt.c b/qemu/roms/ipxe/src/core/getopt.c deleted file mode 100644 index e6c3948d1..000000000 --- a/qemu/roms/ipxe/src/core/getopt.c +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdint.h> -#include <string.h> -#include <stdio.h> -#include <getopt.h> - -/** @file - * - * Parse command-line options - * - */ - -/** - * Option argument - * - * This will point to the argument for the most recently returned - * option, if applicable. - */ -char *optarg; - -/** - * Current option index - * - * This is an index into the argv[] array. When getopt() returns -1, - * @c optind is the index to the first element that is not an option. - */ -int optind; - -/** - * Current option character index - * - * This is an index into the current element of argv[]. - */ -int nextchar; - -/** - * Unrecognised option - * - * When an unrecognised option is encountered, the actual option - * character is stored in @c optopt. - */ -int optopt; - -/** - * Get option argument from argv[] array - * - * @v argc Argument count - * @v argv Argument list - * @ret argument Option argument, or NULL - * - * Grab the next element of argv[], if it exists and is not an option. - */ -static const char * get_argv_argument ( int argc, char * const argv[] ) { - char *arg; - - /* Don't overrun argv[] */ - if ( optind >= argc ) - return NULL; - arg = argv[optind]; - - /* If next argv element is an option, then it's not usable as - * an argument. - */ - if ( *arg == '-' ) - return NULL; - - /** Consume this argv element, and return it */ - optind++; - return arg; -} - -/** - * Match long option - * - * @v argc Argument count - * @v argv Argument list - * @v opttext Option text within current argv[] element - * @v longopt Long option specification - * @ret option Option to return from getopt() - * @ret matched Found a match for this long option - */ -static int match_long_option ( int argc, char * const argv[], - const char *opttext, - const struct option *longopt, int *option ) { - size_t optlen; - const char *argument = NULL; - - /* Compare option name */ - optlen = strlen ( longopt->name ); - if ( strncmp ( opttext, longopt->name, optlen ) != 0 ) - return 0; - - /* Check for inline argument */ - if ( opttext[optlen] == '=' ) { - argument = &opttext[ optlen + 1 ]; - } else if ( opttext[optlen] ) { - /* Long option with trailing garbage - no match */ - return 0; - } - - /* Consume this argv element */ - optind++; - - /* If we want an argument but don't have one yet, try to grab - * the next argv element - */ - if ( ( longopt->has_arg != no_argument ) && ( ! argument ) ) - argument = get_argv_argument ( argc, argv ); - - /* If we need an argument but don't have one, sulk */ - if ( ( longopt->has_arg == required_argument ) && ( ! argument ) ) { - printf ( "Option \"%s\" requires an argument\n", - longopt->name ); - *option = ':'; - return 1; - } - - /* If we have an argument where we shouldn't have one, sulk */ - if ( ( longopt->has_arg == no_argument ) && argument ) { - printf ( "Option \"%s\" takes no argument\n", longopt->name ); - *option = ':'; - return 1; - } - - /* Store values and return success */ - optarg = ( char * ) argument; - if ( longopt->flag ) { - *(longopt->flag) = longopt->val; - *option = 0; - } else { - *option = longopt->val; - } - return 1; -} - -/** - * Match short option - * - * @v argc Argument count - * @v argv Argument list - * @v opttext Option text within current argv[] element - * @v shortopt Option character from option specification - * @ret option Option to return from getopt() - * @ret matched Found a match for this short option - */ -static int match_short_option ( int argc, char * const argv[], - const char *opttext, int shortopt, - enum getopt_argument_requirement has_arg, - int *option ) { - const char *argument = NULL; - - /* Compare option character */ - if ( *opttext != shortopt ) - return 0; - - /* Consume option character */ - opttext++; - nextchar++; - if ( *opttext ) { - if ( has_arg != no_argument ) { - /* Consume remainder of element as inline argument */ - argument = opttext; - optind++; - nextchar = 0; - } - } else { - /* Reached end of argv element */ - optind++; - nextchar = 0; - } - - /* If we want an argument but don't have one yet, try to grab - * the next argv element - */ - if ( ( has_arg != no_argument ) && ( ! argument ) ) - argument = get_argv_argument ( argc, argv ); - - /* If we need an argument but don't have one, sulk */ - if ( ( has_arg == required_argument ) && ( ! argument ) ) { - printf ( "Option \"%c\" requires an argument\n", shortopt ); - *option = ':'; - return 1; - } - - /* Store values and return success */ - optarg = ( char * ) argument; - *option = shortopt; - return 1; -} - -/** - * Parse command-line options - * - * @v argc Argument count - * @v argv Argument list - * @v optstring Option specification string - * @v longopts Long option specification table - * @ret longindex Index of long option (or NULL) - * @ret option Option found, or -1 for no more options - * - * Note that the caller must arrange for reset_getopt() to be called - * before each set of calls to getopt_long(). In Etherboot, this is - * done automatically by execv(). - */ -int getopt_long ( int argc, char * const argv[], const char *optstring, - const struct option *longopts, int *longindex ) { - const char *opttext = argv[optind]; - const struct option *longopt; - int shortopt; - enum getopt_argument_requirement has_arg; - int option; - - /* Check for end of argv array */ - if ( optind >= argc ) - return -1; - - /* Check for end of options */ - if ( *(opttext++) != '-' ) - return -1; - - /* Check for long options */ - if ( *(opttext++) == '-' ) { - /* "--" indicates end of options */ - if ( *opttext == '\0' ) { - optind++; - return -1; - } - for ( longopt = longopts ; longopt->name ; longopt++ ) { - if ( ! match_long_option ( argc, argv, opttext, - longopt, &option ) ) - continue; - if ( longindex ) - *longindex = ( longopt - longopts ); - return option; - } - optopt = '?'; - printf ( "Unrecognised option \"--%s\"\n", opttext ); - return '?'; - } - - /* Check for short options */ - if ( nextchar < 1 ) - nextchar = 1; - opttext = ( argv[optind] + nextchar ); - while ( ( shortopt = *(optstring++) ) ) { - has_arg = no_argument; - while ( *optstring == ':' ) { - has_arg++; - optstring++; - } - if ( match_short_option ( argc, argv, opttext, shortopt, - has_arg, &option ) ) { - return option; - } - } - optopt = *opttext; - printf ( "Unrecognised option \"-%c\"\n", optopt ); - return '?'; -} diff --git a/qemu/roms/ipxe/src/core/hw.c b/qemu/roms/ipxe/src/core/hw.c deleted file mode 100644 index 91736a652..000000000 --- a/qemu/roms/ipxe/src/core/hw.c +++ /dev/null @@ -1,69 +0,0 @@ -#include <stddef.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <ipxe/refcnt.h> -#include <ipxe/process.h> -#include <ipxe/xfer.h> -#include <ipxe/open.h> - -/** @file - * - * "Hello World" data source - * - */ - -struct hw { - struct refcnt refcnt; - struct interface xfer; - struct process process; -}; - -static const char hw_msg[] = "Hello world!\n"; - -static void hw_finished ( struct hw *hw, int rc ) { - intf_shutdown ( &hw->xfer, rc ); - process_del ( &hw->process ); -} - -static void hw_step ( struct hw *hw ) { - int rc; - - if ( xfer_window ( &hw->xfer ) ) { - rc = xfer_deliver_raw ( &hw->xfer, hw_msg, sizeof ( hw_msg ) ); - hw_finished ( hw, rc ); - } -} - -static struct interface_operation hw_xfer_operations[] = { - INTF_OP ( xfer_window_changed, struct hw *, hw_step ), - INTF_OP ( intf_close, struct hw *, hw_finished ), -}; - -static struct interface_descriptor hw_xfer_desc = - INTF_DESC ( struct hw, xfer, hw_xfer_operations ); - -static struct process_descriptor hw_process_desc = - PROC_DESC_ONCE ( struct hw, process, hw_step ); - -static int hw_open ( struct interface *xfer, struct uri *uri __unused ) { - struct hw *hw; - - /* Allocate and initialise structure */ - hw = zalloc ( sizeof ( *hw ) ); - if ( ! hw ) - return -ENOMEM; - ref_init ( &hw->refcnt, NULL ); - intf_init ( &hw->xfer, &hw_xfer_desc, &hw->refcnt ); - process_init ( &hw->process, &hw_process_desc, &hw->refcnt ); - - /* Attach parent interface, mortalise self, and return */ - intf_plug_plug ( &hw->xfer, xfer ); - ref_put ( &hw->refcnt ); - return 0; -} - -struct uri_opener hw_uri_opener __uri_opener = { - .scheme = "hw", - .open = hw_open, -}; diff --git a/qemu/roms/ipxe/src/core/i82365.c b/qemu/roms/ipxe/src/core/i82365.c deleted file mode 100644 index c26639e0b..000000000 --- a/qemu/roms/ipxe/src/core/i82365.c +++ /dev/null @@ -1,656 +0,0 @@ -#ifdef CONFIG_PCMCIA - -/* - * i82365.c - * Support for i82365 and similar ISA-to-PCMCIA bridges - * - * Taken from Linux kernel sources, distributed under GPL2 - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The initial developer of the original code is David A. Hinds - * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds - * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. - * - * Ported by: Anselm Martin Hoffmeister, Stockholm Projekt Computer-Service, Sankt Augustin/Bonn, GERMANY - */ - -/* - * - * - * ****************************** - * PLEASE DO NOT YET WORK ON THIS - * ****************************** - * - * I'm still fixing it up on every end, so we most probably would interfere - * at some point. If there's anything obvious or better, not-so-obvious, - * please contact me by e-mail: anselm (AT) hoffmeister (DOT) be *THANKS* - */ -#include "../include/pcmcia.h" -#include "../include/pcmcia-opts.h" -#include "../include/i82365.h" - -#ifndef CONFIG_ISA -#error PCMCIA_I82365 only works with ISA defined - set CONFIG_ISA -#endif - -typedef enum pcic_id { - IS_I82365A, IS_I82365B, IS_I82365DF, - IS_IBM, IS_RF5Cx96, IS_VLSI, IS_VG468, IS_VG469, - IS_PD6710, IS_PD672X, IS_VT83C469, -} pcic_id; - -/* Flags for classifying groups of controllers */ -#define IS_VADEM 0x0001 -#define IS_CIRRUS 0x0002 -#define IS_TI 0x0004 -#define IS_O2MICRO 0x0008 -#define IS_VIA 0x0010 -#define IS_TOPIC 0x0020 -#define IS_RICOH 0x0040 -#define IS_UNKNOWN 0x0400 -#define IS_VG_PWR 0x0800 -#define IS_DF_PWR 0x1000 -#define IS_PCI 0x2000 -#define IS_ALIVE 0x8000 - -typedef struct pcic_t { - char *name; - u_short flags; -} pcic_t; - -static pcic_t pcic[] = { - { "Intel i82365sl A step", 0 }, - { "Intel i82365sl B step", 0 }, - { "Intel i82365sl DF", IS_DF_PWR }, - { "IBM Clone", 0 }, - { "Ricoh RF5C296/396", 0 }, - { "VLSI 82C146", 0 }, - { "Vadem VG-468", IS_VADEM }, - { "Vadem VG-469", IS_VADEM|IS_VG_PWR }, - { "Cirrus PD6710", IS_CIRRUS }, - { "Cirrus PD672x", IS_CIRRUS }, - { "VIA VT83C469", IS_CIRRUS|IS_VIA }, -}; - -typedef struct cirrus_state_t { - u_char misc1, misc2; - u_char timer[6]; -} cirrus_state_t; - -typedef struct vg46x_state_t { - u_char ctl, ema; -} vg46x_state_t; - -typedef struct socket_info_t { - u_short type, flags; - socket_cap_t cap; - ioaddr_t ioaddr; - u_short psock; - u_char cs_irq, intr; - void (*handler)(void *info, u_int events); - void *info; - union { - cirrus_state_t cirrus; - vg46x_state_t vg46x; - } state; -} socket_info_t; - -//static socket_info_t socket[8]; - -int i365_base = 0x3e0; // Default in Linux kernel -int cycle_time = 120; // External clock time in ns, 120ns =~ 8.33 MHz -int mydriverid = 0; - -void phex ( unsigned char c ); -/*static int to_cycles(int ns) -{ - return ns/cycle_time; -} -*/ -/*static int to_ns(int cycles) -{ - return cycle_time*cycles; -} -*/ - -static u_char i365_get(u_short sock, u_short reg) -{ - //unsigned long flags; - //spin_lock_irqsave(&bus_lock,flags); - { - ioaddr_t port = pccsock[sock].ioaddr; - u_char val; - reg = I365_REG(pccsock[sock].internalid, reg); - outb(reg, port); val = inb(port+1); - //spin_unlock_irqrestore(&bus_lock,flags); - return val; - } -} - -static void i365_set(u_short sock, u_short reg, u_char data) -{ - //unsigned long flags; - //spin_lock_irqsave(&bus_lock,flags); - { - ioaddr_t port = pccsock[sock].ioaddr; - u_char val = I365_REG(pccsock[sock].internalid, reg); - outb(val, port); outb(data, port+1); - //spin_unlock_irqrestore(&bus_lock,flags); - } -} - -void add_socket_i365(u_short port, int psock, int type) { - pccsock[pccsocks].ioaddr = port; - pccsock[pccsocks].internalid = psock; - pccsock[pccsocks].type = type; - pccsock[pccsocks].flags = pcic[type].flags; - pccsock[pccsocks].drivernum = mydriverid; - pccsock[pccsocks].configoffset = -1; - // Find out if a card in inside that socket - pccsock[pccsocks].status = (( 12 == (i365_get(pccsocks,I365_STATUS)&12) ) ? HASCARD : EMPTY ); - // *TODO* check if that's all - if ( 0 == (psock & 1) ) { - printf ( "Found a PCMCIA controller (i82365) at io %x, type '%s'\n", port, pcic[type].name ); - // pccsock[pccsocks].status == HASCARD? "holds card":"empty" ); - } - pccsocks++; - return; -} - -void i365_bset(u_short sock, u_short reg, u_char mask) { - u_char d = i365_get(sock, reg); - d |= mask; - i365_set(sock, reg, d); -} - -void i365_bclr(u_short sock, u_short reg, u_char mask) { - u_char d = i365_get(sock, reg); - d &= ~mask; - i365_set(sock, reg, d); -} - - -/*static void i365_bflip(u_short sock, u_short reg, u_char mask, int b) -{ - u_char d = i365_get(sock, reg); - if (b) - d |= mask; - else - d &= ~mask; - i365_set(sock, reg, d); -} -*/ - -/* -static u_short i365_get_pair(u_short sock, u_short reg) -{ - u_short a, b; - a = i365_get(sock, reg); - b = i365_get(sock, reg+1); - return (a + (b<<8)); -} -*/ - -/* -static void i365_set_pair(u_short sock, u_short reg, u_short data) -{ - i365_set(sock, reg, data & 0xff); - i365_set(sock, reg+1, data >> 8); -} -*/ -int identify_i365 ( u_short port, u_short sock ) { - u_char val; - int type = -1; - /* Use the next free entry in the socket table */ - pccsock[pccsocks].ioaddr = port; - pccsock[pccsocks].internalid = sock; - // *TODO* wakeup a sleepy cirrus controller? - - if ((val = i365_get(pccsocks, I365_IDENT)) & 0x70) - return -1; - switch (val) { - case 0x82: - type = IS_I82365A; break; - case 0x83: - type = IS_I82365B; break; - case 0x84: - type = IS_I82365DF; break; - case 0x88: case 0x89: case 0x8a: - type = IS_IBM; break; - } - /* Check for Vadem VG-468 chips */ - outb(0x0e, port); - outb(0x37, port); - i365_bset(pccsocks, VG468_MISC, VG468_MISC_VADEMREV); - val = i365_get(pccsocks, I365_IDENT); - if (val & I365_IDENT_VADEM) { - i365_bclr(pccsocks, VG468_MISC, VG468_MISC_VADEMREV); - type = ((val & 7) >= 4) ? IS_VG469 : IS_VG468; - } - - /* Check for Ricoh chips */ - val = i365_get(pccsocks, RF5C_CHIP_ID); - if ((val == RF5C_CHIP_RF5C296) || (val == RF5C_CHIP_RF5C396)) type = IS_RF5Cx96; - - /* Check for Cirrus CL-PD67xx chips */ - i365_set(pccsocks, PD67_CHIP_INFO, 0); - val = i365_get(pccsocks, PD67_CHIP_INFO); - if ((val & PD67_INFO_CHIP_ID) == PD67_INFO_CHIP_ID) { - val = i365_get(pccsocks, PD67_CHIP_INFO); - if ((val & PD67_INFO_CHIP_ID) == 0) { - type = (val & PD67_INFO_SLOTS) ? IS_PD672X : IS_PD6710; - i365_set(pccsocks, PD67_EXT_INDEX, 0xe5); - if (i365_get(pccsocks, PD67_EXT_INDEX) != 0xe5) type = IS_VT83C469; - } - } - return type; -} - -int init_i82365(void) { - int i, j, sock, k, ns, id; - //unsigned int ui,uj; - //unsigned char * upc; - ioaddr_t port; - int i82365s = 0; - // Change from kernel: No irq init, no check_region, no isapnp support - // No ignore socket, no extra sockets to check (so it's easier here :-/) - // Probably we don't need any of them; in case YOU do, SHOUT AT ME! - id = identify_i365(i365_base, 0); - if ((id == IS_I82365DF) && (identify_i365(i365_base, 1) != id)) { - for (i = 0; i < 4; i++) { - port = i365_base + ((i & 1) << 2) + ((i & 2) << 1); - sock = (i & 1) << 1; - if (identify_i365(port, sock) == IS_I82365DF) { - add_socket_i365(port, sock, IS_VLSI); - } - } - } else { - for (i = 0; i < 4; i += 2) { - port = i365_base + 2*(i>>2); - sock = (i & 3); - id = identify_i365(port, sock); - if (id < 0) continue; - - for (j = ns = 0; j < 2; j++) { - /* Does the socket exist? */ - if (identify_i365(port, sock+j) < 0) continue; - /* Check for bad socket decode */ - for (k = 0; k <= i82365s; k++) - i365_set(k, I365_MEM(0)+I365_W_OFF, k); - for (k = 0; k <= i82365s; k++) - if (i365_get(k, I365_MEM(0)+I365_W_OFF) != k) - break; - if (k <= i82365s) break; - add_socket_i365(port, sock+j, id); ns++; - } - } - } - return 0; - - - - - - - -/* printf ( "Selecting config 1: io 0x300 @byte 87*2.." ); - upc[(2*87)] = 2; - i365_bclr(1, I365_ADDRWIN, 1 ); - i365_set(1,I365_INTCTL, 0x65 ); //no-reset, memory-card - i365_set(1, I365_IO(0)+0, 0x20 ); - i365_set(1, I365_IO(0)+1, 0x03 ); - i365_set(1, I365_IO(0)+2, 0x3f ); - i365_set(1, I365_IO(0)+3, 0x03 ); - i365_set(1, 0x3a, 0x05 ); - i365_set(1, 0x3b, 0x05 ); - i365_set(1, 0x3c, 0x05 ); - i365_set(1, 0x3d, 0x05 ); - i365_set(1, 0x3e, 0x05 ); - i365_set(1, 0x3f, 0x05 ); - i365_set(1, 0x07, 0x0a ); - i365_set(1, I365_ADDRWIN, 0x40 ); // 0x40 - printf ( "!\n" ); getchar(); - printf ( "\n" ); - return 0; */ -} - -void phex ( unsigned char c ) { - unsigned char a = 0, b = 0; - b = ( c & 0xf ); - if ( b > 9 ) b += ('a'-'9'-1); - b += '0'; - a = ( c & 0xf0 ) >> 4; - if ( a > 9 ) a += ('a'-'9'-1); - a += '0'; - printf ( "%c%c ", a, b ); - return; -} - -int deinit_i82365(void) { - printf("Deinitializing i82365\n" ); - return 0; -} - -/*static int i365_get_status(u_short sock, u_int *value) -{ - u_int status; - - status = i365_get(sock, I365_STATUS); - *value = ((status & I365_CS_DETECT) == I365_CS_DETECT) - ? SS_DETECT : 0; - - if (i365_get(sock, I365_INTCTL) & I365_PC_IOCARD) - *value |= (status & I365_CS_STSCHG) ? 0 : SS_STSCHG; - else { - *value |= (status & I365_CS_BVD1) ? 0 : SS_BATDEAD; - *value |= (status & I365_CS_BVD2) ? 0 : SS_BATWARN; - } - *value |= (status & I365_CS_WRPROT) ? SS_WRPROT : 0; - *value |= (status & I365_CS_READY) ? SS_READY : 0; - *value |= (status & I365_CS_POWERON) ? SS_POWERON : 0; - -#ifdef CONFIG_ISA - if (pccsock[sock].type == IS_VG469) { - status = i365_get(sock, VG469_VSENSE); - if (pccsock[sock].internalid & 1) { - *value |= (status & VG469_VSENSE_B_VS1) ? 0 : SS_3VCARD; - *value |= (status & VG469_VSENSE_B_VS2) ? 0 : SS_XVCARD; - } else { - *value |= (status & VG469_VSENSE_A_VS1) ? 0 : SS_3VCARD; - *value |= (status & VG469_VSENSE_A_VS2) ? 0 : SS_XVCARD; - } - } -#endif - - printf("i82365: GetStatus(%d) = %#4.4x\n", sock, *value); - return 0; -} //i365_get_status -*/ - -/*static int i365_set_socket(u_short sock, socket_state_t *state) -{ - socket_info_t *t = &socket[sock]; - u_char reg; - - printf("i82365: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, " - "io_irq %d, csc_mask %#2.2x)\n", sock, state->flags, - state->Vcc, state->Vpp, state->io_irq, state->csc_mask); -printf ("\nERROR:UNIMPLEMENTED\n" ); -return 0; - // First set global controller options - // set_bridge_state(sock); *TODO* check: need this here? - - // IO card, RESET flag, IO interrupt - reg = t->intr; - if (state->io_irq != t->cap.pci_irq) reg |= state->io_irq; - reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET; - reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0; - i365_set(sock, I365_INTCTL, reg); - - reg = I365_PWR_NORESET; - if (state->flags & SS_PWR_AUTO) reg |= I365_PWR_AUTO; - if (state->flags & SS_OUTPUT_ENA) reg |= I365_PWR_OUT; - - if (t->flags & IS_CIRRUS) { - if (state->Vpp != 0) { - if (state->Vpp == 120) - reg |= I365_VPP1_12V; - else if (state->Vpp == state->Vcc) - reg |= I365_VPP1_5V; - else return -EINVAL; - } - if (state->Vcc != 0) { - reg |= I365_VCC_5V; - if (state->Vcc == 33) - i365_bset(sock, PD67_MISC_CTL_1, PD67_MC1_VCC_3V); - else if (state->Vcc == 50) - i365_bclr(sock, PD67_MISC_CTL_1, PD67_MC1_VCC_3V); - else return -EINVAL; - } - } else if (t->flags & IS_VG_PWR) { - if (state->Vpp != 0) { - if (state->Vpp == 120) - reg |= I365_VPP1_12V; - else if (state->Vpp == state->Vcc) - reg |= I365_VPP1_5V; - else return -EINVAL; - } - if (state->Vcc != 0) { - reg |= I365_VCC_5V; - if (state->Vcc == 33) - i365_bset(sock, VG469_VSELECT, VG469_VSEL_VCC); - else if (state->Vcc == 50) - i365_bclr(sock, VG469_VSELECT, VG469_VSEL_VCC); - else return -EINVAL; - } - } else if (t->flags & IS_DF_PWR) { - switch (state->Vcc) { - case 0: break; - case 33: reg |= I365_VCC_3V; break; - case 50: reg |= I365_VCC_5V; break; - default: return -EINVAL; - } - switch (state->Vpp) { - case 0: break; - case 50: reg |= I365_VPP1_5V; break; - case 120: reg |= I365_VPP1_12V; break; - default: return -EINVAL; - } - } else { - switch (state->Vcc) { - case 0: break; - case 50: reg |= I365_VCC_5V; break; - default: return -EINVAL; - } - switch (state->Vpp) { - case 0: break; - case 50: reg |= I365_VPP1_5V | I365_VPP2_5V; break; - case 120: reg |= I365_VPP1_12V | I365_VPP2_12V; break; - default: return -EINVAL; - } - } - - if (reg != i365_get(sock, I365_POWER)) - i365_set(sock, I365_POWER, reg); - - // Chipset-specific functions - if (t->flags & IS_CIRRUS) { - // Speaker control - i365_bflip(sock, PD67_MISC_CTL_1, PD67_MC1_SPKR_ENA, - state->flags & SS_SPKR_ENA); - } - - // Card status change interrupt mask - reg = t->cs_irq << 4; - if (state->csc_mask & SS_DETECT) reg |= I365_CSC_DETECT; - if (state->flags & SS_IOCARD) { - if (state->csc_mask & SS_STSCHG) reg |= I365_CSC_STSCHG; - } else { - if (state->csc_mask & SS_BATDEAD) reg |= I365_CSC_BVD1; - if (state->csc_mask & SS_BATWARN) reg |= I365_CSC_BVD2; - if (state->csc_mask & SS_READY) reg |= I365_CSC_READY; - } - i365_set(sock, I365_CSCINT, reg); - i365_get(sock, I365_CSC); - - return 0; -} // i365_set_socket -*/ - -/*static int i365_get_io_map(u_short sock, struct pccard_io_map *io) -{ - u_char map, ioctl, addr; - printf ( "GETIOMAP unimplemented\n" ); return 0; - map = io->map; - if (map > 1) return -EINVAL; - io->start = i365_get_pair(sock, I365_IO(map)+I365_W_START); - io->stop = i365_get_pair(sock, I365_IO(map)+I365_W_STOP); - ioctl = i365_get(sock, I365_IOCTL); - addr = i365_get(sock, I365_ADDRWIN); - io->speed = to_ns(ioctl & I365_IOCTL_WAIT(map)) ? 1 : 0; - io->flags = (addr & I365_ENA_IO(map)) ? MAP_ACTIVE : 0; - io->flags |= (ioctl & I365_IOCTL_0WS(map)) ? MAP_0WS : 0; - io->flags |= (ioctl & I365_IOCTL_16BIT(map)) ? MAP_16BIT : 0; - io->flags |= (ioctl & I365_IOCTL_IOCS16(map)) ? MAP_AUTOSZ : 0; - printf("i82365: GetIOMap(%d, %d) = %#2.2x, %d ns, " - "%#4.4x-%#4.4x\n", sock, map, io->flags, io->speed, - io->start, io->stop); - return 0; -} // i365_get_io_map -*/ - -/*====================================================================*/ - -/*static int i365_set_io_map(u_short sock, struct pccard_io_map *io) -{ - u_char map, ioctl; - - printf("i82365: SetIOMap(%d, %d, %#2.2x, %d ns, " - "%#4.4x-%#4.4x)\n", sock, io->map, io->flags, - io->speed, io->start, io->stop); -printf ( "UNIMPLEMENTED\n" ); - return 0; - map = io->map; - //if ((map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) || - if ((map > 1) || - (io->stop < io->start)) return -EINVAL; - // Turn off the window before changing anything - if (i365_get(sock, I365_ADDRWIN) & I365_ENA_IO(map)) - i365_bclr(sock, I365_ADDRWIN, I365_ENA_IO(map)); - i365_set_pair(sock, I365_IO(map)+I365_W_START, io->start); - i365_set_pair(sock, I365_IO(map)+I365_W_STOP, io->stop); - ioctl = i365_get(sock, I365_IOCTL) & ~I365_IOCTL_MASK(map); - if (io->speed) ioctl |= I365_IOCTL_WAIT(map); - if (io->flags & MAP_0WS) ioctl |= I365_IOCTL_0WS(map); - if (io->flags & MAP_16BIT) ioctl |= I365_IOCTL_16BIT(map); - if (io->flags & MAP_AUTOSZ) ioctl |= I365_IOCTL_IOCS16(map); - i365_set(sock, I365_IOCTL, ioctl); - // Turn on the window if necessary - if (io->flags & MAP_ACTIVE) - i365_bset(sock, I365_ADDRWIN, I365_ENA_IO(map)); - return 0; -} // i365_set_io_map -*/ - -/* -static int i365_set_mem_map(u_short sock, struct pccard_mem_map *mem) -{ - u_short base, i; - u_char map; - - printf("i82365: SetMemMap(%d, %d, %#2.2x, %d ns, %#5.5lx-%#5.5" - "lx, %#5.5x)\n", sock, mem->map, mem->flags, mem->speed, - mem->sys_start, mem->sys_stop, mem->card_start); - -printf ( "UNIMPLEMENTED\n" ); - return 0; - map = mem->map; - if ((map > 4) || (mem->card_start > 0x3ffffff) || - (mem->sys_start > mem->sys_stop) || (mem->speed > 1000)) - return -EINVAL; - if (!(socket[sock].flags & IS_PCI) && - ((mem->sys_start > 0xffffff) || (mem->sys_stop > 0xffffff))) - return -EINVAL; - - // Turn off the window before changing anything - if (i365_get(sock, I365_ADDRWIN) & I365_ENA_MEM(map)) - i365_bclr(sock, I365_ADDRWIN, I365_ENA_MEM(map)); - - base = I365_MEM(map); - i = (mem->sys_start >> 12) & 0x0fff; - if (mem->flags & MAP_16BIT) i |= I365_MEM_16BIT; - if (mem->flags & MAP_0WS) i |= I365_MEM_0WS; - i365_set_pair(sock, base+I365_W_START, i); - - i = (mem->sys_stop >> 12) & 0x0fff; - switch (to_cycles(mem->speed)) { - case 0: break; - case 1: i |= I365_MEM_WS0; break; - case 2: i |= I365_MEM_WS1; break; - default: i |= I365_MEM_WS1 | I365_MEM_WS0; break; - } - i365_set_pair(sock, base+I365_W_STOP, i); - - i = ((mem->card_start - mem->sys_start) >> 12) & 0x3fff; - if (mem->flags & MAP_WRPROT) i |= I365_MEM_WRPROT; - if (mem->flags & MAP_ATTRIB) i |= I365_MEM_REG; - i365_set_pair(sock, base+I365_W_OFF, i); - - // Turn on the window if necessary - if (mem->flags & MAP_ACTIVE) - i365_bset(sock, I365_ADDRWIN, I365_ENA_MEM(map)); - return 0; -} // i365_set_mem_map -*/ - - -int i82365_interfacer ( interface_func_t func, int sockno, int par1, int par2, void* par3 ) { - //int i, j, k; - //u_int ui; - u_char *upc; - struct pcc_config_t * pccc; - switch ( func ) { - case INIT: - mydriverid = par1; - return init_i82365(); - case SHUTDOWN: - i365_set(sockno, I365_ADDRWIN, i365_get(sockno, I365_ADDRWIN) & 0x20 ); - i365_set(sockno, I365_INTCTL, 0x05 ); - sleepticks(2); - i365_set(sockno,I365_INTCTL, 0x45 ); //no-reset, memory-card - break; - case MAPATTRMEM: - i365_set(sockno,I365_POWER, 0xb1 ); - i365_set(sockno, I365_INTCTL, 0x05 ); - sleepticks(2); - i365_set(sockno,I365_INTCTL, 0x45 ); //no-reset, memory-card - i365_set(sockno, I365_ADDRWIN, i365_get(sockno, I365_ADDRWIN) & 0x20 ); - //i365_bclr(sockno, I365_ADDRWIN, 1 ); - i365_set(sockno, I365_MEM(0)+0, ( par1 >> 12 )& 0xff ); //start - i365_set(sockno, I365_MEM(0)+1, ( par1 >> 20 ) & 0x0f ); - i365_set(sockno, I365_MEM(0)+2, ((par1 + par2 - 1 ) >> 12 ) & 0xff ); //end - i365_set(sockno, I365_MEM(0)+3, (( par1 + par2 - 1 ) >> 20 ) & 0x0f ); - i365_set(sockno, I365_MEM(0)+4, ((0x4000000 - par1) >> 12) & 0xff ); //offset low - i365_set(sockno, I365_MEM(0)+5, 0x40 | (((0x40000000 - par1) >> 12) & 0x3f)); - i365_bset(sockno, I365_ADDRWIN, 1 ); - if ( ! ( 1 & i365_get ( sockno, I365_ADDRWIN ) ) ) return 1; - break; - case UNMAPATTRMEM: - i365_set(sockno, I365_ADDRWIN, i365_get(sockno, I365_ADDRWIN) & 0x20 ); - i365_set(sockno,I365_INTCTL, 0x45 ); //no-reset, memory-card - break; - case SELECTCONFIG: // Params: par1: config number; par3 config pointer pointer - if ( 0 > pccsock[sockno].configoffset ) return 1; - if ( NULL == (pccc = par3 ) ) return 2; - // write config number to - upc = ioremap ( MAP_ATTRMEM_TO, MAP_ATTRMEM_LEN ); - if ( pccsock[sockno].configoffset > MAP_ATTRMEM_LEN ) return 3; - if ( ( par1 & 0x7fffffc0 ) ) return 4; - if ( pccc->index != par1 ) return 5; - upc[pccsock[sockno].configoffset] = ( upc[pccsock[sockno].configoffset] & 0xc0 ) | ( par1 & 0x3f ); - i365_set(sockno, I365_IOCTL, (i365_get(sockno, I365_IOCTL) & 0xfe) | 0x20 ); // 16bit autosize - i365_set(sockno, I365_IO(0)+0, pccc->iowin & 0xff); - i365_set(sockno, I365_IO(0)+1, (pccc->iowin >> 8) & 0xff); - i365_set(sockno, I365_IO(0)+2, (pccc->iowin+pccc->iolen - 1) & 0xff); - i365_set(sockno, I365_IO(0)+3, ((pccc->iowin+pccc->iolen- 1) >> 8) & 0xff); - // Disable mem mapping - i365_bclr(sockno, I365_ADDRWIN, 1); - i365_set(sockno, I365_INTCTL, 0x65); - i365_bset(sockno, I365_ADDRWIN,0x40); - break; - default: - return -1; // ERROR: Unknown function called - } - return 0; -} - -// get_mem_map[1320] -// cirrus_get_state/set/opts... -// vg46x_get_state/... -// get_bridge_state/... - -#endif /* CONFIG_PCMCIA */ diff --git a/qemu/roms/ipxe/src/core/image.c b/qemu/roms/ipxe/src/core/image.c deleted file mode 100644 index 529e3d72c..000000000 --- a/qemu/roms/ipxe/src/core/image.c +++ /dev/null @@ -1,489 +0,0 @@ -/* - * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stddef.h> -#include <string.h> -#include <stdlib.h> -#include <stdio.h> -#include <errno.h> -#include <assert.h> -#include <libgen.h> -#include <syslog.h> -#include <ipxe/list.h> -#include <ipxe/umalloc.h> -#include <ipxe/uri.h> -#include <ipxe/image.h> - -/** @file - * - * Executable images - * - */ - -/* Disambiguate the various error causes */ -#define EACCES_UNTRUSTED \ - __einfo_error ( EINFO_EACCES_UNTRUSTED ) -#define EINFO_EACCES_UNTRUSTED \ - __einfo_uniqify ( EINFO_EACCES, 0x01, "Untrusted image" ) -#define EACCES_PERMANENT \ - __einfo_error ( EINFO_EACCES_PERMANENT ) -#define EINFO_EACCES_PERMANENT \ - __einfo_uniqify ( EINFO_EACCES, 0x02, "Trust requirement is permanent" ) - -/** List of registered images */ -struct list_head images = LIST_HEAD_INIT ( images ); - -/** Currently-executing image */ -struct image *current_image; - -/** Current image trust requirement */ -static int require_trusted_images = 0; - -/** Prevent changes to image trust requirement */ -static int require_trusted_images_permanent = 0; - -/** - * Free executable image - * - * @v refcnt Reference counter - */ -static void free_image ( struct refcnt *refcnt ) { - struct image *image = container_of ( refcnt, struct image, refcnt ); - - DBGC ( image, "IMAGE %s freed\n", image->name ); - free ( image->name ); - free ( image->cmdline ); - uri_put ( image->uri ); - ufree ( image->data ); - image_put ( image->replacement ); - free ( image ); -} - -/** - * Allocate executable image - * - * @v uri URI, or NULL - * @ret image Executable image - */ -struct image * alloc_image ( struct uri *uri ) { - const char *name; - struct image *image; - int rc; - - /* Allocate image */ - image = zalloc ( sizeof ( *image ) ); - if ( ! image ) - goto err_alloc; - - /* Initialise image */ - ref_init ( &image->refcnt, free_image ); - if ( uri ) { - image->uri = uri_get ( uri ); - if ( uri->path ) { - name = basename ( ( char * ) uri->path ); - if ( ( rc = image_set_name ( image, name ) ) != 0 ) - goto err_set_name; - } - } - - return image; - - err_set_name: - image_put ( image ); - err_alloc: - return NULL; -} - -/** - * Set image name - * - * @v image Image - * @v name New image name - * @ret rc Return status code - */ -int image_set_name ( struct image *image, const char *name ) { - char *name_copy; - - /* Duplicate name */ - name_copy = strdup ( name ); - if ( ! name_copy ) - return -ENOMEM; - - /* Replace existing name */ - free ( image->name ); - image->name = name_copy; - - return 0; -} - -/** - * Set image command line - * - * @v image Image - * @v cmdline New image command line, or NULL - * @ret rc Return status code - */ -int image_set_cmdline ( struct image *image, const char *cmdline ) { - - free ( image->cmdline ); - image->cmdline = NULL; - if ( cmdline ) { - image->cmdline = strdup ( cmdline ); - if ( ! image->cmdline ) - return -ENOMEM; - } - return 0; -} - -/** - * 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 - * @ret rc Return status code - */ -int register_image ( struct image *image ) { - static unsigned int imgindex = 0; - char name[8]; /* "imgXXXX" */ - int rc; - - /* Create image name if it doesn't already have one */ - if ( ! image->name ) { - snprintf ( name, sizeof ( name ), "img%d", imgindex++ ); - if ( ( rc = image_set_name ( image, name ) ) != 0 ) - return rc; - } - - /* Avoid ending up with multiple "selected" images on - * re-registration - */ - if ( image_find_selected() ) - image->flags &= ~IMAGE_SELECTED; - - /* Add to image list */ - image_get ( image ); - image->flags |= IMAGE_REGISTERED; - list_add_tail ( &image->list, &images ); - DBGC ( image, "IMAGE %s at [%lx,%lx) registered\n", - 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; -} - -/** - * Unregister executable image - * - * @v image Executable image - */ -void unregister_image ( struct image *image ) { - - /* Do nothing unless image is registered */ - if ( ! ( image->flags & IMAGE_REGISTERED ) ) - return; - - DBGC ( image, "IMAGE %s unregistered\n", image->name ); - list_del ( &image->list ); - image->flags &= ~IMAGE_REGISTERED; - image_put ( image ); -} - -/** - * Find image by name - * - * @v name Image name - * @ret image Executable image, or NULL - */ -struct image * find_image ( const char *name ) { - struct image *image; - - list_for_each_entry ( image, &images, list ) { - if ( strcmp ( image->name, name ) == 0 ) - return image; - } - - return NULL; -} - -/** - * Execute image - * - * @v image Executable image - * @ret rc Return status code - * - * The image must already be registered. Note that executing an image - * may cause it to unregister itself. The caller must therefore - * assume that the image pointer becomes invalid. - */ -int image_exec ( struct image *image ) { - struct image *saved_current_image; - struct image *replacement = NULL; - struct uri *old_cwuri; - int rc; - - /* Sanity check */ - assert ( image->flags & IMAGE_REGISTERED ); - - /* Switch current working directory to be that of the image itself */ - old_cwuri = uri_get ( cwuri ); - churi ( image->uri ); - - /* Preserve record of any currently-running image */ - saved_current_image = current_image; - - /* Take out a temporary reference to the image. This allows - * the image to unregister itself if necessary, without - * automatically freeing itself. - */ - current_image = image_get ( image ); - - /* 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 ) ) { - DBGC ( image, "IMAGE %s is not trusted\n", image->name ); - rc = -EACCES_UNTRUSTED; - goto err; - } - - /* Record boot attempt */ - syslog ( LOG_NOTICE, "Executing \"%s\"\n", image->name ); - - /* Try executing the image */ - if ( ( rc = image->type->exec ( image ) ) != 0 ) { - DBGC ( image, "IMAGE %s could not execute: %s\n", - image->name, strerror ( rc ) ); - /* Do not return yet; we still have clean-up to do */ - } - - /* Record result of boot attempt */ - if ( rc == 0 ) { - syslog ( LOG_NOTICE, "Execution of \"%s\" completed\n", - image->name ); - } else { - syslog ( LOG_ERR, "Execution of \"%s\" failed: %s\n", - image->name, strerror ( rc ) ); - } - - /* Pick up replacement image before we drop the original - * image's temporary reference. The replacement image must - * already be registered, so we don't need to hold a temporary - * reference (which would complicate the tail-recursion). - */ - replacement = image->replacement; - if ( replacement ) - assert ( replacement->flags & IMAGE_REGISTERED ); - - err: - /* Unregister image if applicable */ - if ( image->flags & IMAGE_AUTO_UNREGISTER ) - unregister_image ( image ); - - /* Debug message for tail-recursion. Placed here because the - * image_put() may end up freeing the image. - */ - if ( replacement ) { - DBGC ( image, "IMAGE %s replacing self with IMAGE %s\n", - image->name, replacement->name ); - } - - /* Drop temporary reference to the original image */ - image_put ( image ); - - /* Restore previous currently-running image */ - current_image = saved_current_image; - - /* Reset current working directory */ - churi ( old_cwuri ); - uri_put ( old_cwuri ); - - /* Tail-recurse into replacement image, if one exists */ - if ( replacement ) - return image_exec ( replacement ); - - return rc; -} - -/** - * Set replacement image - * - * @v replacement Replacement image - * @ret rc Return status code - * - * The replacement image must already be registered, and must remain - * registered until the currently-executing image returns. - */ -int image_replace ( struct image *replacement ) { - struct image *image = current_image; - int rc; - - /* Sanity check */ - assert ( replacement->flags & IMAGE_REGISTERED ); - - /* Fail unless there is a currently-executing image */ - if ( ! image ) { - rc = -ENOTTY; - DBGC ( replacement, "IMAGE %s cannot replace non-existent " - "image: %s\n", replacement->name, strerror ( rc ) ); - return rc; - } - - /* Check that the replacement image can be executed */ - if ( ! ( replacement->type && replacement->type->exec ) ) - return -ENOEXEC; - - /* Clear any existing replacement */ - image_put ( image->replacement ); - - /* Set replacement */ - image->replacement = image_get ( replacement ); - DBGC ( image, "IMAGE %s will replace self with IMAGE %s\n", - image->name, replacement->name ); - - return 0; -} - -/** - * Select image for execution - * - * @v image Executable image - * @ret rc Return status code - */ -int image_select ( struct image *image ) { - struct image *tmp; - - /* Unselect all other images */ - for_each_image ( tmp ) - tmp->flags &= ~IMAGE_SELECTED; - - /* Check that this image can be executed */ - if ( ! ( image->type && image->type->exec ) ) - return -ENOEXEC; - - /* Mark image as selected */ - image->flags |= IMAGE_SELECTED; - - return 0; -} - -/** - * Find selected image - * - * @ret image Executable image, or NULL - */ -struct image * image_find_selected ( void ) { - struct image *image; - - for_each_image ( image ) { - if ( image->flags & IMAGE_SELECTED ) - return image; - } - return NULL; -} - -/** - * Change image trust requirement - * - * @v require_trusted Require trusted images - * @v permanent Make trust requirement permanent - * @ret rc Return status code - */ -int image_set_trust ( int require_trusted, int permanent ) { - - /* Update trust requirement, if permitted to do so */ - if ( ! require_trusted_images_permanent ) { - require_trusted_images = require_trusted; - require_trusted_images_permanent = permanent; - } - - /* Fail if we attempted to change the trust requirement but - * were not permitted to do so. - */ - if ( require_trusted_images != require_trusted ) - return -EACCES_PERMANENT; - - return 0; -} - -/** - * Create pixel buffer from image - * - * @v image Image - * @v pixbuf Pixel buffer to fill in - * @ret rc Return status code - */ -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 ( ! ( image->type && image->type->pixbuf ) ) - return -ENOTSUP; - - /* Try creating pixel buffer */ - if ( ( rc = image->type->pixbuf ( image, pixbuf ) ) != 0 ) { - DBGC ( image, "IMAGE %s could not create pixel buffer: %s\n", - image->name, strerror ( rc ) ); - return rc; - } - - return 0; -} diff --git a/qemu/roms/ipxe/src/core/init.c b/qemu/roms/ipxe/src/core/init.c deleted file mode 100644 index d91e44669..000000000 --- a/qemu/roms/ipxe/src/core/init.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <ipxe/device.h> -#include <ipxe/console.h> -#include <ipxe/init.h> - -/** @file - * - * Initialisation, startup and shutdown routines - * - */ - -/** "startup() has been called" flag */ -static int started = 0; - -/** - * Initialise iPXE - * - * This function performs the one-time-only and irreversible - * initialisation steps, such as initialising the heap. It must be - * called before (almost) any other function. - * - * There is, by definition, no counterpart to this function on the - * shutdown path. - */ -void initialise ( void ) { - struct init_fn *init_fn; - - /* Call registered initialisation functions */ - for_each_table_entry ( init_fn, INIT_FNS ) - init_fn->initialise (); -} - -/** - * Start up iPXE - * - * This function performs the repeatable initialisation steps, such as - * probing devices. You may call startup() and shutdown() multiple - * times (as is done via the PXE API when PXENV_START_UNDI is used). - */ -void startup ( void ) { - struct startup_fn *startup_fn; - - if ( started ) - return; - - /* Call registered startup functions */ - for_each_table_entry ( startup_fn, STARTUP_FNS ) { - if ( startup_fn->startup ) - startup_fn->startup(); - } - - started = 1; -} - -/** - * Shut down iPXE - * - * @v flags Shutdown behaviour flags - * - * This function reverses the actions of startup(), and leaves iPXE in - * a state ready to be removed from memory. You may call startup() - * again after calling shutdown(). - * - * Call this function only once, before either exiting main() or - * starting up a non-returnable image. - */ -void shutdown ( int flags ) { - struct startup_fn *startup_fn; - - if ( ! started ) - return; - - /* Call registered shutdown functions (in reverse order) */ - for_each_table_entry_reverse ( startup_fn, STARTUP_FNS ) { - if ( startup_fn->shutdown ) - startup_fn->shutdown ( flags ); - } - - /* Reset console */ - console_reset(); - - started = 0; -} diff --git a/qemu/roms/ipxe/src/core/interface.c b/qemu/roms/ipxe/src/core/interface.c deleted file mode 100644 index ba148c13d..000000000 --- a/qemu/roms/ipxe/src/core/interface.c +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <string.h> -#include <ipxe/interface.h> - -/** @file - * - * Object interfaces - * - */ - -/***************************************************************************** - * - * The null interface - * - */ - -/** - * Close null interface - * - * @v intf Null interface - * @v rc Reason for close - */ -static void null_intf_close ( struct interface *intf __unused, - int rc __unused ) { - - /* Do nothing. In particular, do not call intf_restart(), - * since that would result in an infinite loop. - */ -} - -/** Null interface operations */ -static struct interface_operation null_intf_op[] = { - INTF_OP ( intf_close, struct interface *, null_intf_close ), -}; - -/** Null interface descriptor */ -struct interface_descriptor null_intf_desc = - INTF_DESC_PURE ( null_intf_op ); - -/** The null interface */ -struct interface null_intf = INTF_INIT ( null_intf_desc ); - -/***************************************************************************** - * - * Object interface plumbing - * - */ - -/** - * Plug an object interface into a new destination object interface - * - * @v intf Object interface - * @v dest New destination object interface - * - * The reference to the existing destination interface is dropped, a - * reference to the new destination interface is obtained, and the - * interface is updated to point to the new destination interface. - * - * Note that there is no "unplug" call; instead you must plug the - * interface into a null interface. - */ -void intf_plug ( struct interface *intf, struct interface *dest ) { - DBGC ( INTF_COL ( intf ), - "INTF " INTF_INTF_FMT " replug to " INTF_FMT "\n", - INTF_INTF_DBG ( intf, intf->dest ), INTF_DBG ( dest ) ); - intf_get ( dest ); - intf_put ( intf->dest ); - intf->dest = dest; -} - -/** - * Plug two object interfaces together - * - * @v a Object interface A - * @v b Object interface B - * - * Plugs interface A into interface B, and interface B into interface - * A. (The basic plug() function is unidirectional; this function is - * merely a shorthand for two calls to plug(), hence the name.) - */ -void intf_plug_plug ( struct interface *a, struct interface *b ) { - intf_plug ( a, b ); - intf_plug ( b, a ); -} - -/** - * Unplug an object interface - * - * @v intf Object interface - */ -void intf_unplug ( struct interface *intf ) { - intf_plug ( intf, &null_intf ); -} - -/** - * Ignore all further operations on an object interface - * - * @v intf Object interface - */ -void intf_nullify ( struct interface *intf ) { - intf->desc = &null_intf_desc; -} - -/** - * Increment reference count on an object interface - * - * @v intf Object interface - * @ret intf Object interface - */ -struct interface * intf_get ( struct interface *intf ) { - ref_get ( intf->refcnt ); - return intf; -} - -/** - * Decrement reference count on an object interface - * - * @v intf Object interface - */ -void intf_put ( struct interface *intf ) { - ref_put ( intf->refcnt ); -} - -/** - * Get pointer to object containing object interface - * - * @v intf Object interface - * @ret object Containing object - */ -void * intf_object ( struct interface *intf ) { - return ( ( ( void * ) intf ) - intf->desc->offset ); -} - -/** - * Get pass-through interface - * - * @v intf Object interface - * @ret passthru Pass-through interface, or NULL - */ -static struct interface * intf_get_passthru ( struct interface *intf ) { - struct interface_descriptor *desc = intf->desc; - - if ( desc->passthru_offset ) { - return ( ( ( void * ) intf ) + desc->passthru_offset ); - } else { - return NULL; - } -} - -/** - * Get object interface destination and operation method (without pass-through) - * - * @v intf Object interface - * @v type Operation type - * @ret dest Destination interface - * @ret func Implementing method, or NULL - */ -void * intf_get_dest_op_no_passthru_untyped ( struct interface *intf, - void *type, - struct interface **dest ) { - struct interface_descriptor *desc; - struct interface_operation *op; - unsigned int i; - - *dest = intf_get ( intf->dest ); - desc = (*dest)->desc; - for ( i = desc->num_op, op = desc->op ; i ; i--, op++ ) { - if ( op->type == type ) - return op->func; - } - - return NULL; -} - -/** - * Get object interface destination and operation method - * - * @v intf Object interface - * @v type Operation type - * @ret dest Destination interface - * @ret func Implementing method, or NULL - */ -void * intf_get_dest_op_untyped ( struct interface *intf, void *type, - struct interface **dest ) { - void *func; - - while ( 1 ) { - - /* Search for an implementing method provided by the - * current destination interface. - */ - func = intf_get_dest_op_no_passthru_untyped( intf, type, dest ); - if ( func ) - return func; - - /* Pass through to the underlying interface, if applicable */ - if ( ! ( intf = intf_get_passthru ( *dest ) ) ) - return NULL; - intf_put ( *dest ); - } -} - -/***************************************************************************** - * - * Generic interface operations - * - */ - -/** - * Close an object interface - * - * @v intf Object interface - * @v rc Reason for close - * - * Note that this function merely informs the destination object that - * the interface is about to be closed; it doesn't actually disconnect - * the interface. In most cases, you probably want to use - * intf_shutdown() or intf_restart() instead. - */ -void intf_close ( struct interface *intf, int rc ) { - struct interface *dest; - intf_close_TYPE ( void * ) *op = - intf_get_dest_op ( intf, intf_close, &dest ); - void *object = intf_object ( dest ); - - DBGC ( INTF_COL ( intf ), "INTF " INTF_INTF_FMT " close (%s)\n", - INTF_INTF_DBG ( intf, dest ), strerror ( rc ) ); - - if ( op ) { - op ( object, rc ); - } else { - /* Default is to restart the interface */ - intf_restart ( dest, rc ); - } - - intf_put ( dest ); -} - -/** - * Shut down an object interface - * - * @v intf Object interface - * @v rc Reason for close - * - * Blocks further operations from being received via the interface, - * executes a close operation on the destination interface, and - * unplugs the interface. - */ -void intf_shutdown ( struct interface *intf, int rc ) { - - DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " shutting down (%s)\n", - INTF_DBG ( intf ), strerror ( rc ) ); - - /* Block further operations */ - intf_nullify ( intf ); - - /* Notify destination of close */ - intf_close ( intf, rc ); - - /* Unplug interface */ - intf_unplug ( intf ); -} - -/** - * Shut down and restart an object interface - * - * @v intf Object interface - * @v rc Reason for close - * - * Shuts down the interface, then unblocks operations that were - * blocked during shutdown. - */ -void intf_restart ( struct interface *intf, int rc ) { - struct interface_descriptor *desc = intf->desc; - - /* Shut down the interface */ - intf_shutdown ( intf, rc ); - - DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " restarting\n", - INTF_DBG ( intf ) ); - - /* Restore the interface descriptor. Must be done after - * shutdown (rather than inhibiting intf_shutdown() from - * nullifying the descriptor) in order to avoid a potential - * infinite loop as the intf_close() operations on each side - * of the link call each other recursively. - */ - 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 deleted file mode 100644 index 3e52ada4f..000000000 --- a/qemu/roms/ipxe/src/core/iobuf.c +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdint.h> -#include <strings.h> -#include <errno.h> -#include <ipxe/malloc.h> -#include <ipxe/iobuf.h> - -/** @file - * - * I/O buffers - * - */ - -/** - * Allocate I/O buffer with specified alignment and offset - * - * @v len Required length of buffer - * @v align Physical alignment - * @v offset Offset from physical alignment - * @ret iobuf I/O buffer, or NULL if none available - * - * @c align will be rounded up to the nearest power of two. - */ -struct io_buffer * alloc_iob_raw ( size_t len, size_t align, size_t offset ) { - struct io_buffer *iobuf; - void *data; - - /* Align buffer length to ensure that struct io_buffer is aligned */ - len = ( len + __alignof__ ( *iobuf ) - 1 ) & - ~( __alignof__ ( *iobuf ) - 1 ); - - /* Round up alignment to the nearest power of two */ - align = ( 1 << fls ( align - 1 ) ); - - /* Allocate buffer plus descriptor as a single unit, unless - * doing so will push the total size over the alignment - * boundary. - */ - if ( ( len + sizeof ( *iobuf ) ) <= align ) { - - /* Allocate memory for buffer plus descriptor */ - data = malloc_dma_offset ( len + sizeof ( *iobuf ), align, - offset ); - if ( ! data ) - return NULL; - iobuf = ( data + len ); - - } else { - - /* Allocate memory for buffer */ - data = malloc_dma_offset ( len, align, offset ); - if ( ! data ) - return NULL; - - /* Allocate memory for descriptor */ - iobuf = malloc ( sizeof ( *iobuf ) ); - if ( ! iobuf ) { - free_dma ( data, len ); - return NULL; - } - } - - /* Populate descriptor */ - iobuf->head = iobuf->data = iobuf->tail = data; - iobuf->end = ( data + len ); - - return iobuf; -} - -/** - * Allocate I/O buffer - * - * @v len Required length of buffer - * @ret iobuf I/O buffer, or NULL if none available - * - * The I/O buffer will be physically aligned on its own size (rounded - * up to the nearest power of two). - */ -struct io_buffer * alloc_iob ( size_t len ) { - - /* Pad to minimum length */ - if ( len < IOB_ZLEN ) - len = IOB_ZLEN; - - /* Align buffer on its own size to avoid potential problems - * with boundary-crossing DMA. - */ - return alloc_iob_raw ( len, len, 0 ); -} - -/** - * Free I/O buffer - * - * @v iobuf I/O buffer - */ -void free_iob ( struct io_buffer *iobuf ) { - size_t len; - - /* Allow free_iob(NULL) to be valid */ - if ( ! iobuf ) - return; - - /* Sanity checks */ - assert ( iobuf->head <= iobuf->data ); - assert ( iobuf->data <= iobuf->tail ); - assert ( iobuf->tail <= iobuf->end ); - - /* Free buffer */ - len = ( iobuf->end - iobuf->head ); - if ( iobuf->end == iobuf ) { - - /* Descriptor is inline */ - free_dma ( iobuf->head, ( len + sizeof ( *iobuf ) ) ); - - } else { - - /* Descriptor is detached */ - free_dma ( iobuf->head, len ); - free ( iobuf ); - } -} - -/** - * Ensure I/O buffer has sufficient headroom - * - * @v iobuf I/O buffer - * @v len Required headroom - * - * This function currently only checks for the required headroom; it - * does not reallocate the I/O buffer if required. If we ever have a - * code path that requires this functionality, it's a fairly trivial - * change to make. - */ -int iob_ensure_headroom ( struct io_buffer *iobuf, size_t len ) { - - if ( iob_headroom ( iobuf ) >= len ) - return 0; - return -ENOBUFS; -} - -/** - * Concatenate I/O buffers into a single buffer - * - * @v list List of I/O buffers - * @ret iobuf Concatenated I/O buffer, or NULL on allocation failure - * - * After a successful concatenation, the list will be empty. - */ -struct io_buffer * iob_concatenate ( struct list_head *list ) { - struct io_buffer *iobuf; - struct io_buffer *tmp; - struct io_buffer *concatenated; - size_t len = 0; - - /* If the list contains only a single entry, avoid an - * unnecessary additional allocation. - */ - if ( list_is_singular ( list ) ) { - iobuf = list_first_entry ( list, struct io_buffer, list ); - INIT_LIST_HEAD ( list ); - return iobuf; - } - - /* Calculate total length */ - list_for_each_entry ( iobuf, list, list ) - len += iob_len ( iobuf ); - - /* Allocate new I/O buffer */ - concatenated = alloc_iob_raw ( len, __alignof__ ( *iobuf ), 0 ); - if ( ! concatenated ) - return NULL; - - /* Move data to new I/O buffer */ - list_for_each_entry_safe ( iobuf, tmp, list, list ) { - list_del ( &iobuf->list ); - memcpy ( iob_put ( concatenated, iob_len ( iobuf ) ), - iobuf->data, iob_len ( iobuf ) ); - free_iob ( iobuf ); - } - - 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 deleted file mode 100644 index c4d0571e7..000000000 --- a/qemu/roms/ipxe/src/core/isqrt.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/** @file - * - * Integer square root - * - */ - -#include <ipxe/isqrt.h> - -/** - * Find integer square root - * - * @v value Value - * @v isqrt Integer square root of value - */ -unsigned long isqrt ( unsigned long value ) { - unsigned long result = 0; - unsigned long bit = ( 1UL << ( ( 8 * sizeof ( bit ) ) - 2 ) ); - - while ( bit > value ) - bit >>= 2; - while ( bit ) { - if ( value >= ( result + bit ) ) { - value -= ( result + bit ); - result = ( ( result >> 1 ) + bit ); - } else { - result >>= 1; - } - bit >>= 2; - } - return result; -} diff --git a/qemu/roms/ipxe/src/core/job.c b/qemu/roms/ipxe/src/core/job.c deleted file mode 100644 index 65df80056..000000000 --- a/qemu/roms/ipxe/src/core/job.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <string.h> -#include <errno.h> -#include <ipxe/job.h> - -/** @file - * - * Job control interfaces - * - */ - -/** - * Get job progress - * - * @v intf Object interface - * @v progress Progress data to fill in - * @ret ongoing_rc Ongoing job status code (if known) - */ -int job_progress ( struct interface *intf, struct job_progress *progress ) { - struct interface *dest; - job_progress_TYPE ( void * ) *op = - intf_get_dest_op ( intf, job_progress, &dest ); - void *object = intf_object ( dest ); - int ongoing_rc; - - DBGC ( INTF_COL ( intf ), "INTF " INTF_INTF_FMT " job_progress\n", - INTF_INTF_DBG ( intf, dest ) ); - - /* Initialise progress to zero */ - memset ( progress, 0, sizeof ( *progress ) ); - - if ( op ) { - ongoing_rc = op ( object, progress ); - } else { - /* Default is to leave progress as zero and have no - * known return status code. - */ - ongoing_rc = 0; - } - - intf_put ( dest ); - return ongoing_rc; -} diff --git a/qemu/roms/ipxe/src/core/linebuf.c b/qemu/roms/ipxe/src/core/linebuf.c deleted file mode 100644 index c197e383c..000000000 --- a/qemu/roms/ipxe/src/core/linebuf.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/** - * @file - * - * Line buffering - * - */ - -#include <stdint.h> -#include <string.h> -#include <stdlib.h> -#include <errno.h> -#include <ipxe/linebuf.h> - -/** - * Retrieve buffered-up line - * - * @v linebuf Line buffer - * @ret line Buffered line, or NULL if no line ready to read - */ -char * buffered_line ( struct line_buffer *linebuf ) { - 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; -} - -/** - * Discard line buffer contents - * - * @v linebuf Line buffer - */ -void empty_line_buffer ( struct line_buffer *linebuf ) { - - free ( linebuf->data ); - linebuf->data = NULL; - linebuf->len = 0; - linebuf->consumed = 0; -} - -/** - * Buffer up received data by lines - * - * @v linebuf Line buffer - * @v data New data to add - * @v len Length of new data to add - * @ret len Consumed length, or negative error number - * - * After calling line_buffer(), use buffered_line() to determine - * whether or not a complete line is available. Carriage returns and - * newlines will have been stripped, and the line will be - * NUL-terminated. This buffered line is valid only until the next - * call to line_buffer() (or to empty_line_buffer()). - * - * Note that line buffers use dynamically allocated storage; you - * should call empty_line_buffer() before freeing a @c struct @c - * line_buffer. - */ -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; - char *lf; - char *cr; - - /* Search for line terminator */ - if ( ( eol = memchr ( data, '\n', len ) ) ) { - consume = ( eol - data + 1 ); - } else { - 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 ) ); - if ( ! new_data ) - return -ENOMEM; - memcpy ( ( new_data + linebuf->len ), data, consume ); - new_data[new_len] = '\0'; - linebuf->data = new_data; - linebuf->len = new_len; - - /* If we have reached end of line, terminate the line */ - if ( eol ) { - - /* 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 deleted file mode 100644 index bb3bfafc9..000000000 --- a/qemu/roms/ipxe/src/core/lineconsole.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/** @file - * - * Line-based console - * - */ - -#include <stdint.h> -#include <stddef.h> -#include <ipxe/ansiesc.h> -#include <ipxe/lineconsole.h> - -/** - * Print a character to a line-based console - * - * @v character Character to be printed - * @ret print Print line - */ -size_t line_putchar ( struct line_console *line, int character ) { - - /* Strip ANSI escape sequences */ - character = ansiesc_process ( &line->ctx, character ); - if ( character < 0 ) - return 0; - - /* Ignore carriage return */ - if ( character == '\r' ) - return 0; - - /* Treat newline as a terminator */ - if ( character == '\n' ) - character = 0; - - /* Add character to buffer */ - line->buffer[line->index++] = character; - - /* Do nothing more unless we reach end-of-line (or end-of-buffer) */ - if ( ( character != 0 ) && - ( line->index < ( line->len - 1 /* NUL */ ) ) ) { - return 0; - } - - /* Reset to start of buffer */ - line->index = 0; - - return 1; -} diff --git a/qemu/roms/ipxe/src/core/list.c b/qemu/roms/ipxe/src/core/list.c deleted file mode 100644 index 5175c84ec..000000000 --- a/qemu/roms/ipxe/src/core/list.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/** @file - * - * Linked lists - * - */ - -#include <ipxe/list.h> - -void extern_list_add ( struct list_head *new, struct list_head *head ) { - inline_list_add ( new, head ); -} - -void extern_list_add_tail ( struct list_head *new, struct list_head *head ) { - inline_list_add_tail ( new, head ); -} - -void extern_list_del ( struct list_head *list ) { - inline_list_del ( list ); -} - -int extern_list_empty ( const struct list_head *list ) { - return inline_list_empty ( list ); -} - -int extern_list_is_singular ( const struct list_head *list ) { - return inline_list_is_singular ( list ); -} - -int extern_list_is_last ( const struct list_head *list, - const struct list_head *head ) { - return inline_list_is_last ( list, head ); -} - -void extern_list_cut_position ( struct list_head *new, - struct list_head *list, - struct list_head *entry ) { - inline_list_cut_position ( new, list, entry ); -} - -void extern_list_splice ( const struct list_head *list, - struct list_head *entry ) { - inline_list_splice ( list, entry ); -} - -void extern_list_splice_tail ( const struct list_head *list, - struct list_head *entry ) { - inline_list_splice_tail ( list, entry ); -} - -void extern_list_splice_init ( struct list_head *list, - struct list_head *entry ) { - inline_list_splice_init ( list, entry ); -} - -void extern_list_splice_tail_init ( struct list_head *list, - struct list_head *entry ) { - inline_list_splice_tail_init ( list, entry ); -} - -int extern_list_contains ( struct list_head *entry, - struct list_head *head ) { - return inline_list_contains ( entry, head ); -} diff --git a/qemu/roms/ipxe/src/core/log.c b/qemu/roms/ipxe/src/core/log.c deleted file mode 100644 index c08e4bb9b..000000000 --- a/qemu/roms/ipxe/src/core/log.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/** @file - * - * System logger - * - */ - -#include <stdarg.h> -#include <syslog.h> -#include <ipxe/console.h> - -/** - * Write message to system log - * - * @v fmt Format string - * @v args Arguments - */ -void log_vprintf ( const char *fmt, va_list args ) { - int saved_usage; - - /* Mark console as in use for log messages */ - saved_usage = console_set_usage ( CONSOLE_USAGE_LOG ); - - /* Print message */ - vprintf ( fmt, args ); - - /* Restore console usage */ - console_set_usage ( saved_usage ); -} - -/** - * Write message to system log - * - * @v fmt Format string - * @v ... Arguments - */ -void log_printf ( const char *fmt, ... ) { - va_list args; - - va_start ( args, fmt ); - log_vprintf ( fmt, args ); - va_end ( args ); -} diff --git a/qemu/roms/ipxe/src/core/main.c b/qemu/roms/ipxe/src/core/main.c deleted file mode 100644 index 638dea9cf..000000000 --- a/qemu/roms/ipxe/src/core/main.c +++ /dev/null @@ -1,46 +0,0 @@ -/************************************************************************** -iPXE - Network Bootstrap Program - -Literature dealing with the network protocols: - ARP - RFC826 - RARP - RFC903 - UDP - RFC768 - BOOTP - RFC951, RFC2132 (vendor extensions) - DHCP - RFC2131, RFC2132 (options) - TFTP - RFC1350, RFC2347 (options), RFC2348 (blocksize), RFC2349 (tsize) - RPC - RFC1831, RFC1832 (XDR), RFC1833 (rpcbind/portmapper) - -**************************************************************************/ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stddef.h> -#include <stdio.h> -#include <ipxe/init.h> -#include <ipxe/version.h> -#include <usr/autoboot.h> - -/** - * Main entry point - * - * @ret rc Return status code - */ -__asmcall int main ( void ) { - int rc; - - /* Perform one-time-only initialisation (e.g. heap) */ - initialise(); - - /* Some devices take an unreasonably long time to initialise */ - printf ( "%s initialising devices...", product_short_name ); - startup(); - printf ( "ok\n" ); - - /* Attempt to boot */ - if ( ( rc = ipxe ( NULL ) ) != 0 ) - goto err_ipxe; - - err_ipxe: - shutdown_exit(); - return rc; -} diff --git a/qemu/roms/ipxe/src/core/malloc.c b/qemu/roms/ipxe/src/core/malloc.c deleted file mode 100644 index b120c0325..000000000 --- a/qemu/roms/ipxe/src/core/malloc.c +++ /dev/null @@ -1,669 +0,0 @@ -/* - * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stddef.h> -#include <stdint.h> -#include <string.h> -#include <strings.h> -#include <ipxe/io.h> -#include <ipxe/list.h> -#include <ipxe/init.h> -#include <ipxe/refcnt.h> -#include <ipxe/malloc.h> -#include <valgrind/memcheck.h> - -/** @file - * - * Dynamic memory allocation - * - */ - -/** A free block of memory */ -struct memory_block { - /** Size of this block */ - size_t size; - /** Padding - * - * This padding exists to cover the "count" field of a - * reference counter, in the common case where a reference - * counter is the first element of a dynamically-allocated - * object. It avoids clobbering the "count" field as soon as - * the memory is freed, and so allows for the possibility of - * detecting reference counting errors. - */ - char pad[ offsetof ( struct refcnt, count ) + - sizeof ( ( ( struct refcnt * ) NULL )->count ) ]; - /** List of free blocks */ - struct list_head list; -}; - -#define MIN_MEMBLOCK_SIZE \ - ( ( size_t ) ( 1 << ( fls ( sizeof ( struct memory_block ) - 1 ) ) ) ) - -/** A block of allocated memory complete with size information */ -struct autosized_block { - /** Size of this block */ - size_t size; - /** Remaining data */ - char data[0]; -}; - -/** - * Address for zero-length memory blocks - * - * @c malloc(0) or @c realloc(ptr,0) will return the special value @c - * NOWHERE. Calling @c free(NOWHERE) will have no effect. - * - * This is consistent with the ANSI C standards, which state that - * "either NULL or a pointer suitable to be passed to free()" must be - * returned in these cases. Using a special non-NULL value means that - * the caller can take a NULL return value to indicate failure, - * without first having to check for a requested size of zero. - * - * Code outside of malloc.c do not ever need to refer to the actual - * value of @c NOWHERE; this is an internal definition. - */ -#define NOWHERE ( ( void * ) ~( ( intptr_t ) 0 ) ) - -/** List of free memory blocks */ -static LIST_HEAD ( free_blocks ); - -/** Total amount of free memory */ -size_t freemem; - -/** - * Heap size - * - * Currently fixed at 512kB. - */ -#define HEAP_SIZE ( 512 * 1024 ) - -/** The heap itself */ -static char heap[HEAP_SIZE] __attribute__ (( aligned ( __alignof__(void *) ))); - -/** - * Mark all blocks in free list as defined - * - */ -static inline void valgrind_make_blocks_defined ( void ) { - struct memory_block *block; - - /* Do nothing unless running under Valgrind */ - if ( RUNNING_ON_VALGRIND <= 0 ) - return; - - /* Traverse free block list, marking each block structure as - * defined. Some contortions are necessary to avoid errors - * from list_check(). - */ - - /* Mark block list itself as defined */ - VALGRIND_MAKE_MEM_DEFINED ( &free_blocks, sizeof ( free_blocks ) ); - - /* Mark areas accessed by list_check() as defined */ - VALGRIND_MAKE_MEM_DEFINED ( &free_blocks.prev->next, - sizeof ( free_blocks.prev->next ) ); - VALGRIND_MAKE_MEM_DEFINED ( free_blocks.next, - sizeof ( *free_blocks.next ) ); - VALGRIND_MAKE_MEM_DEFINED ( &free_blocks.next->next->prev, - sizeof ( free_blocks.next->next->prev ) ); - - /* Mark each block in list as defined */ - list_for_each_entry ( block, &free_blocks, list ) { - - /* Mark block as defined */ - VALGRIND_MAKE_MEM_DEFINED ( block, sizeof ( *block ) ); - - /* Mark areas accessed by list_check() as defined */ - VALGRIND_MAKE_MEM_DEFINED ( block->list.next, - sizeof ( *block->list.next ) ); - VALGRIND_MAKE_MEM_DEFINED ( &block->list.next->next->prev, - sizeof ( block->list.next->next->prev ) ); - } -} - -/** - * Mark all blocks in free list as inaccessible - * - */ -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; - - /* Traverse free block list, marking each block structure as - * inaccessible. Some contortions are necessary to avoid - * errors from list_check(). - */ - - /* Mark each block in list as inaccessible */ - list_for_each_entry ( block, &free_blocks, list ) { - - /* Mark previous block (if any) as inaccessible. (Current - * block will be accessed by list_check().) - */ - if ( prev ) - VALGRIND_MAKE_MEM_NOACCESS ( prev, sizeof ( *prev ) ); - prev = block; - - /* At the end of the list, list_check() will end up - * accessing the first list item. Temporarily mark - * this area as defined. - */ - VALGRIND_MAKE_MEM_DEFINED ( &free_blocks.next->prev, - sizeof ( free_blocks.next->prev ) ); - } - /* Mark last block (if any) as inaccessible */ - if ( prev ) - VALGRIND_MAKE_MEM_NOACCESS ( prev, sizeof ( *prev ) ); - - /* Mark as inaccessible the area that was temporarily marked - * as defined to avoid errors from list_check(). - */ - VALGRIND_MAKE_MEM_NOACCESS ( &free_blocks.next->prev, - sizeof ( free_blocks.next->prev ) ); - - /* Mark block list itself as inaccessible */ - VALGRIND_MAKE_MEM_NOACCESS ( &free_blocks, sizeof ( free_blocks ) ); -} - -/** - * Check integrity of the blocks in the free list - * - */ -static inline void check_blocks ( void ) { - struct memory_block *block; - struct memory_block *prev = NULL; - - if ( ! ASSERTING ) - return; - - list_for_each_entry ( block, &free_blocks, list ) { - - /* Check that list structure is intact */ - list_check ( &block->list ); - - /* Check that block size is not too small */ - assert ( block->size >= sizeof ( *block ) ); - assert ( block->size >= MIN_MEMBLOCK_SIZE ); - - /* Check that block does not wrap beyond end of address space */ - assert ( ( ( void * ) block + block->size ) > - ( ( void * ) block ) ); - - /* Check that blocks remain in ascending order, and - * that adjacent blocks have been merged. - */ - if ( prev ) { - assert ( ( ( void * ) block ) > ( ( void * ) prev ) ); - assert ( ( ( void * ) block ) > - ( ( ( void * ) prev ) + prev->size ) ); - } - prev = block; - } -} - -/** - * Discard some cached data - * - * @ret discarded Number of cached items discarded - */ -static unsigned int discard_cache ( void ) { - struct cache_discarder *discarder; - unsigned int discarded; - - for_each_table_entry ( discarder, CACHE_DISCARDERS ) { - discarded = discarder->discard(); - if ( discarded ) - return discarded; - } - return 0; -} - -/** - * Discard all cached data - * - */ -static void discard_all_cache ( void ) { - unsigned int discarded; - - do { - discarded = discard_cache(); - } while ( discarded ); -} - -/** - * Allocate a memory block - * - * @v size Requested size - * @v align Physical alignment - * @v offset Offset from physical alignment - * @ret ptr Memory block, or NULL - * - * Allocates a memory block @b physically aligned as requested. No - * guarantees are provided for the alignment of the virtual address. - * - * @c align must be a power of two. @c size may not be zero. - */ -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; - 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. - */ - 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 ); - while ( 1 ) { - /* Search through blocks for the first one with enough space */ - list_for_each_entry ( block, &free_blocks, list ) { - pre_size = ( ( offset - virt_to_phys ( block ) ) - & align_mask ); - 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" - * block is the one currently linked into the - * free list. - */ - pre = block; - block = ( ( ( void * ) pre ) + pre_size ); - post = ( ( ( void * ) block ) + actual_size ); - DBGC2 ( &heap, "[%p,%p) -> [%p,%p) + [%p,%p)\n", - pre, ( ( ( void * ) pre ) + pre->size ), - pre, block, post, - ( ( ( void * ) pre ) + pre->size ) ); - /* If there is a "post" block, add it in to - * the free list. Leak it if it is too small - * (which can happen only at the very end of - * the heap). - */ - if ( (size_t) post_size >= MIN_MEMBLOCK_SIZE ) { - VALGRIND_MAKE_MEM_UNDEFINED - ( post, sizeof ( *post ) ); - post->size = post_size; - list_add ( &post->list, &pre->list ); - } - /* Shrink "pre" block, leaving the main block - * isolated and no longer part of the free - * list. - */ - pre->size = pre_size; - /* If there is no "pre" block, remove it from - * the list. Also remove it (i.e. leak it) if - * it is too small, which can happen only at - * the very start of the heap. - */ - if ( pre_size < MIN_MEMBLOCK_SIZE ) { - list_del ( &pre->list ); - VALGRIND_MAKE_MEM_NOACCESS - ( pre, sizeof ( *pre ) ); - } - /* Update total free memory */ - 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; - } - } - - /* Try discarding some cached data to free up memory */ - if ( ! discard_cache() ) { - /* Nothing available to discard */ - DBGC ( &heap, "Failed to allocate %#zx (aligned " - "%#zx)\n", size, align ); - ptr = NULL; - goto done; - } - } - - done: - check_blocks(); - valgrind_make_blocks_noaccess(); - return ptr; -} - -/** - * Free a memory block - * - * @v ptr Memory allocated by alloc_memblock(), or NULL - * @v size Size of the memory - * - * If @c ptr is NULL, no action is taken. - */ -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(); - - /* Round up size to match actual size that alloc_memblock() - * would have used. - */ - assert ( size != 0 ); - actual_size = ( ( size + MIN_MEMBLOCK_SIZE - 1 ) & - ~( MIN_MEMBLOCK_SIZE - 1 ) ); - freeing = ptr; - VALGRIND_MAKE_MEM_UNDEFINED ( freeing, sizeof ( *freeing ) ); - DBGC2 ( &heap, "Freeing [%p,%p)\n", - freeing, ( ( ( void * ) freeing ) + size ) ); - - /* Check that this block does not overlap the free list */ - if ( ASSERTING ) { - list_for_each_entry ( block, &free_blocks, list ) { - if ( ( ( ( void * ) block ) < - ( ( void * ) freeing + actual_size ) ) && - ( ( void * ) freeing < - ( ( void * ) block + block->size ) ) ) { - assert ( 0 ); - DBGC ( &heap, "Double free of [%p,%p) " - "overlapping [%p,%p) detected from %p\n", - freeing, - ( ( ( void * ) freeing ) + size ), block, - ( ( void * ) block + block->size ), - __builtin_return_address ( 0 ) ); - } - } - } - - /* Insert/merge into free list */ - 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 ) - - ( ( ( void * ) block ) + block->size ) ); - gap_after = ( ( ( void * ) block ) - - ( ( ( void * ) freeing ) + freeing->size ) ); - /* Merge with immediately preceding block, if possible */ - if ( gap_before == 0 ) { - DBGC2 ( &heap, "[%p,%p) + [%p,%p) -> [%p,%p)\n", block, - ( ( ( void * ) block ) + block->size ), freeing, - ( ( ( void * ) freeing ) + freeing->size ), - block, - ( ( ( void * ) freeing ) + freeing->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 */ - if ( gap_after >= 0 ) - break; - } - - /* Insert before the immediately following block. If - * possible, merge the following block into the "freeing" - * block. - */ - DBGC2 ( &heap, "[%p,%p)\n", - freeing, ( ( ( void * ) freeing ) + freeing->size ) ); - list_add_tail ( &freeing->list, &block->list ); - if ( gap_after == 0 ) { - DBGC2 ( &heap, "[%p,%p) + [%p,%p) -> [%p,%p)\n", freeing, - ( ( ( void * ) freeing ) + freeing->size ), block, - ( ( ( void * ) block ) + block->size ), freeing, - ( ( ( void * ) block ) + block->size ) ); - freeing->size += block->size; - list_del ( &block->list ); - VALGRIND_MAKE_MEM_NOACCESS ( block, sizeof ( *block ) ); - } - - /* Update free memory counter */ - freemem += actual_size; - - check_blocks(); - valgrind_make_blocks_noaccess(); -} - -/** - * Reallocate memory - * - * @v old_ptr Memory previously allocated by malloc(), or NULL - * @v new_size Requested size - * @ret new_ptr Allocated memory, or NULL - * - * Allocates memory with no particular alignment requirement. @c - * new_ptr will be aligned to at least a multiple of sizeof(void*). - * If @c old_ptr is non-NULL, then the contents of the newly allocated - * memory will be the same as the contents of the previously allocated - * memory, up to the minimum of the old and new sizes. The old memory - * will be freed. - * - * If allocation fails the previously allocated block is left - * untouched and NULL is returned. - * - * Calling realloc() with a new size of zero is a valid way to free a - * memory block. - */ -void * realloc ( void *old_ptr, size_t new_size ) { - struct autosized_block *old_block; - struct autosized_block *new_block; - size_t old_total_size; - size_t new_total_size; - size_t old_size; - void *new_ptr = NOWHERE; - - /* Allocate new memory if necessary. If allocation fails, - * return without touching the old block. - */ - if ( new_size ) { - new_total_size = ( new_size + - offsetof ( struct autosized_block, data ) ); - new_block = alloc_memblock ( new_total_size, 1, 0 ); - if ( ! new_block ) - return NULL; - new_block->size = new_total_size; - 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 ); - } - - /* Copy across relevant part of the old data region (if any), - * then free it. Note that at this point either (a) new_ptr - * is valid, or (b) new_size is 0; either way, the memcpy() is - * valid. - */ - if ( old_ptr && ( old_ptr != NOWHERE ) ) { - old_block = container_of ( old_ptr, 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 ) ); - VALGRIND_FREELIKE_BLOCK ( old_ptr, 0 ); - free_memblock ( old_block, old_total_size ); - } - - if ( ASSERTED ) { - DBGC ( &heap, "Possible memory corruption detected from %p\n", - __builtin_return_address ( 0 ) ); - } - return new_ptr; -} - -/** - * Allocate memory - * - * @v size Requested size - * @ret ptr Memory, or NULL - * - * Allocates memory with no particular alignment requirement. @c ptr - * will be aligned to at least a multiple of sizeof(void*). - */ -void * malloc ( size_t size ) { - void *ptr; - - ptr = realloc ( NULL, size ); - if ( ASSERTED ) { - DBGC ( &heap, "Possible memory corruption detected from %p\n", - __builtin_return_address ( 0 ) ); - } - return ptr; -} - -/** - * Free memory - * - * @v ptr Memory allocated by malloc(), or NULL - * - * Memory allocated with malloc_dma() cannot be freed with free(); it - * must be freed with free_dma() instead. - * - * If @c ptr is NULL, no action is taken. - */ -void free ( void *ptr ) { - - realloc ( ptr, 0 ); - if ( ASSERTED ) { - DBGC ( &heap, "Possible memory corruption detected from %p\n", - __builtin_return_address ( 0 ) ); - } -} - -/** - * Allocate cleared memory - * - * @v size Requested size - * @ret ptr Allocated memory - * - * Allocate memory as per malloc(), and zero it. - * - * This function name is non-standard, but pretty intuitive. - * zalloc(size) is always equivalent to calloc(1,size) - */ -void * zalloc ( size_t size ) { - void *data; - - data = malloc ( size ); - if ( data ) - memset ( data, 0, size ); - if ( ASSERTED ) { - DBGC ( &heap, "Possible memory corruption detected from %p\n", - __builtin_return_address ( 0 ) ); - } - return data; -} - -/** - * Add memory to allocation pool - * - * @v start Start address - * @v end End address - * - * Adds a block of memory [start,end) to the allocation pool. This is - * a one-way operation; there is no way to reclaim this memory. - * - * @c start must be aligned to at least a multiple of sizeof(void*). - */ -void mpopulate ( void *start, size_t len ) { - /* Prevent free_memblock() from rounding up len beyond the end - * of what we were actually given... - */ - free_memblock ( start, ( len & ~( MIN_MEMBLOCK_SIZE - 1 ) ) ); -} - -/** - * Initialise the heap - * - */ -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 ) ); -} - -/** Memory allocator initialisation function */ -struct init_fn heap_init_fn __init_fn ( INIT_EARLY ) = { - .initialise = init_heap, -}; - -/** - * Discard all cached data on shutdown - * - */ -static void shutdown_cache ( int booting __unused ) { - discard_all_cache(); -} - -/** Memory allocator shutdown function */ -struct startup_fn heap_startup_fn __startup_fn ( STARTUP_EARLY ) = { - .shutdown = shutdown_cache, -}; - -#if 0 -#include <stdio.h> -/** - * Dump free block list - * - */ -void mdumpfree ( void ) { - struct memory_block *block; - - printf ( "Free block list:\n" ); - list_for_each_entry ( block, &free_blocks, list ) { - printf ( "[%p,%p] (size %#zx)\n", block, - ( ( ( void * ) block ) + block->size ), block->size ); - } -} -#endif diff --git a/qemu/roms/ipxe/src/core/memblock.c b/qemu/roms/ipxe/src/core/memblock.c deleted file mode 100644 index aecddc22c..000000000 --- a/qemu/roms/ipxe/src/core/memblock.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/** @file - * - * Largest memory block - * - */ - -#include <stdint.h> -#include <ipxe/uaccess.h> -#include <ipxe/io.h> -#include <ipxe/memblock.h> - -/** - * Find largest usable memory region - * - * @ret start Start of region - * @ret len Length of region - */ -size_t largest_memblock ( userptr_t *start ) { - struct memory_map memmap; - struct memory_region *region; - physaddr_t max = ~( ( physaddr_t ) 0 ); - physaddr_t region_start; - physaddr_t region_end; - size_t region_len; - unsigned int i; - size_t len = 0; - - /* Avoid returning uninitialised data on error */ - *start = UNULL; - - /* Scan through all memory regions */ - get_memmap ( &memmap ); - for ( i = 0 ; i < memmap.count ; i++ ) { - region = &memmap.regions[i]; - DBG ( "Considering [%llx,%llx)\n", region->start, region->end ); - - /* Truncate block to maximum physical address */ - if ( region->start > max ) { - DBG ( "...starts after maximum address %lx\n", max ); - continue; - } - region_start = region->start; - if ( region->end > max ) { - DBG ( "...end truncated to maximum address %lx\n", max); - region_end = 0; /* =max, given the wraparound */ - } else { - region_end = region->end; - } - region_len = ( region_end - region_start ); - - /* Use largest block */ - if ( region_len > len ) { - DBG ( "...new best block found\n" ); - *start = phys_to_user ( region_start ); - len = region_len; - } - } - - return len; -} diff --git a/qemu/roms/ipxe/src/core/memmap_settings.c b/qemu/roms/ipxe/src/core/memmap_settings.c deleted file mode 100644 index fab3e5f3a..000000000 --- a/qemu/roms/ipxe/src/core/memmap_settings.c +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Copyright (C) 2013 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <string.h> -#include <errno.h> -#include <byteswap.h> -#include <ipxe/init.h> -#include <ipxe/settings.h> -#include <ipxe/io.h> - -/** @file - * - * Memory map settings - * - * Memory map settings are numerically encoded as: - * - * Bits 31-24 Number of regions, minus one - * Bits 23-16 Starting region - * Bits 15-11 Unused - * Bit 10 Ignore non-existent regions (rather than generating an error) - * Bit 9 Include length - * Bit 8 Include start address - * Bits 7-6 Unused - * Bits 5-0 Scale factor (i.e. right shift count) - */ - -/** - * Construct memory map setting tag - * - * @v start Starting region - * @v count Number of regions - * @v include_start Include start address - * @v include_length Include length - * @v ignore Ignore non-existent regions - * @v scale Scale factor - * @ret tag Setting tag - */ -#define MEMMAP_TAG( start, count, include_start, include_length, \ - ignore, scale ) \ - ( ( (start) << 16 ) | ( ( (count) - 1 ) << 24 ) | \ - ( (ignore) << 10 ) | ( (include_length) << 9 ) | \ - ( (include_start) << 8 ) | (scale) ) - -/** - * Extract number of regions from setting tag - * - * @v tag Setting tag - * @ret count Number of regions - */ -#define MEMMAP_COUNT( tag ) ( ( ( (tag) >> 24 ) & 0xff ) + 1 ) - -/** - * Extract starting region from setting tag - * - * @v tag Setting tag - * @ret start Starting region - */ -#define MEMMAP_START( tag ) ( ( (tag) >> 16 ) & 0xff ) - -/** - * Extract ignore flag from setting tag - * - * @v tag Setting tag - * @ret ignore Ignore non-existent regions - */ -#define MEMMAP_IGNORE_NONEXISTENT( tag ) ( (tag) & 0x00000400UL ) - -/** - * Extract length inclusion flag from setting tag - * - * @v tag Setting tag - * @ret include_length Include length - */ -#define MEMMAP_INCLUDE_LENGTH( tag ) ( (tag) & 0x00000200UL ) - -/** - * Extract start address inclusion flag from setting tag - * - * @v tag Setting tag - * @ret include_start Include start address - */ -#define MEMMAP_INCLUDE_START( tag ) ( (tag) & 0x00000100UL ) - -/** - * Extract scale factor from setting tag - * - * @v tag Setting tag - * @v scale Scale factor - */ -#define MEMMAP_SCALE( tag ) ( (tag) & 0x3f ) - -/** Memory map settings scope */ -static const struct settings_scope memmap_settings_scope; - -/** - * Check applicability of memory map setting - * - * @v settings Settings block - * @v setting Setting - * @ret applies Setting applies within this settings block - */ -static int memmap_settings_applies ( struct settings *settings __unused, - const struct setting *setting ) { - - return ( setting->scope == &memmap_settings_scope ); -} - -/** - * Fetch value of memory map setting - * - * @v settings Settings block - * @v setting Setting to fetch - * @v data Buffer to fill with setting data - * @v len Length of buffer - * @ret len Length of setting data, or negative error - */ -static int memmap_settings_fetch ( struct settings *settings, - struct setting *setting, - void *data, size_t len ) { - struct memory_map memmap; - struct memory_region *region; - uint64_t result = 0; - unsigned int i; - unsigned int count; - - DBGC ( settings, "MEMMAP start %d count %d %s%s%s%s scale %d\n", - MEMMAP_START ( setting->tag ), MEMMAP_COUNT ( setting->tag ), - ( MEMMAP_INCLUDE_START ( setting->tag ) ? "start" : "" ), - ( ( MEMMAP_INCLUDE_START ( setting->tag ) && - MEMMAP_INCLUDE_LENGTH ( setting->tag ) ) ? "+" : "" ), - ( MEMMAP_INCLUDE_LENGTH ( setting->tag ) ? "length" : "" ), - ( MEMMAP_IGNORE_NONEXISTENT ( setting->tag ) ? " ignore" : "" ), - MEMMAP_SCALE ( setting->tag ) ); - - /* Fetch memory map */ - get_memmap ( &memmap ); - - /* Extract results from memory map */ - count = MEMMAP_COUNT ( setting->tag ); - for ( i = MEMMAP_START ( setting->tag ) ; count-- ; i++ ) { - - /* Check that region exists */ - if ( i >= memmap.count ) { - if ( MEMMAP_IGNORE_NONEXISTENT ( setting->tag ) ) { - continue; - } else { - DBGC ( settings, "MEMMAP region %d does not " - "exist\n", i ); - return -ENOENT; - } - } - - /* Extract results from this region */ - region = &memmap.regions[i]; - if ( MEMMAP_INCLUDE_START ( setting->tag ) ) { - result += region->start; - DBGC ( settings, "MEMMAP %d start %08llx\n", - i, region->start ); - } - if ( MEMMAP_INCLUDE_LENGTH ( setting->tag ) ) { - result += ( region->end - region->start ); - DBGC ( settings, "MEMMAP %d length %08llx\n", - i, ( region->end - region->start ) ); - } - } - - /* Scale result */ - result >>= MEMMAP_SCALE ( setting->tag ); - - /* Return result */ - result = cpu_to_be64 ( result ); - if ( len > sizeof ( result ) ) - len = sizeof ( result ); - memcpy ( data, &result, len ); - - /* Set type if not already specified */ - if ( ! setting->type ) - setting->type = &setting_type_hexraw; - - return sizeof ( result ); -} - -/** Memory map settings operations */ -static struct settings_operations memmap_settings_operations = { - .applies = memmap_settings_applies, - .fetch = memmap_settings_fetch, -}; - -/** Memory map settings */ -static struct settings memmap_settings = { - .refcnt = NULL, - .siblings = LIST_HEAD_INIT ( memmap_settings.siblings ), - .children = LIST_HEAD_INIT ( memmap_settings.children ), - .op = &memmap_settings_operations, - .default_scope = &memmap_settings_scope, -}; - -/** Initialise memory map settings */ -static void memmap_settings_init ( void ) { - int rc; - - if ( ( rc = register_settings ( &memmap_settings, NULL, - "memmap" ) ) != 0 ) { - DBG ( "MEMMAP could not register settings: %s\n", - strerror ( rc ) ); - return; - } -} - -/** Memory map settings initialiser */ -struct init_fn memmap_settings_init_fn __init_fn ( INIT_NORMAL ) = { - .initialise = memmap_settings_init, -}; - -/** Memory map predefined settings */ -const struct setting memsize_setting __setting ( SETTING_MISC, memsize ) = { - .name = "memsize", - .description = "Memory size (in MB)", - .tag = MEMMAP_TAG ( 0, 0x100, 0, 1, 1, 20 ), - .type = &setting_type_int32, - .scope = &memmap_settings_scope, -}; diff --git a/qemu/roms/ipxe/src/core/menu.c b/qemu/roms/ipxe/src/core/menu.c deleted file mode 100644 index ab5b0c7f5..000000000 --- a/qemu/roms/ipxe/src/core/menu.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/** @file - * - * Menu selection - * - */ - -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#include <ipxe/list.h> -#include <ipxe/menu.h> - -/** List of all menus */ -static LIST_HEAD ( menus ); - -/** - * Create menu - * - * @v name Menu name, or NULL - * @v title Menu title, or NULL - * @ret menu Menu, or NULL on failure - */ -struct menu * create_menu ( const char *name, const char *title ) { - size_t name_len; - size_t title_len; - size_t len; - struct menu *menu; - char *name_copy; - char *title_copy; - - /* Destroy any existing menu of this name */ - menu = find_menu ( name ); - if ( menu ) - destroy_menu ( menu ); - - /* Use empty title if none given */ - if ( ! title ) - title = ""; - - /* Allocate menu */ - name_len = ( name ? ( strlen ( name ) + 1 /* NUL */ ) : 0 ); - title_len = ( strlen ( title ) + 1 /* NUL */ ); - len = ( sizeof ( *menu ) + name_len + title_len ); - menu = zalloc ( len ); - if ( ! menu ) - return NULL; - name_copy = ( ( void * ) ( menu + 1 ) ); - title_copy = ( name_copy + name_len ); - - /* Initialise menu */ - if ( name ) { - strcpy ( name_copy, name ); - menu->name = name_copy; - } - strcpy ( title_copy, title ); - menu->title = title_copy; - INIT_LIST_HEAD ( &menu->items ); - - /* Add to list of menus */ - list_add_tail ( &menu->list, &menus ); - - DBGC ( menu, "MENU %s created with title \"%s\"\n", - menu->name, menu->title ); - - return menu; -} - -/** - * Add menu item - * - * @v menu Menu - * @v label Label, or NULL - * @v text Text, or NULL - * @v shortcut Shortcut key - * @v is_default Item is the default item - * @ret item Menu item, or NULL on failure - */ -struct menu_item * add_menu_item ( struct menu *menu, const char *label, - const char *text, int shortcut, - int is_default ) { - size_t label_len; - size_t text_len; - size_t len; - struct menu_item *item; - char *label_copy; - char *text_copy; - - /* Use empty text if none given */ - if ( ! text ) - text = ""; - - /* Allocate item */ - label_len = ( label ? ( strlen ( label ) + 1 /* NUL */ ) : 0 ); - text_len = ( strlen ( text ) + 1 /* NUL */ ); - len = ( sizeof ( *item ) + label_len + text_len ); - item = zalloc ( len ); - if ( ! item ) - return NULL; - label_copy = ( ( void * ) ( item + 1 ) ); - text_copy = ( label_copy + label_len ); - - /* Initialise item */ - if ( label ) { - strcpy ( label_copy, label ); - item->label = label_copy; - } - strcpy ( text_copy, text ); - item->text = text_copy; - item->shortcut = shortcut; - item->is_default = is_default; - - /* Add to list of items */ - list_add_tail ( &item->list, &menu->items ); - - return item; -} - -/** - * Destroy menu - * - * @v menu Menu - */ -void destroy_menu ( struct menu *menu ) { - struct menu_item *item; - struct menu_item *tmp; - - /* Remove from list of menus */ - list_del ( &menu->list ); - - /* Free items */ - list_for_each_entry_safe ( item, tmp, &menu->items, list ) { - list_del ( &item->list ); - free ( item ); - } - - /* Free menu */ - free ( menu ); -} - -/** - * Find menu - * - * @v name Menu name, or NULL - * @ret menu Menu, or NULL if not found - */ -struct menu * find_menu ( const char *name ) { - struct menu *menu; - - list_for_each_entry ( menu, &menus, list ) { - if ( ( menu->name == name ) || - ( strcmp ( menu->name, name ) == 0 ) ) { - return menu; - } - } - - return NULL; -} diff --git a/qemu/roms/ipxe/src/core/monojob.c b/qemu/roms/ipxe/src/core/monojob.c deleted file mode 100644 index 817f21b2c..000000000 --- a/qemu/roms/ipxe/src/core/monojob.c +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <string.h> -#include <stdio.h> -#include <errno.h> -#include <ipxe/process.h> -#include <ipxe/console.h> -#include <ipxe/keys.h> -#include <ipxe/job.h> -#include <ipxe/monojob.h> -#include <ipxe/timer.h> - -/** @file - * - * Single foreground job - * - */ - -static int monojob_rc; - -static void monojob_close ( struct interface *intf, int rc ) { - monojob_rc = rc; - intf_restart ( intf, rc ); -} - -static struct interface_operation monojob_intf_op[] = { - INTF_OP ( intf_close, struct interface *, monojob_close ), -}; - -static struct interface_descriptor monojob_intf_desc = - INTF_DESC_PURE ( monojob_intf_op ); - -struct interface monojob = INTF_INIT ( monojob_intf_desc ); - -/** - * Wait for single foreground job to complete - * - * @v string Job description to display, or NULL to be silent - * @v timeout Timeout period, in ticks (0=indefinite) - * @ret rc Job final status code - */ -int monojob_wait ( const char *string, unsigned long timeout ) { - struct job_progress progress; - unsigned long last_keycheck; - unsigned long last_progress; - unsigned long last_display; - unsigned long now; - unsigned long elapsed; - unsigned long completed = 0; - unsigned long scaled_completed; - unsigned long scaled_total; - unsigned int percentage; - int shown_percentage = 0; - int ongoing_rc; - int key; - int rc; - - if ( string ) - printf ( "%s...", string ); - monojob_rc = -EINPROGRESS; - last_keycheck = last_progress = last_display = currticks(); - while ( monojob_rc == -EINPROGRESS ) { - - /* Allow job to progress */ - step(); - now = currticks(); - - /* Check for keypresses. This can be time-consuming, - * so check only once per clock tick. - */ - elapsed = ( now - last_keycheck ); - if ( elapsed ) { - if ( iskey() ) { - key = getchar(); - if ( key == CTRL_C ) { - monojob_rc = -ECANCELED; - break; - } - } - last_keycheck = now; - } - - /* Monitor progress */ - ongoing_rc = job_progress ( &monojob, &progress ); - - /* Reset timeout if progress has been made */ - if ( completed != progress.completed ) - last_progress = now; - completed = progress.completed; - - /* Check for timeout, if applicable */ - elapsed = ( now - last_progress ); - if ( timeout && ( elapsed >= timeout ) ) { - monojob_rc = ( ongoing_rc ? ongoing_rc : -ETIMEDOUT ); - break; - } - - /* Display progress, if applicable */ - elapsed = ( now - last_display ); - if ( string && ( elapsed >= TICKS_PER_SEC ) ) { - if ( shown_percentage ) - printf ( "\b\b\b\b \b\b\b\b" ); - /* Normalise progress figures to avoid overflow */ - scaled_completed = ( progress.completed / 128 ); - scaled_total = ( progress.total / 128 ); - if ( scaled_total ) { - percentage = ( ( 100 * scaled_completed ) / - scaled_total ); - printf ( "%3d%%", percentage ); - shown_percentage = 1; - } else { - printf ( "." ); - shown_percentage = 0; - } - last_display = now; - } - } - rc = monojob_rc; - monojob_close ( &monojob, rc ); - - if ( shown_percentage ) - printf ( "\b\b\b\b \b\b\b\b" ); - - if ( string ) { - if ( rc ) { - printf ( " %s\n", strerror ( rc ) ); - } else { - printf ( " ok\n" ); - } - } - - return rc; -} diff --git a/qemu/roms/ipxe/src/core/null_nap.c b/qemu/roms/ipxe/src/core/null_nap.c deleted file mode 100644 index c886f548e..000000000 --- a/qemu/roms/ipxe/src/core/null_nap.c +++ /dev/null @@ -1,3 +0,0 @@ -#include <ipxe/nap.h> - -PROVIDE_NAP_INLINE ( null, cpu_nap ); diff --git a/qemu/roms/ipxe/src/core/null_reboot.c b/qemu/roms/ipxe/src/core/null_reboot.c deleted file mode 100644 index 7be5612a3..000000000 --- a/qemu/roms/ipxe/src/core/null_reboot.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2013 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/** - * @file - * - * Null reboot mechanism - * - */ - -#include <stdio.h> -#include <errno.h> -#include <ipxe/reboot.h> - -/** - * Reboot system - * - * @v warm Perform a warm reboot - */ -static void null_reboot ( int warm __unused ) { - - printf ( "Cannot reboot; not implemented\n" ); - while ( 1 ) {} -} - -/** - * Power off system - * - * @ret rc Return status code - */ -static int null_poweroff ( void ) { - - return -ENOTSUP; -} - -PROVIDE_REBOOT ( null, reboot, null_reboot ); -PROVIDE_REBOOT ( null, poweroff, null_poweroff ); diff --git a/qemu/roms/ipxe/src/core/null_sanboot.c b/qemu/roms/ipxe/src/core/null_sanboot.c deleted file mode 100644 index 2f7522c6c..000000000 --- a/qemu/roms/ipxe/src/core/null_sanboot.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2010 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <errno.h> -#include <ipxe/sanboot.h> - -static int null_san_hook ( struct uri *uri __unused, - unsigned int drive __unused ) { - return -EOPNOTSUPP; -} - -static void null_san_unhook ( unsigned int drive __unused ) { - /* Do nothing */ -} - -static int null_san_boot ( unsigned int drive __unused ) { - return -EOPNOTSUPP; -} - -static int null_san_describe ( unsigned int drive __unused ) { - return -EOPNOTSUPP; -} - -PROVIDE_SANBOOT_INLINE ( null, san_default_drive ); -PROVIDE_SANBOOT ( null, san_hook, null_san_hook ); -PROVIDE_SANBOOT ( null, san_unhook, null_san_unhook ); -PROVIDE_SANBOOT ( null, san_boot, null_san_boot ); -PROVIDE_SANBOOT ( null, san_describe, null_san_describe ); diff --git a/qemu/roms/ipxe/src/core/null_time.c b/qemu/roms/ipxe/src/core/null_time.c deleted file mode 100644 index 90041a456..000000000 --- a/qemu/roms/ipxe/src/core/null_time.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/** @file - * - * Nonexistent time source - * - */ - -#include <ipxe/time.h> - -PROVIDE_TIME_INLINE ( null, time_now ); diff --git a/qemu/roms/ipxe/src/core/nvo.c b/qemu/roms/ipxe/src/core/nvo.c deleted file mode 100644 index d2c9b5e73..000000000 --- a/qemu/roms/ipxe/src/core/nvo.c +++ /dev/null @@ -1,328 +0,0 @@ -/* - * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <ipxe/dhcp.h> -#include <ipxe/nvs.h> -#include <ipxe/nvo.h> - -/** @file - * - * Non-volatile stored options - * - */ - -/** - * Calculate checksum over non-volatile stored options - * - * @v nvo Non-volatile options block - * @ret sum Checksum - */ -static unsigned int nvo_checksum ( struct nvo_block *nvo ) { - uint8_t *data = nvo->data; - uint8_t sum = 0; - unsigned int i; - - for ( i = 0 ; i < nvo->len ; i++ ) { - sum += *(data++); - } - return sum; -} - -/** - * Reallocate non-volatile stored options block - * - * @v nvo Non-volatile options block - * @v len New length - * @ret rc Return status code - */ -static int nvo_realloc ( struct nvo_block *nvo, size_t len ) { - void *new_data; - - /* Reallocate data */ - new_data = realloc ( nvo->data, len ); - if ( ! new_data ) { - DBGC ( nvo, "NVO %p could not allocate %zd bytes\n", - nvo, len ); - return -ENOMEM; - } - nvo->data = new_data; - nvo->len = len; - - /* Update DHCP option block */ - if ( len ) { - nvo->dhcpopts.data = ( nvo->data + 1 /* checksum */ ); - nvo->dhcpopts.alloc_len = ( len - 1 /* checksum */ ); - } else { - nvo->dhcpopts.data = NULL; - nvo->dhcpopts.used_len = 0; - nvo->dhcpopts.alloc_len = 0; - } - - return 0; -} - -/** - * Reallocate non-volatile stored options DHCP option block - * - * @v options DHCP option block - * @v len New length - * @ret rc Return status code - */ -static int nvo_realloc_dhcpopt ( struct dhcp_options *options, size_t len ) { - struct nvo_block *nvo = - container_of ( options, struct nvo_block, dhcpopts ); - int rc; - - /* Refuse to reallocate if we have no way to resize the block */ - if ( ! nvo->resize ) - return dhcpopt_no_realloc ( options, len ); - - /* Allow one byte for the checksum (if any data is present) */ - if ( len ) - len += 1; - - /* Resize underlying non-volatile options block */ - if ( ( rc = nvo->resize ( nvo, len ) ) != 0 ) { - DBGC ( nvo, "NVO %p could not resize to %zd bytes: %s\n", - nvo, len, strerror ( rc ) ); - return rc; - } - - /* Reallocate in-memory options block */ - if ( ( rc = nvo_realloc ( nvo, len ) ) != 0 ) - return rc; - - return 0; -} - -/** - * Load non-volatile stored options from non-volatile storage device - * - * @v nvo Non-volatile options block - * @ret rc Return status code - */ -static int nvo_load ( struct nvo_block *nvo ) { - uint8_t *options_data = nvo->dhcpopts.data; - int rc; - - /* Skip reading zero-length NVO fields */ - if ( nvo->len == 0 ) { - DBGC ( nvo, "NVO %p is empty; skipping load\n", nvo ); - return 0; - } - - /* Read data */ - if ( ( rc = nvs_read ( nvo->nvs, nvo->address, nvo->data, - nvo->len ) ) != 0 ) { - DBGC ( nvo, "NVO %p could not read %zd bytes at %#04x: %s\n", - nvo, nvo->len, nvo->address, strerror ( rc ) ); - return rc; - } - - /* If checksum fails, or options data starts with a zero, - * assume the whole block is invalid. This should capture the - * case of random initial contents. - */ - if ( ( nvo_checksum ( nvo ) != 0 ) || ( options_data[0] == 0 ) ) { - DBGC ( nvo, "NVO %p has checksum %02x and initial byte %02x; " - "assuming empty\n", nvo, nvo_checksum ( nvo ), - options_data[0] ); - memset ( nvo->data, 0, nvo->len ); - } - - /* Rescan DHCP option block */ - dhcpopt_update_used_len ( &nvo->dhcpopts ); - - DBGC ( nvo, "NVO %p loaded from non-volatile storage\n", nvo ); - return 0; -} - -/** - * Save non-volatile stored options back to non-volatile storage device - * - * @v nvo Non-volatile options block - * @ret rc Return status code - */ -static int nvo_save ( struct nvo_block *nvo ) { - uint8_t *checksum = nvo->data; - int rc; - - /* Recalculate checksum, if applicable */ - if ( nvo->len > 0 ) - *checksum -= nvo_checksum ( nvo ); - - /* Write data */ - if ( ( rc = nvs_write ( nvo->nvs, nvo->address, nvo->data, - nvo->len ) ) != 0 ) { - DBGC ( nvo, "NVO %p could not write %zd bytes at %#04x: %s\n", - nvo, nvo->len, nvo->address, strerror ( rc ) ); - return rc; - } - - DBGC ( nvo, "NVO %p saved to non-volatile storage\n", nvo ); - return 0; -} - -/** - * Check applicability of NVO setting - * - * @v settings Settings block - * @v setting Setting - * @ret applies Setting applies within this settings block - */ -int nvo_applies ( struct settings *settings __unused, - const struct setting *setting ) { - - return ( ( setting->scope == NULL ) && - dhcpopt_applies ( setting->tag ) ); -} - -/** - * Store value of NVO setting - * - * @v settings Settings block - * @v setting Setting to store - * @v data Setting data, or NULL to clear setting - * @v len Length of setting data - * @ret rc Return status code - */ -static int nvo_store ( struct settings *settings, const struct setting *setting, - const void *data, size_t len ) { - struct nvo_block *nvo = - container_of ( settings, struct nvo_block, settings ); - int rc; - - /* Update stored options */ - if ( ( rc = dhcpopt_store ( &nvo->dhcpopts, setting->tag, - data, len ) ) != 0 ) { - DBGC ( nvo, "NVO %p could not store %zd bytes: %s\n", - nvo, len, strerror ( rc ) ); - return rc; - } - - /* Save updated options to NVS */ - if ( ( rc = nvo_save ( nvo ) ) != 0 ) - return rc; - - return 0; -} - -/** - * Fetch value of NVO setting - * - * @v settings Settings block - * @v setting Setting to fetch - * @v data Buffer to fill with setting data - * @v len Length of buffer - * @ret len Length of setting data, or negative error - * - * The actual length of the setting will be returned even if - * the buffer was too small. - */ -static int nvo_fetch ( struct settings *settings, struct setting *setting, - void *data, size_t len ) { - struct nvo_block *nvo = - container_of ( settings, struct nvo_block, settings ); - - return dhcpopt_fetch ( &nvo->dhcpopts, setting->tag, data, len ); -} - -/** NVO settings operations */ -static struct settings_operations nvo_settings_operations = { - .applies = nvo_applies, - .store = nvo_store, - .fetch = nvo_fetch, -}; - -/** - * Initialise non-volatile stored options - * - * @v nvo Non-volatile options block - * @v nvs Underlying non-volatile storage device - * @v address Address within NVS device - * @v len Length of non-volatile options data - * @v resize Resize method - * @v refcnt Containing object reference counter, or NULL - */ -void nvo_init ( struct nvo_block *nvo, struct nvs_device *nvs, - size_t address, size_t len, - int ( * resize ) ( struct nvo_block *nvo, size_t len ), - struct refcnt *refcnt ) { - nvo->nvs = nvs; - nvo->address = address; - nvo->len = len; - nvo->resize = resize; - dhcpopt_init ( &nvo->dhcpopts, NULL, 0, nvo_realloc_dhcpopt ); - settings_init ( &nvo->settings, &nvo_settings_operations, - refcnt, NULL ); -} - -/** - * Register non-volatile stored options - * - * @v nvo Non-volatile options block - * @v parent Parent settings block, or NULL - * @ret rc Return status code - */ -int register_nvo ( struct nvo_block *nvo, struct settings *parent ) { - int rc; - - /* Allocate memory for options */ - if ( ( rc = nvo_realloc ( nvo, nvo->len ) ) != 0 ) - goto err_realloc; - - /* Read data from NVS */ - if ( ( rc = nvo_load ( nvo ) ) != 0 ) - goto err_load; - - /* Register settings */ - if ( ( rc = register_settings ( &nvo->settings, parent, - NVO_SETTINGS_NAME ) ) != 0 ) - goto err_register; - - DBGC ( nvo, "NVO %p registered\n", nvo ); - return 0; - - err_register: - err_load: - nvo_realloc ( nvo, 0 ); - err_realloc: - return rc; -} - -/** - * Unregister non-volatile stored options - * - * @v nvo Non-volatile options block - */ -void unregister_nvo ( struct nvo_block *nvo ) { - unregister_settings ( &nvo->settings ); - nvo_realloc ( nvo, 0 ); - DBGC ( nvo, "NVO %p unregistered\n", nvo ); -} diff --git a/qemu/roms/ipxe/src/core/open.c b/qemu/roms/ipxe/src/core/open.c deleted file mode 100644 index 9d665ffda..000000000 --- a/qemu/roms/ipxe/src/core/open.c +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdarg.h> -#include <string.h> -#include <errno.h> -#include <ipxe/xfer.h> -#include <ipxe/uri.h> -#include <ipxe/socket.h> -#include <ipxe/open.h> - -/** @file - * - * Data transfer interface opening - * - */ - -/** - * Find opener for URI scheme - * - * @v scheme URI scheme - * @ret opener Opener, or NULL - */ -struct uri_opener * xfer_uri_opener ( const char *scheme ) { - struct uri_opener *opener; - - for_each_table_entry ( opener, URI_OPENERS ) { - if ( strcmp ( scheme, opener->scheme ) == 0 ) - return opener; - } - return NULL; -} - -/** - * Open URI - * - * @v intf Data transfer interface - * @v uri URI - * @ret rc Return status code - * - * The URI will be regarded as being relative to the current working - * URI (see churi()). - */ -int xfer_open_uri ( struct interface *intf, struct uri *uri ) { - struct uri_opener *opener; - struct uri *resolved_uri; - int rc; - - /* Resolve URI */ - resolved_uri = resolve_uri ( cwuri, uri ); - if ( ! resolved_uri ) { - rc = -ENOMEM; - goto err_resolve_uri; - } - - /* Find opener which supports this URI scheme */ - opener = xfer_uri_opener ( resolved_uri->scheme ); - if ( ! opener ) { - DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " attempted to open " - "unsupported URI scheme \"%s\"\n", - INTF_DBG ( intf ), resolved_uri->scheme ); - rc = -ENOTSUP; - goto err_opener; - } - - /* Call opener */ - DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " opening %s URI\n", - INTF_DBG ( intf ), resolved_uri->scheme ); - if ( ( rc = opener->open ( intf, resolved_uri ) ) != 0 ) { - DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " could not open: " - "%s\n", INTF_DBG ( intf ), strerror ( rc ) ); - goto err_open; - } - - err_open: - err_opener: - uri_put ( resolved_uri ); - err_resolve_uri: - return rc; -} - -/** - * Open URI string - * - * @v intf Data transfer interface - * @v uri_string URI string (e.g. "http://ipxe.org/kernel") - * @ret rc Return status code - * - * The URI will be regarded as being relative to the current working - * URI (see churi()). - */ -int xfer_open_uri_string ( struct interface *intf, - const char *uri_string ) { - struct uri *uri; - int rc; - - DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " opening URI %s\n", - INTF_DBG ( intf ), uri_string ); - - uri = parse_uri ( uri_string ); - if ( ! uri ) - return -ENOMEM; - - rc = xfer_open_uri ( intf, uri ); - - uri_put ( uri ); - return rc; -} - -/** - * Open socket - * - * @v intf Data transfer interface - * @v semantics Communication semantics (e.g. SOCK_STREAM) - * @v peer Peer socket address - * @v local Local socket address, or NULL - * @ret rc Return status code - */ -int xfer_open_socket ( struct interface *intf, int semantics, - struct sockaddr *peer, struct sockaddr *local ) { - struct socket_opener *opener; - - DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " opening (%s,%s) socket\n", - INTF_DBG ( intf ), socket_semantics_name ( semantics ), - socket_family_name ( peer->sa_family ) ); - - for_each_table_entry ( opener, SOCKET_OPENERS ) { - if ( ( opener->semantics == semantics ) && - ( opener->family == peer->sa_family ) ) { - return opener->open ( intf, peer, local ); - } - } - - DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " attempted to open " - "unsupported socket type (%s,%s)\n", - INTF_DBG ( intf ), socket_semantics_name ( semantics ), - socket_family_name ( peer->sa_family ) ); - return -ENOTSUP; -} - -/** - * Open location - * - * @v intf Data transfer interface - * @v type Location type - * @v args Remaining arguments depend upon location type - * @ret rc Return status code - */ -int xfer_vopen ( struct interface *intf, int type, va_list args ) { - switch ( type ) { - case LOCATION_URI_STRING: { - const char *uri_string = va_arg ( args, const char * ); - - return xfer_open_uri_string ( intf, uri_string ); } - case LOCATION_URI: { - struct uri *uri = va_arg ( args, struct uri * ); - - return xfer_open_uri ( intf, uri ); } - case LOCATION_SOCKET: { - int semantics = va_arg ( args, int ); - struct sockaddr *peer = va_arg ( args, struct sockaddr * ); - struct sockaddr *local = va_arg ( args, struct sockaddr * ); - - return xfer_open_socket ( intf, semantics, peer, local ); } - default: - DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " attempted to " - "open unsupported location type %d\n", - INTF_DBG ( intf ), type ); - return -ENOTSUP; - } -} - -/** - * Open location - * - * @v intf Data transfer interface - * @v type Location type - * @v ... Remaining arguments depend upon location type - * @ret rc Return status code - */ -int xfer_open ( struct interface *intf, int type, ... ) { - va_list args; - int rc; - - va_start ( args, type ); - rc = xfer_vopen ( intf, type, args ); - va_end ( args ); - return rc; -} - -/** - * Reopen location - * - * @v intf Data transfer interface - * @v type Location type - * @v args Remaining arguments depend upon location type - * @ret rc Return status code - * - * This will close the existing connection and open a new connection - * using xfer_vopen(). It is intended to be used as a .vredirect - * method handler. - */ -int xfer_vreopen ( struct interface *intf, int type, va_list args ) { - - /* Close existing connection */ - intf_restart ( intf, 0 ); - - /* Open new location */ - return xfer_vopen ( intf, type, args ); -} diff --git a/qemu/roms/ipxe/src/core/params.c b/qemu/roms/ipxe/src/core/params.c deleted file mode 100644 index e1f66acca..000000000 --- a/qemu/roms/ipxe/src/core/params.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (C) 2013 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/** @file - * - * Form parameters - * - */ - -#include <stdlib.h> -#include <string.h> -#include <ipxe/params.h> - -/** List of all parameter lists */ -static LIST_HEAD ( parameters ); - -/** - * Free form parameter list - * - * @v refcnt Reference count - */ -static void free_parameters ( struct refcnt *refcnt ) { - struct parameters *params = - container_of ( refcnt, struct parameters, refcnt ); - struct parameter *param; - struct parameter *tmp; - - DBGC ( params, "PARAMS \"%s\" destroyed\n", params->name ); - - /* Free all parameters */ - list_for_each_entry_safe ( param, tmp, ¶ms->entries, list ) { - list_del ( ¶m->list ); - free ( param ); - } - - /* Free parameter list */ - free ( params ); -} - -/** - * Find form parameter list by name - * - * @v name Parameter list name (may be NULL) - * @ret params Parameter list, or NULL if not found - */ -struct parameters * find_parameters ( const char *name ) { - struct parameters *params; - - list_for_each_entry ( params, ¶meters, list ) { - if ( ( params->name == name ) || - ( strcmp ( params->name, name ) == 0 ) ) { - return params; - } - } - return NULL; -} - -/** - * Create form parameter list - * - * @v name Parameter list name (may be NULL) - * @ret params Parameter list, or NULL on failure - */ -struct parameters * create_parameters ( const char *name ) { - struct parameters *params; - size_t name_len; - char *name_copy; - - /* Destroy any existing parameter list of this name */ - params = find_parameters ( name ); - if ( params ) { - claim_parameters ( params ); - params_put ( params ); - } - - /* Allocate parameter list */ - name_len = ( name ? ( strlen ( name ) + 1 /* NUL */ ) : 0 ); - params = zalloc ( sizeof ( *params ) + name_len ); - if ( ! params ) - return NULL; - ref_init ( ¶ms->refcnt, free_parameters ); - name_copy = ( ( void * ) ( params + 1 ) ); - - /* Populate parameter list */ - if ( name ) { - strcpy ( name_copy, name ); - params->name = name_copy; - } - INIT_LIST_HEAD ( ¶ms->entries ); - - /* Add to list of parameter lists */ - list_add_tail ( ¶ms->list, ¶meters ); - - DBGC ( params, "PARAMS \"%s\" created\n", params->name ); - return params; -} - -/** - * Add form parameter - * - * @v params Parameter list - * @v key Parameter key - * @v value Parameter value - * @ret param Parameter, or NULL on failure - */ -struct parameter * add_parameter ( struct parameters *params, - const char *key, const char *value ) { - struct parameter *param; - size_t key_len; - size_t value_len; - char *key_copy; - char *value_copy; - - /* Allocate parameter */ - key_len = ( strlen ( key ) + 1 /* NUL */ ); - value_len = ( strlen ( value ) + 1 /* NUL */ ); - param = zalloc ( sizeof ( *param ) + key_len + value_len ); - if ( ! param ) - return NULL; - key_copy = ( ( void * ) ( param + 1 ) ); - value_copy = ( key_copy + key_len ); - - /* Populate parameter */ - strcpy ( key_copy, key ); - param->key = key_copy; - strcpy ( value_copy, value ); - param->value = value_copy; - - /* Add to list of parameters */ - list_add_tail ( ¶m->list, ¶ms->entries ); - - DBGC ( params, "PARAMS \"%s\" added \"%s\"=\"%s\"\n", - params->name, param->key, param->value ); - return param; -} diff --git a/qemu/roms/ipxe/src/core/parseopt.c b/qemu/roms/ipxe/src/core/parseopt.c deleted file mode 100644 index 66f60158c..000000000 --- a/qemu/roms/ipxe/src/core/parseopt.c +++ /dev/null @@ -1,454 +0,0 @@ -/* - * Copyright (C) 2010 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stddef.h> -#include <stdint.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <getopt.h> -#include <ipxe/netdevice.h> -#include <ipxe/menu.h> -#include <ipxe/settings.h> -#include <ipxe/params.h> -#include <ipxe/timer.h> -#include <ipxe/parseopt.h> -#include <config/branding.h> - -/** @file - * - * Command line option parsing - * - */ - -/** Return status code for "--help" option */ -#define ECANCELED_NO_OP __einfo_error ( EINFO_ECANCELED_NO_OP ) -#define EINFO_ECANCELED_NO_OP \ - __einfo_uniqify ( EINFO_ECANCELED, 0x01, "Nothing to do" ) - -/* Disambiguate the various error codes */ -#define EINVAL_INTEGER __einfo_error ( EINFO_EINVAL_INTEGER ) -#define EINFO_EINVAL_INTEGER \ - __einfo_uniqify ( EINFO_EINVAL, 0x01, "Invalid integer value" ) -#define EINVAL_UNKNOWN_OPTION __einfo_error ( EINFO_EINVAL_UNKNOWN_OPTION ) -#define EINFO_EINVAL_UNKNOWN_OPTION \ - __einfo_uniqify ( EINFO_EINVAL, 0x02, "Unrecognised option" ) -#define EINVAL_MISSING_ARGUMENT __einfo_error ( EINFO_EINVAL_MISSING_ARGUMENT ) -#define EINFO_EINVAL_MISSING_ARGUMENT \ - __einfo_uniqify ( EINFO_EINVAL, 0x03, "Missing argument" ) - -/** -* Parse string value - * - * @v text Text - * @ret value String value - * @ret rc Return status code - */ -int parse_string ( char *text, char **value ) { - - /* Sanity check */ - assert ( text != NULL ); - - /* Parse string */ - *value = text; - - return 0; -} - -/** - * Parse integer value - * - * @v text Text - * @ret value Integer value - * @ret rc Return status code - */ -int parse_integer ( char *text, unsigned int *value ) { - char *endp; - - /* Sanity check */ - assert ( text != NULL ); - - /* Parse integer */ - *value = strtoul ( text, &endp, 0 ); - if ( *endp ) { - printf ( "\"%s\": invalid integer value\n", text ); - return -EINVAL_INTEGER; - } - - return 0; -} - -/** - * Parse timeout value (in ms) - * - * @v text Text - * @ret value Integer value - * @ret rc Return status code - */ -int parse_timeout ( char *text, unsigned long *value ) { - unsigned int value_ms; - int rc; - - /* Parse raw integer value */ - if ( ( rc = parse_integer ( text, &value_ms ) ) != 0 ) - return rc; - - /* Convert to a number of timer ticks */ - *value = ( ( value_ms * TICKS_PER_SEC ) / 1000 ); - - return 0; -} - -/** - * Parse network device name - * - * @v text Text - * @ret netdev Network device - * @ret rc Return status code - */ -int parse_netdev ( char *text, struct net_device **netdev ) { - - /* Sanity check */ - assert ( text != NULL ); - - /* Find network device */ - *netdev = find_netdev ( text ); - if ( ! *netdev ) { - printf ( "\"%s\": no such network device\n", text ); - return -ENODEV; - } - - return 0; -} - -/** - * Parse network device configurator name - * - * @v text Text - * @ret configurator Network device configurator - * @ret rc Return status code - */ -int parse_netdev_configurator ( char *text, - struct net_device_configurator **configurator ){ - - /* Sanity check */ - assert ( text != NULL ); - - /* Find network device configurator */ - *configurator = find_netdev_configurator ( text ); - if ( ! *configurator ) { - printf ( "\"%s\": no such configurator\n", text ); - return -ENOTSUP; - } - - return 0; -} - -/** - * Parse menu name - * - * @v text Text - * @ret menu Menu - * @ret rc Return status code - */ -int parse_menu ( char *text, struct menu **menu ) { - - /* Find menu */ - *menu = find_menu ( text ); - if ( ! *menu ) { - if ( text ) { - printf ( "\"%s\": no such menu\n", text ); - } else { - printf ( "No default menu\n" ); - } - return -ENOENT; - } - - return 0; -} - -/** - * Parse flag - * - * @v text Text (ignored) - * @ret flag Flag to set - * @ret rc Return status code - */ -int parse_flag ( char *text __unused, int *flag ) { - - /* Set flag */ - *flag = 1; - - return 0; -} - -/** - * Parse key - * - * @v text Text - * @ret key Key - * @ret rc Return status code - */ -int parse_key ( char *text, unsigned int *key ) { - - /* Interpret single characters as being a literal key character */ - if ( text[0] && ! text[1] ) { - *key = text[0]; - return 0; - } - - /* Otherwise, interpret as an integer */ - return parse_integer ( text, key ); -} - -/** - * Parse settings block name - * - * @v text Text - * @ret value Integer value - * @ret rc Return status code - */ -int parse_settings ( char *text, struct settings **value ) { - - /* Sanity check */ - assert ( text != NULL ); - - /* Parse scope name */ - *value = find_settings ( text ); - if ( ! *value ) { - printf ( "\"%s\": no such scope\n", text ); - return -EINVAL; - } - - return 0; -} - -/** - * Parse setting name - * - * @v text Text - * @v setting Named setting to fill in - * @v get_child Function to find or create child settings block - * @ret rc Return status code - * - * Note that this function modifies the original @c text. - */ -int parse_setting ( char *text, struct named_setting *setting, - get_child_settings_t get_child ) { - int rc; - - /* Sanity check */ - assert ( text != NULL ); - - /* Parse setting name */ - if ( ( rc = parse_setting_name ( text, get_child, &setting->settings, - &setting->setting ) ) != 0 ) { - printf ( "\"%s\": invalid setting\n", text ); - return rc; - } - - return 0; -} - -/** - * Parse existing setting name - * - * @v text Text - * @v setting Named setting to fill in - * @ret rc Return status code - * - * Note that this function modifies the original @c text. - */ -int parse_existing_setting ( char *text, struct named_setting *setting ) { - - return parse_setting ( text, setting, find_child_settings ); -} - -/** - * Parse and autovivify setting name - * - * @v text Text - * @v setting Named setting to fill in - * @ret rc Return status code - * - * Note that this function modifies the original @c text. - */ -int parse_autovivified_setting ( char *text, struct named_setting *setting ) { - - return parse_setting ( text, setting, autovivify_child_settings ); -} - -/** - * Parse form parameter list name - * - * @v text Text - * @ret params Parameter list - * @ret rc Return status code - */ -int parse_parameters ( char *text, struct parameters **params ) { - - /* Find parameter list */ - *params = find_parameters ( text ); - if ( ! *params ) { - if ( text ) { - printf ( "\"%s\": no such parameter list\n", text ); - } else { - printf ( "No default parameter list\n" ); - } - return -ENOENT; - } - - return 0; -} - -/** - * Print command usage message - * - * @v cmd Command descriptor - * @v argv Argument list - */ -void print_usage ( struct command_descriptor *cmd, char **argv ) { - struct option_descriptor *option; - unsigned int i; - int is_optional; - - printf ( "Usage:\n\n %s", argv[0] ); - for ( i = 0 ; i < cmd->num_options ; i++ ) { - option = &cmd->options[i]; - printf ( " [-%c|--%s", option->shortopt, option->longopt ); - if ( option->has_arg ) { - is_optional = ( option->has_arg == optional_argument ); - printf ( " %s<%s>%s", ( is_optional ? "[" : "" ), - option->longopt, ( is_optional ? "]" : "" ) ); - } - printf ( "]" ); - } - if ( cmd->usage ) - printf ( " %s", cmd->usage ); - printf ( "\n\nSee " PRODUCT_COMMAND_URI " for further information\n", - argv[0] ); -} - -/** - * Reparse command-line options - * - * @v argc Argument count - * @v argv Argument list - * @v cmd Command descriptor - * @v opts Options (already initialised with default values) - * @ret rc Return status code - */ -int reparse_options ( int argc, char **argv, struct command_descriptor *cmd, - void *opts ) { - struct option longopts[ cmd->num_options + 1 /* help */ + 1 /* end */ ]; - char shortopts[ cmd->num_options * 3 /* possible "::" */ + 1 /* "h" */ - + 1 /* NUL */ ]; - unsigned int shortopt_idx = 0; - int ( * parse ) ( char *text, void *value ); - void *value; - unsigned int i; - unsigned int j; - unsigned int num_args; - int c; - int rc; - - /* Construct long and short option lists for getopt_long() */ - memset ( longopts, 0, sizeof ( longopts ) ); - for ( i = 0 ; i < cmd->num_options ; i++ ) { - longopts[i].name = cmd->options[i].longopt; - longopts[i].has_arg = cmd->options[i].has_arg; - longopts[i].val = cmd->options[i].shortopt; - shortopts[shortopt_idx++] = cmd->options[i].shortopt; - assert ( cmd->options[i].has_arg <= optional_argument ); - for ( j = cmd->options[i].has_arg ; j > 0 ; j-- ) - shortopts[shortopt_idx++] = ':'; - } - longopts[i].name = "help"; - longopts[i].val = 'h'; - shortopts[shortopt_idx++] = 'h'; - shortopts[shortopt_idx++] = '\0'; - assert ( shortopt_idx <= sizeof ( shortopts ) ); - DBGC ( cmd, "Command \"%s\" has options \"%s\", %d-%d args, len %d\n", - argv[0], shortopts, cmd->min_args, cmd->max_args, cmd->len ); - - /* Parse options */ - while ( ( c = getopt_long ( argc, argv, shortopts, longopts, - NULL ) ) >= 0 ) { - switch ( c ) { - case 'h' : - /* Print help */ - print_usage ( cmd, argv ); - return -ECANCELED_NO_OP; - case '?' : - /* Print usage message */ - print_usage ( cmd, argv ); - return -EINVAL_UNKNOWN_OPTION; - case ':' : - /* Print usage message */ - print_usage ( cmd, argv ); - return -EINVAL_MISSING_ARGUMENT; - default: - /* Search for an option to parse */ - for ( i = 0 ; i < cmd->num_options ; i++ ) { - if ( c != cmd->options[i].shortopt ) - continue; - parse = cmd->options[i].parse; - value = ( opts + cmd->options[i].offset ); - if ( ( rc = parse ( optarg, value ) ) != 0 ) - return rc; - break; - } - assert ( i < cmd->num_options ); - } - } - - /* Check remaining arguments */ - num_args = ( argc - optind ); - if ( ( num_args < cmd->min_args ) || ( num_args > cmd->max_args ) ) { - print_usage ( cmd, argv ); - return -ERANGE; - } - - return 0; -} - -/** - * Parse command-line options - * - * @v argc Argument count - * @v argv Argument list - * @v cmd Command descriptor - * @v opts Options (may be uninitialised) - * @ret rc Return status code - */ -int parse_options ( int argc, char **argv, struct command_descriptor *cmd, - void *opts ) { - - /* Clear options */ - memset ( opts, 0, cmd->len ); - - return reparse_options ( argc, argv, cmd, opts ); -} diff --git a/qemu/roms/ipxe/src/core/pc_kbd.c b/qemu/roms/ipxe/src/core/pc_kbd.c deleted file mode 100644 index 42df755b5..000000000 --- a/qemu/roms/ipxe/src/core/pc_kbd.c +++ /dev/null @@ -1,112 +0,0 @@ -/* Minimal polling PC keyboard driver - * - No interrupt - * - No LED - * - No special keys - * - * still Enough For Me to type a filename. - * - * 2003-07 by SONE Takesh - * 2004-04 moved by LYH From filo to Etherboot - * yhlu@tyan.com - */ - -#include <ipxe/io.h> -#include <ipxe/console.h> - -static char key_map[][128] = { - { - "\0\x1b""1234567890-=\b\t" - "qwertyuiop[]\r\0as" - "dfghjkl;'`\0\\zxcv" - "bnm,./\0*\0 \0\0\0\0\0\0" - "\0\0\0\0\0\0\0""789-456+1" - "230." - },{ - "\0\x1b""!@#$%^&*()_+\b\t" - "QWERTYUIOP{}\r\0AS" - "DFGHJKL:\"~\0|ZXCV" - "BNM<>?\0\0\0 \0\0\0\0\0\0" - "\0\0\0\0\0\0\0""789-456+1" - "230." - } -}; - -static int cur_scan; -static unsigned int shift_state; -#define SHIFT 1 -#define CONTROL 2 -#define CAPS 4 - -static int get_scancode(void) -{ - int scan; - - if ((inb(0x64) & 1) == 0) - return 0; - scan = inb(0x60); - - switch (scan) { - case 0x2a: - case 0x36: - shift_state |= SHIFT; - break; - case 0xaa: - case 0xb6: - shift_state &= ~SHIFT; - break; - case 0x1d: - shift_state |= CONTROL; - break; - case 0x9d: - shift_state &= ~CONTROL; - break; - case 0x3a: - shift_state ^= CAPS; - break; - } - - if (scan & 0x80) - return 0; /* ignore break code or 0xe0 etc! */ - return scan; -} - -static int kbd_havekey(void) -{ - if (!cur_scan) - cur_scan = get_scancode(); - return cur_scan != 0; -} - -static int kbd_ischar(void) -{ - if (!kbd_havekey()) - return 0; - if (!key_map[shift_state & SHIFT][cur_scan]) { - cur_scan = 0; - return 0; - } - return 1; -} - -static int kbd_getc(void) -{ - int c; - - while (!kbd_ischar()) - ; - c = key_map[shift_state & SHIFT][cur_scan]; - if (shift_state & (CONTROL | CAPS)) { - if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) { - if (shift_state & CONTROL) - c &= 0x1f; - else if (shift_state & CAPS) - c ^= ('A' ^ 'a'); - } - } - cur_scan = 0; - return c; -} - -struct console_driver pc_kbd_console __console_driver = { - .getchar = kbd_getc, -}; diff --git a/qemu/roms/ipxe/src/core/pcmcia.c b/qemu/roms/ipxe/src/core/pcmcia.c deleted file mode 100644 index 5fd21f4a9..000000000 --- a/qemu/roms/ipxe/src/core/pcmcia.c +++ /dev/null @@ -1,269 +0,0 @@ -#if 0 - -/* - * pcmcia.c - * - * PCMCIA support routines for etherboot - generic stuff - * - * This code has partly be taken from the linux kernel sources, .../drivers/pcmcia/ - * Started & put together by - * Anselm Martin Hoffmeister - * Stockholm Projekt Computer-Service - * Sankt Augustin / Bonn, Germany - * - * Distributed under GPL2 - */ - -/* - * - * - * ****************************** - * PLEASE DO NOT YET WORK ON THIS - * ****************************** - * - * I'm still fixing it up on every end, so we most probably would interfere - * at some point. If there's anything obvious or better, not-so-obvious, - * please contact me by e-mail: anselm (AT) hoffmeister (DOT) be *THANKS* - */ - -FILE_LICENCE ( GPL2_ONLY ); - -#include <stdio.h> -#include <pcmcia.h> -#include <i82365.h> -#define CODE_STATUS "alpha" -#define CODE_VERSION "0.1.3" -#include <pcmcia-opts.h> -#include <ipxe/init.h> - -int sockets; /* AHTODO: Phase this out! */ -u_int pccsocks; -struct pccsock_t pccsock[MAXPCCSOCKS]; -int inited = -1; -struct pcc_config_t pccconfig[MAXPCCCONFIGS]; - -struct driver_interact_t driver[] = { -#ifdef SUPPORT_I82365 - { I82365, i82365_interfacer, "Intel_82365" }, -#endif -}; - -#define NUM_DRIVERS (sizeof(driver)/(sizeof(struct driver_interact_t))) - -void sleepticks(int numticks ) { - u_int tmo; - for (tmo = currticks()+numticks; currticks() < tmo; ) { - } - return; -} - -static void pcmcia_init_all(void) { - u_int i, j, k, l, m, n, ui, configs = 0; - u_int multicard[8]; - u_char *uc, upc; - if ( PDEBUG > 0 ) printf("Initializing PCMCIA subsystem (code-status: " CODE_STATUS ", Version " CODE_VERSION ")\n"); - if ( PDEBUG > 2 ) { - printf ( "Supporting %d driver(s): ", NUM_DRIVERS ); - for ( i = 0; i < NUM_DRIVERS; ++i ) { - printf ( "[%s] ", driver[i].name ); - } - printf ( "\n" ); - } - pccsocks = 0; - sockets = 0; - // Init all drivers in the driver[] array: - for ( i = 0; i < NUM_DRIVERS; ++i ) { - driver[i].f(INIT,0,i,0,0); // init needs no params. It uses pccsocks and pccsock[]. - // Only i tells it which driver_id itself is. - } - for ( i = 0; i < pccsocks; ++i ) { - printf ( "Socket %d: ", i ); - if ( pccsock[i].status != HASCARD ) { - printf ( "is %s: skipping\n", pccsock[i].status == EMPTY? "empty":"[status unknown]" ); - continue; - } - if ( 0 != driver[pccsock[i].drivernum].f(MAPATTRMEM,pccsock[i].internalid,MAP_ATTRMEM_TO, MAP_ATTRMEM_LEN,0 ) ) { - printf ("PCMCIA controller failed to map attribute memory.\n**** SEVERE ERROR CONDITION. Skipping controller.\n" ); - if ( PDEBUG > 2 ) { - printf ( "<press key. THIS CONDITION SHOULD BE REPORTED!>\n" ); getchar(); - } - continue; - } - // parse configuration information - uc = ioremap ( MAP_ATTRMEM_TO, MAP_ATTRMEM_LEN ); - pccsock[i].stringoffset = pccsock[i].configoffset = pccsock[i].stringlength = 0; - pccsock[i].type = 0xff; - for ( l = 0; l < 8; ++l ) multicard[l] = 0; - sleepticks(2); - for ( l = ui = 0; ui < 0x800; ui += uc[(2*ui)+2] + 2 ) { - if ( uc[(2*ui)] == 0xff ) { - break; - } - // This loop is complete rubbish AFAICS. - // But without it, my test system won't come up. - // It's too bad to develop on broken hardware - // - Anselm - } - sleepticks(2); - configs = 0; - inited = -1; - for ( l = ui = 0; ui < 0x800; ui += uc[(2*ui)+2] + 2 ) { - if ( uc[(2*ui)] == 0xff ) break; - else if ( uc[2*ui] == 0x15 ) { - for ( k = 2 * ( ui + 2 ); ( uc[k] <= ' ' ) && ( k < ( 2 * ( uc[2*(ui+1)] + ui + 2 ) ) ) ; k += 2 ) { ; } - pccsock[i].stringoffset = k; - pccsock[i].stringlength = ( 2 * ( ui + 2 + uc[(2*ui)+2] ) - k ) / 2; - } else if ( uc[2*ui] == 0x21 ) { - pccsock[i].type = uc[(2*ui)+4]; - } else if ( uc[2*ui] == 0x1a ) { // Configuration map - printf ( "\nConfig map 0x1a found [" ); - for ( k = 0; k < uc[2*(ui+1)]; ++k ) { - printf ( "%02x ", uc[2*(ui+k+2)] ); - } - printf ( "]\nHighest config available is %d\n", uc[2*(ui+3)] ); - m = uc[2*(ui+2)]; - pccsock[i].configoffset = 0; - for ( j = 0; j <= (m & 3); ++j ) { - pccsock[i].configoffset += uc[2*(ui+4+j)] << (8*j); - } - pccsock[i].rmask0 = 0; - for ( j = 0; j <= ( ( ( m & 0x3c ) >> 2 ) & 3 ); ++j ) { - pccsock[i].rmask0 += uc[2*(ui+5+(m&3)+j)] << (8*j); - } - j = pccsock[i].rmask0; - printf ( "Config offset is %x, card has regs: < %s%s%s%s%s>\n", pccsock[i].configoffset, - j & 1 ? "COR ":"", j & 2 ? "CCSR ":"", j & 4 ? "PRR ":"", j & 8 ? "SCR ":"", j & 16? "ESR ":"" ); - printf ( "COR + CCSR contents (si/du) %x %x/%x %x\n", uc[pccsock[i].configoffset+0], - uc[pccsock[i].configoffset+2],uc[pccsock[i].configoffset*2],uc[(pccsock[i].configoffset*2)+2] ); - printf ( " " ); - } else if ( uc[2*ui] == 0x1b ) { // Configuration data entry - //printf ( "Config data 0x1b found [\n" );getchar(); - for ( k = 0; k < uc[2*(ui+1)]; ++k ) { - // printf ( "%02x ", uc[2*(ui+k+2)] ); - } - // Parse this tuple into pccconfig[configs] - // printf ( "]\n" ); - if ( configs == MAXPCCCONFIGS ) continue; - k = 2*ui+4; - pccconfig[configs].index = uc[k] & 0x3f; - if ( uc[k] & 0x80 ) { - // printf ( "Special config, unsupp. for now\n" ); - continue; - } - k+=2; - // printf ( "Features: %2x\n", uc[k] ); - if ( uc[k] & 0x7 ) { - // printf ( "Cannot work with Vcc/Timing configs right now\n" ); - continue; - } - pccconfig[configs].iowin = pccconfig[configs].iolen = 0; - if ( 0 != ( uc[k] & 0x8 ) ) { - k+=2; - // printf ( "Reading IO config: " ); - if ( 0 == ( uc[k] & 0x80 ) ) { - // printf ( "Cannot work with auto/io config\n" ); - continue; - } - k+=2; - if ( 0 != ( uc[k] & 0x0f ) ) { - // printf ( "Don't support more than 1 iowin right now\n" ); - continue; - } - j = (uc[k] & 0x30) >> 4; - m = (uc[k] & 0xc0) >> 6; - if ( 3 == j ) ++j; - if ( 3 == m ) ++m; - k += 2; - pccconfig[configs].iowin = 0; - pccconfig[configs].iolen = 1; - for ( n = 0; n < j; ++n, k+=2 ) { - pccconfig[configs].iowin += uc[k] << (n*8); - } - for ( n = 0; n < m; ++n, k+=2 ) { - pccconfig[configs].iolen += uc[k] << (n*8); - } - // printf ( "io %x len %d (%d)\n", pccconfig[configs].iowin, pccconfig[configs].iolen,configs ); - } - for ( j = 0; j < (uc[k] & 3); ++j ) { - // pccconfig[configs].iowin += (uc[k+(2*j)+2]) << (8*j); - } - ++configs; - } - } - if ( pccsock[i].stringoffset > 0 ) { // If no identifier, it's not a valid CIS (as of documentation...) - printf ( "[" ); - for ( k = 0; ( k < pccsock[i].stringlength ) && ( k < 64 ); ++k ) { - j = uc[pccsock[i].stringoffset + 2 * k]; - printf ( "%c", (j>=' '? j:' ' ) ); - } - printf ("]\n is type %d (", pccsock[i].type ); - switch ( pccsock[i].type ) { - case 0x00: - printf ( "MULTI" ); break; - case 0x01: - printf ( "Memory" ); break; - case 0x02: - printf ( "Serial" ); break; - case 0x03: - printf ( "Parallel" ); break; - case 0x04: - printf ( "Fixed" ); break; - case 0x05: - printf ( "Video" ); break; - case 0x06: - printf ( "Network" ); break; - case 0x07: - printf ( "AIMS" ); break; - case 0x08: - printf ( "SCSI" ); break; - case 0x106: // Special / homebrew to say "Multi/network" - printf ( "MULTI, with Network" ); break; // AHTODO find a card for this - default: - printf ( "UNSUPPORTED/UNKNOWN" ); - } - printf ( ") with %d possible configuration(s)\n", configs ); - // Now set dependency: If it's Network or multi->network, accept - if ( (inited <= 0 ) && (6 == (0xff & pccsock[i].type) ) && (0 < configs ) ) { - printf ( "activating this device with ioport %x-%x (config #%d)\n", - pccconfig[0].iowin, pccconfig[0].iowin+pccconfig[0].iolen-1, pccconfig[0].index ); - inited = i; - // And unmap attrmem ourselves! - printf ( "Activating config..." ); - if ( m=driver[pccsock[i].drivernum].f(SELECTCONFIG,pccsock[i].internalid,pccconfig[0].index,0,&pccconfig[0]) ) { - printf ("Failure(%d)!",m); inited = -1; - driver[pccsock[i].drivernum].f(UNMAPATTRMEM,pccsock[i].internalid,0,0,0); - } - printf ( "done!\n" ); - continue; - } - } else { - printf ( "unsupported - no identifier string found in CIS\n" ); - } - // unmap the PCMCIA device - if ( i != inited ) { - if ( 0 != driver[pccsock[i].drivernum].f(UNMAPATTRMEM,pccsock[i].internalid,0,0,0) ) { - printf ("PCMCIA controller failed to unmap attribute memory.\n**** SEVERE ERROR CONDITION ****\n" ); - if ( PDEBUG > 2 ) { - printf ( "<press key. THIS CONDITION SHOULD BE REPORTED!>\n" ); getchar(); - } - continue; - } - } - } - if ( PDEBUG > 2 ) { - printf ( "<press key to exit the pcmcia_init_all routine>\n" ); - getchar(); - } - -} - -static void pcmcia_shutdown_all(void) { - int i; - //if ( PDEBUG > 2 ) {printf("<press key to continue>\n" ); getchar(); } - for ( i = 0; i < pccsocks; ++i ) { - driver[pccsock[i].drivernum].f(SHUTDOWN,pccsock[i].internalid,0,0,0); - } - printf("Shutdown of PCMCIA subsystem completed"); -} - -#endif diff --git a/qemu/roms/ipxe/src/core/pending.c b/qemu/roms/ipxe/src/core/pending.c deleted file mode 100644 index 96d0cf197..000000000 --- a/qemu/roms/ipxe/src/core/pending.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <errno.h> -#include <ipxe/process.h> -#include <ipxe/timer.h> -#include <ipxe/pending.h> - -/** @file - * - * Pending operations - * - */ - -/** Total count of pending operations */ -int pending_total; - -/** - * Mark an operation as pending - * - * @v pending Pending operation - */ -void pending_get ( struct pending_operation *pending ) { - - pending->count++; - pending_total++; - DBGC ( pending, "PENDING %p incremented to %d (total %d)\n", - pending, pending->count, pending_total ); -} - -/** - * Mark an operation as no longer pending - * - * @v pending Pending operation - */ -void pending_put ( struct pending_operation *pending ) { - - if ( pending->count ) { - pending_total--; - pending->count--; - DBGC ( pending, "PENDING %p decremented to %d (total %d)\n", - pending, pending->count, pending_total ); - } -} diff --git a/qemu/roms/ipxe/src/core/pinger.c b/qemu/roms/ipxe/src/core/pinger.c deleted file mode 100644 index 0ff7bb9f2..000000000 --- a/qemu/roms/ipxe/src/core/pinger.c +++ /dev/null @@ -1,355 +0,0 @@ -/* - * Copyright (C) 2013 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <ipxe/refcnt.h> -#include <ipxe/interface.h> -#include <ipxe/job.h> -#include <ipxe/xfer.h> -#include <ipxe/iobuf.h> -#include <ipxe/open.h> -#include <ipxe/socket.h> -#include <ipxe/retry.h> -#include <ipxe/pinger.h> - -/** @file - * - * ICMP ping sender - * - */ - -/* Disambiguate the various error causes */ -#define EPROTO_LEN __einfo_error ( EINFO_EPROTO_LEN ) -#define EINFO_EPROTO_LEN __einfo_uniqify ( EINFO_EPROTO, 0x01, \ - "Incorrect reply length" ) -#define EPROTO_DATA __einfo_error ( EINFO_EPROTO_DATA ) -#define EINFO_EPROTO_DATA __einfo_uniqify ( EINFO_EPROTO, 0x02, \ - "Incorrect reply data" ) -#define EPROTO_SEQ __einfo_error ( EINFO_EPROTO_SEQ ) -#define EINFO_EPROTO_SEQ __einfo_uniqify ( EINFO_EPROTO, 0x03, \ - "Delayed or out-of-sequence reply" ) - -/** A pinger */ -struct pinger { - /** Reference count */ - struct refcnt refcnt; - - /** Job control interface */ - struct interface job; - /** Data transfer interface */ - struct interface xfer; - - /** Timer */ - struct retry_timer timer; - /** Timeout */ - unsigned long timeout; - - /** Payload length */ - size_t len; - /** Current sequence number */ - uint16_t sequence; - /** Response for current sequence number is still pending */ - int pending; - /** Number of remaining expiry events (zero to continue indefinitely) */ - unsigned int remaining; - /** Return status */ - int rc; - - /** Callback function - * - * @v src Source socket address, or NULL - * @v sequence Sequence number - * @v len Payload length - * @v rc Status code - */ - void ( * callback ) ( struct sockaddr *src, unsigned int sequence, - size_t len, int rc ); -}; - -/** - * Generate payload - * - * @v pinger Pinger - * @v data Data buffer - */ -static void pinger_generate ( struct pinger *pinger, void *data ) { - uint8_t *bytes = data; - unsigned int i; - - /* Generate byte sequence */ - for ( i = 0 ; i < pinger->len ; i++ ) - bytes[i] = ( i & 0xff ); -} - -/** - * Verify payload - * - * @v pinger Pinger - * @v data Data buffer - * @ret rc Return status code - */ -static int pinger_verify ( struct pinger *pinger, const void *data ) { - const uint8_t *bytes = data; - unsigned int i; - - /* Check byte sequence */ - for ( i = 0 ; i < pinger->len ; i++ ) { - if ( bytes[i] != ( i & 0xff ) ) - return -EPROTO_DATA; - } - - return 0; -} - -/** - * Close pinger - * - * @v pinger Pinger - * @v rc Reason for close - */ -static void pinger_close ( struct pinger *pinger, int rc ) { - - /* Stop timer */ - stop_timer ( &pinger->timer ); - - /* Shut down interfaces */ - intf_shutdown ( &pinger->xfer, rc ); - intf_shutdown ( &pinger->job, rc ); -} - -/** - * Handle data transfer window change - * - * @v pinger Pinger - */ -static void pinger_window_changed ( struct pinger *pinger ) { - - /* Do nothing if timer is already running */ - if ( timer_running ( &pinger->timer ) ) - return; - - /* Start timer when window opens for the first time */ - if ( xfer_window ( &pinger->xfer ) ) - start_timer_nodelay ( &pinger->timer ); -} - -/** - * Handle timer expiry - * - * @v timer Timer - * @v over Failure indicator - */ -static void pinger_expired ( struct retry_timer *timer, int over __unused ) { - struct pinger *pinger = container_of ( timer, struct pinger, timer ); - struct xfer_metadata meta; - struct io_buffer *iobuf; - int rc; - - /* If no response has been received, notify the callback function */ - if ( pinger->pending && pinger->callback ) - pinger->callback ( NULL, pinger->sequence, 0, -ETIMEDOUT ); - - /* Check for termination */ - if ( pinger->remaining && ( --pinger->remaining == 0 ) ) { - pinger_close ( pinger, pinger->rc ); - return; - } - - /* Increase sequence number */ - pinger->sequence++; - - /* Restart timer. Do this before attempting to transmit, in - * case the transmission attempt fails. - */ - start_timer_fixed ( &pinger->timer, pinger->timeout ); - pinger->pending = 1; - - /* Allocate I/O buffer */ - iobuf = xfer_alloc_iob ( &pinger->xfer, pinger->len ); - if ( ! iobuf ) { - DBGC ( pinger, "PINGER %p could not allocate I/O buffer\n", - pinger ); - return; - } - - /* Generate payload */ - pinger_generate ( pinger, iob_put ( iobuf, pinger->len ) ); - - /* Generate metadata */ - memset ( &meta, 0, sizeof ( meta ) ); - meta.flags = XFER_FL_ABS_OFFSET; - meta.offset = pinger->sequence; - - /* Transmit packet */ - if ( ( rc = xfer_deliver ( &pinger->xfer, iobuf, &meta ) ) != 0 ) { - DBGC ( pinger, "PINGER %p could not transmit: %s\n", - pinger, strerror ( rc ) ); - return; - } -} - -/** - * Handle received data - * - * @v pinger Pinger - * @v iobuf I/O buffer - * @v meta Data transfer metadata - * @ret rc Return status code - */ -static int pinger_deliver ( struct pinger *pinger, struct io_buffer *iobuf, - struct xfer_metadata *meta ) { - size_t len = iob_len ( iobuf ); - uint16_t sequence = meta->offset; - int terminate = 0; - int rc; - - /* Clear response pending flag, if applicable */ - if ( sequence == pinger->sequence ) - pinger->pending = 0; - - /* Check for errors */ - if ( len != pinger->len ) { - /* Incorrect length: terminate immediately if we are - * not pinging indefinitely. - */ - DBGC ( pinger, "PINGER %p received incorrect length %zd " - "(expected %zd)\n", pinger, len, pinger->len ); - rc = -EPROTO_LEN; - terminate = ( pinger->remaining != 0 ); - } else if ( ( rc = pinger_verify ( pinger, iobuf->data ) ) != 0 ) { - /* Incorrect data: terminate immediately if we are not - * pinging indefinitely. - */ - DBGC ( pinger, "PINGER %p received incorrect data:\n", pinger ); - DBGC_HDA ( pinger, 0, iobuf->data, iob_len ( iobuf ) ); - terminate = ( pinger->remaining != 0 ); - } else if ( sequence != pinger->sequence ) { - /* Incorrect sequence number (probably a delayed response): - * report via callback but otherwise ignore. - */ - DBGC ( pinger, "PINGER %p received sequence %d (expected %d)\n", - pinger, sequence, pinger->sequence ); - rc = -EPROTO_SEQ; - terminate = 0; - } else { - /* Success: record that a packet was successfully received, - * and terminate if we expect to send no further packets. - */ - rc = 0; - pinger->rc = 0; - terminate = ( pinger->remaining == 1 ); - } - - /* Discard I/O buffer */ - free_iob ( iobuf ); - - /* Notify callback function, if applicable */ - if ( pinger->callback ) - pinger->callback ( meta->src, sequence, len, rc ); - - /* Terminate if applicable */ - if ( terminate ) - pinger_close ( pinger, rc ); - - return rc; -} - -/** Pinger data transfer interface operations */ -static struct interface_operation pinger_xfer_op[] = { - INTF_OP ( xfer_deliver, struct pinger *, pinger_deliver ), - INTF_OP ( xfer_window_changed, struct pinger *, pinger_window_changed ), - INTF_OP ( intf_close, struct pinger *, pinger_close ), -}; - -/** Pinger data transfer interface descriptor */ -static struct interface_descriptor pinger_xfer_desc = - INTF_DESC ( struct pinger, xfer, pinger_xfer_op ); - -/** Pinger job control interface operations */ -static struct interface_operation pinger_job_op[] = { - INTF_OP ( intf_close, struct pinger *, pinger_close ), -}; - -/** Pinger job control interface descriptor */ -static struct interface_descriptor pinger_job_desc = - INTF_DESC ( struct pinger, job, pinger_job_op ); - -/** - * Create pinger - * - * @v job Job control interface - * @v hostname Hostname to ping - * @v timeout Timeout (in ticks) - * @v len Payload length - * @v count Number of packets to send (or zero for no limit) - * @v callback Callback function (or NULL) - * @ret rc Return status code - */ -int create_pinger ( struct interface *job, const char *hostname, - unsigned long timeout, size_t len, unsigned int count, - void ( * callback ) ( struct sockaddr *src, - unsigned int sequence, size_t len, - int rc ) ) { - struct pinger *pinger; - int rc; - - /* Sanity check */ - if ( ! timeout ) - return -EINVAL; - - /* Allocate and initialise structure */ - pinger = zalloc ( sizeof ( *pinger ) ); - if ( ! pinger ) - return -ENOMEM; - ref_init ( &pinger->refcnt, NULL ); - intf_init ( &pinger->job, &pinger_job_desc, &pinger->refcnt ); - intf_init ( &pinger->xfer, &pinger_xfer_desc, &pinger->refcnt ); - timer_init ( &pinger->timer, pinger_expired, &pinger->refcnt ); - pinger->timeout = timeout; - pinger->len = len; - pinger->remaining = ( count ? ( count + 1 /* Initial packet */ ) : 0 ); - pinger->callback = callback; - pinger->rc = -ETIMEDOUT; - - /* Open socket */ - if ( ( rc = xfer_open_named_socket ( &pinger->xfer, SOCK_ECHO, NULL, - hostname, NULL ) ) != 0 ) { - DBGC ( pinger, "PINGER %p could not open socket: %s\n", - pinger, strerror ( rc ) ); - goto err; - } - - /* Attach parent interface, mortalise self, and return */ - intf_plug_plug ( &pinger->job, job ); - ref_put ( &pinger->refcnt ); - return 0; - - err: - pinger_close ( pinger, rc ); - ref_put ( &pinger->refcnt ); - return rc; -} diff --git a/qemu/roms/ipxe/src/core/pixbuf.c b/qemu/roms/ipxe/src/core/pixbuf.c deleted file mode 100644 index 41e18f8dc..000000000 --- a/qemu/roms/ipxe/src/core/pixbuf.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2013 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/** @file - * - * Pixel buffer - * - */ - -#include <stdlib.h> -#include <ipxe/umalloc.h> -#include <ipxe/pixbuf.h> - -/** - * Free pixel buffer - * - * @v refcnt Reference count - */ -static void free_pixbuf ( struct refcnt *refcnt ) { - struct pixel_buffer *pixbuf = - container_of ( refcnt, struct pixel_buffer, refcnt ); - - ufree ( pixbuf->data ); - free ( pixbuf ); -} - -/** - * Allocate pixel buffer - * - * @v width Width - * @h height Height - * @ret pixbuf Pixel buffer, or NULL on failure - */ -struct pixel_buffer * alloc_pixbuf ( unsigned int width, unsigned int height ) { - struct pixel_buffer *pixbuf; - - /* Allocate and initialise structure */ - pixbuf = zalloc ( sizeof ( *pixbuf ) ); - if ( ! pixbuf ) - goto err_alloc_pixbuf; - ref_init ( &pixbuf->refcnt, free_pixbuf ); - pixbuf->width = width; - pixbuf->height = height; - pixbuf->len = ( width * height * sizeof ( uint32_t ) ); - - /* Allocate pixel data buffer */ - pixbuf->data = umalloc ( pixbuf->len ); - if ( ! pixbuf->data ) - goto err_alloc_data; - - return pixbuf; - - err_alloc_data: - pixbuf_put ( pixbuf ); - err_alloc_pixbuf: - return NULL; -} diff --git a/qemu/roms/ipxe/src/core/pool.c b/qemu/roms/ipxe/src/core/pool.c deleted file mode 100644 index 0163405f7..000000000 --- a/qemu/roms/ipxe/src/core/pool.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/** - * @file - * - * 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 deleted file mode 100644 index 35b52beeb..000000000 --- a/qemu/roms/ipxe/src/core/posix_io.c +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <ipxe/list.h> -#include <ipxe/iobuf.h> -#include <ipxe/xfer.h> -#include <ipxe/open.h> -#include <ipxe/process.h> -#include <ipxe/posix_io.h> - -/** @file - * - * POSIX-like I/O - * - * These functions provide traditional blocking I/O semantics. They - * are designed to be used by the PXE TFTP API. Because they block, - * they may not be used by most other portions of the iPXE codebase. - */ - -/** An open file */ -struct posix_file { - /** Reference count for this object */ - struct refcnt refcnt; - /** List of open files */ - struct list_head list; - /** File descriptor */ - int fd; - /** Overall status - * - * Set to -EINPROGRESS while data transfer is in progress. - */ - int rc; - /** Data transfer interface */ - struct interface xfer; - /** Current seek position */ - size_t pos; - /** File size */ - size_t filesize; - /** Received data queue */ - struct list_head data; -}; - -/** List of open files */ -static LIST_HEAD ( posix_files ); - -/** - * Free open file - * - * @v refcnt Reference counter - */ -static void posix_file_free ( struct refcnt *refcnt ) { - struct posix_file *file = - container_of ( refcnt, struct posix_file, refcnt ); - struct io_buffer *iobuf; - struct io_buffer *tmp; - - list_for_each_entry_safe ( iobuf, tmp, &file->data, list ) { - list_del ( &iobuf->list ); - free_iob ( iobuf ); - } - free ( file ); -} - -/** - * Terminate file data transfer - * - * @v file POSIX file - * @v rc Reason for termination - */ -static void posix_file_finished ( struct posix_file *file, int rc ) { - intf_shutdown ( &file->xfer, rc ); - file->rc = rc; -} - -/** - * Handle deliver_iob() event - * - * @v file POSIX file - * @v iobuf I/O buffer - * @v meta Data transfer metadata - * @ret rc Return status code - */ -static int posix_file_xfer_deliver ( struct posix_file *file, - struct io_buffer *iobuf, - struct xfer_metadata *meta ) { - - /* Keep track of file position solely for the filesize */ - if ( meta->flags & XFER_FL_ABS_OFFSET ) - file->pos = 0; - file->pos += meta->offset; - if ( file->filesize < file->pos ) - file->filesize = file->pos; - - if ( iob_len ( iobuf ) ) { - list_add_tail ( &iobuf->list, &file->data ); - } else { - free_iob ( iobuf ); - } - - return 0; -} - -/** POSIX file data transfer interface operations */ -static struct interface_operation posix_file_xfer_operations[] = { - INTF_OP ( xfer_deliver, struct posix_file *, posix_file_xfer_deliver ), - INTF_OP ( intf_close, struct posix_file *, posix_file_finished ), -}; - -/** POSIX file data transfer interface descriptor */ -static struct interface_descriptor posix_file_xfer_desc = - INTF_DESC ( struct posix_file, xfer, posix_file_xfer_operations ); - -/** - * Identify file by file descriptor - * - * @v fd File descriptor - * @ret file Corresponding file, or NULL - */ -static struct posix_file * posix_fd_to_file ( int fd ) { - struct posix_file *file; - - list_for_each_entry ( file, &posix_files, list ) { - if ( file->fd == fd ) - return file; - } - return NULL; -} - -/** - * Find an available file descriptor - * - * @ret fd File descriptor, or negative error number - */ -static int posix_find_free_fd ( void ) { - int fd; - - for ( fd = POSIX_FD_MIN ; fd <= POSIX_FD_MAX ; fd++ ) { - if ( ! posix_fd_to_file ( fd ) ) - return fd; - } - DBG ( "POSIX could not find free file descriptor\n" ); - return -ENFILE; -} - -/** - * Open file - * - * @v uri_string URI string - * @ret fd File descriptor, or negative error number - */ -int open ( const char *uri_string ) { - struct posix_file *file; - int fd; - int rc; - - /* Find a free file descriptor to use */ - fd = posix_find_free_fd(); - if ( fd < 0 ) - return fd; - - /* Allocate and initialise structure */ - file = zalloc ( sizeof ( *file ) ); - if ( ! file ) - return -ENOMEM; - ref_init ( &file->refcnt, posix_file_free ); - file->fd = fd; - file->rc = -EINPROGRESS; - intf_init ( &file->xfer, &posix_file_xfer_desc, &file->refcnt ); - INIT_LIST_HEAD ( &file->data ); - - /* Open URI on data transfer interface */ - if ( ( rc = xfer_open_uri_string ( &file->xfer, uri_string ) ) != 0 ) - goto err; - - /* Wait for open to succeed or fail */ - while ( list_empty ( &file->data ) ) { - step(); - if ( file->rc == 0 ) - break; - if ( file->rc != -EINPROGRESS ) { - rc = file->rc; - goto err; - } - } - - /* Add to list of open files. List takes reference ownership. */ - list_add ( &file->list, &posix_files ); - DBG ( "POSIX opened %s as file %d\n", uri_string, fd ); - return fd; - - err: - posix_file_finished ( file, rc ); - ref_put ( &file->refcnt ); - return rc; -} - -/** - * Check file descriptors for readiness - * - * @v readfds File descriptors to check - * @v wait Wait until data is ready - * @ret nready Number of ready file descriptors - */ -int select ( fd_set *readfds, int wait ) { - struct posix_file *file; - int fd; - - do { - for ( fd = POSIX_FD_MIN ; fd <= POSIX_FD_MAX ; fd++ ) { - if ( ! FD_ISSET ( fd, readfds ) ) - continue; - file = posix_fd_to_file ( fd ); - if ( ! file ) - return -EBADF; - if ( ( list_empty ( &file->data ) ) && - ( file->rc == -EINPROGRESS ) ) - continue; - /* Data is available or status has changed */ - FD_ZERO ( readfds ); - FD_SET ( fd, readfds ); - return 1; - } - step(); - } while ( wait ); - - return 0; -} - -/** - * Read data from file - * - * @v buffer Data buffer - * @v offset Starting offset within data buffer - * @v len Maximum length to read - * @ret len Actual length read, or negative error number - * - * This call is non-blocking; if no data is available to read then - * -EWOULDBLOCK will be returned. - */ -ssize_t read_user ( int fd, userptr_t buffer, off_t offset, size_t max_len ) { - struct posix_file *file; - struct io_buffer *iobuf; - size_t len; - - /* Identify file */ - file = posix_fd_to_file ( fd ); - if ( ! file ) - return -EBADF; - - /* Try to fetch more data if none available */ - if ( list_empty ( &file->data ) ) - step(); - - /* Dequeue at most one received I/O buffer into user buffer */ - list_for_each_entry ( iobuf, &file->data, list ) { - len = iob_len ( iobuf ); - if ( len > max_len ) - len = max_len; - copy_to_user ( buffer, offset, iobuf->data, len ); - iob_pull ( iobuf, len ); - if ( ! iob_len ( iobuf ) ) { - list_del ( &iobuf->list ); - free_iob ( iobuf ); - } - file->pos += len; - assert ( len != 0 ); - return len; - } - - /* If file has completed, return (after returning all data) */ - if ( file->rc != -EINPROGRESS ) { - assert ( list_empty ( &file->data ) ); - return file->rc; - } - - /* No data ready and file still in progress; return -WOULDBLOCK */ - return -EWOULDBLOCK; -} - -/** - * Determine file size - * - * @v fd File descriptor - * @ret size File size, or negative error number - */ -ssize_t fsize ( int fd ) { - struct posix_file *file; - - /* Identify file */ - file = posix_fd_to_file ( fd ); - if ( ! file ) - return -EBADF; - - return file->filesize; -} - -/** - * Close file - * - * @v fd File descriptor - * @ret rc Return status code - */ -int close ( int fd ) { - struct posix_file *file; - - /* Identify file */ - file = posix_fd_to_file ( fd ); - if ( ! file ) - return -EBADF; - - /* Terminate data transfer */ - posix_file_finished ( file, 0 ); - - /* Remove from list of open files and drop reference */ - list_del ( &file->list ); - ref_put ( &file->refcnt ); - return 0; -} diff --git a/qemu/roms/ipxe/src/core/process.c b/qemu/roms/ipxe/src/core/process.c deleted file mode 100644 index 69852c416..000000000 --- a/qemu/roms/ipxe/src/core/process.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <ipxe/list.h> -#include <ipxe/init.h> -#include <ipxe/process.h> - -/** @file - * - * Processes - * - * We implement a trivial form of cooperative multitasking, in which - * all processes share a single stack and address space. - */ - -/** Process run queue */ -static LIST_HEAD ( run_queue ); - -/** - * Get pointer to object containing process - * - * @v process Process - * @ret object Containing object - */ -void * process_object ( struct process *process ) { - return ( ( ( void * ) process ) - process->desc->offset ); -} - -/** - * Add process to process list - * - * @v process Process - * - * It is safe to call process_add() multiple times; further calls will - * have no effect. - */ -void process_add ( struct process *process ) { - if ( ! process_running ( process ) ) { - DBGC ( PROC_COL ( process ), "PROCESS " PROC_FMT - " starting\n", PROC_DBG ( process ) ); - ref_get ( process->refcnt ); - list_add_tail ( &process->list, &run_queue ); - } else { - DBGC ( PROC_COL ( process ), "PROCESS " PROC_FMT - " already started\n", PROC_DBG ( process ) ); - } -} - -/** - * Remove process from process list - * - * @v process Process - * - * It is safe to call process_del() multiple times; further calls will - * have no effect. - */ -void process_del ( struct process *process ) { - if ( process_running ( process ) ) { - DBGC ( PROC_COL ( process ), "PROCESS " PROC_FMT - " stopping\n", PROC_DBG ( process ) ); - list_del ( &process->list ); - INIT_LIST_HEAD ( &process->list ); - ref_put ( process->refcnt ); - } else { - DBGC ( PROC_COL ( process ), "PROCESS " PROC_FMT - " already stopped\n", PROC_DBG ( process ) ); - } -} - -/** - * Single-step a single process - * - * This executes a single step of the first process in the run queue, - * and moves the process to the end of the run queue. - */ -void step ( void ) { - struct process *process; - struct process_descriptor *desc; - void *object; - - if ( ( process = list_first_entry ( &run_queue, struct process, - list ) ) ) { - ref_get ( process->refcnt ); /* Inhibit destruction mid-step */ - desc = process->desc; - object = process_object ( process ); - if ( desc->reschedule ) { - list_del ( &process->list ); - list_add_tail ( &process->list, &run_queue ); - } else { - process_del ( process ); - } - DBGC2 ( PROC_COL ( process ), "PROCESS " PROC_FMT - " executing\n", PROC_DBG ( process ) ); - desc->step ( object ); - DBGC2 ( PROC_COL ( process ), "PROCESS " PROC_FMT - " finished executing\n", PROC_DBG ( process ) ); - ref_put ( process->refcnt ); /* Allow destruction */ - } -} - -/** - * Initialise processes - * - */ -static void init_processes ( void ) { - struct process *process; - - for_each_table_entry ( process, PERMANENT_PROCESSES ) - process_add ( process ); -} - -/** Process initialiser */ -struct init_fn process_init_fn __init_fn ( INIT_NORMAL ) = { - .initialise = init_processes, -}; diff --git a/qemu/roms/ipxe/src/core/profile.c b/qemu/roms/ipxe/src/core/profile.c deleted file mode 100644 index 1075047b9..000000000 --- a/qemu/roms/ipxe/src/core/profile.c +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdint.h> -#include <stdio.h> -#include <strings.h> -#include <assert.h> -#include <ipxe/isqrt.h> -#include <ipxe/profile.h> - -/** @file - * - * Profiling - * - * The profiler computes basic statistics (mean, variance, and - * standard deviation) for the samples which it records. Note that - * these statistics need not be completely accurate; it is sufficient - * to give a rough approximation. - * - * The algorithm for updating the mean and variance estimators is from - * The Art of Computer Programming (via Wikipedia), with adjustments - * to avoid the use of floating-point instructions. - */ - -/** Accumulated time excluded from profiling */ -unsigned long profile_excluded; - -/** - * Format a hex fraction (for debugging) - * - * @v value Value - * @v shift Bit shift - * @ret string Formatted hex fraction - */ -static const char * profile_hex_fraction ( signed long long value, - unsigned int shift ) { - static char buf[23] = "-"; /* -0xXXXXXXXXXXXXXXXX.XX + NUL */ - unsigned long long int_part; - uint8_t frac_part; - char *ptr; - - if ( value < 0 ) { - value = -value; - ptr = &buf[0]; - } else { - ptr = &buf[1]; - } - int_part = ( value >> shift ); - frac_part = ( value >> ( shift - ( 8 * sizeof ( frac_part ) ) ) ); - snprintf ( &buf[1], ( sizeof ( buf ) - 1 ), "%#llx.%02x", - int_part, frac_part ); - return ptr; -} - -/** - * Calculate bit shift for mean sample value - * - * @v profiler Profiler - * @ret shift Bit shift - */ -static inline unsigned int profile_mean_shift ( struct profiler *profiler ) { - - return ( ( ( 8 * sizeof ( profiler->mean ) ) - 1 ) /* MSB */ - - 1 /* Leave sign bit unused */ - - profiler->mean_msb ); -} - -/** - * Calculate bit shift for accumulated variance value - * - * @v profiler Profiler - * @ret shift Bit shift - */ -static inline unsigned int profile_accvar_shift ( struct profiler *profiler ) { - - return ( ( ( 8 * sizeof ( profiler->accvar ) ) - 1 ) /* MSB */ - - 1 /* Leave top bit unused */ - - profiler->accvar_msb ); -} - -/** - * Update profiler with a new sample - * - * @v profiler Profiler - * @v sample Sample value - */ -void profile_update ( struct profiler *profiler, unsigned long sample ) { - unsigned int sample_msb; - unsigned int mean_shift; - unsigned int delta_shift; - signed long pre_delta; - signed long post_delta; - signed long long accvar_delta; - unsigned int accvar_delta_shift; - unsigned int accvar_delta_msb; - unsigned int accvar_shift; - - /* Our scaling logic assumes that sample values never overflow - * a signed long (i.e. that the high bit is always zero). - */ - assert ( ( ( signed ) sample ) >= 0 ); - - /* Update sample count */ - profiler->count++; - - /* Adjust mean sample value scale if necessary. Skip if - * sample is zero (in which case flsl(sample)-1 would - * underflow): in the case of a zero sample we have no need to - * adjust the scale anyway. - */ - if ( sample ) { - sample_msb = ( flsl ( sample ) - 1 ); - if ( profiler->mean_msb < sample_msb ) { - profiler->mean >>= ( sample_msb - profiler->mean_msb ); - profiler->mean_msb = sample_msb; - } - } - - /* Scale sample to internal units */ - mean_shift = profile_mean_shift ( profiler ); - sample <<= mean_shift; - - /* Update mean */ - pre_delta = ( sample - profiler->mean ); - profiler->mean += ( pre_delta / ( ( signed ) profiler->count ) ); - post_delta = ( sample - profiler->mean ); - delta_shift = mean_shift; - DBGC ( profiler, "PROFILER %p sample %#lx mean %s", profiler, - ( sample >> mean_shift ), - profile_hex_fraction ( profiler->mean, mean_shift ) ); - DBGC ( profiler, " pre %s", - profile_hex_fraction ( pre_delta, delta_shift ) ); - DBGC ( profiler, " post %s\n", - profile_hex_fraction ( post_delta, delta_shift ) ); - - /* Scale both deltas to fit in half of an unsigned long long - * to avoid potential overflow on multiplication. Note that - * shifting a signed quantity is "implementation-defined" - * behaviour in the C standard, but gcc documents that it will - * always perform sign extension. - */ - if ( sizeof ( pre_delta ) > ( sizeof ( accvar_delta ) / 2 ) ) { - unsigned int shift = ( 8 * ( sizeof ( pre_delta ) - - ( sizeof ( accvar_delta ) / 2 ) )); - pre_delta >>= shift; - post_delta >>= shift; - delta_shift -= shift; - } - - /* Update variance, if applicable. Skip if either delta is - * zero (in which case flsl(delta)-1 would underflow): in the - * case of a zero delta there is no change to the accumulated - * variance anyway. - */ - if ( pre_delta && post_delta ) { - - /* Calculate variance delta */ - accvar_delta = ( ( ( signed long long ) pre_delta ) * - ( ( signed long long ) post_delta ) ); - accvar_delta_shift = ( 2 * delta_shift ); - assert ( accvar_delta > 0 ); - - /* Calculate variance delta MSB, using flsl() on each - * delta individually to provide an upper bound rather - * than requiring the existence of flsll(). - */ - accvar_delta_msb = ( flsll ( accvar_delta ) - 1 ); - if ( accvar_delta_msb > accvar_delta_shift ) { - accvar_delta_msb -= accvar_delta_shift; - } else { - accvar_delta_msb = 0; - } - - /* Adjust scales as necessary */ - if ( profiler->accvar_msb < accvar_delta_msb ) { - /* Rescale accumulated variance */ - profiler->accvar >>= ( accvar_delta_msb - - profiler->accvar_msb ); - profiler->accvar_msb = accvar_delta_msb; - } else { - /* Rescale variance delta */ - accvar_delta >>= ( profiler->accvar_msb - - accvar_delta_msb ); - accvar_delta_shift -= ( profiler->accvar_msb - - accvar_delta_msb ); - } - - /* Scale delta to internal units */ - accvar_shift = profile_accvar_shift ( profiler ); - accvar_delta <<= ( accvar_shift - accvar_delta_shift ); - - /* Accumulate variance */ - profiler->accvar += accvar_delta; - - /* Adjust scale if necessary */ - if ( profiler->accvar & - ( 1ULL << ( ( 8 * sizeof ( profiler->accvar ) ) - 1 ) ) ) { - profiler->accvar >>= 1; - profiler->accvar_msb++; - accvar_delta >>= 1; - accvar_shift--; - } - - DBGC ( profiler, "PROFILER %p accvar %s", profiler, - profile_hex_fraction ( profiler->accvar, accvar_shift )); - DBGC ( profiler, " delta %s\n", - profile_hex_fraction ( accvar_delta, accvar_shift ) ); - } -} - -/** - * Get mean sample value - * - * @v profiler Profiler - * @ret mean Mean sample value - */ -unsigned long profile_mean ( struct profiler *profiler ) { - unsigned int mean_shift = profile_mean_shift ( profiler ); - - /* Round to nearest and scale down to original units */ - return ( ( profiler->mean + ( 1UL << ( mean_shift - 1 ) ) ) - >> mean_shift ); -} - -/** - * Get sample variance - * - * @v profiler Profiler - * @ret variance Sample variance - */ -unsigned long profile_variance ( struct profiler *profiler ) { - unsigned int accvar_shift = profile_accvar_shift ( profiler ); - - /* Variance is zero if fewer than two samples exist (avoiding - * division by zero error). - */ - if ( profiler->count < 2 ) - return 0; - - /* Calculate variance, round to nearest, and scale to original units */ - return ( ( ( profiler->accvar / ( profiler->count - 1 ) ) - + ( 1ULL << ( accvar_shift - 1 ) ) ) >> accvar_shift ); -} - -/** - * Get sample standard deviation - * - * @v profiler Profiler - * @ret stddev Sample standard deviation - */ -unsigned long profile_stddev ( struct profiler *profiler ) { - - return isqrt ( profile_variance ( profiler ) ); -} diff --git a/qemu/roms/ipxe/src/core/random.c b/qemu/roms/ipxe/src/core/random.c deleted file mode 100644 index a74175a79..000000000 --- a/qemu/roms/ipxe/src/core/random.c +++ /dev/null @@ -1,41 +0,0 @@ -/** @file - * - * Random number generation - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdlib.h> -#include <ipxe/timer.h> - -static int32_t rnd_seed = 0; - -/** - * Seed the pseudo-random number generator - * - * @v seed Seed value - */ -void srandom ( unsigned int seed ) { - rnd_seed = seed; -} - -/** - * Generate a pseudo-random number between 0 and 2147483647L or 2147483562? - * - * @ret rand Pseudo-random number - */ -long int random ( void ) { - int32_t q; - - if ( ! rnd_seed ) /* Initialize linear congruential generator */ - srandom ( currticks() ); - - /* simplified version of the LCG given in Bruce Schneier's - "Applied Cryptography" */ - q = ( rnd_seed / 53668 ); - rnd_seed = ( 40014 * ( rnd_seed - 53668 * q ) - 12211 * q ); - if ( rnd_seed < 0 ) - rnd_seed += 2147483563L; - return rnd_seed; -} diff --git a/qemu/roms/ipxe/src/core/refcnt.c b/qemu/roms/ipxe/src/core/refcnt.c deleted file mode 100644 index 47c975a0b..000000000 --- a/qemu/roms/ipxe/src/core/refcnt.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdlib.h> -#include <ipxe/refcnt.h> - -/** @file - * - * Reference counting - * - */ - -/** - * Increment reference count - * - * @v refcnt Reference counter, or NULL - * - * If @c refcnt is NULL, no action is taken. - */ -void ref_increment ( struct refcnt *refcnt ) { - - if ( refcnt ) { - refcnt->count++; - DBGC2 ( refcnt, "REFCNT %p incremented to %d\n", - refcnt, refcnt->count ); - } -} - -/** - * Decrement reference count - * - * @v refcnt Reference counter, or NULL - * - * If the reference count decreases below zero, the object's free() - * method will be called. - * - * If @c refcnt is NULL, no action is taken. - */ -void ref_decrement ( struct refcnt *refcnt ) { - - if ( ! refcnt ) - return; - - refcnt->count--; - DBGC2 ( refcnt, "REFCNT %p decremented to %d\n", - refcnt, refcnt->count ); - - if ( refcnt->count >= 0 ) - return; - - if ( refcnt->count < -1 ) { - DBGC ( refcnt, "REFCNT %p decremented too far (%d)!\n", - refcnt, refcnt->count ); - /* Avoid multiple calls to free(), which typically - * result in memory corruption that is very hard to - * track down. - */ - return; - } - - if ( refcnt->free ) { - DBGC ( refcnt, "REFCNT %p being freed via method %p\n", - refcnt, refcnt->free ); - refcnt->free ( refcnt ); - } else { - DBGC ( refcnt, "REFCNT %p being freed\n", refcnt ); - free ( refcnt ); - } -} - -/** - * Do not free reference-counted object - * - * @v refcnt Reference counter - * - * This is meant for initializing a reference counter structure in a - * statically allocated object. - */ -void ref_no_free ( struct refcnt *refcnt __unused ) { - /* Do nothing */ -} diff --git a/qemu/roms/ipxe/src/core/resolv.c b/qemu/roms/ipxe/src/core/resolv.c deleted file mode 100644 index 1e3182b0b..000000000 --- a/qemu/roms/ipxe/src/core/resolv.c +++ /dev/null @@ -1,427 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <ipxe/xfer.h> -#include <ipxe/open.h> -#include <ipxe/process.h> -#include <ipxe/socket.h> -#include <ipxe/resolv.h> - -/** @file - * - * Name resolution - * - */ - -/*************************************************************************** - * - * Name resolution interfaces - * - *************************************************************************** - */ - -/** - * Name resolved - * - * @v intf Object interface - * @v sa Completed socket address (if successful) - */ -void resolv_done ( struct interface *intf, struct sockaddr *sa ) { - struct interface *dest; - resolv_done_TYPE ( void * ) *op = - intf_get_dest_op ( intf, resolv_done, &dest ); - void *object = intf_object ( dest ); - - DBGC ( INTF_COL ( intf ), "INTF " INTF_INTF_FMT " resolv_done\n", - INTF_INTF_DBG ( intf, dest ) ); - - if ( op ) { - op ( object, sa ); - } else { - /* Default is to ignore resolutions */ - } - - intf_put ( dest ); -} - -/*************************************************************************** - * - * Numeric name resolver - * - *************************************************************************** - */ - -/** A numeric name resolver */ -struct numeric_resolv { - /** Reference counter */ - struct refcnt refcnt; - /** Name resolution interface */ - struct interface resolv; - /** Process */ - struct process process; - /** Completed socket address */ - struct sockaddr sa; - /** Overall status code */ - int rc; -}; - -static void numeric_step ( struct numeric_resolv *numeric ) { - - if ( numeric->rc == 0 ) - resolv_done ( &numeric->resolv, &numeric->sa ); - intf_shutdown ( &numeric->resolv, numeric->rc ); -} - -static struct process_descriptor numeric_process_desc = - PROC_DESC_ONCE ( struct numeric_resolv, process, numeric_step ); - -static int numeric_resolv ( struct interface *resolv, - const char *name, struct sockaddr *sa ) { - struct numeric_resolv *numeric; - - /* Allocate and initialise structure */ - numeric = zalloc ( sizeof ( *numeric ) ); - if ( ! numeric ) - return -ENOMEM; - ref_init ( &numeric->refcnt, NULL ); - intf_init ( &numeric->resolv, &null_intf_desc, &numeric->refcnt ); - process_init ( &numeric->process, &numeric_process_desc, - &numeric->refcnt ); - memcpy ( &numeric->sa, sa, sizeof ( numeric->sa ) ); - - /* Attempt to resolve name */ - numeric->rc = sock_aton ( name, &numeric->sa ); - - /* Attach to parent interface, mortalise self, and return */ - intf_plug_plug ( &numeric->resolv, resolv ); - ref_put ( &numeric->refcnt ); - return 0; -} - -struct resolver numeric_resolver __resolver ( RESOLV_NUMERIC ) = { - .name = "NUMERIC", - .resolv = numeric_resolv, -}; - -/*************************************************************************** - * - * Name resolution multiplexer - * - *************************************************************************** - */ - -/** A name resolution multiplexer */ -struct resolv_mux { - /** Reference counter */ - struct refcnt refcnt; - /** Parent name resolution interface */ - struct interface parent; - - /** Child name resolution interface */ - struct interface child; - /** Current child resolver */ - struct resolver *resolver; - - /** Socket address to complete */ - struct sockaddr sa; - /** Name to be resolved - * - * Must be at end of structure - */ - char name[0]; -}; - -/** - * Try current child name resolver - * - * @v mux Name resolution multiplexer - * @ret rc Return status code - */ -static int resmux_try ( struct resolv_mux *mux ) { - struct resolver *resolver = mux->resolver; - int rc; - - DBGC ( mux, "RESOLV %p trying method %s\n", mux, resolver->name ); - - if ( ( rc = resolver->resolv ( &mux->child, mux->name, - &mux->sa ) ) != 0 ) { - DBGC ( mux, "RESOLV %p could not use method %s: %s\n", - mux, resolver->name, strerror ( rc ) ); - return rc; - } - - return 0; -} - -/** - * Child resolved name - * - * @v mux Name resolution multiplexer - * @v sa Completed socket address - */ -static void resmux_child_resolv_done ( struct resolv_mux *mux, - struct sockaddr *sa ) { - - DBGC ( mux, "RESOLV %p resolved \"%s\" to %s using method %s\n", - mux, mux->name, sock_ntoa ( sa ), mux->resolver->name ); - - /* Pass resolution to parent */ - resolv_done ( &mux->parent, sa ); -} - -/** - * Child finished resolution - * - * @v mux Name resolution multiplexer - * @v rc Return status code - */ -static void resmux_child_close ( struct resolv_mux *mux, int rc ) { - - /* Restart child interface */ - intf_restart ( &mux->child, rc ); - - /* If this resolution succeeded, stop now */ - if ( rc == 0 ) { - DBGC ( mux, "RESOLV %p succeeded using method %s\n", - mux, mux->resolver->name ); - goto finished; - } - - /* Attempt next child resolver, if possible */ - mux->resolver++; - if ( mux->resolver >= table_end ( RESOLVERS ) ) { - DBGC ( mux, "RESOLV %p failed to resolve name\n", mux ); - goto finished; - } - if ( ( rc = resmux_try ( mux ) ) != 0 ) - goto finished; - - /* Next resolver is now running */ - return; - - finished: - intf_shutdown ( &mux->parent, rc ); -} - -/** Name resolution multiplexer child interface operations */ -static struct interface_operation resmux_child_op[] = { - INTF_OP ( resolv_done, struct resolv_mux *, resmux_child_resolv_done ), - INTF_OP ( intf_close, struct resolv_mux *, resmux_child_close ), -}; - -/** Name resolution multiplexer child interface descriptor */ -static struct interface_descriptor resmux_child_desc = - INTF_DESC ( struct resolv_mux, child, resmux_child_op ); - -/** - * Start name resolution - * - * @v resolv Name resolution interface - * @v name Name to resolve - * @v sa Socket address to complete - * @ret rc Return status code - */ -int resolv ( struct interface *resolv, const char *name, - struct sockaddr *sa ) { - struct resolv_mux *mux; - size_t name_len = ( strlen ( name ) + 1 ); - int rc; - - /* Allocate and initialise structure */ - mux = zalloc ( sizeof ( *mux ) + name_len ); - if ( ! mux ) - return -ENOMEM; - ref_init ( &mux->refcnt, NULL ); - intf_init ( &mux->parent, &null_intf_desc, &mux->refcnt ); - intf_init ( &mux->child, &resmux_child_desc, &mux->refcnt ); - mux->resolver = table_start ( RESOLVERS ); - if ( sa ) - memcpy ( &mux->sa, sa, sizeof ( mux->sa ) ); - memcpy ( mux->name, name, name_len ); - - DBGC ( mux, "RESOLV %p attempting to resolve \"%s\"\n", mux, name ); - - /* Start first resolver in chain. There will always be at - * least one resolver (the numeric resolver), so no need to - * check for the zero-resolvers-available case. - */ - if ( ( rc = resmux_try ( mux ) ) != 0 ) - goto err; - - /* Attach parent interface, mortalise self, and return */ - intf_plug_plug ( &mux->parent, resolv ); - ref_put ( &mux->refcnt ); - return 0; - - err: - ref_put ( &mux->refcnt ); - return rc; -} - -/*************************************************************************** - * - * Named socket opening - * - *************************************************************************** - */ - -/** A named socket */ -struct named_socket { - /** Reference counter */ - struct refcnt refcnt; - /** Data transfer interface */ - struct interface xfer; - /** Name resolution interface */ - struct interface resolv; - /** Communication semantics (e.g. SOCK_STREAM) */ - int semantics; - /** Stored local socket address, if applicable */ - struct sockaddr local; - /** Stored local socket address exists */ - int have_local; -}; - -/** - * Terminate named socket opener - * - * @v named Named socket - * @v rc Reason for termination - */ -static void named_close ( struct named_socket *named, int rc ) { - /* Shut down interfaces */ - intf_shutdown ( &named->resolv, rc ); - intf_shutdown ( &named->xfer, rc ); -} - -/** - * Check flow control window - * - * @v named Named socket - * @ret len Length of window - */ -static size_t named_window ( struct named_socket *named __unused ) { - /* Not ready for data until we have redirected away */ - return 0; -} - -/** Named socket opener data transfer interface operations */ -static struct interface_operation named_xfer_ops[] = { - INTF_OP ( xfer_window, struct named_socket *, named_window ), - INTF_OP ( intf_close, struct named_socket *, named_close ), -}; - -/** Named socket opener data transfer interface descriptor */ -static struct interface_descriptor named_xfer_desc = - INTF_DESC ( struct named_socket, xfer, named_xfer_ops ); - -/** - * Name resolved - * - * @v named Named socket - * @v sa Completed socket address - */ -static void named_resolv_done ( struct named_socket *named, - struct sockaddr *sa ) { - int rc; - - /* Nullify data transfer interface */ - intf_nullify ( &named->xfer ); - - /* Redirect data-xfer interface */ - if ( ( rc = xfer_redirect ( &named->xfer, LOCATION_SOCKET, - named->semantics, sa, - ( named->have_local ? - &named->local : NULL ) ) ) != 0 ) { - /* Redirection failed - do not unplug data-xfer interface */ - DBGC ( named, "NAMED %p could not redirect: %s\n", - named, strerror ( rc ) ); - } else { - /* Redirection succeeded - unplug data-xfer interface */ - DBGC ( named, "NAMED %p redirected successfully\n", named ); - intf_unplug ( &named->xfer ); - } - - /* Terminate named socket opener */ - named_close ( named, rc ); -} - -/** Named socket opener resolver interface operations */ -static struct interface_operation named_resolv_op[] = { - INTF_OP ( intf_close, struct named_socket *, named_close ), - INTF_OP ( resolv_done, struct named_socket *, named_resolv_done ), -}; - -/** Named socket opener resolver interface descriptor */ -static struct interface_descriptor named_resolv_desc = - INTF_DESC ( struct named_socket, resolv, named_resolv_op ); - -/** - * Open named socket - * - * @v semantics Communication semantics (e.g. SOCK_STREAM) - * @v peer Peer socket address to complete - * @v name Name to resolve - * @v local Local socket address, or NULL - * @ret rc Return status code - */ -int xfer_open_named_socket ( struct interface *xfer, int semantics, - struct sockaddr *peer, const char *name, - struct sockaddr *local ) { - struct named_socket *named; - int rc; - - /* Allocate and initialise structure */ - named = zalloc ( sizeof ( *named ) ); - if ( ! named ) - return -ENOMEM; - ref_init ( &named->refcnt, NULL ); - intf_init ( &named->xfer, &named_xfer_desc, &named->refcnt ); - intf_init ( &named->resolv, &named_resolv_desc, &named->refcnt ); - named->semantics = semantics; - if ( local ) { - memcpy ( &named->local, local, sizeof ( named->local ) ); - named->have_local = 1; - } - - DBGC ( named, "NAMED %p opening \"%s\"\n", - named, name ); - - /* Start name resolution */ - if ( ( rc = resolv ( &named->resolv, name, peer ) ) != 0 ) - goto err; - - /* Attach parent interface, mortalise self, and return */ - intf_plug_plug ( &named->xfer, xfer ); - ref_put ( &named->refcnt ); - return 0; - - err: - ref_put ( &named->refcnt ); - return rc; -} diff --git a/qemu/roms/ipxe/src/core/serial.c b/qemu/roms/ipxe/src/core/serial.c deleted file mode 100644 index 4ce025519..000000000 --- a/qemu/roms/ipxe/src/core/serial.c +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/** @file - * - * Serial console - * - */ - -#include <stddef.h> -#include <ipxe/init.h> -#include <ipxe/uart.h> -#include <ipxe/console.h> -#include <ipxe/serial.h> -#include <config/console.h> -#include <config/serial.h> - -/* 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 - -/* UART port number */ -#ifdef COMCONSOLE -#define CONSOLE_PORT COMCONSOLE -#else -#define CONSOLE_PORT 0 -#endif - -/* UART baud rate */ -#ifdef COMPRESERVE -#define CONSOLE_BAUD 0 -#else -#define CONSOLE_BAUD COMSPEED -#endif - -/* UART line control register value */ -#ifdef COMPRESERVE -#define CONSOLE_LCR 0 -#else -#define CONSOLE_LCR UART_LCR_WPS ( COMDATA, COMPARITY, COMSTOP ) -#endif - -/** Serial console UART */ -struct uart serial_console; - -/** - * Print a character to serial console - * - * @v character Character to be printed - */ -static void serial_putchar ( int character ) { - - /* Do nothing if we have no UART */ - if ( ! serial_console.base ) - return; - - /* Transmit character */ - uart_transmit ( &serial_console, character ); -} - -/** - * Get character from serial console - * - * @ret character Character read from console - */ -static int serial_getchar ( void ) { - uint8_t data; - - /* Do nothing if we have no UART */ - if ( ! serial_console.base ) - return 0; - - /* Wait for data to be ready */ - while ( ! uart_data_ready ( &serial_console ) ) {} - - /* Receive data */ - data = uart_receive ( &serial_console ); - - /* Strip any high bit and convert DEL to backspace */ - data &= 0x7f; - if ( data == 0x7f ) - data = 0x08; - - return data; -} - -/** - * Check for character ready to read from serial console - * - * @ret True Character available to read - * @ret False No character available to read - */ -static int serial_iskey ( void ) { - - /* Do nothing if we have no UART */ - if ( ! serial_console.base ) - return 0; - - /* Check UART */ - return uart_data_ready ( &serial_console ); -} - -/** 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; - - /* Do nothing if we have no default port */ - if ( ! CONSOLE_PORT ) - return; - - /* Select UART */ - if ( ( rc = uart_select ( &serial_console, CONSOLE_PORT ) ) != 0 ) { - DBG ( "Could not select UART %d: %s\n", - CONSOLE_PORT, strerror ( rc ) ); - return; - } - - /* 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; - } -} - -/** - * Shut down serial console - * - * @v flags Shutdown flags - */ -static void serial_shutdown ( int flags __unused ) { - - /* Do nothing if we have no UART */ - if ( ! serial_console.base ) - return; - - /* Flush any pending output */ - uart_flush ( &serial_console ); - - /* Leave console enabled; it's still usable */ -} - -/** Serial console initialisation function */ -struct init_fn serial_console_init_fn __init_fn ( INIT_CONSOLE ) = { - .initialise = serial_init, -}; - -/** Serial console startup function */ -struct startup_fn serial_startup_fn __startup_fn ( STARTUP_EARLY ) = { - .shutdown = serial_shutdown, -}; diff --git a/qemu/roms/ipxe/src/core/settings.c b/qemu/roms/ipxe/src/core/settings.c deleted file mode 100644 index 12e6c7d61..000000000 --- a/qemu/roms/ipxe/src/core/settings.c +++ /dev/null @@ -1,2578 +0,0 @@ -/* - * Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdint.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <strings.h> -#include <byteswap.h> -#include <errno.h> -#include <assert.h> -#include <ipxe/in.h> -#include <ipxe/ip.h> -#include <ipxe/ipv6.h> -#include <ipxe/vsprintf.h> -#include <ipxe/dhcp.h> -#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> -#include <ipxe/settings.h> - -/** @file - * - * Configuration settings - * - */ - -/****************************************************************************** - * - * Generic settings blocks - * - ****************************************************************************** - */ - -/** - * A generic setting - * - */ -struct generic_setting { - /** List of generic settings */ - struct list_head list; - /** Setting */ - struct setting setting; - /** Size of setting name */ - size_t name_len; - /** Size of setting data */ - size_t data_len; -}; - -/** - * Get generic setting name - * - * @v generic Generic setting - * @ret name Generic setting name - */ -static inline void * generic_setting_name ( struct generic_setting *generic ) { - return ( ( ( void * ) generic ) + sizeof ( *generic ) ); -} - -/** - * Get generic setting data - * - * @v generic Generic setting - * @ret data Generic setting data - */ -static inline void * generic_setting_data ( struct generic_setting *generic ) { - return ( ( ( void * ) generic ) + sizeof ( *generic ) + - generic->name_len ); -} - -/** - * Find generic setting - * - * @v generics Generic settings block - * @v setting Setting to find - * @ret generic Generic setting, or NULL - */ -static struct generic_setting * -find_generic_setting ( struct generic_settings *generics, - const struct setting *setting ) { - struct generic_setting *generic; - - list_for_each_entry ( generic, &generics->list, list ) { - if ( setting_cmp ( &generic->setting, setting ) == 0 ) - return generic; - } - return NULL; -} - -/** - * Store value of generic setting - * - * @v settings Settings block - * @v setting Setting to store - * @v data Setting data, or NULL to clear setting - * @v len Length of setting data - * @ret rc Return status code - */ -int generic_settings_store ( struct settings *settings, - const struct setting *setting, - const void *data, size_t len ) { - struct generic_settings *generics = - container_of ( settings, struct generic_settings, settings ); - struct generic_setting *old; - struct generic_setting *new = NULL; - size_t name_len; - - /* Identify existing generic setting, if any */ - old = find_generic_setting ( generics, setting ); - - /* Create new generic setting, if required */ - if ( len ) { - /* Allocate new generic setting */ - name_len = ( strlen ( setting->name ) + 1 ); - new = zalloc ( sizeof ( *new ) + name_len + len ); - if ( ! new ) - return -ENOMEM; - - /* Populate new generic setting */ - new->name_len = name_len; - new->data_len = len; - memcpy ( &new->setting, setting, sizeof ( new->setting ) ); - new->setting.name = generic_setting_name ( new ); - memcpy ( generic_setting_name ( new ), - setting->name, name_len ); - memcpy ( generic_setting_data ( new ), data, len ); - } - - /* Delete existing generic setting, if any */ - if ( old ) { - list_del ( &old->list ); - free ( old ); - } - - /* Add new setting to list, if any */ - if ( new ) - list_add ( &new->list, &generics->list ); - - return 0; -} - -/** - * Fetch value of generic setting - * - * @v settings Settings block - * @v setting Setting to fetch - * @v data Buffer to fill with setting data - * @v len Length of buffer - * @ret len Length of setting data, or negative error - */ -int generic_settings_fetch ( struct settings *settings, - struct setting *setting, - void *data, size_t len ) { - struct generic_settings *generics = - container_of ( settings, struct generic_settings, settings ); - struct generic_setting *generic; - - /* Find generic setting */ - generic = find_generic_setting ( generics, setting ); - if ( ! generic ) - return -ENOENT; - - /* Copy out generic setting data */ - if ( len > generic->data_len ) - len = generic->data_len; - memcpy ( data, generic_setting_data ( generic ), len ); - - /* Set setting type, if not yet specified */ - if ( ! setting->type ) - setting->type = generic->setting.type; - - return generic->data_len; -} - -/** - * Clear generic settings block - * - * @v settings Settings block - */ -void generic_settings_clear ( struct settings *settings ) { - struct generic_settings *generics = - container_of ( settings, struct generic_settings, settings ); - struct generic_setting *generic; - struct generic_setting *tmp; - - list_for_each_entry_safe ( generic, tmp, &generics->list, list ) { - list_del ( &generic->list ); - free ( generic ); - } - assert ( list_empty ( &generics->list ) ); -} - -/** Generic settings operations */ -struct settings_operations generic_settings_operations = { - .store = generic_settings_store, - .fetch = generic_settings_fetch, - .clear = generic_settings_clear, -}; - -/****************************************************************************** - * - * Registered settings blocks - * - ****************************************************************************** - */ - -/** Root generic settings block */ -struct generic_settings generic_settings_root = { - .settings = { - .refcnt = NULL, - .name = "", - .siblings = - LIST_HEAD_INIT ( generic_settings_root.settings.siblings ), - .children = - LIST_HEAD_INIT ( generic_settings_root.settings.children ), - .op = &generic_settings_operations, - }, - .list = LIST_HEAD_INIT ( generic_settings_root.list ), -}; - -/** Root settings block */ -#define settings_root generic_settings_root.settings - -/** Autovivified settings block */ -struct autovivified_settings { - /** Reference count */ - struct refcnt refcnt; - /** Generic settings block */ - struct generic_settings generic; -}; - -/** - * Free autovivified settings block - * - * @v refcnt Reference count - */ -static void autovivified_settings_free ( struct refcnt *refcnt ) { - struct autovivified_settings *autovivified = - container_of ( refcnt, struct autovivified_settings, refcnt ); - - generic_settings_clear ( &autovivified->generic.settings ); - free ( autovivified ); -} - -/** - * Find child settings block - * - * @v parent Parent settings block - * @v name Name within this parent - * @ret settings Settings block, or NULL - */ -struct settings * find_child_settings ( struct settings *parent, - const char *name ) { - struct settings *settings; - - /* Find target parent settings block */ - parent = settings_target ( parent ); - - /* Treat empty name as meaning "this block" */ - if ( ! *name ) - return parent; - - /* Look for child with matching name */ - list_for_each_entry ( settings, &parent->children, siblings ) { - if ( strcmp ( settings->name, name ) == 0 ) - return settings_target ( settings ); - } - - return NULL; -} - -/** - * Find or create child settings block - * - * @v parent Parent settings block - * @v name Name within this parent - * @ret settings Settings block, or NULL - */ -struct settings * autovivify_child_settings ( struct settings *parent, - const char *name ) { - struct { - struct autovivified_settings autovivified; - char name[ strlen ( name ) + 1 /* NUL */ ]; - } *new_child; - struct settings *settings; - - /* Find target parent settings block */ - parent = settings_target ( parent ); - - /* Return existing settings, if existent */ - if ( ( settings = find_child_settings ( parent, name ) ) != NULL ) - return settings; - - /* Create new generic settings block */ - new_child = zalloc ( sizeof ( *new_child ) ); - if ( ! new_child ) { - DBGC ( parent, "Settings %p could not create child %s\n", - parent, name ); - return NULL; - } - memcpy ( new_child->name, name, sizeof ( new_child->name ) ); - ref_init ( &new_child->autovivified.refcnt, - autovivified_settings_free ); - generic_settings_init ( &new_child->autovivified.generic, - &new_child->autovivified.refcnt ); - settings = &new_child->autovivified.generic.settings; - register_settings ( settings, parent, new_child->name ); - return settings; -} - -/** - * Return settings block name - * - * @v settings Settings block - * @ret name Settings block name - */ -const char * settings_name ( struct settings *settings ) { - static char buf[16]; - char tmp[ 1 /* '.' */ + sizeof ( buf ) ]; - - /* Find target settings block */ - settings = settings_target ( settings ); - - /* Construct name */ - 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; -} - -/** - * Parse settings block name - * - * @v name Name - * @v get_child Function to find or create child settings block - * @ret settings Settings block, or NULL - */ -static struct settings * -parse_settings_name ( const char *name, get_child_settings_t get_child ) { - struct settings *settings = &settings_root; - char name_copy[ strlen ( name ) + 1 ]; - char *subname; - char *remainder; - - /* Create modifiable copy of name */ - memcpy ( name_copy, name, sizeof ( name_copy ) ); - remainder = name_copy; - - /* Parse each name component in turn */ - while ( remainder ) { - subname = remainder; - remainder = strchr ( subname, '.' ); - if ( remainder ) - *(remainder++) = '\0'; - settings = get_child ( settings, subname ); - if ( ! settings ) - break; - } - - return settings; -} - -/** - * Find settings block - * - * @v name Name - * @ret settings Settings block, or NULL - */ -struct settings * find_settings ( const char *name ) { - - return parse_settings_name ( name, find_child_settings ); -} - -/** - * Apply all settings - * - * @ret rc Return status code - */ -static int apply_settings ( void ) { - struct settings_applicator *applicator; - int rc; - - /* Call all settings applicators */ - for_each_table_entry ( applicator, SETTINGS_APPLICATORS ) { - if ( ( rc = applicator->apply() ) != 0 ) { - DBG ( "Could not apply settings using applicator " - "%p: %s\n", applicator, strerror ( rc ) ); - return rc; - } - } - - return 0; -} - -/** - * Reprioritise settings - * - * @v settings Settings block - * - * Reorders the settings block amongst its siblings according to its - * priority. - */ -static void reprioritise_settings ( struct settings *settings ) { - struct settings *parent = settings->parent; - long priority; - struct settings *tmp; - long tmp_priority; - - /* Stop when we reach the top of the tree */ - if ( ! parent ) - return; - - /* Read priority, if present */ - priority = fetch_intz_setting ( settings, &priority_setting ); - - /* Remove from siblings list */ - list_del ( &settings->siblings ); - - /* Reinsert after any existing blocks which have a higher priority */ - list_for_each_entry ( tmp, &parent->children, siblings ) { - tmp_priority = fetch_intz_setting ( tmp, &priority_setting ); - if ( priority > tmp_priority ) - break; - } - list_add_tail ( &settings->siblings, &tmp->siblings ); - - /* Recurse up the tree */ - reprioritise_settings ( parent ); -} - -/** - * Register settings block - * - * @v settings Settings block - * @v parent Parent settings block, or NULL - * @v name Settings block name - * @ret rc Return status code - */ -int register_settings ( struct settings *settings, struct settings *parent, - const char *name ) { - struct settings *old_settings; - - /* Sanity check */ - assert ( settings != NULL ); - - /* Find target parent settings block */ - parent = settings_target ( parent ); - - /* Apply settings block name */ - settings->name = name; - - /* Remove any existing settings with the same name */ - if ( ( old_settings = find_child_settings ( parent, settings->name ) )) - unregister_settings ( old_settings ); - - /* Add to list of settings */ - ref_get ( settings->refcnt ); - ref_get ( parent->refcnt ); - settings->parent = parent; - list_add_tail ( &settings->siblings, &parent->children ); - DBGC ( settings, "Settings %p (\"%s\") registered\n", - settings, settings_name ( settings ) ); - - /* Fix up settings priority */ - reprioritise_settings ( settings ); - - /* Apply potentially-updated settings */ - apply_settings(); - - return 0; -} - -/** - * Unregister settings block - * - * @v settings Settings block - */ -void unregister_settings ( struct settings *settings ) { - struct settings *child; - - /* Unregister child settings */ - while ( ( child = list_first_entry ( &settings->children, - struct settings, siblings ) ) ) { - unregister_settings ( child ); - } - - DBGC ( settings, "Settings %p (\"%s\") unregistered\n", - settings, settings_name ( settings ) ); - - /* Remove from list of settings */ - ref_put ( settings->parent->refcnt ); - settings->parent = NULL; - list_del ( &settings->siblings ); - ref_put ( settings->refcnt ); - - /* Apply potentially-updated settings */ - apply_settings(); -} - -/****************************************************************************** - * - * Core settings routines - * - ****************************************************************************** - */ - -/** - * Redirect to target settings block - * - * @v settings Settings block, or NULL - * @ret settings Underlying settings block - */ -struct settings * settings_target ( struct settings *settings ) { - - /* NULL settings implies the global settings root */ - if ( ! settings ) - settings = &settings_root; - - /* Redirect to underlying settings block, if applicable */ - if ( settings->op->redirect ) - return settings->op->redirect ( settings ); - - /* Otherwise, return this settings block */ - return settings; -} - -/** - * Check applicability of setting - * - * @v settings Settings block - * @v setting Setting - * @ret applies Setting applies within this settings block - */ -int setting_applies ( struct settings *settings, - const struct setting *setting ) { - - /* Find target settings block */ - settings = settings_target ( settings ); - - /* Check applicability of setting */ - return ( settings->op->applies ? - settings->op->applies ( settings, setting ) : 1 ); -} - -/** - * Find setting applicable to settings block, if any - * - * @v settings Settings block - * @v setting Setting - * @ret setting Applicable setting, if any - */ -static const struct setting * -applicable_setting ( struct settings *settings, const struct setting *setting ){ - const struct setting *applicable; - - /* If setting is already applicable, use it */ - if ( setting_applies ( settings, setting ) ) - return setting; - - /* Otherwise, look for a matching predefined setting which does apply */ - for_each_table_entry ( applicable, SETTINGS ) { - if ( ( setting_cmp ( setting, applicable ) == 0 ) && - ( setting_applies ( settings, applicable ) ) ) - return applicable; - } - - return NULL; -} - -/** - * Store value of setting - * - * @v settings Settings block, or NULL - * @v setting Setting to store - * @v data Setting data, or NULL to clear setting - * @v len Length of setting data - * @ret rc Return status code - */ -int store_setting ( struct settings *settings, const struct setting *setting, - const void *data, size_t len ) { - int rc; - - /* Find target settings block */ - settings = settings_target ( settings ); - - /* Fail if setting does not apply to this settings block */ - if ( ! setting_applies ( settings, setting ) ) - return -ENOTTY; - - /* Sanity check */ - if ( ! settings->op->store ) - return -ENOTSUP; - - /* Store setting */ - if ( ( rc = settings->op->store ( settings, setting, - data, len ) ) != 0 ) - return rc; - - /* Reprioritise settings if necessary */ - if ( setting_cmp ( setting, &priority_setting ) == 0 ) - reprioritise_settings ( settings ); - - /* If these settings are registered, apply potentially-updated - * settings - */ - for ( ; settings ; settings = settings->parent ) { - if ( settings == &settings_root ) { - if ( ( rc = apply_settings() ) != 0 ) - return rc; - break; - } - } - - return 0; -} - -/** - * Fetch setting - * - * @v settings Settings block, or NULL to search all blocks - * @v setting Setting to fetch - * @v origin Origin of setting to fill in, or NULL - * @v fetched Fetched setting to fill in, or NULL - * @v data Buffer to fill with setting data - * @v len Length of buffer - * @ret len Length of setting data, or negative error - * - * The actual length of the setting will be returned even if - * the buffer was too small. - */ -int fetch_setting ( struct settings *settings, const struct setting *setting, - struct settings **origin, struct setting *fetched, - void *data, size_t len ) { - const struct setting *applicable; - struct settings *child; - struct setting tmp; - int ret; - - /* Avoid returning uninitialised data on error */ - memset ( data, 0, len ); - if ( origin ) - *origin = NULL; - if ( fetched ) - memcpy ( fetched, setting, sizeof ( *fetched ) ); - - /* Find target settings block */ - settings = settings_target ( settings ); - - /* Sanity check */ - if ( ! settings->op->fetch ) - return -ENOTSUP; - - /* Try this block first, if an applicable setting exists */ - if ( ( applicable = applicable_setting ( settings, setting ) ) ) { - - /* Create modifiable copy of setting */ - memcpy ( &tmp, applicable, sizeof ( tmp ) ); - if ( ( ret = settings->op->fetch ( settings, &tmp, - data, len ) ) >= 0 ) { - - /* Default to string type, if not yet specified */ - if ( ! tmp.type ) - tmp.type = &setting_type_string; - - /* Record origin, if applicable */ - if ( origin ) - *origin = settings; - - /* Record fetched setting, if applicable */ - if ( fetched ) - memcpy ( fetched, &tmp, sizeof ( *fetched ) ); - - return ret; - } - } - - /* Recurse into each child block in turn */ - list_for_each_entry ( child, &settings->children, siblings ) { - if ( ( ret = fetch_setting ( child, setting, origin, fetched, - data, len ) ) >= 0 ) - return ret; - } - - return -ENOENT; -} - -/** - * Fetch allocated copy of setting - * - * @v settings Settings block, or NULL to search all blocks - * @v setting Setting to fetch - * @v origin Origin of setting to fill in, or NULL - * @v fetched Fetched setting to fill in, or NULL - * @v data Buffer to allocate and fill with setting data - * @v alloc Allocation function - * @ret len Length of setting, or negative error - * - * The caller is responsible for eventually freeing the allocated - * buffer. - */ -static int fetch_setting_alloc ( struct settings *settings, - const struct setting *setting, - struct settings **origin, - struct setting *fetched, - void **data, - void * ( * alloc ) ( size_t len ) ) { - struct settings *tmp_origin; - struct setting tmp_fetched; - int len; - int check_len; - - /* Use local buffers if necessary */ - if ( ! origin ) - origin = &tmp_origin; - if ( ! fetched ) - fetched = &tmp_fetched; - - /* Avoid returning uninitialised data on error */ - *data = NULL; - - /* Check existence, and fetch setting length */ - len = fetch_setting ( settings, setting, origin, fetched, NULL, 0 ); - if ( len < 0 ) - return len; - - /* Allocate buffer */ - *data = alloc ( len ); - if ( ! *data ) - return -ENOMEM; - - /* Fetch setting value */ - check_len = fetch_setting ( *origin, fetched, NULL, NULL, *data, len ); - assert ( check_len == len ); - return len; -} - -/** - * Fetch copy of setting - * - * @v settings Settings block, or NULL to search all blocks - * @v setting Setting to fetch - * @v origin Origin of setting to fill in, or NULL - * @v fetched Fetched setting to fill in, or NULL - * @v data Buffer to allocate and fill with setting data - * @ret len Length of setting, or negative error - * - * The caller is responsible for eventually freeing the allocated - * buffer. - */ -int fetch_setting_copy ( struct settings *settings, - const struct setting *setting, - struct settings **origin, struct setting *fetched, - void **data ) { - - return fetch_setting_alloc ( settings, setting, origin, fetched, - data, malloc ); -} - -/** - * Fetch value of setting - * - * @v settings Settings block, or NULL to search all blocks - * @v setting Setting to fetch - * @v data Buffer to fill with setting string data - * @v len Length of buffer - * @ret len Length of setting, or negative error - */ -int fetch_raw_setting ( struct settings *settings, - const struct setting *setting, - void *data, size_t len ) { - - return fetch_setting ( settings, setting, NULL, NULL, data, len ); -} - -/** - * Fetch value of setting - * - * @v settings Settings block, or NULL to search all blocks - * @v setting Setting to fetch - * @v data Buffer to allocate and fill with setting data - * @ret len Length of setting, or negative error - * - * The caller is responsible for eventually freeing the allocated - * buffer. - */ -int fetch_raw_setting_copy ( struct settings *settings, - const struct setting *setting, - void **data ) { - - return fetch_setting_copy ( settings, setting, NULL, NULL, data ); -} - -/** - * Fetch value of string setting - * - * @v settings Settings block, or NULL to search all blocks - * @v setting Setting to fetch - * @v data Buffer to fill with setting string data - * @v len Length of buffer - * @ret len Length of string setting, or negative error - * - * The resulting string is guaranteed to be correctly NUL-terminated. - * The returned length will be the length of the underlying setting - * data. - */ -int fetch_string_setting ( struct settings *settings, - const struct setting *setting, - char *data, size_t len ) { - - memset ( data, 0, len ); - return fetch_raw_setting ( settings, setting, data, - ( ( len > 0 ) ? ( len - 1 ) : 0 ) ); -} - -/** - * Allocate memory for copy of string setting - * - * @v len Length of setting - * @ret ptr Allocated memory - */ -static void * fetch_string_setting_copy_alloc ( size_t len ) { - return zalloc ( len + 1 /* NUL */ ); -} - -/** - * Fetch value of string setting - * - * @v settings Settings block, or NULL to search all blocks - * @v setting Setting to fetch - * @v data Buffer to allocate and fill with setting string data - * @ret len Length of string setting, or negative error - * - * The resulting string is guaranteed to be correctly NUL-terminated. - * The returned length will be the length of the underlying setting - * data. The caller is responsible for eventually freeing the - * allocated buffer. - */ -int fetch_string_setting_copy ( struct settings *settings, - const struct setting *setting, char **data ) { - - return fetch_setting_alloc ( settings, setting, NULL, NULL, - ( ( void ** ) data ), - fetch_string_setting_copy_alloc ); -} - -/** - * Fetch value of IPv4 address setting - * - * @v settings Settings block, or NULL to search all blocks - * @v setting Setting to fetch - * @v inp IPv4 addresses to fill in - * @v count Maximum number of IPv4 addresses - * @ret len Length of setting, or negative error - */ -int fetch_ipv4_array_setting ( struct settings *settings, - const struct setting *setting, - struct in_addr *inp, unsigned int count ) { - int len; - - len = fetch_raw_setting ( settings, setting, inp, - ( sizeof ( *inp ) * count ) ); - if ( len < 0 ) - return len; - if ( ( len % sizeof ( *inp ) ) != 0 ) - return -ERANGE; - return len; -} - -/** - * Fetch value of IPv4 address setting - * - * @v settings Settings block, or NULL to search all blocks - * @v setting Setting to fetch - * @v inp IPv4 address to fill in - * @ret len Length of setting, or negative error - */ -int fetch_ipv4_setting ( struct settings *settings, - const struct setting *setting, - struct in_addr *inp ) { - - return fetch_ipv4_array_setting ( settings, setting, inp, 1 ); -} - -/** - * Fetch value of IPv6 address setting - * - * @v settings Settings block, or NULL to search all blocks - * @v setting Setting to fetch - * @v inp IPv6 addresses to fill in - * @v count Maximum number of IPv6 addresses - * @ret len Length of setting, or negative error - */ -int fetch_ipv6_array_setting ( struct settings *settings, - const struct setting *setting, - struct in6_addr *inp, unsigned int count ) { - int len; - - len = fetch_raw_setting ( settings, setting, inp, - ( sizeof ( *inp ) * count ) ); - if ( len < 0 ) - return len; - if ( ( len % sizeof ( *inp ) ) != 0 ) - return -ERANGE; - return len; -} - -/** - * Fetch value of IPv6 address setting - * - * @v settings Settings block, or NULL to search all blocks - * @v setting Setting to fetch - * @v inp IPv6 address to fill in - * @ret len Length of setting, or negative error - */ -int fetch_ipv6_setting ( struct settings *settings, - const struct setting *setting, - struct in6_addr *inp ) { - - return fetch_ipv6_array_setting ( settings, setting, inp, 1 ); -} - -/** - * Extract numeric value of setting - * - * @v is_signed Treat value as a signed integer - * @v raw Raw setting data - * @v len Length of raw setting data - * @ret value Numeric value - * @ret len Length of setting, or negative error - */ -static int numeric_setting_value ( int is_signed, const void *raw, size_t len, - unsigned long *value ) { - const uint8_t *unsigned_bytes = raw; - const int8_t *signed_bytes = raw; - int is_negative; - unsigned int i; - uint8_t pad; - uint8_t byte; - - /* Convert to host-ordered longs */ - is_negative = ( len && ( signed_bytes[0] < 0 ) ); - *value = ( ( is_signed && is_negative ) ? -1L : 0 ); - pad = *value; - for ( i = 0 ; i < len ; i++ ) { - byte = unsigned_bytes[i]; - *value = ( ( *value << 8 ) | byte ); - if ( ( ( i + sizeof ( *value ) ) < len ) && ( byte != pad ) ) - return -ERANGE; - } - - return len; -} - -/** - * Fetch value of numeric setting - * - * @v settings Settings block, or NULL to search all blocks - * @v setting Setting to fetch - * @v value Integer value to fill in - * @ret len Length of setting, or negative error - */ -int fetch_numeric_setting ( struct settings *settings, - const struct setting *setting, - unsigned long *value, int is_signed ) { - unsigned long tmp; - int len; - - /* Avoid returning uninitialised data on error */ - *value = 0; - - /* Fetch raw (network-ordered, variable-length) setting */ - len = fetch_raw_setting ( settings, setting, &tmp, sizeof ( tmp ) ); - if ( len < 0 ) - return len; - - /* Extract numeric value */ - return numeric_setting_value ( is_signed, &tmp, len, value ); -} - -/** - * Fetch value of signed integer setting - * - * @v settings Settings block, or NULL to search all blocks - * @v setting Setting to fetch - * @v value Integer value to fill in - * @ret len Length of setting, or negative error - */ -int fetch_int_setting ( struct settings *settings, - const struct setting *setting, - long *value ) { - - return fetch_numeric_setting ( settings, setting, - ( ( unsigned long * ) value ), 1 ); -} - -/** - * Fetch value of unsigned integer setting - * - * @v settings Settings block, or NULL to search all blocks - * @v setting Setting to fetch - * @v value Integer value to fill in - * @ret len Length of setting, or negative error - */ -int fetch_uint_setting ( struct settings *settings, - const struct setting *setting, - unsigned long *value ) { - - return fetch_numeric_setting ( settings, setting, value, 0 ); -} - -/** - * Fetch value of signed integer setting, or zero - * - * @v settings Settings block, or NULL to search all blocks - * @v setting Setting to fetch - * @ret value Setting value, or zero - */ -long fetch_intz_setting ( struct settings *settings, - const struct setting *setting ) { - unsigned long value; - - fetch_numeric_setting ( settings, setting, &value, 1 ); - return value; -} - -/** - * Fetch value of unsigned integer setting, or zero - * - * @v settings Settings block, or NULL to search all blocks - * @v setting Setting to fetch - * @ret value Setting value, or zero - */ -unsigned long fetch_uintz_setting ( struct settings *settings, - const struct setting *setting ) { - unsigned long value; - - fetch_numeric_setting ( settings, setting, &value, 0 ); - return value; -} - -/** - * Fetch value of UUID setting - * - * @v settings Settings block, or NULL to search all blocks - * @v setting Setting to fetch - * @v uuid UUID to fill in - * @ret len Length of setting, or negative error - */ -int fetch_uuid_setting ( struct settings *settings, - const struct setting *setting, - union uuid *uuid ) { - int len; - - len = fetch_raw_setting ( settings, setting, uuid, sizeof ( *uuid ) ); - if ( len < 0 ) - return len; - if ( len != sizeof ( *uuid ) ) - return -ERANGE; - return len; -} - -/** - * Clear settings block - * - * @v settings Settings block - */ -void clear_settings ( struct settings *settings ) { - - /* Find target settings block */ - settings = settings_target ( settings ); - - /* Clear settings, if applicable */ - if ( settings->op->clear ) - settings->op->clear ( settings ); -} - -/** - * Compare two settings - * - * @v a Setting to compare - * @v b Setting to compare - * @ret 0 Settings are the same - * @ret non-zero Settings are not the same - */ -int setting_cmp ( const struct setting *a, const struct setting *b ) { - - /* If the settings have tags, compare them */ - if ( a->tag && ( a->tag == b->tag ) && ( a->scope == b->scope ) ) - return 0; - - /* Otherwise, if the settings have names, compare them */ - if ( a->name && b->name && a->name[0] ) - return strcmp ( a->name, b->name ); - - /* Otherwise, return a non-match */ - return ( ! 0 ); -} - -/****************************************************************************** - * - * Formatted setting routines - * - ****************************************************************************** - */ - -/** - * Format setting value as a string - * - * @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 - */ -int setting_format ( const struct setting_type *type, const void *raw, - size_t raw_len, char *buf, size_t len ) { - - /* Sanity check */ - if ( ! type->format ) - return -ENOTSUP; - - return type->format ( type, raw, raw_len, buf, len ); -} - -/** - * Parse formatted string to setting value - * - * @v type Setting type - * @v value Formatted setting value - * @v buf Buffer to contain raw value - * @v len Length of buffer - * @ret len Length of raw value, or negative error - */ -int setting_parse ( const struct setting_type *type, const char *value, - void *buf, size_t len ) { - - /* Sanity check */ - if ( ! type->parse ) - return -ENOTSUP; - - return type->parse ( type, value, buf, len ); -} - -/** - * Convert setting value to number - * - * @v type Setting type - * @v raw Raw setting value - * @v raw_len Length of raw setting value - * @ret value Numeric value - * @ret rc Return status code - */ -int setting_numerate ( const struct setting_type *type, const void *raw, - size_t raw_len, unsigned long *value ) { - - /* Sanity check */ - if ( ! type->numerate ) - return -ENOTSUP; - - return type->numerate ( type, raw, raw_len, value ); -} - -/** - * Convert number to setting value - * - * @v type Setting type - * @v value Numeric value - * @v buf Buffer to contain raw value - * @v len Length of buffer - * @ret len Length of raw value, or negative error - */ -int setting_denumerate ( const struct setting_type *type, unsigned long value, - void *buf, size_t len ) { - - /* Sanity check */ - if ( ! type->denumerate ) - return -ENOTSUP; - - return type->denumerate ( type, value, buf, len ); -} - -/** - * Fetch formatted value of setting - * - * @v settings Settings block, or NULL to search all blocks - * @v setting Setting to fetch - * @v origin Origin of setting to fill in, or NULL - * @v fetched Fetched setting to fill in, or NULL - * @v buf Buffer to contain formatted value - * @v len Length of buffer - * @ret len Length of formatted value, or negative error - */ -int fetchf_setting ( struct settings *settings, const struct setting *setting, - struct settings **origin, struct setting *fetched, - char *buf, size_t len ) { - struct setting tmp_fetched; - void *raw; - int raw_len; - int ret; - - /* Use local buffers if necessary */ - if ( ! fetched ) - fetched = &tmp_fetched; - - /* Fetch raw value */ - raw_len = fetch_setting_copy ( settings, setting, origin, fetched, - &raw ); - if ( raw_len < 0 ) { - ret = raw_len; - goto err_fetch_copy; - } - - /* Sanity check */ - assert ( fetched->type != NULL ); - - /* Format setting */ - if ( ( ret = setting_format ( fetched->type, raw, raw_len, buf, - len ) ) < 0 ) - goto err_format; - - err_format: - free ( raw ); - err_fetch_copy: - return ret; -} - -/** - * Fetch copy of formatted value of setting - * - * @v settings Settings block, or NULL to search all blocks - * @v setting Setting to fetch - * @v origin Origin of setting to fill in, or NULL - * @v fetched Fetched setting to fill in, or NULL - * @v value Buffer to allocate and fill with formatted value - * @ret len Length of formatted value, or negative error - * - * The caller is responsible for eventually freeing the allocated - * buffer. - */ -int fetchf_setting_copy ( struct settings *settings, - const struct setting *setting, - struct settings **origin, struct setting *fetched, - char **value ) { - struct settings *tmp_origin; - struct setting tmp_fetched; - int len; - int check_len; - - /* Use local buffers if necessary */ - if ( ! origin ) - origin = &tmp_origin; - if ( ! fetched ) - fetched = &tmp_fetched; - - /* Avoid returning uninitialised data on error */ - *value = NULL; - - /* Check existence, and fetch formatted value length */ - len = fetchf_setting ( settings, setting, origin, fetched, NULL, 0 ); - if ( len < 0 ) - return len; - - /* Allocate buffer */ - *value = zalloc ( len + 1 /* NUL */ ); - if ( ! *value ) - return -ENOMEM; - - /* Fetch formatted value */ - check_len = fetchf_setting ( *origin, fetched, NULL, NULL, *value, - ( len + 1 /* NUL */ ) ); - assert ( check_len == len ); - return len; -} - -/** - * Store formatted value of setting - * - * @v settings Settings block - * @v setting Setting to store - * @v value Formatted setting data, or NULL - * @ret rc Return status code - */ -int storef_setting ( struct settings *settings, const struct setting *setting, - const char *value ) { - void *raw; - int raw_len; - int check_len; - int rc; - - /* NULL value or empty string implies deletion */ - if ( ( ! value ) || ( ! value[0] ) ) - return delete_setting ( settings, setting ); - - /* Sanity check */ - assert ( setting->type != NULL ); - - /* Get raw value length */ - raw_len = setting_parse ( setting->type, value, NULL, 0 ); - if ( raw_len < 0 ) { - rc = raw_len; - goto err_raw_len; - } - - /* Allocate buffer for raw value */ - raw = malloc ( raw_len ); - if ( ! raw ) { - rc = -ENOMEM; - goto err_alloc_raw; - } - - /* Parse formatted value */ - check_len = setting_parse ( setting->type, value, raw, raw_len ); - assert ( check_len == raw_len ); - - /* Store raw value */ - if ( ( rc = store_setting ( settings, setting, raw, raw_len ) ) != 0 ) - goto err_store; - - err_store: - free ( raw ); - err_alloc_raw: - err_raw_len: - return rc; -} - -/** - * Fetch numeric value of setting - * - * @v settings Settings block, or NULL to search all blocks - * @v setting Setting to fetch - * @v origin Origin of setting to fill in, or NULL - * @v fetched Fetched setting to fill in, or NULL - * @v value Numeric value to fill in - * @ret rc Return status code - */ -int fetchn_setting ( struct settings *settings, const struct setting *setting, - struct settings **origin, struct setting *fetched, - unsigned long *value ) { - struct setting tmp_fetched; - void *raw; - int raw_len; - int rc; - - /* Use local buffers if necessary */ - if ( ! fetched ) - fetched = &tmp_fetched; - - /* Fetch raw value */ - raw_len = fetch_setting_copy ( settings, setting, origin, fetched, - &raw ); - if ( raw_len < 0 ) { - rc = raw_len; - goto err_fetch_copy; - } - - /* Sanity check */ - assert ( fetched->type != NULL ); - - /* Numerate setting */ - if ( ( rc = setting_numerate ( fetched->type, raw, raw_len, - value ) ) < 0 ) - goto err_numerate; - - err_numerate: - free ( raw ); - err_fetch_copy: - return rc; -} - -/** - * Store numeric value of setting - * - * @v settings Settings block - * @v setting Setting - * @v value Numeric value - * @ret rc Return status code - */ -int storen_setting ( struct settings *settings, const struct setting *setting, - unsigned long value ) { - void *raw; - int raw_len; - int check_len; - int rc; - - /* Sanity check */ - assert ( setting->type != NULL ); - - /* Get raw value length */ - raw_len = setting_denumerate ( setting->type, value, NULL, 0 ); - if ( raw_len < 0 ) { - rc = raw_len; - goto err_raw_len; - } - - /* Allocate buffer for raw value */ - raw = malloc ( raw_len ); - if ( ! raw ) { - rc = -ENOMEM; - goto err_alloc_raw; - } - - /* Denumerate value */ - check_len = setting_denumerate ( setting->type, value, raw, raw_len ); - assert ( check_len == raw_len ); - - /* Store raw value */ - if ( ( rc = store_setting ( settings, setting, raw, raw_len ) ) != 0 ) - goto err_store; - - err_store: - free ( raw ); - err_alloc_raw: - err_raw_len: - return rc; -} - -/****************************************************************************** - * - * Named settings - * - ****************************************************************************** - */ - -/** - * Find predefined setting - * - * @v name Name - * @ret setting Setting, or NULL - */ -struct setting * find_setting ( const char *name ) { - struct setting *setting; - - for_each_table_entry ( setting, SETTINGS ) { - if ( strcmp ( name, setting->name ) == 0 ) - return setting; - } - return NULL; -} - -/** - * Parse setting name as tag number - * - * @v name Name - * @ret tag Tag number, or 0 if not a valid number - */ -static unsigned int parse_setting_tag ( const char *name ) { - char *tmp = ( ( char * ) name ); - unsigned int tag = 0; - - while ( 1 ) { - tag = ( ( tag << 8 ) | strtoul ( tmp, &tmp, 0 ) ); - if ( *tmp == 0 ) - return tag; - if ( *tmp != '.' ) - return 0; - tmp++; - } -} - -/** - * Find setting type - * - * @v name Name - * @ret type Setting type, or NULL - */ -static const struct setting_type * find_setting_type ( const char *name ) { - const struct setting_type *type; - - for_each_table_entry ( type, SETTING_TYPES ) { - if ( strcmp ( name, type->name ) == 0 ) - return type; - } - return NULL; -} - -/** - * Parse setting name - * - * @v name Name of setting - * @v get_child Function to find or create child settings block - * @v settings Settings block to fill in - * @v setting Setting to fill in - * @ret rc Return status code - * - * Interprets a name of the form - * "[settings_name/]tag_name[:type_name]" and fills in the appropriate - * fields. - * - * Note that on success, this function will have modified the original - * setting @c name. - */ -int parse_setting_name ( char *name, get_child_settings_t get_child, - struct settings **settings, struct setting *setting ) { - char *settings_name; - char *setting_name; - char *type_name; - struct setting *predefined; - int rc; - - /* Set defaults */ - *settings = &settings_root; - memset ( setting, 0, sizeof ( *setting ) ); - setting->name = ""; - - /* Split name into "[settings_name/]setting_name[:type_name]" */ - if ( ( setting_name = strchr ( name, '/' ) ) != NULL ) { - *(setting_name++) = 0; - settings_name = name; - } else { - setting_name = name; - settings_name = NULL; - } - if ( ( type_name = strchr ( setting_name, ':' ) ) != NULL ) - *(type_name++) = 0; - - /* Identify settings block, if specified */ - if ( settings_name ) { - *settings = parse_settings_name ( settings_name, get_child ); - if ( *settings == NULL ) { - DBG ( "Unrecognised settings block \"%s\" in \"%s\"\n", - settings_name, name ); - rc = -ENODEV; - goto err; - } - } - - /* Identify setting */ - setting->tag = parse_setting_tag ( setting_name ); - setting->scope = (*settings)->default_scope; - setting->name = setting_name; - for_each_table_entry ( predefined, SETTINGS ) { - /* Matches a predefined setting; use that setting */ - if ( setting_cmp ( predefined, setting ) == 0 ) { - memcpy ( setting, predefined, sizeof ( *setting ) ); - break; - } - } - - /* Identify setting type, if specified */ - if ( type_name ) { - setting->type = find_setting_type ( type_name ); - if ( setting->type == NULL ) { - DBG ( "Invalid setting type \"%s\" in \"%s\"\n", - type_name, name ); - rc = -ENOTSUP; - goto err; - } - } - - return 0; - - err: - /* Restore original name */ - if ( settings_name ) - *( setting_name - 1 ) = '/'; - if ( type_name ) - *( type_name - 1 ) = ':'; - return rc; -} - -/** - * Return full setting name - * - * @v settings Settings block, or NULL - * @v setting Setting - * @v buf Buffer - * @v len Length of buffer - * @ret len Length of setting name, or negative error - */ -int setting_name ( struct settings *settings, const struct setting *setting, - char *buf, size_t len ) { - const char *name; - - settings = settings_target ( settings ); - name = settings_name ( settings ); - return snprintf ( buf, len, "%s%s%s:%s", name, ( name[0] ? "/" : "" ), - setting->name, setting->type->name ); -} - -/****************************************************************************** - * - * Setting types - * - ****************************************************************************** - */ - -/** - * Parse string setting value - * - * @v type Setting type - * @v value Formatted setting value - * @v buf Buffer to contain raw value - * @v len Length of buffer - * @ret len Length of raw value, or negative error - */ -static int parse_string_setting ( const struct setting_type *type __unused, - const char *value, void *buf, size_t len ) { - size_t raw_len = strlen ( value ); /* Exclude terminating NUL */ - - /* Copy string to buffer */ - if ( len > raw_len ) - len = raw_len; - memcpy ( buf, value, len ); - - return raw_len; -} - -/** - * Format string 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_string_setting ( const struct setting_type *type __unused, - const void *raw, size_t raw_len, char *buf, - size_t len ) { - - /* Copy string to buffer, and terminate */ - memset ( buf, 0, len ); - if ( len > raw_len ) - len = raw_len; - memcpy ( buf, raw, len ); - - return raw_len; -} - -/** A string setting type */ -const struct setting_type setting_type_string __setting_type = { - .name = "string", - .parse = parse_string_setting, - .format = format_string_setting, -}; - -/** A URI-encoded string setting type - * - * This setting type is obsolete; the name ":uristring" is retained to - * avoid breaking existing scripts. - */ -const struct setting_type setting_type_uristring __setting_type = { - .name = "uristring", - .parse = parse_string_setting, - .format = format_string_setting, -}; - -/** - * Parse IPv4 address setting value (when IPv4 support is not present) - * - * @v type Setting type - * @v value Formatted setting value - * @v buf Buffer to contain raw value - * @v len Length of buffer - * @ret len Length of raw value, or negative error - */ -__weak int parse_ipv4_setting ( const struct setting_type *type __unused, - const char *value __unused, void *buf __unused, - size_t len __unused ) { - return -ENOTSUP; -} - -/** - * Format IPv4 address setting value (when IPv4 support is not present) - * - * @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 - */ -__weak int format_ipv4_setting ( const struct setting_type *type __unused, - const void *raw __unused, - size_t raw_len __unused, char *buf __unused, - size_t len __unused ) { - return -ENOTSUP; -} - -/** An IPv4 address setting type */ -const struct setting_type setting_type_ipv4 __setting_type = { - .name = "ipv4", - .parse = parse_ipv4_setting, - .format = format_ipv4_setting, -}; - -/** - * Parse IPv6 address setting value (when IPv6 support is not present) - * - * @v type Setting type - * @v value Formatted setting value - * @v buf Buffer to contain raw value - * @v len Length of buffer - * @ret len Length of raw value, or negative error - */ -__weak int parse_ipv6_setting ( const struct setting_type *type __unused, - const char *value __unused, void *buf __unused, - size_t len __unused ) { - return -ENOTSUP; -} - -/** - * Format IPv6 address setting value (when IPv6 support is not present) - * - * @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 - */ -__weak int format_ipv6_setting ( const struct setting_type *type __unused, - const void *raw __unused, - size_t raw_len __unused, char *buf __unused, - size_t len __unused ) { - return -ENOTSUP; -} - -/** An IPv6 address setting type */ -const struct setting_type setting_type_ipv6 __setting_type = { - .name = "ipv6", - .parse = parse_ipv6_setting, - .format = format_ipv6_setting, -}; - -/** IPv6 settings scope */ -const struct settings_scope ipv6_scope; - -/** - * Integer setting type indices - * - * These indexes are defined such that (1<<index) gives the width of - * the integer, in bytes. - */ -enum setting_type_int_index { - SETTING_TYPE_INT8 = 0, - SETTING_TYPE_INT16 = 1, - SETTING_TYPE_INT32 = 2, -}; - -/** - * Integer setting type names - * - * These names exist as a static array in order to allow the type's - * integer size and signedness to be determined from the type's name. - * Note that there are no separate entries for the signed integer - * types: the name pointers simply point to the second character of - * the relevant string. - */ -static const char setting_type_int_name[][8] = { - [SETTING_TYPE_INT8] = "uint8", - [SETTING_TYPE_INT16] = "uint16", - [SETTING_TYPE_INT32] = "uint32", -}; - -/** - * Get unsigned integer setting type name - * - * @v index Integer setting type index - * @ret name Setting type name - */ -#define SETTING_TYPE_UINT_NAME( index ) setting_type_int_name[index] - -/** - * Get signed integer setting type name - * - * @v index Integer setting type index - * @ret name Setting type name - */ -#define SETTING_TYPE_INT_NAME( index ) ( setting_type_int_name[index] + 1 ) - -/** - * Get integer setting type index - * - * @v type Setting type - * @ret index Integer setting type index - */ -static unsigned int setting_type_int_index ( const struct setting_type *type ) { - - return ( ( type->name - setting_type_int_name[0] ) / - sizeof ( setting_type_int_name[0] ) ); -} - -/** - * Get integer setting type width - * - * @v type Setting type - * @ret index Integer setting type width - */ -static unsigned int setting_type_int_width ( const struct setting_type *type ) { - - return ( 1 << setting_type_int_index ( type ) ); -} - -/** - * Get integer setting type signedness - * - * @v type Setting type - * @ret is_signed Integer setting type is signed - */ -static int setting_type_int_is_signed ( const struct setting_type *type ) { - return ( ( type->name - setting_type_int_name[0] ) & 1 ); -} - -/** - * Convert number to setting value - * - * @v type Setting type - * @v value Numeric value - * @v buf Buffer to contain raw value - * @v len Length of buffer - * @ret len Length of raw value, or negative error - */ -static int denumerate_int_setting ( const struct setting_type *type, - unsigned long value, void *buf, - size_t len ) { - unsigned int size = setting_type_int_width ( type ); - union { - uint32_t num; - uint8_t bytes[4]; - } u; - - u.num = htonl ( value ); - if ( len > size ) - len = size; - memcpy ( buf, &u.bytes[ sizeof ( u ) - size ], len ); - - return size; -} - -/** - * Convert setting value to number - * - * @v type Setting type - * @v raw Raw setting value - * @v raw_len Length of raw setting value - * @v value Numeric value to fill in - * @ret rc Return status code - */ -static int numerate_int_setting ( const struct setting_type *type, - const void *raw, size_t raw_len, - unsigned long *value ) { - int is_signed = setting_type_int_is_signed ( type ); - int check_len; - - /* Extract numeric value */ - check_len = numeric_setting_value ( is_signed, raw, raw_len, value ); - if ( check_len < 0 ) - return check_len; - assert ( check_len == ( int ) raw_len ); - - return 0; -} - -/** - * Parse integer setting value - * - * @v type Setting type - * @v value Formatted setting value - * @v buf Buffer to contain raw value - * @v len Length of buffer - * @ret len Length of raw value, or negative error - */ -static int parse_int_setting ( const struct setting_type *type, - const char *value, void *buf, size_t len ) { - char *endp; - unsigned long num_value; - - /* Parse value */ - num_value = strtoul ( value, &endp, 0 ); - if ( *endp ) - return -EINVAL; - - return type->denumerate ( type, num_value, buf, len ); -} - -/** - * Format signed integer 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_int_setting ( const struct setting_type *type, - const void *raw, size_t raw_len, - char *buf, size_t len ) { - unsigned long value; - int ret; - - /* Extract numeric value */ - if ( ( ret = type->numerate ( type, raw, raw_len, &value ) ) < 0 ) - return ret; - - /* Format value */ - return snprintf ( buf, len, "%ld", value ); -} - -/** - * Format unsigned integer 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_uint_setting ( const struct setting_type *type, - const void *raw, size_t raw_len, - char *buf, size_t len ) { - unsigned long value; - int ret; - - /* Extract numeric value */ - if ( ( ret = type->numerate ( type, raw, raw_len, &value ) ) < 0 ) - return ret; - - /* Format value */ - return snprintf ( buf, len, "%#lx", value ); -} - -/** - * Define a signed integer setting type - * - * @v index Integer setting type index - * @ret type Setting type - */ -#define SETTING_TYPE_INT( index ) { \ - .name = SETTING_TYPE_INT_NAME ( index ), \ - .parse = parse_int_setting, \ - .format = format_int_setting, \ - .denumerate = denumerate_int_setting, \ - .numerate = numerate_int_setting, \ -} - -/** - * Define an unsigned integer setting type - * - * @v index Integer setting type index - * @ret type Setting type - */ -#define SETTING_TYPE_UINT( index ) { \ - .name = SETTING_TYPE_UINT_NAME ( index ), \ - .parse = parse_int_setting, \ - .format = format_uint_setting, \ - .denumerate = denumerate_int_setting, \ - .numerate = numerate_int_setting, \ -} - -/** A signed 8-bit integer setting type */ -const struct setting_type setting_type_int8 __setting_type = - SETTING_TYPE_INT ( SETTING_TYPE_INT8 ); - -/** A signed 16-bit integer setting type */ -const struct setting_type setting_type_int16 __setting_type = - SETTING_TYPE_INT ( SETTING_TYPE_INT16 ); - -/** A signed 32-bit integer setting type */ -const struct setting_type setting_type_int32 __setting_type = - SETTING_TYPE_INT ( SETTING_TYPE_INT32 ); - -/** An unsigned 8-bit integer setting type */ -const struct setting_type setting_type_uint8 __setting_type = - SETTING_TYPE_UINT ( SETTING_TYPE_INT8 ); - -/** An unsigned 16-bit integer setting type */ -const struct setting_type setting_type_uint16 __setting_type = - SETTING_TYPE_UINT ( SETTING_TYPE_INT16 ); - -/** An unsigned 32-bit integer setting type */ -const struct setting_type setting_type_uint32 __setting_type = - SETTING_TYPE_UINT ( SETTING_TYPE_INT32 ); - -/** - * Parse hex string setting value (using colon delimiter) - * - * @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_hex_setting ( const struct setting_type *type __unused, - const char *value, void *buf, size_t len ) { - return hex_decode ( ':', value, buf, len ); -} - -/** - * Format hex string setting value (using colon delimiter) - * - * @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_hex_colon_setting ( const struct setting_type *type __unused, - const void *raw, size_t raw_len, - char *buf, size_t len ) { - return hex_encode ( ':', raw, raw_len, buf, len ); -} - -/** - * Parse hex string setting value (using hyphen delimiter) - * - * @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_hex_hyphen_setting ( const struct setting_type *type __unused, - const char *value, void *buf, - size_t len ) { - return hex_decode ( '-', value, buf, len ); -} - -/** - * Format hex string setting value (using hyphen delimiter) - * - * @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_hex_hyphen_setting ( const struct setting_type *type __unused, - const void *raw, size_t raw_len, - char *buf, size_t len ) { - return hex_encode ( '-', raw, raw_len, buf, len ); -} - -/** - * Parse hex string setting value (using no delimiter) - * - * @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_hex_raw_setting ( const struct setting_type *type __unused, - const char *value, void *buf, size_t len ) { - return hex_decode ( 0, value, buf, len ); -} - -/** - * Format hex string setting value (using no delimiter) - * - * @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_hex_raw_setting ( const struct setting_type *type __unused, - const void *raw, size_t raw_len, - char *buf, size_t len ) { - return hex_encode ( 0, raw, raw_len, buf, len ); -} - -/** A hex-string setting (colon-delimited) */ -const struct setting_type setting_type_hex __setting_type = { - .name = "hex", - .parse = parse_hex_setting, - .format = format_hex_colon_setting, -}; - -/** A hex-string setting (hyphen-delimited) */ -const struct setting_type setting_type_hexhyp __setting_type = { - .name = "hexhyp", - .parse = parse_hex_hyphen_setting, - .format = format_hex_hyphen_setting, -}; - -/** A hex-string setting (non-delimited) */ -const struct setting_type setting_type_hexraw __setting_type = { - .name = "hexraw", - .parse = parse_hex_raw_setting, - .format = format_hex_raw_setting, -}; - -/** - * 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 - * @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_uuid_setting ( const struct setting_type *type __unused, - const void *raw, size_t raw_len, char *buf, - size_t len ) { - const union uuid *uuid = raw; - - /* Range check */ - if ( raw_len != sizeof ( *uuid ) ) - return -ERANGE; - - /* Format value */ - return snprintf ( buf, len, "%s", uuid_ntoa ( uuid ) ); -} - -/** UUID setting type */ -const struct setting_type setting_type_uuid __setting_type = { - .name = "uuid", - .format = format_uuid_setting, -}; - -/** - * Format PCI bus:dev.fn 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_busdevfn_setting ( const struct setting_type *type __unused, - const void *raw, size_t raw_len, char *buf, - size_t len ) { - unsigned long busdevfn; - int check_len; - - /* Extract numeric value */ - check_len = numeric_setting_value ( 0, raw, raw_len, &busdevfn ); - if ( check_len < 0 ) - return check_len; - assert ( check_len == ( int ) raw_len ); - - /* Format value */ - return snprintf ( buf, len, "%02lx:%02lx.%lx", PCI_BUS ( busdevfn ), - PCI_SLOT ( busdevfn ), PCI_FUNC ( busdevfn ) ); -} - -/** PCI bus:dev.fn setting type */ -const struct setting_type setting_type_busdevfn __setting_type = { - .name = "busdevfn", - .format = format_busdevfn_setting, -}; - -/****************************************************************************** - * - * Setting expansion - * - ****************************************************************************** - */ - -/** - * Expand variables within string - * - * @v string String - * @ret expstr Expanded string - * - * The expanded string is allocated with malloc() and the caller must - * eventually free() it. - */ -char * expand_settings ( const char *string ) { - struct settings *settings; - struct setting setting; - char *expstr; - char *start; - char *end; - char *head; - char *name; - char *tail; - char *value; - char *tmp; - int new_len; - int rc; - - /* Obtain temporary modifiable copy of string */ - expstr = strdup ( string ); - if ( ! expstr ) - return NULL; - - /* Expand while expansions remain */ - while ( 1 ) { - - head = expstr; - - /* Locate setting to be expanded */ - start = NULL; - end = NULL; - for ( tmp = expstr ; *tmp ; tmp++ ) { - if ( ( tmp[0] == '$' ) && ( tmp[1] == '{' ) ) - start = tmp; - if ( start && ( tmp[0] == '}' ) ) { - end = tmp; - break; - } - } - if ( ! end ) - break; - *start = '\0'; - name = ( start + 2 ); - *end = '\0'; - tail = ( end + 1 ); - - /* Expand setting */ - if ( ( rc = parse_setting_name ( name, find_child_settings, - &settings, - &setting ) ) != 0 ) { - /* Treat invalid setting names as empty */ - value = NULL; - } else { - /* Fetch and format setting value. Ignore - * errors; treat non-existent settings as empty. - */ - fetchf_setting_copy ( settings, &setting, NULL, NULL, - &value ); - } - - /* Construct expanded string and discard old string */ - tmp = expstr; - new_len = asprintf ( &expstr, "%s%s%s", - head, ( value ? value : "" ), tail ); - free ( value ); - free ( tmp ); - if ( new_len < 0 ) - return NULL; - } - - return expstr; -} - -/****************************************************************************** - * - * Settings - * - ****************************************************************************** - */ - -/** Hostname setting */ -const struct setting hostname_setting __setting ( SETTING_HOST, hostname ) = { - .name = "hostname", - .description = "Host name", - .tag = DHCP_HOST_NAME, - .type = &setting_type_string, -}; - -/** Domain name setting */ -const struct setting domain_setting __setting ( SETTING_IP_EXTRA, domain ) = { - .name = "domain", - .description = "DNS domain", - .tag = DHCP_DOMAIN_NAME, - .type = &setting_type_string, -}; - -/** TFTP server setting */ -const struct setting next_server_setting __setting ( SETTING_BOOT,next-server)={ - .name = "next-server", - .description = "TFTP server", - .tag = DHCP_EB_SIADDR, - .type = &setting_type_ipv4, -}; - -/** Filename setting */ -const struct setting filename_setting __setting ( SETTING_BOOT, filename ) = { - .name = "filename", - .description = "Boot filename", - .tag = DHCP_BOOTFILE_NAME, - .type = &setting_type_string, -}; - -/** Root path setting */ -const struct setting root_path_setting __setting ( SETTING_SANBOOT, root-path)={ - .name = "root-path", - .description = "SAN root path", - .tag = DHCP_ROOT_PATH, - .type = &setting_type_string, -}; - -/** Username setting */ -const struct setting username_setting __setting ( SETTING_AUTH, username ) = { - .name = "username", - .description = "User name", - .tag = DHCP_EB_USERNAME, - .type = &setting_type_string, -}; - -/** Password setting */ -const struct setting password_setting __setting ( SETTING_AUTH, password ) = { - .name = "password", - .description = "Password", - .tag = DHCP_EB_PASSWORD, - .type = &setting_type_string, -}; - -/** Priority setting */ -const struct setting priority_setting __setting ( SETTING_MISC, priority ) = { - .name = "priority", - .description = "Settings priority", - .tag = DHCP_EB_PRIORITY, - .type = &setting_type_int8, -}; - -/** DHCP user class setting */ -const struct setting user_class_setting __setting ( SETTING_HOST_EXTRA, - user-class ) = { - .name = "user-class", - .description = "DHCP user class", - .tag = DHCP_USER_CLASS_ID, - .type = &setting_type_string, -}; - -/****************************************************************************** - * - * Built-in settings block - * - ****************************************************************************** - */ - -/** Built-in setting scope */ -const struct settings_scope builtin_scope; - -/** - * Fetch error number setting - * - * @v data Buffer to fill with setting data - * @v len Length of buffer - * @ret len Length of setting data, or negative error - */ -static int errno_fetch ( void *data, size_t len ) { - uint32_t content; - - /* Return current error */ - content = htonl ( errno ); - if ( len > sizeof ( content ) ) - len = sizeof ( content ); - memcpy ( data, &content, len ); - return sizeof ( content ); -} - -/** Error number setting */ -const struct setting errno_setting __setting ( SETTING_MISC, errno ) = { - .name = "errno", - .description = "Last error", - .type = &setting_type_uint32, - .scope = &builtin_scope, -}; - -/** Error number built-in setting */ -struct builtin_setting errno_builtin_setting __builtin_setting = { - .setting = &errno_setting, - .fetch = errno_fetch, -}; - -/** - * Fetch build architecture setting - * - * @v data Buffer to fill with setting data - * @v len Length of buffer - * @ret len Length of setting data, or negative error - */ -static int buildarch_fetch ( void *data, size_t len ) { - static const char buildarch[] = _S2 ( ARCH ); - - strncpy ( data, buildarch, len ); - return ( sizeof ( buildarch ) - 1 /* NUL */ ); -} - -/** Build architecture setting */ -const struct setting buildarch_setting __setting ( SETTING_MISC, buildarch ) = { - .name = "buildarch", - .description = "Build architecture", - .type = &setting_type_string, - .scope = &builtin_scope, -}; - -/** Build architecture built-in setting */ -struct builtin_setting buildarch_builtin_setting __builtin_setting = { - .setting = &buildarch_setting, - .fetch = buildarch_fetch, -}; - -/** - * Fetch platform setting - * - * @v data Buffer to fill with setting data - * @v len Length of buffer - * @ret len Length of setting data, or negative error - */ -static int platform_fetch ( void *data, size_t len ) { - static const char platform[] = _S2 ( PLATFORM ); - - strncpy ( data, platform, len ); - return ( sizeof ( platform ) - 1 /* NUL */ ); -} - -/** Platform setting */ -const struct setting platform_setting __setting ( SETTING_MISC, platform ) = { - .name = "platform", - .description = "Platform", - .type = &setting_type_string, - .scope = &builtin_scope, -}; - -/** Platform built-in setting */ -struct builtin_setting platform_builtin_setting __builtin_setting = { - .setting = &platform_setting, - .fetch = platform_fetch, -}; - -/** - * Fetch version setting - * - * @v data Buffer to fill with setting data - * @v len Length of buffer - * @ret len Length of setting data, or negative error - */ -static int version_fetch ( void *data, size_t len ) { - strncpy ( data, product_version, len ); - return ( strlen ( product_version ) ); -} - -/** Version setting */ -const struct setting version_setting __setting ( SETTING_MISC, version ) = { - .name = "version", - .description = "Version", - .type = &setting_type_string, - .scope = &builtin_scope, -}; - -/** Version built-in setting */ -struct builtin_setting version_builtin_setting __builtin_setting = { - .setting = &version_setting, - .fetch = version_fetch, -}; - -/** - * Fetch built-in setting - * - * @v settings Settings block - * @v setting Setting to fetch - * @v data Buffer to fill with setting data - * @v len Length of buffer - * @ret len Length of setting data, or negative error - */ -static int builtin_fetch ( struct settings *settings __unused, - struct setting *setting, - void *data, size_t len ) { - struct builtin_setting *builtin; - - for_each_table_entry ( builtin, BUILTIN_SETTINGS ) { - if ( setting_cmp ( setting, builtin->setting ) == 0 ) - return builtin->fetch ( data, len ); - } - return -ENOENT; -} - -/** - * Check applicability of built-in setting - * - * @v settings Settings block - * @v setting Setting - * @ret applies Setting applies within this settings block - */ -static int builtin_applies ( struct settings *settings __unused, - const struct setting *setting ) { - - return ( setting->scope == &builtin_scope ); -} - -/** Built-in settings operations */ -static struct settings_operations builtin_settings_operations = { - .applies = builtin_applies, - .fetch = builtin_fetch, -}; - -/** Built-in settings */ -static struct settings builtin_settings = { - .refcnt = NULL, - .siblings = LIST_HEAD_INIT ( builtin_settings.siblings ), - .children = LIST_HEAD_INIT ( builtin_settings.children ), - .op = &builtin_settings_operations, -}; - -/** Initialise built-in settings */ -static void builtin_init ( void ) { - int rc; - - if ( ( rc = register_settings ( &builtin_settings, NULL, - "builtin" ) ) != 0 ) { - DBG ( "Could not register built-in settings: %s\n", - strerror ( rc ) ); - return; - } -} - -/** Built-in settings initialiser */ -struct init_fn builtin_init_fn __init_fn ( INIT_NORMAL ) = { - .initialise = builtin_init, -}; diff --git a/qemu/roms/ipxe/src/core/string.c b/qemu/roms/ipxe/src/core/string.c deleted file mode 100644 index 3e658e54e..000000000 --- a/qemu/roms/ipxe/src/core/string.c +++ /dev/null @@ -1,501 +0,0 @@ -/* - * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stddef.h> -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> - -/** @file - * - * String functions - * - */ - -/** - * Fill memory region - * - * @v dest Destination region - * @v character Fill character - * @v len Length - * @ret dest Destination region - */ -void * generic_memset ( void *dest, int character, size_t len ) { - uint8_t *dest_bytes = dest; - - while ( len-- ) - *(dest_bytes++) = character; - return dest; -} - -/** - * Copy memory region - * - * @v dest Destination region - * @v src Source region - * @v len Length - * @ret dest Destination region - */ -void * generic_memcpy ( void *dest, const void *src, size_t len ) { - const uint8_t *src_bytes = src; - uint8_t *dest_bytes = dest; - - while ( len-- ) - *(dest_bytes++) = *(src_bytes++); - return dest; -} - -/** - * Copy (possibly overlapping) memory region - * - * @v dest Destination region - * @v src Source region - * @v len Length - * @ret dest Destination region - */ -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; -} - -/** - * 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; -} - -/** - * 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 - */ -void * memchr ( const void *src, int character, size_t len ) { - const uint8_t *src_bytes = src; - - for ( ; len-- ; src_bytes++ ) { - if ( *src_bytes == character ) - return ( ( void * ) src_bytes ); - } - return NULL; -} - -/** - * Swap memory regions - * - * @v first First region - * @v second Second region - * @v len Length - * @ret first First region - */ -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 strncmp ( first, second, ~( ( size_t ) 0 ) ); -} - -/** - * 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; -} - -/** - * Compare case-insensitive strings - * - * @v first First string - * @v second Second string - * @ret diff Difference - */ -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; - } -} - -/** - * Get length of string - * - * @v src String - * @ret len Length - */ -size_t strlen ( const char *src ) { - - return strnlen ( src, ~( ( size_t ) 0 ) ); -} - -/** - * Get length of string - * - * @v src String - * @v max Maximum length - * @ret len Length - */ -size_t strnlen ( const char *src, size_t max ) { - const uint8_t *src_bytes = ( ( const uint8_t * ) src ); - size_t len = 0; - - while ( max-- && *(src_bytes++) ) - len++; - return len; -} - -/** - * Find character within a string - * - * @v src String - * @v character Character to find - * @ret found Found character, or NULL if not found - */ -char * strchr ( const char *src, int character ) { - const uint8_t *src_bytes = ( ( const uint8_t * ) src ); - - for ( ; ; src_bytes++ ) { - if ( *src_bytes == character ) - return ( ( char * ) src_bytes ); - if ( ! *src_bytes ) - return NULL; - } -} - -/** - * Find rightmost character within a string - * - * @v src String - * @v character Character to find - * @ret found Found character, or NULL if not found - */ -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; -} - -/** - * 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 ); - - for ( ; *haystack ; haystack++ ) { - if ( memcmp ( haystack, needle, len ) == 0 ) - return ( ( char * ) haystack ); - } - return NULL; -} - -/** - * Copy string - * - * @v dest Destination string - * @v src Source string - * @ret dest Destination string - */ -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; -} - -/** - * 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; -} - -/** - * Concatenate string - * - * @v dest Destination string - * @v src Source string - * @ret dest Destination string - */ -char * strcat ( char *dest, const char *src ) { - - strcpy ( ( dest + strlen ( dest ) ), src ); - return dest; -} - -/** - * Duplicate string - * - * @v src Source string - * @ret dup Duplicated string, or NULL if allocation failed - */ -char * strdup ( const char *src ) { - - return strndup ( src, ~( ( size_t ) 0 ) ); -} - -/** - * Duplicate string - * - * @v src Source string - * @v max Maximum length - * @ret dup Duplicated string, or NULL if allocation failed - */ -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; -} - -/** - * Preprocess string for strtoul() or strtoull() - * - * @v string String - * @v negate Final value should be negated - * @v base Numeric base - * @ret string Remaining string - */ -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 string; -} - -/** - * 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; - - /* Fill in end pointer, if applicable */ - if ( endp ) - *endp = ( ( char * ) string ); - - return value; -} - -/** - * 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 deleted file mode 100644 index 18ffc6301..000000000 --- a/qemu/roms/ipxe/src/core/stringextra.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 1991, 1992 Linus Torvalds - * Copyright (C) 2004 Tobias Lorenz - * - * 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 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> - * - * These are buggy as well.. - * - * * 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. - */ - -/* - * these are the standard string functions that are currently not used by - * any code in etherboot. put into a separate file to avoid linking them in - * with the rest of string.o - * if anything ever does want to use a function of these, consider moving - * the function in question back into string.c - */ - -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> - -/* *** FROM string.c *** */ - -#ifndef __HAVE_ARCH_STRPBRK -/** - * strpbrk - Find the first occurrence of a set of characters - * @cs: The string to be searched - * @ct: The characters to search for - */ -char * strpbrk(const char * cs,const char * ct) -{ - const char *sc1,*sc2; - - for( sc1 = cs; *sc1 != '\0'; ++sc1) { - for( sc2 = ct; *sc2 != '\0'; ++sc2) { - if (*sc1 == *sc2) - return (char *) sc1; - } - } - return NULL; -} -#endif - -#ifndef __HAVE_ARCH_STRSEP -/** - * strsep - Split a string into tokens - * @s: The string to be searched - * @ct: The characters to search for - * - * strsep() updates @s to point after the token, ready for the next call. - * - * It returns empty tokens, too, behaving exactly like the libc function - * of that name. In fact, it was stolen from glibc2 and de-fancy-fied. - * Same semantics, slimmer shape. ;) - */ -char * strsep(char **s, const char *ct) -{ - char *sbegin = *s, *end; - - if (sbegin == NULL) - return NULL; - - end = strpbrk(sbegin, ct); - if (end) - *end++ = '\0'; - *s = end; - - return sbegin; -} -#endif diff --git a/qemu/roms/ipxe/src/core/time.c b/qemu/roms/ipxe/src/core/time.c deleted file mode 100644 index 29a924ebe..000000000 --- a/qemu/roms/ipxe/src/core/time.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <time.h> - -/** @file - * - * Date and time - * - * POSIX:2008 section 4.15 defines "seconds since the Epoch" as an - * abstract measure approximating the number of seconds that have - * elapsed since the Epoch, excluding leap seconds. The formula given - * is - * - * tm_sec + tm_min*60 + tm_hour*3600 + tm_yday*86400 + - * (tm_year-70)*31536000 + ((tm_year-69)/4)*86400 - - * ((tm_year-1)/100)*86400 + ((tm_year+299)/400)*86400 - * - * This calculation assumes that leap years occur in each year that is - * either divisible by 4 but not divisible by 100, or is divisible by - * 400. - */ - -/** Days of week (for debugging) */ -static const char *weekdays[] = { - "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" -}; - -/** - * Determine whether or not year is a leap year - * - * @v tm_year Years since 1900 - * @v is_leap_year Year is a leap year - */ -static int is_leap_year ( int tm_year ) { - int leap_year = 0; - - if ( ( tm_year % 4 ) == 0 ) - leap_year = 1; - if ( ( tm_year % 100 ) == 0 ) - leap_year = 0; - if ( ( tm_year % 400 ) == 100 ) - leap_year = 1; - - return leap_year; -} - -/** - * Calculate number of leap years since 1900 - * - * @v tm_year Years since 1900 - * @v num_leap_years Number of leap years - */ -static int leap_years_to_end ( int tm_year ) { - int leap_years = 0; - - leap_years += ( tm_year / 4 ); - leap_years -= ( tm_year / 100 ); - leap_years += ( ( tm_year + 300 ) / 400 ); - - return leap_years; -} - -/** - * Calculate day of week - * - * @v tm_year Years since 1900 - * @v tm_mon Month of year [0,11] - * @v tm_day Day of month [1,31] - */ -static int day_of_week ( int tm_year, int tm_mon, int tm_mday ) { - static const uint8_t offset[12] = - { 1, 4, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5 }; - int pseudo_year = tm_year; - - if ( tm_mon < 2 ) - pseudo_year--; - return ( ( pseudo_year + leap_years_to_end ( pseudo_year ) + - offset[tm_mon] + tm_mday ) % 7 ); -} - -/** Days from start of year until start of months (in non-leap years) */ -static const uint16_t days_to_month_start[] = - { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; - -/** - * Calculate seconds since the Epoch - * - * @v tm Broken-down time - * @ret time Seconds since the Epoch - */ -time_t mktime ( struct tm *tm ) { - int days_since_epoch; - int seconds_since_day; - time_t seconds; - - /* Calculate day of year */ - tm->tm_yday = ( ( tm->tm_mday - 1 ) + - days_to_month_start[ tm->tm_mon ] ); - if ( ( tm->tm_mon >= 2 ) && is_leap_year ( tm->tm_year ) ) - tm->tm_yday++; - - /* Calculate day of week */ - tm->tm_wday = day_of_week ( tm->tm_year, tm->tm_mon, tm->tm_mday ); - - /* Calculate seconds since the Epoch */ - days_since_epoch = ( tm->tm_yday + ( 365 * tm->tm_year ) - 25567 + - leap_years_to_end ( tm->tm_year - 1 ) ); - seconds_since_day = - ( ( ( ( tm->tm_hour * 60 ) + tm->tm_min ) * 60 ) + tm->tm_sec ); - seconds = ( ( ( ( time_t ) days_since_epoch ) * ( ( time_t ) 86400 ) ) + - seconds_since_day ); - - DBGC ( &weekdays, "TIME %04d-%02d-%02d %02d:%02d:%02d => %lld (%s, " - "day %d)\n", ( tm->tm_year + 1900 ), ( tm->tm_mon + 1 ), - tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, seconds, - weekdays[ tm->tm_wday ], tm->tm_yday ); - - return seconds; -} diff --git a/qemu/roms/ipxe/src/core/timer.c b/qemu/roms/ipxe/src/core/timer.c deleted file mode 100644 index dbd89f12b..000000000 --- a/qemu/roms/ipxe/src/core/timer.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <unistd.h> - -/** - * Delay for a fixed number of milliseconds - * - * @v msecs Number of milliseconds for which to delay - */ -void mdelay ( unsigned long msecs ) { - while ( msecs-- ) - udelay ( 1000 ); -} - -/** - * Delay for a fixed number of seconds - * - * @v secs Number of seconds for which to delay - */ -unsigned int sleep ( unsigned int secs ) { - while ( secs-- ) - mdelay ( 1000 ); - return 0; -} diff --git a/qemu/roms/ipxe/src/core/uart.c b/qemu/roms/ipxe/src/core/uart.c deleted file mode 100644 index b85fe0767..000000000 --- a/qemu/roms/ipxe/src/core/uart.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/** @file - * - * 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 deleted file mode 100644 index 3b5f270fe..000000000 --- a/qemu/roms/ipxe/src/core/uri.c +++ /dev/null @@ -1,691 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/** @file - * - * Uniform Resource Identifiers - * - */ - -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <libgen.h> -#include <ctype.h> -#include <ipxe/vsprintf.h> -#include <ipxe/params.h> -#include <ipxe/uri.h> - -/** - * Decode URI field (in place) - * - * @v string String - * - * URI decoding can never increase the length of a string; we can - * therefore safely decode in place. - */ -static void uri_decode ( char *string ) { - char *dest = string; - char hexbuf[3]; - char *hexbuf_end; - char c; - char decoded; - unsigned int skip; - - /* Copy string, decoding escaped characters as necessary */ - do { - c = *(string++); - if ( c == '%' ) { - snprintf ( hexbuf, sizeof ( hexbuf ), "%s", string ); - decoded = strtoul ( hexbuf, &hexbuf_end, 16 ); - skip = ( hexbuf_end - hexbuf ); - string += skip; - if ( skip ) - c = decoded; - } - *(dest++) = c; - } while ( c ); -} - -/** - * Check if character should be escaped within a URI field - * - * @v c Character - * @v field URI field index - * @ret escaped Character should be escaped - */ -static int uri_character_escaped ( char c, unsigned int field ) { - - /* Non-printing characters and whitespace should always be - * escaped, since they cannot sensibly be displayed as part of - * a coherent URL string. (This test also catches control - * characters such as CR and LF, which could affect the - * operation of line-based protocols such as HTTP.) - * - * We should also escape characters which would alter the - * interpretation of the URL if not escaped, i.e. characters - * which have significance to the URL parser. We should not - * blindly escape all such characters, because this would lead - * to some very strange-looking URLs (e.g. if we were to - * always escape '/' as "%2F" even within the URI path). - * - * We do not need to be perfect. Our primary role is as a - * consumer of URIs rather than a producer; the main situation - * in which we produce a URI string is for display to a human - * user, who can probably tolerate some variance from the - * formal specification. The only situation in which we - * currently produce a URI string to be consumed by a computer - * is when constructing an HTTP request URI, which contains - * only the path and query fields. - * - * We can therefore sacrifice some correctness for the sake of - * code size. For example, colons within the URI host should - * be escaped unless they form part of an IPv6 literal - * address; doing this correctly would require the URI - * formatter to be aware of whether or not the URI host - * contained an IPv4 address, an IPv6 address, or a host name. - * We choose to simplify and never escape colons within the - * URI host field: in the event of a pathological hostname - * containing colons, this could potentially produce a URI - * string which could not be reparsed. - * - * After excluding non-printing characters, whitespace, and - * '%', the full set of characters with significance to the - * URL parser is "/#:@?". We choose for each URI field which - * of these require escaping in our use cases. - */ - static const char *escaped[URI_FIELDS] = { - /* Scheme: escape everything */ - [URI_SCHEME] = "/#:@?", - /* Opaque part: escape characters which would affect - * the reparsing of the URI, allowing everything else - * (e.g. ':', which will appear in iSCSI URIs). - */ - [URI_OPAQUE] = "/#", - /* User name: escape everything */ - [URI_USER] = "/#:@?", - /* Password: escape everything */ - [URI_PASSWORD] = "/#:@?", - /* Host name: escape everything except ':', which may - * appear as part of an IPv6 literal address. - */ - [URI_HOST] = "/#@?", - /* Port number: escape everything */ - [URI_PORT] = "/#:@?", - /* Path: escape everything except '/', which usually - * appears within paths. - */ - [URI_PATH] = "#:@?", - /* Query: escape everything except '/', which - * sometimes appears within queries. - */ - [URI_QUERY] = "#:@?", - /* Fragment: escape everything */ - [URI_FRAGMENT] = "/#:@?", - }; - - return ( /* Always escape non-printing characters and whitespace */ - ( ! isprint ( c ) ) || ( c == ' ' ) || - /* Always escape '%' */ - ( c == '%' ) || - /* Escape field-specific characters */ - strchr ( escaped[field], c ) ); -} - -/** - * Encode URI field - * - * @v uri URI - * @v field URI field index - * @v buf Buffer to contain encoded string - * @v len Length of buffer - * @ret len Length of encoded string (excluding NUL) - */ -size_t uri_encode ( const char *string, unsigned int field, - char *buf, ssize_t len ) { - ssize_t remaining = len; - size_t used; - char c; - - /* Ensure encoded string is NUL-terminated even if empty */ - if ( len > 0 ) - buf[0] = '\0'; - - /* Copy string, escaping as necessary */ - while ( ( c = *(string++) ) ) { - if ( uri_character_escaped ( c, field ) ) { - used = ssnprintf ( buf, remaining, "%%%02X", c ); - } else { - used = ssnprintf ( buf, remaining, "%c", c ); - } - buf += used; - remaining -= used; - } - - return ( len - remaining ); -} - -/** - * Dump URI for debugging - * - * @v uri URI - */ -static void uri_dump ( const struct uri *uri ) { - - if ( ! uri ) - return; - if ( uri->scheme ) - DBGC ( uri, " scheme \"%s\"", uri->scheme ); - if ( uri->opaque ) - DBGC ( uri, " opaque \"%s\"", uri->opaque ); - if ( uri->user ) - DBGC ( uri, " user \"%s\"", uri->user ); - if ( uri->password ) - DBGC ( uri, " password \"%s\"", uri->password ); - if ( uri->host ) - DBGC ( uri, " host \"%s\"", uri->host ); - if ( uri->port ) - DBGC ( uri, " port \"%s\"", uri->port ); - if ( uri->path ) - DBGC ( uri, " path \"%s\"", uri->path ); - if ( uri->query ) - DBGC ( uri, " query \"%s\"", uri->query ); - if ( uri->fragment ) - DBGC ( uri, " fragment \"%s\"", uri->fragment ); - if ( uri->params ) - DBGC ( uri, " params \"%s\"", uri->params->name ); -} - -/** - * Free URI - * - * @v refcnt Reference count - */ -static void uri_free ( struct refcnt *refcnt ) { - struct uri *uri = container_of ( refcnt, struct uri, refcnt ); - - params_put ( uri->params ); - free ( uri ); -} - -/** - * Parse URI - * - * @v uri_string URI as a string - * @ret uri URI - * - * Splits a URI into its component parts. The return URI structure is - * dynamically allocated and must eventually be freed by calling - * uri_put(). - */ -struct uri * parse_uri ( const char *uri_string ) { - struct uri *uri; - struct parameters *params; - char *raw; - char *tmp; - char *path; - char *authority; - size_t raw_len; - unsigned int field; - - /* Allocate space for URI struct and a copy of the string */ - raw_len = ( strlen ( uri_string ) + 1 /* NUL */ ); - uri = zalloc ( sizeof ( *uri ) + raw_len ); - if ( ! uri ) - return NULL; - ref_init ( &uri->refcnt, uri_free ); - raw = ( ( ( void * ) uri ) + sizeof ( *uri ) ); - - /* Copy in the raw string */ - memcpy ( raw, uri_string, raw_len ); - - /* Identify the parameter list, if present */ - if ( ( tmp = strstr ( raw, "##params" ) ) ) { - *tmp = '\0'; - tmp += 8 /* "##params" */; - params = find_parameters ( *tmp ? ( tmp + 1 ) : NULL ); - if ( params ) { - uri->params = claim_parameters ( params ); - } else { - /* Ignore non-existent submission blocks */ - } - } - - /* Chop off the fragment, if it exists */ - if ( ( tmp = strchr ( raw, '#' ) ) ) { - *(tmp++) = '\0'; - uri->fragment = tmp; - } - - /* Identify absolute/relative URI */ - if ( ( tmp = strchr ( raw, ':' ) ) ) { - /* Absolute URI: identify hierarchical/opaque */ - uri->scheme = raw; - *(tmp++) = '\0'; - if ( *tmp == '/' ) { - /* Absolute URI with hierarchical part */ - path = tmp; - } else { - /* Absolute URI with opaque part */ - uri->opaque = tmp; - path = NULL; - } - } else { - /* Relative URI */ - path = raw; - } - - /* If we don't have a path (i.e. we have an absolute URI with - * an opaque portion, we're already finished processing - */ - if ( ! path ) - goto done; - - /* Chop off the query, if it exists */ - if ( ( tmp = strchr ( path, '?' ) ) ) { - *(tmp++) = '\0'; - uri->query = tmp; - } - - /* If we have no path remaining, then we're already finished - * processing. - */ - if ( ! path[0] ) - goto done; - - /* Identify net/absolute/relative path */ - if ( strncmp ( path, "//", 2 ) == 0 ) { - /* Net path. If this is terminated by the first '/' - * of an absolute path, then we have no space for a - * terminator after the authority field, so shuffle - * the authority down by one byte, overwriting one of - * the two slashes. - */ - authority = ( path + 2 ); - if ( ( tmp = strchr ( authority, '/' ) ) ) { - /* Shuffle down */ - uri->path = tmp; - memmove ( ( authority - 1 ), authority, - ( tmp - authority ) ); - authority--; - *(--tmp) = '\0'; - } - } else { - /* Absolute/relative path */ - uri->path = path; - authority = NULL; - } - - /* If we don't have an authority (i.e. we have a non-net - * path), we're already finished processing - */ - if ( ! authority ) - goto done; - - /* Split authority into user[:password] and host[:port] portions */ - if ( ( tmp = strchr ( authority, '@' ) ) ) { - /* Has user[:password] */ - *(tmp++) = '\0'; - uri->host = tmp; - uri->user = authority; - if ( ( tmp = strchr ( authority, ':' ) ) ) { - /* Has password */ - *(tmp++) = '\0'; - uri->password = tmp; - } - } else { - /* No user:password */ - uri->host = authority; - } - - /* Split host into host[:port] */ - if ( ( uri->host[ strlen ( uri->host ) - 1 ] != ']' ) && - ( tmp = strrchr ( uri->host, ':' ) ) ) { - *(tmp++) = '\0'; - uri->port = tmp; - } - - /* Decode fields in-place */ - for ( field = 0 ; field < URI_FIELDS ; field++ ) { - if ( uri_field ( uri, field ) ) - uri_decode ( ( char * ) uri_field ( uri, field ) ); - } - - done: - DBGC ( uri, "URI parsed \"%s\" to", uri_string ); - uri_dump ( uri ); - DBGC ( uri, "\n" ); - - return uri; -} - -/** - * Get port from URI - * - * @v uri URI, or NULL - * @v default_port Default port to use if none specified in URI - * @ret port Port - */ -unsigned int uri_port ( const struct uri *uri, unsigned int default_port ) { - - if ( ( ! uri ) || ( ! uri->port ) ) - return default_port; - - return ( strtoul ( uri->port, NULL, 0 ) ); -} - -/** - * Format URI - * - * @v uri URI - * @v buf Buffer to fill with URI string - * @v size Size of buffer - * @ret len Length of URI string - */ -size_t format_uri ( const struct uri *uri, char *buf, size_t len ) { - static const char prefixes[URI_FIELDS] = { - [URI_OPAQUE] = ':', - [URI_PASSWORD] = ':', - [URI_PORT] = ':', - [URI_PATH] = '/', - [URI_QUERY] = '?', - [URI_FRAGMENT] = '#', - }; - char prefix; - size_t used = 0; - unsigned int field; - - /* Ensure buffer is NUL-terminated */ - if ( len ) - buf[0] = '\0'; - - /* Special-case NULL URI */ - if ( ! uri ) - return 0; - - /* Generate fields */ - for ( field = 0 ; field < URI_FIELDS ; field++ ) { - - /* Skip non-existent fields */ - if ( ! uri_field ( uri, field ) ) - continue; - - /* Prefix this field, if applicable */ - prefix = prefixes[field]; - if ( ( field == URI_HOST ) && ( uri->user != NULL ) ) - prefix = '@'; - if ( ( field == URI_PATH ) && ( uri->path[0] == '/' ) ) - prefix = '\0'; - if ( prefix ) { - used += ssnprintf ( ( buf + used ), ( len - used ), - "%c", prefix ); - } - - /* Encode this field */ - used += uri_encode ( uri_field ( uri, field ), field, - ( buf + used ), ( len - used ) ); - - /* Suffix this field, if applicable */ - if ( ( field == URI_SCHEME ) && ( ! uri->opaque ) ) { - used += ssnprintf ( ( buf + used ), ( len - used ), - "://" ); - } - } - - if ( len ) { - DBGC ( uri, "URI formatted" ); - uri_dump ( uri ); - DBGC ( uri, " to \"%s%s\"\n", buf, - ( ( used > len ) ? "<TRUNCATED>" : "" ) ); - } - - return used; -} - -/** - * Format URI - * - * @v uri URI - * @ret string URI string, or NULL on failure - * - * The caller is responsible for eventually freeing the allocated - * memory. - */ -char * format_uri_alloc ( const struct uri *uri ) { - size_t len; - char *string; - - len = ( format_uri ( uri, NULL, 0 ) + 1 /* NUL */ ); - string = malloc ( len ); - if ( string ) - format_uri ( uri, string, len ); - return string; -} - -/** - * Copy URI fields - * - * @v src Source URI - * @v dest Destination URI, or NULL to calculate length - * @ret len Length of raw URI - */ -static size_t uri_copy_fields ( const struct uri *src, struct uri *dest ) { - size_t len = sizeof ( *dest ); - char *out = ( ( void * ) dest + len ); - unsigned int field; - size_t field_len; - - /* Copy existent fields */ - for ( field = 0 ; field < URI_FIELDS ; field++ ) { - - /* Skip non-existent fields */ - if ( ! uri_field ( src, field ) ) - continue; - - /* Calculate field length */ - field_len = ( strlen ( uri_field ( src, field ) ) - + 1 /* NUL */ ); - len += field_len; - - /* Copy field, if applicable */ - if ( dest ) { - memcpy ( out, uri_field ( src, field ), field_len ); - uri_field ( dest, field ) = out; - out += field_len; - } - } - return len; -} - -/** - * Duplicate URI - * - * @v uri URI - * @ret uri Duplicate URI - * - * Creates a modifiable copy of a URI. - */ -struct uri * uri_dup ( const struct uri *uri ) { - struct uri *dup; - size_t len; - - /* Allocate new URI */ - len = uri_copy_fields ( uri, NULL ); - dup = zalloc ( len ); - if ( ! dup ) - return NULL; - ref_init ( &dup->refcnt, uri_free ); - - /* Copy fields */ - uri_copy_fields ( uri, dup ); - - /* Copy parameters */ - dup->params = params_get ( uri->params ); - - DBGC ( uri, "URI duplicated" ); - uri_dump ( uri ); - DBGC ( uri, "\n" ); - - return dup; -} - -/** - * Resolve base+relative path - * - * @v base_uri Base path - * @v relative_uri Relative path - * @ret resolved_uri Resolved path - * - * Takes a base path (e.g. "/var/lib/tftpboot/vmlinuz" and a relative - * path (e.g. "initrd.gz") and produces a new path - * (e.g. "/var/lib/tftpboot/initrd.gz"). Note that any non-directory - * portion of the base path will automatically be stripped; this - * matches the semantics used when resolving the path component of - * URIs. - */ -char * resolve_path ( const char *base_path, - const char *relative_path ) { - size_t base_len = ( strlen ( base_path ) + 1 ); - char base_path_copy[base_len]; - char *base_tmp = base_path_copy; - char *resolved; - - /* If relative path is absolute, just re-use it */ - if ( relative_path[0] == '/' ) - return strdup ( relative_path ); - - /* Create modifiable copy of path for dirname() */ - memcpy ( base_tmp, base_path, base_len ); - base_tmp = dirname ( base_tmp ); - - /* Process "./" and "../" elements */ - while ( *relative_path == '.' ) { - relative_path++; - if ( *relative_path == 0 ) { - /* Do nothing */ - } else if ( *relative_path == '/' ) { - relative_path++; - } else if ( *relative_path == '.' ) { - relative_path++; - if ( *relative_path == 0 ) { - base_tmp = dirname ( base_tmp ); - } else if ( *relative_path == '/' ) { - base_tmp = dirname ( base_tmp ); - relative_path++; - } else { - relative_path -= 2; - break; - } - } else { - relative_path--; - break; - } - } - - /* Create and return new path */ - if ( asprintf ( &resolved, "%s%s%s", base_tmp, - ( ( base_tmp[ strlen ( base_tmp ) - 1 ] == '/' ) ? - "" : "/" ), relative_path ) < 0 ) - return NULL; - - return resolved; -} - -/** - * Resolve base+relative URI - * - * @v base_uri Base URI, or NULL - * @v relative_uri Relative URI - * @ret resolved_uri Resolved URI - * - * Takes a base URI (e.g. "http://ipxe.org/kernels/vmlinuz" and a - * relative URI (e.g. "../initrds/initrd.gz") and produces a new URI - * (e.g. "http://ipxe.org/initrds/initrd.gz"). - */ -struct uri * resolve_uri ( const struct uri *base_uri, - struct uri *relative_uri ) { - struct uri tmp_uri; - char *tmp_path = NULL; - struct uri *new_uri; - - /* If relative URI is absolute, just re-use it */ - if ( uri_is_absolute ( relative_uri ) || ( ! base_uri ) ) - return uri_get ( relative_uri ); - - /* Mangle URI */ - memcpy ( &tmp_uri, base_uri, sizeof ( tmp_uri ) ); - if ( relative_uri->path ) { - tmp_path = resolve_path ( ( base_uri->path ? - base_uri->path : "/" ), - relative_uri->path ); - tmp_uri.path = tmp_path; - tmp_uri.query = relative_uri->query; - tmp_uri.fragment = relative_uri->fragment; - tmp_uri.params = relative_uri->params; - } else if ( relative_uri->query ) { - tmp_uri.query = relative_uri->query; - tmp_uri.fragment = relative_uri->fragment; - tmp_uri.params = relative_uri->params; - } else if ( relative_uri->fragment ) { - tmp_uri.fragment = relative_uri->fragment; - tmp_uri.params = relative_uri->params; - } else if ( relative_uri->params ) { - tmp_uri.params = relative_uri->params; - } - - /* Create demangled URI */ - new_uri = uri_dup ( &tmp_uri ); - free ( tmp_path ); - return new_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 - * - * TFTP filenames specified via the DHCP next-server field often - * contain characters such as ':' or '#' which would confuse the - * 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, 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 deleted file mode 100644 index b8d21de17..000000000 --- a/qemu/roms/ipxe/src/core/uuid.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdint.h> -#include <stdio.h> -#include <byteswap.h> -#include <ipxe/uuid.h> - -/** @file - * - * Universally unique IDs - * - */ - -/** - * Convert UUID to printable string - * - * @v uuid UUID - * @ret string UUID in canonical form - */ -char * uuid_ntoa ( const union uuid *uuid ) { - static char buf[37]; /* "00000000-0000-0000-0000-000000000000" */ - - sprintf ( buf, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x", - be32_to_cpu ( uuid->canonical.a ), - be16_to_cpu ( uuid->canonical.b ), - be16_to_cpu ( uuid->canonical.c ), - be16_to_cpu ( uuid->canonical.d ), - uuid->canonical.e[0], uuid->canonical.e[1], - uuid->canonical.e[2], uuid->canonical.e[3], - uuid->canonical.e[4], uuid->canonical.e[5] ); - return buf; -} diff --git a/qemu/roms/ipxe/src/core/version.c b/qemu/roms/ipxe/src/core/version.c deleted file mode 100644 index c984335c2..000000000 --- a/qemu/roms/ipxe/src/core/version.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/** @file - * - * Version number - * - */ - -#include <wchar.h> -#include <ipxe/features.h> -#include <ipxe/version.h> -#include <config/general.h> -#include <config/branding.h> - -/** - * Create wide-character version of string - * - * @v string String - * @ret wstring Wide-character version of string - */ -#define WSTRING( string ) _WSTRING ( string ) -#define _WSTRING( string ) L ## string - -/** Version number feature */ -FEATURE_VERSION ( VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH ); - -/** Build timestamp (generated by linker) */ -extern char _build_timestamp[]; - -/** Build ID (generated by linker) */ -extern char _build_id[]; - -/** Build timestamp */ -unsigned long build_timestamp = ( ( unsigned long ) _build_timestamp ); - -/** Build ID */ -unsigned long build_id = ( ( unsigned long ) _build_id ); - -/** Product major version */ -const int product_major_version = VERSION_MAJOR; - -/** Product minor version */ -const int product_minor_version = VERSION_MINOR; - -/** Product version string */ -const char product_version[] = VERSION; - -/** Product name string */ -const char product_name[] = PRODUCT_NAME; - -/** Product short name string */ -const char product_short_name[] = PRODUCT_SHORT_NAME; - -/** Build name string */ -const char build_name[] = BUILD_NAME; - -/** Wide-character product version string */ -const wchar_t product_wversion[] = WSTRING ( VERSION ); - -/** Wide-character product name string */ -const wchar_t product_wname[] = WSTRING ( PRODUCT_NAME ); - -/** Wide-character product short name string */ -const wchar_t product_short_wname[] = WSTRING ( PRODUCT_SHORT_NAME ); - -/** Wide-character build name string */ -const wchar_t build_wname[] = WSTRING ( BUILD_NAME ); - -/** Copy of build name string within ".prefix" */ -const char build_name_prefix[] __attribute__ (( section ( ".prefix.name" ) )) - = BUILD_NAME; diff --git a/qemu/roms/ipxe/src/core/vsprintf.c b/qemu/roms/ipxe/src/core/vsprintf.c deleted file mode 100644 index cb3bec5dd..000000000 --- a/qemu/roms/ipxe/src/core/vsprintf.c +++ /dev/null @@ -1,470 +0,0 @@ -/* - * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stddef.h> -#include <stdarg.h> -#include <stdio.h> -#include <errno.h> -#include <wchar.h> -#include <ipxe/vsprintf.h> - -/** @file */ - -#define CHAR_LEN 0 /**< "hh" length modifier */ -#define SHORT_LEN 1 /**< "h" length modifier */ -#define INT_LEN 2 /**< no length modifier */ -#define LONG_LEN 3 /**< "l" length modifier */ -#define LONGLONG_LEN 4 /**< "ll" length modifier */ -#define SIZE_T_LEN 5 /**< "z" length modifier */ - -static uint8_t type_sizes[] = { - [CHAR_LEN] = sizeof ( char ), - [SHORT_LEN] = sizeof ( short ), - [INT_LEN] = sizeof ( int ), - [LONG_LEN] = sizeof ( long ), - [LONGLONG_LEN] = sizeof ( long long ), - [SIZE_T_LEN] = sizeof ( size_t ), -}; - -/** - * Use lower-case for hexadecimal digits - * - * Note that this value is set to 0x20 since that makes for very - * efficient calculations. (Bitwise-ORing with @c LCASE converts to a - * lower-case character, for example.) - */ -#define LCASE 0x20 - -/** - * Use "alternate form" - * - * For hexadecimal numbers, this means to add a "0x" or "0X" prefix to - * the number. - */ -#define ALT_FORM 0x02 - -/** - * Use zero padding - * - * Note that this value is set to 0x10 since that allows the pad - * character to be calculated as @c 0x20|(flags&ZPAD) - */ -#define ZPAD 0x10 - -/** - * Format a hexadecimal number - * - * @v end End of buffer to contain number - * @v num Number to format - * @v width Minimum field width - * @v flags Format flags - * @ret ptr End of buffer - * - * Fills a buffer in reverse order with a formatted hexadecimal - * number. The number will be zero-padded to the specified width. - * Lower-case and "alternate form" (i.e. "0x" prefix) flags may be - * set. - * - * There must be enough space in the buffer to contain the largest - * number that this function can format. - */ -static char * format_hex ( char *end, unsigned long long num, int width, - int flags ) { - char *ptr = end; - int case_mod = ( flags & LCASE ); - int pad = ( ( flags & ZPAD ) | ' ' ); - - /* Generate the number */ - do { - *(--ptr) = "0123456789ABCDEF"[ num & 0xf ] | case_mod; - num >>= 4; - } while ( num ); - - /* Pad to width */ - while ( ( end - ptr ) < width ) - *(--ptr) = pad; - - /* Add "0x" or "0X" if alternate form specified */ - if ( flags & ALT_FORM ) { - *(--ptr) = 'X' | case_mod; - *(--ptr) = '0'; - } - - return ptr; -} - -/** - * Format a decimal number - * - * @v end End of buffer to contain number - * @v num Number to format - * @v width Minimum field width - * @v flags Format flags - * @ret ptr End of buffer - * - * Fills a buffer in reverse order with a formatted decimal number. - * The number will be space-padded to the specified width. - * - * There must be enough space in the buffer to contain the largest - * number that this function can format. - */ -static char * format_decimal ( char *end, signed long num, int width, - int flags ) { - char *ptr = end; - int negative = 0; - int zpad = ( flags & ZPAD ); - int pad = ( zpad | ' ' ); - - /* Generate the number */ - if ( num < 0 ) { - negative = 1; - num = -num; - } - do { - *(--ptr) = '0' + ( num % 10 ); - num /= 10; - } while ( num ); - - /* Add "-" if necessary */ - if ( negative && ( ! zpad ) ) - *(--ptr) = '-'; - - /* Pad to width */ - while ( ( end - ptr ) < width ) - *(--ptr) = pad; - - /* Add "-" if necessary */ - if ( negative && zpad ) - *ptr = '-'; - - return ptr; -} - -/** - * Print character via a printf context - * - * @v ctx Context - * @v c Character - * - * Call's the printf_context::handler() method and increments - * printf_context::len. - */ -static inline void cputchar ( struct printf_context *ctx, unsigned char c ) { - ctx->handler ( ctx, c ); - ++ctx->len; -} - -/** - * Write a formatted string to a printf context - * - * @v ctx Context - * @v fmt Format string - * @v args Arguments corresponding to the format string - * @ret len Length of formatted string - */ -size_t vcprintf ( struct printf_context *ctx, const char *fmt, va_list args ) { - int flags; - int width; - uint8_t *length; - char *ptr; - char tmp_buf[32]; /* 32 is enough for all numerical formats. - * Insane width fields could overflow this buffer. */ - wchar_t *wptr; - - /* Initialise context */ - ctx->len = 0; - - for ( ; *fmt ; fmt++ ) { - /* Pass through ordinary characters */ - if ( *fmt != '%' ) { - cputchar ( ctx, *fmt ); - continue; - } - fmt++; - /* Process flag characters */ - flags = 0; - for ( ; ; fmt++ ) { - if ( *fmt == '#' ) { - flags |= ALT_FORM; - } else if ( *fmt == '0' ) { - flags |= ZPAD; - } else { - /* End of flag characters */ - break; - } - } - /* Process field width */ - width = 0; - for ( ; ; fmt++ ) { - if ( ( ( unsigned ) ( *fmt - '0' ) ) < 10 ) { - width = ( width * 10 ) + ( *fmt - '0' ); - } else { - break; - } - } - /* We don't do floating point */ - /* Process length modifier */ - length = &type_sizes[INT_LEN]; - for ( ; ; fmt++ ) { - if ( *fmt == 'h' ) { - length--; - } else if ( *fmt == 'l' ) { - length++; - } else if ( *fmt == 'z' ) { - length = &type_sizes[SIZE_T_LEN]; - } else { - break; - } - } - /* Process conversion specifier */ - ptr = tmp_buf + sizeof ( tmp_buf ) - 1; - *ptr = '\0'; - wptr = NULL; - if ( *fmt == 'c' ) { - if ( length < &type_sizes[LONG_LEN] ) { - cputchar ( ctx, va_arg ( args, unsigned int ) ); - } else { - wchar_t wc; - size_t len; - - wc = va_arg ( args, wint_t ); - len = wcrtomb ( tmp_buf, wc, NULL ); - tmp_buf[len] = '\0'; - ptr = tmp_buf; - } - } else if ( *fmt == 's' ) { - if ( length < &type_sizes[LONG_LEN] ) { - ptr = va_arg ( args, char * ); - } else { - wptr = va_arg ( args, wchar_t * ); - } - if ( ( ptr == NULL ) && ( wptr == NULL ) ) - ptr = "<NULL>"; - } else if ( *fmt == 'p' ) { - intptr_t ptrval; - - ptrval = ( intptr_t ) va_arg ( args, void * ); - ptr = format_hex ( ptr, ptrval, width, - ( ALT_FORM | LCASE ) ); - } else if ( ( *fmt & ~0x20 ) == 'X' ) { - unsigned long long hex; - - flags |= ( *fmt & 0x20 ); /* LCASE */ - if ( *length >= sizeof ( unsigned long long ) ) { - hex = va_arg ( args, unsigned long long ); - } else if ( *length >= sizeof ( unsigned long ) ) { - hex = va_arg ( args, unsigned long ); - } else { - hex = va_arg ( args, unsigned int ); - } - ptr = format_hex ( ptr, hex, width, flags ); - } else if ( ( *fmt == 'd' ) || ( *fmt == 'i' ) ){ - signed long decimal; - - if ( *length >= sizeof ( signed long ) ) { - decimal = va_arg ( args, signed long ); - } else { - decimal = va_arg ( args, signed int ); - } - ptr = format_decimal ( ptr, decimal, width, flags ); - } else { - *(--ptr) = *fmt; - } - /* Write out conversion result */ - if ( wptr == NULL ) { - for ( ; *ptr ; ptr++ ) { - cputchar ( ctx, *ptr ); - } - } else { - for ( ; *wptr ; wptr++ ) { - size_t len = wcrtomb ( tmp_buf, *wptr, NULL ); - for ( ptr = tmp_buf ; len-- ; ptr++ ) { - cputchar ( ctx, *ptr ); - } - } - } - } - - return ctx->len; -} - -/** Context used by vsnprintf() and friends */ -struct sputc_context { - struct printf_context ctx; - /** Buffer for formatted string (used by printf_sputc()) */ - char *buf; - /** Buffer length (used by printf_sputc()) */ - size_t max_len; -}; - -/** - * Write character to buffer - * - * @v ctx Context - * @v c Character - */ -static void printf_sputc ( struct printf_context *ctx, unsigned int c ) { - struct sputc_context * sctx = - container_of ( ctx, struct sputc_context, ctx ); - - if ( ctx->len < sctx->max_len ) - sctx->buf[ctx->len] = c; -} - -/** - * Write a formatted string to a buffer - * - * @v buf Buffer into which to write the string - * @v size Size of buffer - * @v fmt Format string - * @v args Arguments corresponding to the format string - * @ret len Length of formatted string - * - * If the buffer is too small to contain the string, the returned - * length is the length that would have been written had enough space - * been available. - */ -int vsnprintf ( char *buf, size_t size, const char *fmt, va_list args ) { - struct sputc_context sctx; - size_t len; - size_t end; - - /* Hand off to vcprintf */ - sctx.ctx.handler = printf_sputc; - sctx.buf = buf; - sctx.max_len = size; - len = vcprintf ( &sctx.ctx, fmt, args ); - - /* Add trailing NUL */ - if ( size ) { - end = size - 1; - if ( len < end ) - end = len; - buf[end] = '\0'; - } - - return len; -} - -/** - * Write a formatted string to a buffer - * - * @v buf Buffer into which to write the string - * @v size Size of buffer - * @v fmt Format string - * @v ... Arguments corresponding to the format string - * @ret len Length of formatted string - */ -int snprintf ( char *buf, size_t size, const char *fmt, ... ) { - va_list args; - int i; - - va_start ( args, fmt ); - i = vsnprintf ( buf, size, fmt, args ); - va_end ( args ); - return i; -} - -/** - * Version of vsnprintf() that accepts a signed buffer size - * - * @v buf Buffer into which to write the string - * @v size Size of buffer - * @v fmt Format string - * @v args Arguments corresponding to the format string - * @ret len Length of formatted string - */ -int vssnprintf ( char *buf, ssize_t ssize, const char *fmt, va_list args ) { - - /* Treat negative buffer size as zero buffer size */ - if ( ssize < 0 ) - ssize = 0; - - /* Hand off to vsnprintf */ - return vsnprintf ( buf, ssize, fmt, args ); -} - -/** - * Version of vsnprintf() that accepts a signed buffer size - * - * @v buf Buffer into which to write the string - * @v size Size of buffer - * @v fmt Format string - * @v ... Arguments corresponding to the format string - * @ret len Length of formatted string - */ -int ssnprintf ( char *buf, ssize_t ssize, const char *fmt, ... ) { - va_list args; - int len; - - /* Hand off to vssnprintf */ - va_start ( args, fmt ); - len = vssnprintf ( buf, ssize, fmt, args ); - va_end ( args ); - return len; -} - -/** - * Write character to console - * - * @v ctx Context - * @v c Character - */ -static void printf_putchar ( struct printf_context *ctx __unused, - unsigned int c ) { - putchar ( c ); -} - -/** - * Write a formatted string to the console - * - * @v fmt Format string - * @v args Arguments corresponding to the format string - * @ret len Length of formatted string - */ -int vprintf ( const char *fmt, va_list args ) { - struct printf_context ctx; - - /* Hand off to vcprintf */ - ctx.handler = printf_putchar; - return vcprintf ( &ctx, fmt, args ); -} - -/** - * Write a formatted string to the console. - * - * @v fmt Format string - * @v ... Arguments corresponding to the format string - * @ret len Length of formatted string - */ -int printf ( const char *fmt, ... ) { - va_list args; - int i; - - va_start ( args, fmt ); - i = vprintf ( fmt, args ); - va_end ( args ); - return i; -} diff --git a/qemu/roms/ipxe/src/core/wchar.c b/qemu/roms/ipxe/src/core/wchar.c deleted file mode 100644 index 860322820..000000000 --- a/qemu/roms/ipxe/src/core/wchar.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/** - * @file - * - * Wide-character strings - * - */ - -#include <wchar.h> - -/** - * Calculate length of wide-character string - * - * @v string String - * @ret len Length (excluding terminating NUL) - */ -size_t wcslen ( const wchar_t *string ) { - size_t len = 0; - - while ( *(string++) ) - len++; - return len; -} diff --git a/qemu/roms/ipxe/src/core/xfer.c b/qemu/roms/ipxe/src/core/xfer.c deleted file mode 100644 index 112fee1bf..000000000 --- a/qemu/roms/ipxe/src/core/xfer.c +++ /dev/null @@ -1,392 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <string.h> -#include <stdlib.h> -#include <stdio.h> -#include <errno.h> -#include <ipxe/iobuf.h> -#include <ipxe/xfer.h> -#include <ipxe/open.h> - -/** @file - * - * Data transfer interfaces - * - */ - -/** - * Dummy transfer metadata - * - * This gets passed to xfer_interface::deliver() and equivalents when - * no metadata is available. - */ -static struct xfer_metadata dummy_metadata; - -/***************************************************************************** - * - * Data transfer interface operations - * - */ - -/** - * Send redirection event - * - * @v intf Data transfer interface - * @v type New location type - * @v args Remaining arguments depend upon location type - * @ret rc Return status code - */ -int xfer_vredirect ( struct interface *intf, int type, va_list args ) { - struct interface tmp = INTF_INIT ( null_intf_desc ); - struct interface *dest; - xfer_vredirect_TYPE ( void * ) *op = - intf_get_dest_op_no_passthru ( intf, xfer_vredirect, &dest ); - void *object = intf_object ( dest ); - int rc; - - DBGC ( INTF_COL ( intf ), "INTF " INTF_INTF_FMT " redirect\n", - INTF_INTF_DBG ( intf, dest ) ); - - if ( op ) { - rc = op ( object, type, args ); - } else { - /* Default is to reopen the interface as instructed, - * then send xfer_window_changed() messages to both - * new child and parent interfaces. Since our - * original child interface is likely to be closed and - * unplugged as a result of the call to - * xfer_vreopen(), we create a temporary interface in - * order to be able to send xfer_window_changed() to - * the parent. - */ - intf_plug ( &tmp, dest ); - rc = xfer_vreopen ( dest, type, args ); - if ( rc == 0 ) { - xfer_window_changed ( dest ); - xfer_window_changed ( &tmp ); - } - intf_unplug ( &tmp ); - } - - if ( rc != 0 ) { - DBGC ( INTF_COL ( intf ), "INTF " INTF_INTF_FMT " redirect " - "failed: %s\n", INTF_INTF_DBG ( intf, dest ), - strerror ( rc ) ); - } - - intf_put ( dest ); - return rc; -} - -/** - * Check flow control window - * - * @v intf Data transfer interface - * @ret len Length of window - */ -size_t xfer_window ( struct interface *intf ) { - struct interface *dest; - xfer_window_TYPE ( void * ) *op = - intf_get_dest_op ( intf, xfer_window, &dest ); - void *object = intf_object ( dest ); - size_t len; - - if ( op ) { - len = op ( object ); - } else { - /* Default is to provide an unlimited window */ - len = ~( ( size_t ) 0 ); - } - - intf_put ( dest ); - return len; -} - -/** - * Report change of flow control window - * - * @v intf Data transfer interface - * - * Note that this method is used to indicate only unsolicited changes - * in the flow control window. In particular, this method must not be - * called as part of the response to xfer_deliver(), since that could - * easily lead to an infinite loop. Callers of xfer_deliver() should - * assume that the flow control window will have changed without - * generating an xfer_window_changed() message. - */ -void xfer_window_changed ( struct interface *intf ) { - - intf_poke ( intf, xfer_window_changed ); -} - -/** - * Allocate I/O buffer - * - * @v intf Data transfer interface - * @v len I/O buffer payload length - * @ret iobuf I/O buffer - */ -struct io_buffer * xfer_alloc_iob ( struct interface *intf, size_t len ) { - struct interface *dest; - xfer_alloc_iob_TYPE ( void * ) *op = - intf_get_dest_op ( intf, xfer_alloc_iob, &dest ); - void *object = intf_object ( dest ); - struct io_buffer *iobuf; - - DBGC ( INTF_COL ( intf ), "INTF " INTF_INTF_FMT " alloc_iob %zd\n", - INTF_INTF_DBG ( intf, dest ), len ); - - if ( op ) { - iobuf = op ( object, len ); - } else { - /* Default is to allocate an I/O buffer with no - * reserved space. - */ - iobuf = alloc_iob ( len ); - } - - if ( ! iobuf ) { - DBGC ( INTF_COL ( intf ), "INTF " INTF_INTF_FMT " alloc_iob " - "failed\n", INTF_INTF_DBG ( intf, dest ) ); - } - - intf_put ( dest ); - return iobuf; -} - -/** - * Deliver datagram - * - * @v intf Data transfer interface - * @v iobuf Datagram I/O buffer - * @v meta Data transfer metadata - * @ret rc Return status code - */ -int xfer_deliver ( struct interface *intf, - struct io_buffer *iobuf, - struct xfer_metadata *meta ) { - struct interface *dest; - xfer_deliver_TYPE ( void * ) *op = - intf_get_dest_op ( intf, xfer_deliver, &dest ); - void *object = intf_object ( dest ); - int rc; - - DBGC ( INTF_COL ( intf ), "INTF " INTF_INTF_FMT " deliver %zd\n", - INTF_INTF_DBG ( intf, dest ), iob_len ( iobuf ) ); - - if ( op ) { - rc = op ( object, iobuf, meta ); - } else { - /* Default is to discard the I/O buffer */ - free_iob ( iobuf ); - rc = -EPIPE; - } - - if ( rc != 0 ) { - DBGC ( INTF_COL ( intf ), "INTF " INTF_INTF_FMT - " deliver failed: %s\n", - INTF_INTF_DBG ( intf, dest ), strerror ( rc ) ); - } - - intf_put ( dest ); - return rc; -} - -/***************************************************************************** - * - * Data transfer interface helper functions - * - */ - -/** - * Send redirection event - * - * @v intf Data transfer interface - * @v type New location type - * @v ... Remaining arguments depend upon location type - * @ret rc Return status code - */ -int xfer_redirect ( struct interface *intf, int type, ... ) { - va_list args; - int rc; - - va_start ( args, type ); - rc = xfer_vredirect ( intf, type, args ); - va_end ( args ); - return rc; -} - -/** - * Deliver datagram as I/O buffer without metadata - * - * @v intf Data transfer interface - * @v iobuf Datagram I/O buffer - * @ret rc Return status code - */ -int xfer_deliver_iob ( struct interface *intf, struct io_buffer *iobuf ) { - return xfer_deliver ( intf, iobuf, &dummy_metadata ); -} - -/** - * Deliver datagram as raw data - * - * @v intf Data transfer interface - * @v data Data - * @v len Length of data - * @v meta Data transfer metadata - * @ret rc Return status code - */ -int xfer_deliver_raw_meta ( struct interface *intf, const void *data, - size_t len, struct xfer_metadata *meta ) { - struct io_buffer *iobuf; - - iobuf = xfer_alloc_iob ( intf, len ); - if ( ! iobuf ) - return -ENOMEM; - - memcpy ( iob_put ( iobuf, len ), data, len ); - return xfer_deliver ( intf, iobuf, meta ); -} - -/** - * Deliver datagram as raw data without metadata - * - * @v intf Data transfer interface - * @v data Data - * @v len Length of data - * @ret rc Return status code - */ -int xfer_deliver_raw ( struct interface *intf, const void *data, size_t len ) { - return xfer_deliver_raw_meta ( intf, data, len, &dummy_metadata ); -} - -/** - * Deliver formatted string - * - * @v intf Data transfer interface - * @v format Format string - * @v args Arguments corresponding to the format string - * @ret rc Return status code - */ -int xfer_vprintf ( struct interface *intf, const char *format, - va_list args ) { - va_list args_tmp; - char *buf; - int len; - int rc; - - /* Create temporary string */ - va_copy ( args_tmp, args ); - len = vasprintf ( &buf, format, args ); - if ( len < 0 ) { - rc = len; - goto err_asprintf; - } - va_end ( args_tmp ); - - /* Transmit string */ - if ( ( rc = xfer_deliver_raw ( intf, buf, len ) ) != 0 ) - goto err_deliver; - - err_deliver: - free ( buf ); - err_asprintf: - return rc; -} - -/** - * Deliver formatted string - * - * @v intf Data transfer interface - * @v format Format string - * @v ... Arguments corresponding to the format string - * @ret rc Return status code - */ -int xfer_printf ( struct interface *intf, const char *format, ... ) { - va_list args; - int rc; - - va_start ( args, format ); - rc = xfer_vprintf ( intf, format, args ); - va_end ( args ); - return rc; -} - -/** - * Seek to position - * - * @v intf Data transfer interface - * @v offset Offset to new position - * @ret rc Return status code - */ -int xfer_seek ( struct interface *intf, off_t offset ) { - struct io_buffer *iobuf; - struct xfer_metadata meta = { - .flags = XFER_FL_ABS_OFFSET, - .offset = offset, - }; - - DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " seek to %ld\n", - INTF_DBG ( intf ), offset ); - - /* Allocate and send a zero-length data buffer */ - iobuf = xfer_alloc_iob ( intf, 0 ); - if ( ! iobuf ) - return -ENOMEM; - - 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 deleted file mode 100644 index 240118557..000000000 --- a/qemu/roms/ipxe/src/core/xferbuf.c +++ /dev/null @@ -1,324 +0,0 @@ -/* - * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <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 - * - * Data transfer buffer - * - */ - -/** 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" }; - -/** - * Free data transfer buffer - * - * @v xferbuf Data transfer buffer - */ -void xferbuf_free ( struct xfer_buffer *xferbuf ) { - - xferbuf->op->realloc ( xferbuf, 0 ); - xferbuf->len = 0; - xferbuf->pos = 0; -} - -/** - * Ensure that data transfer buffer is large enough for the specified size - * - * @v xferbuf Data transfer buffer - * @v len Required minimum size - * @ret rc Return status code - */ -static int xferbuf_ensure_size ( struct xfer_buffer *xferbuf, size_t len ) { - int rc; - - /* If buffer is already large enough, do nothing */ - if ( len <= xferbuf->len ) - return 0; - - /* Extend buffer */ - if ( ( rc = xferbuf->op->realloc ( xferbuf, len ) ) != 0 ) { - DBGC ( xferbuf, "XFERBUF %p could not extend buffer to " - "%zd bytes: %s\n", xferbuf, len, strerror ( rc ) ); - return rc; - } - 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 - * @v iobuf I/O buffer - * @v meta Data transfer metadata - * @ret rc Return status code - */ -int xferbuf_deliver ( struct xfer_buffer *xferbuf, struct io_buffer *iobuf, - struct xfer_metadata *meta ) { - 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 ) - pos = 0; - pos += meta->offset; - - /* Write data to buffer */ - if ( ( rc = xferbuf_write ( xferbuf, pos, iobuf->data, len ) ) != 0 ) - goto done; - - /* Update current buffer position */ - 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; -} |