summaryrefslogtreecommitdiffstats
path: root/qemu/roms/ipxe/src/hci
diff options
context:
space:
mode:
authorYang Zhang <yang.z.zhang@intel.com>2015-08-28 09:58:54 +0800
committerYang Zhang <yang.z.zhang@intel.com>2015-09-01 12:44:00 +0800
commite44e3482bdb4d0ebde2d8b41830ac2cdb07948fb (patch)
tree66b09f592c55df2878107a468a91d21506104d3f /qemu/roms/ipxe/src/hci
parent9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00 (diff)
Add qemu 2.4.0
Change-Id: Ic99cbad4b61f8b127b7dc74d04576c0bcbaaf4f5 Signed-off-by: Yang Zhang <yang.z.zhang@intel.com>
Diffstat (limited to 'qemu/roms/ipxe/src/hci')
-rw-r--r--qemu/roms/ipxe/src/hci/commands/autoboot_cmd.c77
-rw-r--r--qemu/roms/ipxe/src/hci/commands/config_cmd.c81
-rw-r--r--qemu/roms/ipxe/src/hci/commands/console_cmd.c263
-rw-r--r--qemu/roms/ipxe/src/hci/commands/dhcp_cmd.c100
-rw-r--r--qemu/roms/ipxe/src/hci/commands/digest_cmd.c123
-rw-r--r--qemu/roms/ipxe/src/hci/commands/fcmgmt_cmd.c215
-rw-r--r--qemu/roms/ipxe/src/hci/commands/gdbstub_cmd.c111
-rw-r--r--qemu/roms/ipxe/src/hci/commands/ifmgmt_cmd.c261
-rw-r--r--qemu/roms/ipxe/src/hci/commands/image_cmd.c441
-rw-r--r--qemu/roms/ipxe/src/hci/commands/image_trust_cmd.c176
-rw-r--r--qemu/roms/ipxe/src/hci/commands/ipstat_cmd.c70
-rw-r--r--qemu/roms/ipxe/src/hci/commands/iwmgmt_cmd.c125
-rw-r--r--qemu/roms/ipxe/src/hci/commands/login_cmd.c73
-rw-r--r--qemu/roms/ipxe/src/hci/commands/lotest_cmd.c97
-rw-r--r--qemu/roms/ipxe/src/hci/commands/menu_cmd.c290
-rw-r--r--qemu/roms/ipxe/src/hci/commands/neighbour_cmd.c69
-rw-r--r--qemu/roms/ipxe/src/hci/commands/nslookup_cmd.c79
-rw-r--r--qemu/roms/ipxe/src/hci/commands/nvo_cmd.c347
-rw-r--r--qemu/roms/ipxe/src/hci/commands/param_cmd.c163
-rw-r--r--qemu/roms/ipxe/src/hci/commands/pci_cmd.c114
-rw-r--r--qemu/roms/ipxe/src/hci/commands/ping_cmd.c109
-rw-r--r--qemu/roms/ipxe/src/hci/commands/poweroff_cmd.c72
-rw-r--r--qemu/roms/ipxe/src/hci/commands/profstat_cmd.c70
-rw-r--r--qemu/roms/ipxe/src/hci/commands/reboot_cmd.c74
-rw-r--r--qemu/roms/ipxe/src/hci/commands/route_cmd.c70
-rw-r--r--qemu/roms/ipxe/src/hci/commands/sanboot_cmd.c193
-rw-r--r--qemu/roms/ipxe/src/hci/commands/sync_cmd.c79
-rw-r--r--qemu/roms/ipxe/src/hci/commands/time_cmd.c83
-rw-r--r--qemu/roms/ipxe/src/hci/commands/vlan_cmd.c139
-rw-r--r--qemu/roms/ipxe/src/hci/editstring.c254
-rw-r--r--qemu/roms/ipxe/src/hci/keymap/keymap_al.c32
-rw-r--r--qemu/roms/ipxe/src/hci/keymap/keymap_az.c24
-rw-r--r--qemu/roms/ipxe/src/hci/keymap/keymap_bg.c15
-rw-r--r--qemu/roms/ipxe/src/hci/keymap/keymap_by.c15
-rw-r--r--qemu/roms/ipxe/src/hci/keymap/keymap_cf.c24
-rw-r--r--qemu/roms/ipxe/src/hci/keymap/keymap_cz.c27
-rw-r--r--qemu/roms/ipxe/src/hci/keymap/keymap_de.c46
-rw-r--r--qemu/roms/ipxe/src/hci/keymap/keymap_dk.c31
-rw-r--r--qemu/roms/ipxe/src/hci/keymap/keymap_es.c29
-rw-r--r--qemu/roms/ipxe/src/hci/keymap/keymap_et.c30
-rw-r--r--qemu/roms/ipxe/src/hci/keymap/keymap_fi.c38
-rw-r--r--qemu/roms/ipxe/src/hci/keymap/keymap_fr.c68
-rw-r--r--qemu/roms/ipxe/src/hci/keymap/keymap_gr.c15
-rw-r--r--qemu/roms/ipxe/src/hci/keymap/keymap_hu.c34
-rw-r--r--qemu/roms/ipxe/src/hci/keymap/keymap_il.c15
-rw-r--r--qemu/roms/ipxe/src/hci/keymap/keymap_it.c32
-rw-r--r--qemu/roms/ipxe/src/hci/keymap/keymap_lt.c15
-rw-r--r--qemu/roms/ipxe/src/hci/keymap/keymap_mk.c15
-rw-r--r--qemu/roms/ipxe/src/hci/keymap/keymap_mt.c20
-rw-r--r--qemu/roms/ipxe/src/hci/keymap/keymap_nl.c34
-rw-r--r--qemu/roms/ipxe/src/hci/keymap/keymap_no-latin1.c34
-rw-r--r--qemu/roms/ipxe/src/hci/keymap/keymap_no.c105
-rw-r--r--qemu/roms/ipxe/src/hci/keymap/keymap_pl.c15
-rw-r--r--qemu/roms/ipxe/src/hci/keymap/keymap_pt.c29
-rw-r--r--qemu/roms/ipxe/src/hci/keymap/keymap_ro.c15
-rw-r--r--qemu/roms/ipxe/src/hci/keymap/keymap_ru.c15
-rw-r--r--qemu/roms/ipxe/src/hci/keymap/keymap_sg.c41
-rw-r--r--qemu/roms/ipxe/src/hci/keymap/keymap_sr.c35
-rw-r--r--qemu/roms/ipxe/src/hci/keymap/keymap_th.c15
-rw-r--r--qemu/roms/ipxe/src/hci/keymap/keymap_ua.c15
-rw-r--r--qemu/roms/ipxe/src/hci/keymap/keymap_uk.c19
-rw-r--r--qemu/roms/ipxe/src/hci/keymap/keymap_us.c15
-rw-r--r--qemu/roms/ipxe/src/hci/keymap/keymap_wo.c55
-rw-r--r--qemu/roms/ipxe/src/hci/linux_args.c190
-rw-r--r--qemu/roms/ipxe/src/hci/mucurses/alert.c18
-rw-r--r--qemu/roms/ipxe/src/hci/mucurses/ansi_screen.c102
-rw-r--r--qemu/roms/ipxe/src/hci/mucurses/clear.c100
-rw-r--r--qemu/roms/ipxe/src/hci/mucurses/colour.c66
-rw-r--r--qemu/roms/ipxe/src/hci/mucurses/cursor.h37
-rw-r--r--qemu/roms/ipxe/src/hci/mucurses/edging.c111
-rw-r--r--qemu/roms/ipxe/src/hci/mucurses/kb.c143
-rw-r--r--qemu/roms/ipxe/src/hci/mucurses/mucurses.c156
-rw-r--r--qemu/roms/ipxe/src/hci/mucurses/mucurses.h23
-rw-r--r--qemu/roms/ipxe/src/hci/mucurses/print.c86
-rw-r--r--qemu/roms/ipxe/src/hci/mucurses/print_nadv.c26
-rw-r--r--qemu/roms/ipxe/src/hci/mucurses/slk.c363
-rw-r--r--qemu/roms/ipxe/src/hci/mucurses/widgets/editbox.c103
-rw-r--r--qemu/roms/ipxe/src/hci/mucurses/winattrs.c133
-rw-r--r--qemu/roms/ipxe/src/hci/mucurses/windows.c158
-rw-r--r--qemu/roms/ipxe/src/hci/mucurses/wininit.c38
-rw-r--r--qemu/roms/ipxe/src/hci/readline.c343
-rw-r--r--qemu/roms/ipxe/src/hci/shell.c138
-rw-r--r--qemu/roms/ipxe/src/hci/strerror.c125
-rw-r--r--qemu/roms/ipxe/src/hci/tui/login_ui.c133
-rw-r--r--qemu/roms/ipxe/src/hci/tui/menu_ui.c363
-rw-r--r--qemu/roms/ipxe/src/hci/tui/settings_ui.c603
-rw-r--r--qemu/roms/ipxe/src/hci/wireless_errors.c109
87 files changed, 9052 insertions, 0 deletions
diff --git a/qemu/roms/ipxe/src/hci/commands/autoboot_cmd.c b/qemu/roms/ipxe/src/hci/commands/autoboot_cmd.c
new file mode 100644
index 000000000..62235a278
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/commands/autoboot_cmd.c
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+#include <stdio.h>
+#include <getopt.h>
+#include <ipxe/command.h>
+#include <ipxe/parseopt.h>
+#include <ipxe/netdevice.h>
+#include <hci/ifmgmt_cmd.h>
+#include <usr/autoboot.h>
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+/** @file
+ *
+ * Booting commands
+ *
+ */
+
+/** "autoboot" options */
+struct autoboot_options {};
+
+/** "autoboot" option list */
+static struct option_descriptor autoboot_opts[] = {};
+
+/**
+ * "autoboot" payload
+ *
+ * @v netdev Network device
+ * @v opts Command options
+ * @ret rc Return status code
+ */
+static int autoboot_payload ( struct net_device *netdev,
+ struct autoboot_options *opts __unused ) {
+ return netboot ( netdev );
+}
+
+/** "autoboot" command descriptor */
+static struct ifcommon_command_descriptor autoboot_cmd =
+ IFCOMMON_COMMAND_DESC ( struct autoboot_options, autoboot_opts,
+ 0, MAX_ARGUMENTS, "[<interface>...]",
+ autoboot_payload, 0 );
+
+/**
+ * "autoboot" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int autoboot_exec ( int argc, char **argv ) {
+ return ifcommon_exec ( argc, argv, &autoboot_cmd );
+}
+
+/** Booting commands */
+struct command autoboot_commands[] __command = {
+ {
+ .name = "autoboot",
+ .exec = autoboot_exec,
+ },
+};
diff --git a/qemu/roms/ipxe/src/hci/commands/config_cmd.c b/qemu/roms/ipxe/src/hci/commands/config_cmd.c
new file mode 100644
index 000000000..b81c866ff
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/commands/config_cmd.c
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <getopt.h>
+#include <ipxe/command.h>
+#include <ipxe/parseopt.h>
+#include <ipxe/settings.h>
+#include <ipxe/settings_ui.h>
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+/** @file
+ *
+ * Configuration UI commands
+ *
+ */
+
+/** "config" options */
+struct config_options {};
+
+/** "config" option list */
+static struct option_descriptor config_opts[] = {};
+
+/** "config" command descriptor */
+static struct command_descriptor config_cmd =
+ COMMAND_DESC ( struct config_options, config_opts, 0, 1, "[<scope>]" );
+
+/**
+ * "config" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int config_exec ( int argc, char **argv ) {
+ struct config_options opts;
+ struct settings *settings;
+ int rc;
+
+ /* Parse options */
+ if ( ( rc = parse_options ( argc, argv, &config_cmd, &opts ) ) != 0 )
+ return rc;
+
+ /* Parse settings option, if present */
+ if ( ( rc = parse_settings ( ( ( optind < argc ) ? argv[optind] : "" ),
+ &settings ) ) != 0 )
+ return rc;
+
+ /* Run settings UI */
+ if ( ( rc = settings_ui ( settings ) ) != 0 ) {
+ printf ( "Could not save settings: %s\n", strerror ( rc ) );
+ return rc;
+ }
+
+ return 0;
+}
+
+/** Configuration UI commands */
+struct command config_command __command = {
+ .name = "config",
+ .exec = config_exec,
+};
diff --git a/qemu/roms/ipxe/src/hci/commands/console_cmd.c b/qemu/roms/ipxe/src/hci/commands/console_cmd.c
new file mode 100644
index 000000000..d2eae59f0
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/commands/console_cmd.c
@@ -0,0 +1,263 @@
+/*
+ * Copyright (C) 2013 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+/** @file
+ *
+ * Console management commands
+ *
+ */
+
+#include <string.h>
+#include <getopt.h>
+#include <ipxe/command.h>
+#include <ipxe/parseopt.h>
+#include <ipxe/console.h>
+#include <ipxe/image.h>
+#include <ipxe/pixbuf.h>
+#include <ipxe/ansiesc.h>
+#include <ipxe/ansicol.h>
+#include <usr/imgmgmt.h>
+
+/** "console" options */
+struct console_options {
+ /** Console configuration */
+ struct console_configuration config;
+ /** Picture URI */
+ char *picture;
+ /** Keep picture after configuration */
+ int keep;
+};
+
+/** "console" option list */
+static struct option_descriptor console_opts[] = {
+ OPTION_DESC ( "x", 'x', required_argument,
+ struct console_options, config.width, parse_integer ),
+ OPTION_DESC ( "y", 'y', required_argument,
+ struct console_options, config.height, parse_integer ),
+ OPTION_DESC ( "left", 'l', required_argument,
+ struct console_options, config.left, parse_integer ),
+ OPTION_DESC ( "right", 'r', required_argument,
+ struct console_options, config.right, parse_integer ),
+ OPTION_DESC ( "top", 't', required_argument,
+ struct console_options, config.top, parse_integer ),
+ OPTION_DESC ( "bottom", 'b', required_argument,
+ struct console_options, config.bottom, parse_integer ),
+ OPTION_DESC ( "depth", 'd', required_argument,
+ struct console_options, config.depth, parse_integer ),
+ OPTION_DESC ( "picture", 'p', required_argument,
+ struct console_options, picture, parse_string ),
+ OPTION_DESC ( "keep", 'k', no_argument,
+ struct console_options, keep, parse_flag ),
+};
+
+/** "console" command descriptor */
+static struct command_descriptor console_cmd =
+ COMMAND_DESC ( struct console_options, console_opts, 0, 0, NULL );
+
+/**
+ * "console" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int console_exec ( int argc, char **argv ) {
+ struct console_options opts;
+ struct image *image = NULL;
+ int rc;
+
+ /* Parse options */
+ if ( ( rc = parse_options ( argc, argv, &console_cmd, &opts ) ) != 0 )
+ goto err_parse;
+
+ /* Handle background picture, if applicable */
+ if ( opts.picture ) {
+
+ /* Acquire image */
+ if ( ( rc = imgacquire ( opts.picture, 0, &image ) ) != 0 )
+ goto err_acquire;
+
+ /* Convert to pixel buffer */
+ if ( ( rc = image_pixbuf ( image, &opts.config.pixbuf ) ) != 0){
+ printf ( "Could not use picture: %s\n",
+ strerror ( rc ) );
+ goto err_pixbuf;
+ }
+
+ /* Apply image's width and height if none specified */
+ if ( ! opts.config.width )
+ opts.config.width = opts.config.pixbuf->width;
+ if ( ! opts.config.height )
+ opts.config.height = opts.config.pixbuf->height;
+ }
+
+ /* Configure console */
+ if ( ( rc = console_configure ( &opts.config ) ) != 0 ) {
+ printf ( "Could not configure console: %s\n", strerror ( rc ) );
+ goto err_configure;
+ }
+
+ /* Reapply default colour pair and clear screen */
+ ansicol_set_pair ( CPAIR_DEFAULT );
+ printf ( CSI "2J" CSI "H" );
+
+ err_configure:
+ pixbuf_put ( opts.config.pixbuf );
+ err_pixbuf:
+ /* Discard image unless --keep was specified */
+ if ( image && ( ! opts.keep ) )
+ unregister_image ( image );
+ err_acquire:
+ err_parse:
+ return rc;
+}
+
+/** "colour" options */
+struct colour_options {
+ /** Basic colour */
+ unsigned int basic;
+ /** 24-bit RGB value */
+ unsigned int rgb;
+};
+
+/** "colour" option list */
+static struct option_descriptor colour_opts[] = {
+ OPTION_DESC ( "basic", 'b', required_argument,
+ struct colour_options, basic, parse_integer ),
+ OPTION_DESC ( "rgb", 'r', required_argument,
+ struct colour_options, rgb, parse_integer ),
+};
+
+/** "colour" command descriptor */
+static struct command_descriptor colour_cmd =
+ COMMAND_DESC ( struct colour_options, colour_opts, 1, 1, "<colour>" );
+
+/**
+ * "colour" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int colour_exec ( int argc, char **argv ) {
+ struct colour_options opts;
+ unsigned int colour;
+ int rc;
+
+ /* Initialise options */
+ memset ( &opts, 0, sizeof ( opts ) );
+ opts.basic = COLOUR_DEFAULT;
+ opts.rgb = ANSICOL_NO_RGB;
+
+ /* Parse options */
+ if ( ( rc = reparse_options ( argc, argv, &colour_cmd, &opts ) ) != 0 )
+ return rc;
+
+ /* Parse colour index */
+ if ( ( rc = parse_integer ( argv[optind], &colour ) ) != 0 )
+ return rc;
+
+ /* Define colour */
+ if ( ( rc = ansicol_define ( colour, opts.basic, opts.rgb ) ) != 0 ) {
+ printf ( "Could not define colour: %s\n", strerror ( rc ) );
+ return rc;
+ }
+
+ /* Reapply default colour pair, in case definition has changed */
+ ansicol_set_pair ( CPAIR_DEFAULT );
+
+ return 0;
+}
+
+/** "cpair" options */
+struct cpair_options {
+ /** Foreground colour */
+ unsigned int foreground;
+ /** Background colour */
+ unsigned int background;
+};
+
+/** "cpair" option list */
+static struct option_descriptor cpair_opts[] = {
+ OPTION_DESC ( "foreground", 'f', required_argument,
+ struct cpair_options, foreground, parse_integer ),
+ OPTION_DESC ( "background", 'b', required_argument,
+ struct cpair_options, background, parse_integer ),
+};
+
+/** "cpair" command descriptor */
+static struct command_descriptor cpair_cmd =
+ COMMAND_DESC ( struct cpair_options, cpair_opts, 1, 1, "<cpair>" );
+
+/**
+ * "cpair" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int cpair_exec ( int argc, char **argv ) {
+ struct cpair_options opts;
+ unsigned int cpair;
+ int rc;
+
+ /* Initialise options */
+ memset ( &opts, 0, sizeof ( opts ) );
+ opts.foreground = COLOUR_DEFAULT;
+ opts.background = COLOUR_DEFAULT;
+
+ /* Parse options */
+ if ( ( rc = reparse_options ( argc, argv, &cpair_cmd, &opts ) ) != 0 )
+ return rc;
+
+ /* Parse colour pair index */
+ if ( ( rc = parse_integer ( argv[optind], &cpair ) ) != 0 )
+ return rc;
+
+ /* Define colour pair */
+ if ( ( rc = ansicol_define_pair ( cpair, opts.foreground,
+ opts.background ) ) != 0 ) {
+ printf ( "Could not define colour pair: %s\n",
+ strerror ( rc ) );
+ return rc;
+ }
+
+ /* Reapply default colour pair, in case definition has changed */
+ ansicol_set_pair ( CPAIR_DEFAULT );
+
+ return 0;
+}
+
+/** Console management commands */
+struct command console_commands[] __command = {
+ {
+ .name = "console",
+ .exec = console_exec,
+ },
+ {
+ .name = "colour",
+ .exec = colour_exec,
+ },
+ {
+ .name = "cpair",
+ .exec = cpair_exec,
+ },
+};
diff --git a/qemu/roms/ipxe/src/hci/commands/dhcp_cmd.c b/qemu/roms/ipxe/src/hci/commands/dhcp_cmd.c
new file mode 100644
index 000000000..feeb55ee5
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/commands/dhcp_cmd.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stddef.h>
+#include <string.h>
+#include <assert.h>
+#include <getopt.h>
+#include <ipxe/netdevice.h>
+#include <ipxe/in.h>
+#include <ipxe/command.h>
+#include <ipxe/parseopt.h>
+#include <usr/dhcpmgmt.h>
+#include <hci/ifmgmt_cmd.h>
+
+/** @file
+ *
+ * DHCP management commands
+ *
+ */
+
+/** "pxebs" options */
+struct pxebs_options {};
+
+/** "pxebs" option list */
+static struct option_descriptor pxebs_opts[] = {};
+
+/** "pxebs" command descriptor */
+static struct command_descriptor pxebs_cmd =
+ COMMAND_DESC ( struct pxebs_options, pxebs_opts, 2, 2,
+ "<interface> <server type>" );
+
+/**
+ * The "pxebs" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int pxebs_exec ( int argc, char **argv ) {
+ struct pxebs_options opts;
+ struct net_device *netdev;
+ unsigned int pxe_type;
+ int rc;
+
+ /* Parse options */
+ if ( ( rc = parse_options ( argc, argv, &pxebs_cmd, &opts ) ) != 0 )
+ return rc;
+
+ /* Parse net device name */
+ if ( ( rc = parse_netdev ( argv[optind], &netdev ) ) != 0 )
+ return rc;
+
+ /* Parse boot server type */
+ if ( ( rc = parse_integer ( argv[ optind + 1 ], &pxe_type ) ) != 0 )
+ return rc;
+
+ /* Perform Boot Server Discovery */
+ if ( ( rc = pxebs ( netdev, pxe_type ) ) != 0 ) {
+ printf ( "Could not discover boot server on %s: %s\n",
+ netdev->name, strerror ( rc ) );
+ return rc;
+ }
+
+ return 0;
+}
+
+/** DHCP management commands */
+struct command dhcp_commands[] __command = {
+ {
+ .name = "dhcp",
+ .exec = ifconf_exec, /* synonym for "ifconf" */
+ },
+ {
+ .name = "pxebs",
+ .exec = pxebs_exec,
+ },
+};
diff --git a/qemu/roms/ipxe/src/hci/commands/digest_cmd.c b/qemu/roms/ipxe/src/hci/commands/digest_cmd.c
new file mode 100644
index 000000000..71308064f
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/commands/digest_cmd.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2009 Daniel Verkamp <daniel@drv.nu>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <ipxe/command.h>
+#include <ipxe/parseopt.h>
+#include <ipxe/image.h>
+#include <ipxe/crypto.h>
+#include <ipxe/md5.h>
+#include <ipxe/sha1.h>
+#include <usr/imgmgmt.h>
+
+/** @file
+ *
+ * Digest commands
+ *
+ */
+
+/** "digest" options */
+struct digest_options {};
+
+/** "digest" option list */
+static struct option_descriptor digest_opts[] = {};
+
+/** "digest" command descriptor */
+static struct command_descriptor digest_cmd =
+ COMMAND_DESC ( struct digest_options, digest_opts, 1, MAX_ARGUMENTS,
+ "<image> [<image>...]" );
+
+/**
+ * The "digest" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @v digest Digest algorithm
+ * @ret rc Return status code
+ */
+static int digest_exec ( int argc, char **argv,
+ struct digest_algorithm *digest ) {
+ struct digest_options opts;
+ struct image *image;
+ uint8_t digest_ctx[digest->ctxsize];
+ uint8_t digest_out[digest->digestsize];
+ uint8_t buf[128];
+ size_t offset;
+ size_t len;
+ size_t frag_len;
+ int i;
+ unsigned j;
+ int rc;
+
+ /* Parse options */
+ if ( ( rc = parse_options ( argc, argv, &digest_cmd, &opts ) ) != 0 )
+ return rc;
+
+ for ( i = optind ; i < argc ; i++ ) {
+
+ /* Acquire image */
+ if ( ( rc = imgacquire ( argv[i], 0, &image ) ) != 0 )
+ continue;
+ offset = 0;
+ len = image->len;
+
+ /* calculate digest */
+ digest_init ( digest, digest_ctx );
+ while ( len ) {
+ frag_len = len;
+ if ( frag_len > sizeof ( buf ) )
+ frag_len = sizeof ( buf );
+ copy_from_user ( buf, image->data, offset, frag_len );
+ digest_update ( digest, digest_ctx, buf, frag_len );
+ len -= frag_len;
+ offset += frag_len;
+ }
+ digest_final ( digest, digest_ctx, digest_out );
+
+ for ( j = 0 ; j < sizeof ( digest_out ) ; j++ )
+ printf ( "%02x", digest_out[j] );
+
+ printf ( " %s\n", image->name );
+ }
+
+ return 0;
+}
+
+static int md5sum_exec ( int argc, char **argv ) {
+ return digest_exec ( argc, argv, &md5_algorithm );
+}
+
+static int sha1sum_exec ( int argc, char **argv ) {
+ return digest_exec ( argc, argv, &sha1_algorithm );
+}
+
+struct command md5sum_command __command = {
+ .name = "md5sum",
+ .exec = md5sum_exec,
+};
+
+struct command sha1sum_command __command = {
+ .name = "sha1sum",
+ .exec = sha1sum_exec,
+};
diff --git a/qemu/roms/ipxe/src/hci/commands/fcmgmt_cmd.c b/qemu/roms/ipxe/src/hci/commands/fcmgmt_cmd.c
new file mode 100644
index 000000000..1c199b5dc
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/commands/fcmgmt_cmd.c
@@ -0,0 +1,215 @@
+/*
+ * 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.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <stdio.h>
+#include <errno.h>
+#include <getopt.h>
+#include <strings.h>
+#include <ipxe/fc.h>
+#include <ipxe/fcels.h>
+#include <ipxe/command.h>
+#include <ipxe/parseopt.h>
+#include <ipxe/tables.h>
+#include <usr/fcmgmt.h>
+
+/** @file
+ *
+ * Fibre Channel management commands
+ *
+ */
+
+/**
+ * Parse Fibre Channel port name
+ *
+ * @v text Text
+ * @ret port Fibre Channel port
+ * @ret rc Return status code
+ */
+static int parse_fc_port ( char *text, struct fc_port **port ) {
+
+ /* Sanity check */
+ assert ( text != NULL );
+
+ /* Find Fibre Channel port */
+ *port = fc_port_find ( text );
+ if ( ! *port ) {
+ printf ( "\"%s\": no such port\n", text );
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+/**
+ * Parse Fibre Channel port ID
+ *
+ * @v text Text
+ * @ret port_id Fibre Channel port ID
+ * @ret rc Return status code
+ */
+static int parse_fc_port_id ( char *text, struct fc_port_id *port_id ) {
+ int rc;
+
+ /* Sanity check */
+ assert ( text != NULL );
+
+ /* Parse port ID */
+ if ( ( rc = fc_id_aton ( text, port_id ) ) != 0 ) {
+ printf ( "\"%s\": invalid port ID\n", text );
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/**
+ * Parse Fibre Channel ELS handler name
+ *
+ * @v text Text
+ * @ret handler Fibre Channel ELS handler
+ * @ret rc Return status code
+ */
+static int parse_fc_els_handler ( char *text, struct fc_els_handler **handler ){
+
+ for_each_table_entry ( (*handler), FC_ELS_HANDLERS ) {
+ if ( strcasecmp ( (*handler)->name, text ) == 0 )
+ return 0;
+ }
+
+ printf ( "\"%s\": unrecognised ELS\n", text );
+ return -ENOENT;
+}
+
+/** "fcstat" options */
+struct fcstat_options {};
+
+/** "fcstat" option list */
+static struct option_descriptor fcstat_opts[] = {};
+
+/** "fcstat" command descriptor */
+static struct command_descriptor fcstat_cmd =
+ COMMAND_DESC ( struct fcstat_options, fcstat_opts, 0, 0, NULL );
+
+/**
+ * The "fcstat" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int fcstat_exec ( int argc, char **argv ) {
+ struct fcstat_options opts;
+ struct fc_port *port;
+ struct fc_peer *peer;
+ int rc;
+
+ /* Parse options */
+ if ( ( rc = parse_options ( argc, argv, &fcstat_cmd, &opts ) ) != 0 )
+ return rc;
+
+ list_for_each_entry ( port, &fc_ports, list )
+ fcportstat ( port );
+ list_for_each_entry ( peer, &fc_peers, list )
+ fcpeerstat ( peer );
+
+ return 0;
+}
+
+/** "fcels" options */
+struct fcels_options {
+ /** Fibre Channel port */
+ struct fc_port *port;
+ /** Fibre Channel peer port ID */
+ struct fc_port_id peer_port_id;
+};
+
+/** "fcels" option list */
+static struct option_descriptor fcels_opts[] = {
+ OPTION_DESC ( "port", 'p', required_argument,
+ struct fcels_options, port, parse_fc_port ),
+ OPTION_DESC ( "id", 'i', required_argument,
+ struct fcels_options, peer_port_id, parse_fc_port_id ),
+};
+
+/** "fcels" command descriptor */
+static struct command_descriptor fcels_cmd =
+ COMMAND_DESC ( struct fcels_options, fcels_opts, 1, 1, "<request>" );
+
+/**
+ * The "fcels" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int fcels_exec ( int argc, char **argv ) {
+ struct fcels_options opts;
+ struct fc_els_handler *handler;
+ struct fc_port_id *id;
+ int rc;
+
+ /* Parse options */
+ if ( ( rc = parse_options ( argc, argv, &fcels_cmd, &opts ) ) != 0 )
+ return rc;
+
+ /* Parse ELS handler */
+ if ( ( rc = parse_fc_els_handler ( argv[optind], &handler ) ) != 0 )
+ return rc;
+
+ /* Use first port if no port specified */
+ if ( ! opts.port ) {
+ opts.port = list_first_entry ( &fc_ports, struct fc_port,
+ list );
+ if ( ! opts.port ) {
+ printf ( "No ports\n" );
+ return -ENODEV;
+ }
+ }
+
+ /* Use link peer port ID if no peer port ID specified */
+ id = &opts.peer_port_id;
+ if ( memcmp ( id, &fc_empty_port_id, sizeof ( *id ) ) == 0 ) {
+ if ( fc_link_ok ( &opts.port->link ) &&
+ ! ( opts.port->flags & FC_PORT_HAS_FABRIC ) ) {
+ id = &opts.port->ptp_link_port_id;
+ } else {
+ id = &fc_f_port_id;
+ }
+ }
+
+ /** Issue ELS */
+ if ( ( rc = fcels ( opts.port, id, handler ) ) != 0 )
+ return rc;
+
+ return 0;
+}
+
+/** Fibre Channel management commands */
+struct command fcmgmt_commands[] __command = {
+ {
+ .name = "fcstat",
+ .exec = fcstat_exec,
+ },
+ {
+ .name = "fcels",
+ .exec = fcels_exec,
+ },
+};
diff --git a/qemu/roms/ipxe/src/hci/commands/gdbstub_cmd.c b/qemu/roms/ipxe/src/hci/commands/gdbstub_cmd.c
new file mode 100644
index 000000000..33890aebc
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/commands/gdbstub_cmd.c
@@ -0,0 +1,111 @@
+/*
+ * 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.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <stdio.h>
+#include <errno.h>
+#include <assert.h>
+#include <getopt.h>
+#include <ipxe/command.h>
+#include <ipxe/parseopt.h>
+#include <ipxe/gdbstub.h>
+
+/** @file
+ *
+ * GDB stub command
+ *
+ */
+
+/**
+ * Parse GDB transport name
+ *
+ * @v text Text
+ * @ret trans GDB transport
+ * @ret rc Return status code
+ */
+static int parse_gdb_transport ( const char *text,
+ struct gdb_transport **trans ) {
+
+ /* Sanity check */
+ assert ( text != NULL );
+
+ /* Find transport */
+ *trans = find_gdb_transport ( text );
+ if ( ! *trans ) {
+ printf ( "\"%s\": no such transport (is it compiled in?)\n",
+ text );
+ return -ENOTSUP;
+ }
+
+ return 0;
+}
+
+/** "gdbstub" options */
+struct gdbstub_options {};
+
+/** "gdbstub" option list */
+static struct option_descriptor gdbstub_opts[] = {};
+
+/** "gdbstub" command descriptor */
+static struct command_descriptor gdbstub_cmd =
+ COMMAND_DESC ( struct gdbstub_options, gdbstub_opts, 1, MAX_ARGUMENTS,
+ "<transport> [<options>...]" );
+
+/**
+ * The "gdbstub" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int gdbstub_exec ( int argc, char **argv ) {
+ struct gdbstub_options opts;
+ struct gdb_transport *trans;
+ int rc;
+
+ /* Parse options */
+ if ( ( rc = parse_options ( argc, argv, &gdbstub_cmd, &opts ) ) != 0 )
+ return rc;
+
+ /* Parse transport name */
+ if ( ( rc = parse_gdb_transport ( argv[optind++], &trans ) ) != 0 )
+ return rc;
+
+ /* Initialise transport */
+ if ( trans->init ) {
+ if ( ( rc = trans->init ( argc - optind,
+ &argv[optind] ) ) != 0 ) {
+ return rc;
+ }
+ }
+
+ /* Enter GDB stub */
+ gdbstub_start ( trans );
+
+ return 0;
+}
+
+/** GDB stub commands */
+struct command gdbstub_commands[] __command = {
+ {
+ .name = "gdbstub",
+ .exec = gdbstub_exec,
+ },
+};
diff --git a/qemu/roms/ipxe/src/hci/commands/ifmgmt_cmd.c b/qemu/roms/ipxe/src/hci/commands/ifmgmt_cmd.c
new file mode 100644
index 000000000..5307c9423
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/commands/ifmgmt_cmd.c
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <stdio.h>
+#include <errno.h>
+#include <getopt.h>
+#include <ipxe/netdevice.h>
+#include <ipxe/command.h>
+#include <ipxe/parseopt.h>
+#include <usr/ifmgmt.h>
+#include <hci/ifmgmt_cmd.h>
+
+/** @file
+ *
+ * Network interface management commands
+ *
+ */
+
+/**
+ * Execute if<xxx> command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @v cmd Command descriptor
+ * @v payload Command to execute
+ * @v verb Verb describing the action of the command
+ * @ret rc Return status code
+ */
+int ifcommon_exec ( int argc, char **argv,
+ struct ifcommon_command_descriptor *ifcmd ) {
+ struct command_descriptor *cmd = &ifcmd->cmd;
+ uint8_t opts[cmd->len];
+ struct net_device *netdev;
+ int i;
+ int rc;
+
+ /* Parse options */
+ if ( ( rc = parse_options ( argc, argv, cmd, opts ) ) != 0 )
+ return rc;
+
+ if ( optind != argc ) {
+ /* Treat arguments as a list of interfaces to try */
+ for ( i = optind ; i < argc ; i++ ) {
+ if ( ( rc = parse_netdev ( argv[i], &netdev ) ) != 0 )
+ continue;
+ if ( ( ( rc = ifcmd->payload ( netdev, opts ) ) == 0 )
+ && ifcmd->stop_on_first_success ) {
+ return 0;
+ }
+ }
+ } else {
+ /* Try all interfaces */
+ rc = -ENODEV;
+ for_each_netdev ( netdev ) {
+ if ( ( ( rc = ifcmd->payload ( netdev, opts ) ) == 0 )
+ && ifcmd->stop_on_first_success ) {
+ return 0;
+ }
+ }
+ }
+
+ return rc;
+}
+
+/** "ifopen" options */
+struct ifopen_options {};
+
+/** "ifopen" option list */
+static struct option_descriptor ifopen_opts[] = {};
+
+/**
+ * "ifopen" payload
+ *
+ * @v netdev Network device
+ * @v opts Command options
+ * @ret rc Return status code
+ */
+static int ifopen_payload ( struct net_device *netdev,
+ struct ifopen_options *opts __unused ) {
+ return ifopen ( netdev );
+}
+
+/** "ifopen" command descriptor */
+static struct ifcommon_command_descriptor ifopen_cmd =
+ IFCOMMON_COMMAND_DESC ( struct ifopen_options, ifopen_opts,
+ 0, MAX_ARGUMENTS, "[<interface>...]",
+ ifopen_payload, 0 );
+
+/**
+ * The "ifopen" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int ifopen_exec ( int argc, char **argv ) {
+ return ifcommon_exec ( argc, argv, &ifopen_cmd );
+}
+
+/** "ifclose" options */
+struct ifclose_options {};
+
+/** "ifclose" option list */
+static struct option_descriptor ifclose_opts[] = {};
+
+/**
+ * "ifclose" payload
+ *
+ * @v netdev Network device
+ * @v opts Command options
+ * @ret rc Return status code
+ */
+static int ifclose_payload ( struct net_device *netdev,
+ struct ifclose_options *opts __unused ) {
+ ifclose ( netdev );
+ return 0;
+}
+
+/** "ifclose" command descriptor */
+static struct ifcommon_command_descriptor ifclose_cmd =
+ IFCOMMON_COMMAND_DESC ( struct ifclose_options, ifclose_opts,
+ 0, MAX_ARGUMENTS, "[<interface>...]",
+ ifclose_payload, 0 );
+
+/**
+ * The "ifclose" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int ifclose_exec ( int argc, char **argv ) {
+ return ifcommon_exec ( argc, argv, &ifclose_cmd );
+}
+
+/** "ifstat" options */
+struct ifstat_options {};
+
+/** "ifstat" option list */
+static struct option_descriptor ifstat_opts[] = {};
+
+/**
+ * "ifstat" payload
+ *
+ * @v netdev Network device
+ * @v opts Command options
+ * @ret rc Return status code
+ */
+static int ifstat_payload ( struct net_device *netdev,
+ struct ifstat_options *opts __unused ) {
+ ifstat ( netdev );
+ return 0;
+}
+
+/** "ifstat" command descriptor */
+static struct ifcommon_command_descriptor ifstat_cmd =
+ IFCOMMON_COMMAND_DESC ( struct ifstat_options, ifstat_opts,
+ 0, MAX_ARGUMENTS, "[<interface>...]",
+ ifstat_payload, 0 );
+
+/**
+ * The "ifstat" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int ifstat_exec ( int argc, char **argv ) {
+ return ifcommon_exec ( argc, argv, &ifstat_cmd );
+}
+
+/** "ifconf" options */
+struct ifconf_options {
+ /** Configurator */
+ struct net_device_configurator *configurator;
+};
+
+/** "ifconf" option list */
+static struct option_descriptor ifconf_opts[] = {
+ OPTION_DESC ( "configurator", 'c', required_argument,
+ struct ifconf_options, configurator,
+ parse_netdev_configurator ),
+};
+
+/**
+ * "ifconf" payload
+ *
+ * @v netdev Network device
+ * @v opts Command options
+ * @ret rc Return status code
+ */
+static int ifconf_payload ( struct net_device *netdev,
+ struct ifconf_options *opts ) {
+ int rc;
+
+ /* Attempt configuration */
+ if ( ( rc = ifconf ( netdev, opts->configurator ) ) != 0 ) {
+
+ /* Close device on failure, to avoid memory exhaustion */
+ netdev_close ( netdev );
+
+ return rc;
+ }
+
+ return 0;
+}
+
+/** "ifconf" command descriptor */
+static struct ifcommon_command_descriptor ifconf_cmd =
+ IFCOMMON_COMMAND_DESC ( struct ifconf_options, ifconf_opts,
+ 0, MAX_ARGUMENTS, "[<interface>...]",
+ ifconf_payload, 1 );
+
+/**
+ * The "ifconf" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+int ifconf_exec ( int argc, char **argv ) {
+ return ifcommon_exec ( argc, argv, &ifconf_cmd );
+}
+
+/** Interface management commands */
+struct command ifmgmt_commands[] __command = {
+ {
+ .name = "ifopen",
+ .exec = ifopen_exec,
+ },
+ {
+ .name = "ifclose",
+ .exec = ifclose_exec,
+ },
+ {
+ .name = "ifstat",
+ .exec = ifstat_exec,
+ },
+ {
+ .name = "ifconf",
+ .exec = ifconf_exec,
+ },
+};
diff --git a/qemu/roms/ipxe/src/hci/commands/image_cmd.c b/qemu/roms/ipxe/src/hci/commands/image_cmd.c
new file mode 100644
index 000000000..a9e831bf5
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/commands/image_cmd.c
@@ -0,0 +1,441 @@
+/*
+ * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <getopt.h>
+#include <ipxe/image.h>
+#include <ipxe/command.h>
+#include <ipxe/parseopt.h>
+#include <ipxe/shell.h>
+#include <usr/imgmgmt.h>
+
+/** @file
+ *
+ * Image management commands
+ *
+ */
+
+/** "img{single}" options */
+struct imgsingle_options {
+ /** Image name */
+ char *name;
+ /** Download timeout */
+ unsigned long timeout;
+ /** Replace image */
+ int replace;
+ /** Free image after execution */
+ int autofree;
+};
+
+/** "img{single}" option list */
+static union {
+ /* "imgexec" takes all three options */
+ struct option_descriptor imgexec[4];
+ /* Other "img{single}" commands take only --name, --timeout,
+ * and --autofree
+ */
+ struct option_descriptor imgsingle[3];
+} opts = {
+ .imgexec = {
+ OPTION_DESC ( "name", 'n', required_argument,
+ struct imgsingle_options, name, parse_string ),
+ OPTION_DESC ( "timeout", 't', required_argument,
+ struct imgsingle_options, timeout, parse_timeout),
+ OPTION_DESC ( "autofree", 'a', no_argument,
+ struct imgsingle_options, autofree, parse_flag ),
+ OPTION_DESC ( "replace", 'r', no_argument,
+ struct imgsingle_options, replace, parse_flag ),
+ },
+};
+
+/** An "img{single}" family command descriptor */
+struct imgsingle_descriptor {
+ /** Command descriptor */
+ struct command_descriptor *cmd;
+ /** Function to use to acquire the image */
+ int ( * acquire ) ( const char *name, unsigned long timeout,
+ struct image **image );
+ /** Pre-action to take upon image, or NULL */
+ void ( * preaction ) ( struct image *image );
+ /** Action to take upon image, or NULL */
+ int ( * action ) ( struct image *image,
+ struct imgsingle_options *opts );
+ /** Verb to describe action */
+ const char *verb;
+};
+
+/**
+ * The "img{single}" family of commands
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @v desc "img{single}" command descriptor
+ * @v action_name Action name (for error messages)
+ * @v action Action to take upon image
+ * @ret rc Return status code
+ */
+static int imgsingle_exec ( int argc, char **argv,
+ struct imgsingle_descriptor *desc ) {
+ struct imgsingle_options opts;
+ char *name_uri = NULL;
+ char *cmdline = NULL;
+ struct image *image;
+ int rc;
+
+ /* Parse options */
+ if ( ( rc = parse_options ( argc, argv, desc->cmd, &opts ) ) != 0 )
+ goto err_parse_options;
+
+ /* Parse name/URI string and command line, if present */
+ if ( optind < argc ) {
+ name_uri = argv[optind];
+ if ( argv[ optind + 1 ] != NULL ) {
+ cmdline = concat_args ( &argv[ optind + 1 ] );
+ if ( ! cmdline ) {
+ rc = -ENOMEM;
+ goto err_parse_cmdline;
+ }
+ }
+ }
+
+ /* Acquire the image */
+ if ( name_uri ) {
+ if ( ( rc = desc->acquire ( name_uri, opts.timeout,
+ &image ) ) != 0 )
+ goto err_acquire;
+ } else {
+ image = image_find_selected();
+ if ( ! image ) {
+ printf ( "No image selected\n" );
+ goto err_acquire;
+ }
+ }
+
+ /* Carry out command pre-action, if applicable */
+ if ( desc->preaction )
+ desc->preaction ( image );
+
+ /* Set the image name, if applicable */
+ if ( opts.name ) {
+ if ( ( rc = image_set_name ( image, opts.name ) ) != 0 ) {
+ printf ( "Could not name image: %s\n",
+ strerror ( rc ) );
+ goto err_set_name;
+ }
+ }
+
+ /* Set the command-line arguments, if applicable */
+ if ( cmdline ) {
+ if ( ( rc = image_set_cmdline ( image, cmdline ) ) != 0 ) {
+ printf ( "Could not set arguments: %s\n",
+ strerror ( rc ) );
+ goto err_set_cmdline;
+ }
+ }
+
+ /* Set the auto-unregister flag, if applicable */
+ if ( opts.autofree )
+ image->flags |= IMAGE_AUTO_UNREGISTER;
+
+ /* Carry out command action, if applicable */
+ if ( desc->action ) {
+ if ( ( rc = desc->action ( image, &opts ) ) != 0 ) {
+ printf ( "Could not %s: %s\n",
+ desc->verb, strerror ( rc ) );
+ goto err_action;
+ }
+ }
+
+ /* Success */
+ rc = 0;
+
+ err_action:
+ err_set_cmdline:
+ err_set_name:
+ err_acquire:
+ free ( cmdline );
+ err_parse_cmdline:
+ err_parse_options:
+ return rc;
+}
+
+/** "imgfetch" command descriptor */
+static struct command_descriptor imgfetch_cmd =
+ COMMAND_DESC ( struct imgsingle_options, opts.imgsingle,
+ 1, MAX_ARGUMENTS, "<uri> [<arguments>...]" );
+
+/** "imgfetch" family command descriptor */
+struct imgsingle_descriptor imgfetch_desc = {
+ .cmd = &imgfetch_cmd,
+ .acquire = imgdownload_string,
+};
+
+/**
+ * The "imgfetch" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int imgfetch_exec ( int argc, char **argv ) {
+ return imgsingle_exec ( argc, argv, &imgfetch_desc );
+}
+
+/**
+ * "imgselect" command action
+ *
+ * @v image Image
+ * @v opts Options
+ * @ret rc Return status code
+ */
+static int imgselect ( struct image *image,
+ struct imgsingle_options *opts __unused ) {
+ return image_select ( image );
+}
+
+/** "imgselect" command descriptor */
+static struct command_descriptor imgselect_cmd =
+ COMMAND_DESC ( struct imgsingle_options, opts.imgsingle,
+ 1, MAX_ARGUMENTS, "<uri|image> [<arguments>...]" );
+
+/** "imgselect" family command descriptor */
+struct imgsingle_descriptor imgselect_desc = {
+ .cmd = &imgselect_cmd,
+ .acquire = imgacquire,
+ .action = imgselect,
+ .verb = "select",
+};
+
+/**
+ * The "imgselect" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int imgselect_exec ( int argc, char **argv ) {
+ return imgsingle_exec ( argc, argv, &imgselect_desc );
+}
+
+/** "imgexec" command descriptor */
+static struct command_descriptor imgexec_cmd =
+ COMMAND_DESC ( struct imgsingle_options, opts.imgexec,
+ 0, MAX_ARGUMENTS, "[<uri|image> [<arguments>...]]" );
+
+/**
+ * "imgexec" command action
+ *
+ * @v image Image
+ * @v opts Options
+ * @ret rc Return status code
+ */
+static int imgexec ( struct image *image, struct imgsingle_options *opts ) {
+ int rc;
+
+ /* Perform replacement or execution as applicable */
+ if ( opts->replace ) {
+
+ /* Try to replace image */
+ if ( ( rc = image_replace ( image ) ) != 0 )
+ return rc;
+
+ /* Stop script and tail-recurse into replacement image */
+ shell_stop ( SHELL_STOP_COMMAND_SEQUENCE );
+
+ } else {
+
+ /* Try to execute image */
+ if ( ( rc = image_exec ( image ) ) != 0 )
+ return rc;
+ }
+
+ return 0;
+}
+
+/** "imgexec" family command descriptor */
+struct imgsingle_descriptor imgexec_desc = {
+ .cmd = &imgexec_cmd,
+ .acquire = imgacquire,
+ .action = imgexec,
+ .verb = "boot",
+};
+
+/**
+ * The "imgexec" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int imgexec_exec ( int argc, char **argv) {
+ return imgsingle_exec ( argc, argv, &imgexec_desc );
+}
+
+/** "imgargs" command descriptor */
+static struct command_descriptor imgargs_cmd =
+ COMMAND_DESC ( struct imgsingle_options, opts.imgsingle,
+ 1, MAX_ARGUMENTS, "<uri|image> [<arguments>...]" );
+
+/** "imgargs" family command descriptor */
+struct imgsingle_descriptor imgargs_desc = {
+ .cmd = &imgargs_cmd,
+ .acquire = imgacquire,
+ .preaction = image_clear_cmdline,
+};
+
+/**
+ * The "imgargs" command body
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int imgargs_exec ( int argc, char **argv ) {
+ return imgsingle_exec ( argc, argv, &imgargs_desc );
+}
+
+/** "img{multi}" options */
+struct imgmulti_options {};
+
+/** "img{multi}" option list */
+static struct option_descriptor imgmulti_opts[] = {};
+
+/** "img{multi}" command descriptor */
+static struct command_descriptor imgmulti_cmd =
+ COMMAND_DESC ( struct imgmulti_options, imgmulti_opts, 0, MAX_ARGUMENTS,
+ "[<image>...]" );
+
+/**
+ * The "img{multi}" family of commands
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @v payload Function to execute on each image
+ * @ret rc Return status code
+ */
+static int imgmulti_exec ( int argc, char **argv,
+ void ( * payload ) ( struct image *image ) ) {
+ struct imgmulti_options opts;
+ struct image *image;
+ struct image *tmp;
+ int i;
+ int rc;
+
+ /* Parse options */
+ if ( ( rc = parse_options ( argc, argv, &imgmulti_cmd, &opts ) ) != 0 )
+ return rc;
+
+ /* If no images are explicitly specified, process all images */
+ if ( optind == argc ) {
+ for_each_image_safe ( image, tmp )
+ payload ( image );
+ return 0;
+ }
+
+ /* Otherwise, process specified images */
+ for ( i = optind ; i < argc ; i++ ) {
+ image = find_image ( argv[i] );
+ if ( ! image ) {
+ printf ( "\"%s\": no such image\n", argv[i] );
+ return -ENOENT;
+ }
+ payload ( image );
+ }
+
+ return 0;
+}
+
+/**
+ * The "imgstat" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int imgstat_exec ( int argc, char **argv ) {
+ return imgmulti_exec ( argc, argv, imgstat );
+}
+
+/**
+ * The "imgfree" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int imgfree_exec ( int argc, char **argv ) {
+ return imgmulti_exec ( argc, argv, unregister_image );
+}
+
+/** Image management commands */
+struct command image_commands[] __command = {
+ {
+ .name = "imgfetch",
+ .exec = imgfetch_exec,
+ },
+ {
+ .name = "module",
+ .exec = imgfetch_exec, /* synonym for "imgfetch" */
+ },
+ {
+ .name = "initrd",
+ .exec = imgfetch_exec, /* synonym for "imgfetch" */
+ },
+ {
+ .name = "kernel",
+ .exec = imgselect_exec, /* synonym for "imgselect" */
+ },
+ {
+ .name = "chain",
+ .exec = imgexec_exec, /* synonym for "imgexec" */
+ },
+ {
+ .name = "imgselect",
+ .exec = imgselect_exec,
+ },
+ {
+ .name = "imgload",
+ .exec = imgselect_exec, /* synonym for "imgselect" */
+ },
+ {
+ .name = "imgargs",
+ .exec = imgargs_exec,
+ },
+ {
+ .name = "imgexec",
+ .exec = imgexec_exec,
+ },
+ {
+ .name = "boot", /* synonym for "imgexec" */
+ .exec = imgexec_exec,
+ },
+ {
+ .name = "imgstat",
+ .exec = imgstat_exec,
+ },
+ {
+ .name = "imgfree",
+ .exec = imgfree_exec,
+ },
+};
diff --git a/qemu/roms/ipxe/src/hci/commands/image_trust_cmd.c b/qemu/roms/ipxe/src/hci/commands/image_trust_cmd.c
new file mode 100644
index 000000000..ca59a858a
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/commands/image_trust_cmd.c
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <stdint.h>
+#include <stdio.h>
+#include <getopt.h>
+#include <ipxe/image.h>
+#include <ipxe/command.h>
+#include <ipxe/parseopt.h>
+#include <usr/imgmgmt.h>
+#include <usr/imgtrust.h>
+
+/** @file
+ *
+ * Image trust management commands
+ *
+ */
+
+/** "imgtrust" options */
+struct imgtrust_options {
+ /** Allow trusted images */
+ int allow;
+ /** Make trust requirement permanent */
+ int permanent;
+};
+
+/** "imgtrust" option list */
+static struct option_descriptor imgtrust_opts[] = {
+ OPTION_DESC ( "allow", 'a', no_argument,
+ struct imgtrust_options, allow, parse_flag ),
+ OPTION_DESC ( "permanent", 'p', no_argument,
+ struct imgtrust_options, permanent, parse_flag ),
+};
+
+/** "imgtrust" command descriptor */
+static struct command_descriptor imgtrust_cmd =
+ COMMAND_DESC ( struct imgtrust_options, imgtrust_opts, 0, 0, NULL );
+
+/**
+ * The "imgtrust" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int imgtrust_exec ( int argc, char **argv ) {
+ struct imgtrust_options opts;
+ int rc;
+
+ /* Parse options */
+ if ( ( rc = parse_options ( argc, argv, &imgtrust_cmd, &opts ) ) != 0 )
+ return rc;
+
+ /* Set trust requirement */
+ if ( ( rc = image_set_trust ( ( ! opts.allow ),
+ opts.permanent ) ) != 0 ) {
+ printf ( "Could not set image trust requirement: %s\n",
+ strerror ( rc ) );
+ return rc;
+ }
+
+ return 0;
+}
+
+/** "imgverify" options */
+struct imgverify_options {
+ /** Required signer common name */
+ char *signer;
+ /** Keep signature after verification */
+ int keep;
+ /** Download timeout */
+ unsigned long timeout;
+};
+
+/** "imgverify" option list */
+static struct option_descriptor imgverify_opts[] = {
+ OPTION_DESC ( "signer", 's', required_argument,
+ struct imgverify_options, signer, parse_string ),
+ OPTION_DESC ( "keep", 'k', no_argument,
+ struct imgverify_options, keep, parse_flag ),
+ OPTION_DESC ( "timeout", 't', required_argument,
+ struct imgverify_options, timeout, parse_timeout),
+};
+
+/** "imgverify" command descriptor */
+static struct command_descriptor imgverify_cmd =
+ COMMAND_DESC ( struct imgverify_options, imgverify_opts, 2, 2,
+ "<uri|image> <signature uri|image>" );
+
+/**
+ * The "imgverify" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int imgverify_exec ( int argc, char **argv ) {
+ struct imgverify_options opts;
+ const char *image_name_uri;
+ const char *signature_name_uri;
+ struct image *image;
+ struct image *signature;
+ int rc;
+
+ /* Parse options */
+ if ( ( rc = parse_options ( argc, argv, &imgverify_cmd, &opts ) ) != 0 )
+ return rc;
+
+ /* Parse image name/URI string */
+ image_name_uri = argv[optind];
+
+ /* Parse signature name/URI string */
+ signature_name_uri = argv[ optind + 1 ];
+
+ /* Acquire the image */
+ if ( ( rc = imgacquire ( image_name_uri, opts.timeout, &image ) ) != 0 )
+ goto err_acquire_image;
+
+ /* Acquire the signature image */
+ if ( ( rc = imgacquire ( signature_name_uri, opts.timeout,
+ &signature ) ) != 0 )
+ goto err_acquire_signature;
+
+ /* Verify image */
+ if ( ( rc = imgverify ( image, signature, opts.signer ) ) != 0 ) {
+ printf ( "Could not verify: %s\n", strerror ( rc ) );
+ goto err_verify;
+ }
+
+ /* Success */
+ rc = 0;
+
+ err_verify:
+ /* Discard signature unless --keep was specified */
+ if ( ! opts.keep )
+ unregister_image ( signature );
+ err_acquire_signature:
+ err_acquire_image:
+ return rc;
+}
+
+/** Image trust management commands */
+struct command image_trust_commands[] __command = {
+ {
+ .name = "imgtrust",
+ .exec = imgtrust_exec,
+ },
+ {
+ .name = "imgverify",
+ .exec = imgverify_exec,
+ },
+};
+
+/* Drag in objects typically required for signature verification */
+REQUIRE_OBJECT ( rsa );
+REQUIRE_OBJECT ( md5 );
+REQUIRE_OBJECT ( sha1 );
+REQUIRE_OBJECT ( sha256 );
diff --git a/qemu/roms/ipxe/src/hci/commands/ipstat_cmd.c b/qemu/roms/ipxe/src/hci/commands/ipstat_cmd.c
new file mode 100644
index 000000000..d565dc0ae
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/commands/ipstat_cmd.c
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <stdio.h>
+#include <getopt.h>
+#include <ipxe/command.h>
+#include <ipxe/parseopt.h>
+#include <usr/ipstat.h>
+
+/** @file
+ *
+ * IP statistics commands
+ *
+ */
+
+/** "ipstat" options */
+struct ipstat_options {};
+
+/** "ipstat" option list */
+static struct option_descriptor ipstat_opts[] = {};
+
+/** "ipstat" command descriptor */
+static struct command_descriptor ipstat_cmd =
+ COMMAND_DESC ( struct ipstat_options, ipstat_opts, 0, 0, NULL );
+
+/**
+ * The "ipstat" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int ipstat_exec ( int argc, char **argv ) {
+ struct ipstat_options opts;
+ int rc;
+
+ /* Parse options */
+ if ( ( rc = parse_options ( argc, argv, &ipstat_cmd, &opts ) ) != 0 )
+ return rc;
+
+ ipstat();
+
+ return 0;
+}
+
+/** Routing table management commands */
+struct command ipstat_commands[] __command = {
+ {
+ .name = "ipstat",
+ .exec = ipstat_exec,
+ },
+};
diff --git a/qemu/roms/ipxe/src/hci/commands/iwmgmt_cmd.c b/qemu/roms/ipxe/src/hci/commands/iwmgmt_cmd.c
new file mode 100644
index 000000000..b61ee8c7b
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/commands/iwmgmt_cmd.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2009 Joshua Oreman <oremanj@rwcr.net>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <ipxe/netdevice.h>
+#include <ipxe/net80211.h>
+#include <ipxe/command.h>
+#include <ipxe/parseopt.h>
+#include <usr/iwmgmt.h>
+#include <hci/ifmgmt_cmd.h>
+
+/** @file
+ *
+ * Wireless interface management commands
+ *
+ */
+
+/** "iwstat" options */
+struct iwstat_options {};
+
+/** "iwstat" option list */
+static struct option_descriptor iwstat_opts[] = {};
+
+/**
+ * "iwstat" payload
+ *
+ * @v netdev Network device
+ * @v opts Command options
+ * @ret rc Return status code
+ */
+static int iwstat_payload ( struct net_device *netdev,
+ struct iwstat_options *opts __unused ) {
+ struct net80211_device *dev = net80211_get ( netdev );
+
+ if ( dev )
+ iwstat ( dev );
+
+ return 0;
+}
+
+/** "iwstat" command descriptor */
+static struct ifcommon_command_descriptor iwstat_cmd =
+ IFCOMMON_COMMAND_DESC ( struct iwstat_options, iwstat_opts,
+ 0, MAX_ARGUMENTS, "[<interface>...]",
+ iwstat_payload, 0 );
+
+/**
+ * The "iwstat" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int iwstat_exec ( int argc, char **argv ) {
+ return ifcommon_exec ( argc, argv, &iwstat_cmd );
+}
+
+/** "iwlist" options */
+struct iwlist_options {};
+
+/** "iwlist" option list */
+static struct option_descriptor iwlist_opts[] = {};
+
+/**
+ * "iwlist" payload
+ *
+ * @v netdev Network device
+ * @v opts Command options
+ * @ret rc Return status code
+ */
+static int iwlist_payload ( struct net_device *netdev,
+ struct iwlist_options *opts __unused ) {
+ struct net80211_device *dev = net80211_get ( netdev );
+
+ if ( dev )
+ return iwlist ( dev );
+
+ return 0;
+}
+
+/** "iwlist" command descriptor */
+static struct ifcommon_command_descriptor iwlist_cmd =
+ IFCOMMON_COMMAND_DESC ( struct iwlist_options, iwlist_opts,
+ 0, MAX_ARGUMENTS, "[<interface>...]",
+ iwlist_payload, 0 );
+
+/**
+ * The "iwlist" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int iwlist_exec ( int argc, char **argv ) {
+ return ifcommon_exec ( argc, argv, &iwlist_cmd );
+}
+
+/** Wireless interface management commands */
+struct command iwmgmt_commands[] __command = {
+ {
+ .name = "iwstat",
+ .exec = iwstat_exec,
+ },
+ {
+ .name = "iwlist",
+ .exec = iwlist_exec,
+ },
+};
diff --git a/qemu/roms/ipxe/src/hci/commands/login_cmd.c b/qemu/roms/ipxe/src/hci/commands/login_cmd.c
new file mode 100644
index 000000000..f5db427d5
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/commands/login_cmd.c
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <ipxe/command.h>
+#include <ipxe/parseopt.h>
+#include <ipxe/login_ui.h>
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+/** @file
+ *
+ * Login commands
+ *
+ */
+
+/** "login" options */
+struct login_options {};
+
+/** "login" option list */
+static struct option_descriptor login_opts[] = {};
+
+/** "login" command descriptor */
+static struct command_descriptor login_cmd =
+ COMMAND_DESC ( struct login_options, login_opts, 0, 0, NULL );
+
+/**
+ * "login" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int login_exec ( int argc, char **argv ) {
+ struct login_options opts;
+ int rc;
+
+ /* Parse options */
+ if ( ( rc = parse_options ( argc, argv, &login_cmd, &opts ) ) != 0 )
+ return rc;
+
+ /* Show login UI */
+ if ( ( rc = login_ui() ) != 0 ) {
+ printf ( "Could not set credentials: %s\n",
+ strerror ( rc ) );
+ return rc;
+ }
+
+ return 0;
+}
+
+/** Login commands */
+struct command login_command __command = {
+ .name = "login",
+ .exec = login_exec,
+};
diff --git a/qemu/roms/ipxe/src/hci/commands/lotest_cmd.c b/qemu/roms/ipxe/src/hci/commands/lotest_cmd.c
new file mode 100644
index 000000000..0fa031bcb
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/commands/lotest_cmd.c
@@ -0,0 +1,97 @@
+/*
+ * 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.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <ipxe/netdevice.h>
+#include <ipxe/command.h>
+#include <ipxe/parseopt.h>
+#include <ipxe/if_ether.h>
+#include <usr/lotest.h>
+
+/** @file
+ *
+ * Loopback testing commands
+ *
+ */
+
+/** "lotest" options */
+struct lotest_options {
+ /** MTU */
+ unsigned int mtu;
+};
+
+/** "lotest" option list */
+static struct option_descriptor lotest_opts[] = {
+ OPTION_DESC ( "mtu", 'm', required_argument,
+ struct lotest_options, mtu, parse_integer ),
+};
+
+/** "lotest" command descriptor */
+static struct command_descriptor lotest_cmd =
+ COMMAND_DESC ( struct lotest_options, lotest_opts, 2, 2,
+ "<sending interface> <receiving interface>" );
+
+/**
+ * "lotest" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int lotest_exec ( int argc, char **argv ) {
+ struct lotest_options opts;
+ struct net_device *sender;
+ struct net_device *receiver;
+ int rc;
+
+ /* Parse options */
+ if ( ( rc = parse_options ( argc, argv, &lotest_cmd, &opts ) ) != 0 )
+ return rc;
+
+ /* Parse sending interface name */
+ if ( ( rc = parse_netdev ( argv[optind], &sender ) ) != 0 )
+ return rc;
+
+ /* Parse receiving interface name */
+ if ( ( rc = parse_netdev ( argv[ optind + 1 ], &receiver ) ) != 0 )
+ return rc;
+
+ /* Use default MTU if none specified */
+ if ( ! opts.mtu )
+ opts.mtu = ETH_MAX_MTU;
+
+ /* Perform loopback test */
+ if ( ( rc = loopback_test ( sender, receiver, opts.mtu ) ) != 0 ) {
+ printf ( "Test failed: %s\n", strerror ( rc ) );
+ return rc;
+ }
+
+ return 0;
+}
+
+/** Loopback testing commands */
+struct command lotest_command __command = {
+ .name = "lotest",
+ .exec = lotest_exec,
+};
diff --git a/qemu/roms/ipxe/src/hci/commands/menu_cmd.c b/qemu/roms/ipxe/src/hci/commands/menu_cmd.c
new file mode 100644
index 000000000..66a6262e6
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/commands/menu_cmd.c
@@ -0,0 +1,290 @@
+/*
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+/** @file
+ *
+ * Menu commands
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <getopt.h>
+#include <ipxe/menu.h>
+#include <ipxe/command.h>
+#include <ipxe/parseopt.h>
+#include <ipxe/settings.h>
+#include <ipxe/features.h>
+
+FEATURE ( FEATURE_MISC, "Menu", DHCP_EB_FEATURE_MENU, 1 );
+
+/** "menu" options */
+struct menu_options {
+ /** Name */
+ char *name;
+ /** Delete */
+ int delete;
+};
+
+/** "menu" option list */
+static struct option_descriptor menu_opts[] = {
+ OPTION_DESC ( "name", 'n', required_argument,
+ struct menu_options, name, parse_string ),
+ OPTION_DESC ( "delete", 'd', no_argument,
+ struct menu_options, delete, parse_flag ),
+};
+
+/** "menu" command descriptor */
+static struct command_descriptor menu_cmd =
+ COMMAND_DESC ( struct menu_options, menu_opts, 0, MAX_ARGUMENTS,
+ "[<title>]" );
+
+/**
+ * The "menu" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int menu_exec ( int argc, char **argv ) {
+ struct menu_options opts;
+ struct menu *menu;
+ char *title;
+ int rc;
+
+ /* Parse options */
+ if ( ( rc = parse_options ( argc, argv, &menu_cmd, &opts ) ) != 0 )
+ goto err_parse_options;
+
+ /* Parse title */
+ title = concat_args ( &argv[optind] );
+ if ( ! title ) {
+ rc = -ENOMEM;
+ goto err_parse_title;
+ }
+
+ /* Create menu */
+ menu = create_menu ( opts.name, title );
+ if ( ! menu ) {
+ rc = -ENOMEM;
+ goto err_create_menu;
+ }
+
+ /* Destroy menu, if applicable */
+ if ( opts.delete )
+ destroy_menu ( menu );
+
+ /* Success */
+ rc = 0;
+
+ err_create_menu:
+ free ( title );
+ err_parse_title:
+ err_parse_options:
+ return rc;
+}
+
+/** "item" options */
+struct item_options {
+ /** Menu name */
+ char *menu;
+ /** Shortcut key */
+ unsigned int key;
+ /** Use as default */
+ int is_default;
+ /** Use as a separator */
+ int is_gap;
+};
+
+/** "item" option list */
+static struct option_descriptor item_opts[] = {
+ OPTION_DESC ( "menu", 'm', required_argument,
+ struct item_options, menu, parse_string ),
+ OPTION_DESC ( "key", 'k', required_argument,
+ struct item_options, key, parse_key ),
+ OPTION_DESC ( "default", 'd', no_argument,
+ struct item_options, is_default, parse_flag ),
+ OPTION_DESC ( "gap", 'g', no_argument,
+ struct item_options, is_gap, parse_flag ),
+};
+
+/** "item" command descriptor */
+static struct command_descriptor item_cmd =
+ COMMAND_DESC ( struct item_options, item_opts, 0, MAX_ARGUMENTS,
+ "[<label> [<text>]]" );
+
+/**
+ * The "item" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int item_exec ( int argc, char **argv ) {
+ struct item_options opts;
+ struct menu *menu;
+ struct menu_item *item;
+ char *label = NULL;
+ char *text = NULL;
+ int rc;
+
+ /* Parse options */
+ if ( ( rc = parse_options ( argc, argv, &item_cmd, &opts ) ) != 0 )
+ goto err_parse_options;
+
+ /* Parse label, if present */
+ if ( ! opts.is_gap )
+ label = argv[optind++]; /* May be NULL */
+
+ /* Parse text, if present */
+ if ( optind < argc ) {
+ text = concat_args ( &argv[optind] );
+ if ( ! text ) {
+ rc = -ENOMEM;
+ goto err_parse_text;
+ }
+ }
+
+ /* Identify menu */
+ if ( ( rc = parse_menu ( opts.menu, &menu ) ) != 0 )
+ goto err_parse_menu;
+
+ /* Add menu item */
+ item = add_menu_item ( menu, label, ( text ? text : "" ),
+ opts.key, opts.is_default );
+ if ( ! item ) {
+ rc = -ENOMEM;
+ goto err_add_menu_item;
+ }
+
+ /* Success */
+ rc = 0;
+
+ err_add_menu_item:
+ err_parse_menu:
+ free ( text );
+ err_parse_text:
+ err_parse_options:
+ return rc;
+}
+
+/** "choose" options */
+struct choose_options {
+ /** Menu name */
+ char *menu;
+ /** Timeout */
+ unsigned long timeout;
+ /** Default selection */
+ char *select;
+ /** Keep menu */
+ int keep;
+};
+
+/** "choose" option list */
+static struct option_descriptor choose_opts[] = {
+ OPTION_DESC ( "menu", 'm', required_argument,
+ struct choose_options, menu, parse_string ),
+ OPTION_DESC ( "default", 'd', required_argument,
+ struct choose_options, select, parse_string ),
+ OPTION_DESC ( "timeout", 't', required_argument,
+ struct choose_options, timeout, parse_timeout ),
+ OPTION_DESC ( "keep", 'k', no_argument,
+ struct choose_options, keep, parse_flag ),
+};
+
+/** "choose" command descriptor */
+static struct command_descriptor choose_cmd =
+ COMMAND_DESC ( struct choose_options, choose_opts, 1, 1, "<setting>" );
+
+/**
+ * The "choose" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int choose_exec ( int argc, char **argv ) {
+ struct choose_options opts;
+ struct named_setting setting;
+ struct menu *menu;
+ struct menu_item *item;
+ int rc;
+
+ /* Parse options */
+ if ( ( rc = parse_options ( argc, argv, &choose_cmd, &opts ) ) != 0 )
+ goto err_parse_options;
+
+ /* Parse setting name */
+ if ( ( rc = parse_autovivified_setting ( argv[optind],
+ &setting ) ) != 0 )
+ goto err_parse_setting;
+
+ /* Identify menu */
+ if ( ( rc = parse_menu ( opts.menu, &menu ) ) != 0 )
+ goto err_parse_menu;
+
+ /* Show menu */
+ if ( ( rc = show_menu ( menu, opts.timeout, opts.select, &item ) ) != 0)
+ goto err_show_menu;
+
+ /* Apply default type if necessary */
+ if ( ! setting.setting.type )
+ setting.setting.type = &setting_type_string;
+
+ /* Store setting */
+ if ( ( rc = storef_setting ( setting.settings, &setting.setting,
+ item->label ) ) != 0 ) {
+ printf ( "Could not store \"%s\": %s\n",
+ setting.setting.name, strerror ( rc ) );
+ goto err_store;
+ }
+
+ /* Success */
+ rc = 0;
+
+ err_store:
+ err_show_menu:
+ /* Destroy menu, if applicable */
+ if ( ! opts.keep )
+ destroy_menu ( menu );
+ err_parse_menu:
+ err_parse_setting:
+ err_parse_options:
+ return rc;
+}
+
+/** Menu commands */
+struct command menu_commands[] __command = {
+ {
+ .name = "menu",
+ .exec = menu_exec,
+ },
+ {
+ .name = "item",
+ .exec = item_exec,
+ },
+ {
+ .name = "choose",
+ .exec = choose_exec,
+ },
+};
diff --git a/qemu/roms/ipxe/src/hci/commands/neighbour_cmd.c b/qemu/roms/ipxe/src/hci/commands/neighbour_cmd.c
new file mode 100644
index 000000000..a1e052439
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/commands/neighbour_cmd.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2013 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+/** @file
+ *
+ * Neighbour management commands
+ *
+ */
+
+#include <getopt.h>
+#include <ipxe/parseopt.h>
+#include <ipxe/command.h>
+#include <usr/neighmgmt.h>
+
+/** "nstat" options */
+struct nstat_options {};
+
+/** "nstat" option list */
+static struct option_descriptor nstat_opts[] = {};
+
+/** "nstat" command descriptor */
+static struct command_descriptor nstat_cmd =
+ COMMAND_DESC ( struct nstat_options, nstat_opts, 0, 0, NULL );
+
+/**
+ * The "nstat" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int nstat_exec ( int argc, char **argv ) {
+ struct nstat_options opts;
+ int rc;
+
+ /* Parse options */
+ if ( ( rc = parse_options ( argc, argv, &nstat_cmd, &opts ) ) != 0)
+ return rc;
+
+ nstat();
+
+ return 0;
+}
+
+/** Neighbour management commands */
+struct command neighbour_commands[] __command = {
+ {
+ .name = "nstat",
+ .exec = nstat_exec,
+ },
+};
diff --git a/qemu/roms/ipxe/src/hci/commands/nslookup_cmd.c b/qemu/roms/ipxe/src/hci/commands/nslookup_cmd.c
new file mode 100644
index 000000000..265afdc3d
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/commands/nslookup_cmd.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2012 Patrick Plenefisch <phplenefisch@wpi.edu>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <stdio.h>
+#include <getopt.h>
+#include <ipxe/command.h>
+#include <ipxe/parseopt.h>
+#include <usr/nslookup.h>
+
+/** @file
+ *
+ * nslookup command
+ *
+ */
+
+/** "nslookup" options */
+struct nslookup_options {};
+
+/** "nslookup" option list */
+static struct option_descriptor nslookup_opts[] = {};
+
+/** "nslookup" command descriptor */
+static struct command_descriptor nslookup_cmd =
+ COMMAND_DESC ( struct nslookup_options, nslookup_opts, 2, 2,
+ "<setting> <name>" );
+
+/**
+ * The "nslookup" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int nslookup_exec ( int argc, char **argv ) {
+ struct nslookup_options opts;
+ const char *name;
+ const char *setting_name;
+ int rc;
+
+ /* Parse options */
+ if ( ( rc = parse_options ( argc, argv, &nslookup_cmd, &opts ) ) != 0 )
+ return rc;
+
+ /* Parse setting name */
+ setting_name = argv[optind];
+
+ /* Parse name to be resolved */
+ name = argv[ optind + 1 ];
+
+ /* Look up name */
+ if ( ( rc = nslookup ( name, setting_name ) ) != 0 )
+ return rc;
+
+ return 0;
+}
+
+/** The "nslookup" command */
+struct command nslookup_command __command = {
+ .name = "nslookup",
+ .exec = nslookup_exec,
+};
diff --git a/qemu/roms/ipxe/src/hci/commands/nvo_cmd.c b/qemu/roms/ipxe/src/hci/commands/nvo_cmd.c
new file mode 100644
index 000000000..e63dab08e
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/commands/nvo_cmd.c
@@ -0,0 +1,347 @@
+/*
+ * 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.
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <getopt.h>
+#include <byteswap.h>
+#include <ipxe/settings.h>
+#include <ipxe/command.h>
+#include <ipxe/parseopt.h>
+#include <readline/readline.h>
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+/** @file
+ *
+ * Non-volatile option commands
+ *
+ */
+
+/** "show" options */
+struct show_options {};
+
+/** "show" option list */
+static struct option_descriptor show_opts[] = {};
+
+/** "show" command descriptor */
+static struct command_descriptor show_cmd =
+ COMMAND_DESC ( struct show_options, show_opts, 1, 1, "<setting>" );
+
+/**
+ * "show" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int show_exec ( int argc, char **argv ) {
+ struct show_options opts;
+ struct named_setting setting;
+ struct settings *origin;
+ struct setting fetched;
+ char name_buf[32];
+ char *value;
+ int len;
+ int rc;
+
+ /* Parse options */
+ if ( ( rc = parse_options ( argc, argv, &show_cmd, &opts ) ) != 0 )
+ goto err_parse_options;
+
+ /* Parse setting name */
+ if ( ( rc = parse_existing_setting ( argv[optind], &setting ) ) != 0 )
+ goto err_parse_setting;
+
+ /* Fetch formatted setting value */
+ if ( ( len = fetchf_setting_copy ( setting.settings, &setting.setting,
+ &origin, &fetched, &value ) ) < 0 ) {
+ rc = len;
+ printf ( "Could not find \"%s\": %s\n",
+ setting.setting.name, strerror ( rc ) );
+ goto err_fetchf;
+ }
+
+ /* Print setting value */
+ setting_name ( origin, &fetched, name_buf, sizeof ( name_buf ) );
+ printf ( "%s = %s\n", name_buf, value );
+
+ /* Success */
+ rc = 0;
+
+ free ( value );
+ err_fetchf:
+ err_parse_setting:
+ err_parse_options:
+ return rc;
+}
+
+/** "set", "clear", and "read" options */
+struct set_core_options {};
+
+/** "set", "clear", and "read" option list */
+static struct option_descriptor set_core_opts[] = {};
+
+/** "set" command descriptor */
+static struct command_descriptor set_cmd =
+ COMMAND_DESC ( struct set_core_options, set_core_opts, 1, MAX_ARGUMENTS,
+ "<setting> <value>" );
+
+/** "clear" and "read" command descriptor */
+static struct command_descriptor clear_read_cmd =
+ COMMAND_DESC ( struct set_core_options, set_core_opts, 1, 1,
+ "<setting>" );
+
+/**
+ * "set", "clear", and "read" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @v cmd Command descriptor
+ * @v get_value Method to obtain setting value
+ * @ret rc Return status code
+ */
+static int set_core_exec ( int argc, char **argv,
+ struct command_descriptor *cmd,
+ int ( * get_value ) ( struct named_setting *setting,
+ char **args, char **value ) ) {
+ struct set_core_options opts;
+ struct named_setting setting;
+ char *value;
+ int rc;
+
+ /* Parse options */
+ if ( ( rc = parse_options ( argc, argv, cmd, &opts ) ) != 0 )
+ goto err_parse_options;
+
+ /* Parse setting name */
+ if ( ( rc = parse_autovivified_setting ( argv[optind],
+ &setting ) ) != 0 )
+ goto err_parse_setting;
+
+ /* Parse setting value */
+ if ( ( rc = get_value ( &setting, &argv[ optind + 1 ], &value ) ) != 0 )
+ goto err_get_value;
+
+ /* Apply default type if necessary */
+ if ( ! setting.setting.type )
+ setting.setting.type = &setting_type_string;
+
+ /* Store setting */
+ if ( ( rc = storef_setting ( setting.settings, &setting.setting,
+ value ) ) != 0 ) {
+ printf ( "Could not store \"%s\": %s\n",
+ setting.setting.name, strerror ( rc ) );
+ goto err_store;
+ }
+
+ err_store:
+ free ( value );
+ err_get_value:
+ err_parse_setting:
+ err_parse_options:
+ return rc;
+}
+
+/**
+ * Get setting value for "set" command
+ *
+ * @v setting Named setting
+ * @v args Remaining arguments
+ * @ret value Setting value
+ * @ret rc Return status code
+ */
+static int set_value ( struct named_setting *setting __unused,
+ char **args, char **value ) {
+
+ *value = concat_args ( args );
+ if ( ! *value )
+ return -ENOMEM;
+
+ return 0;
+}
+
+/**
+ * "set" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int set_exec ( int argc, char **argv ) {
+ return set_core_exec ( argc, argv, &set_cmd, set_value );
+}
+
+/**
+ * Get setting value for "clear" command
+ *
+ * @v setting Named setting
+ * @v args Remaining arguments
+ * @ret value Setting value
+ * @ret rc Return status code
+ */
+static int clear_value ( struct named_setting *setting __unused,
+ char **args __unused, char **value ) {
+
+ *value = NULL;
+ return 0;
+}
+
+/**
+ * "clear" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int clear_exec ( int argc, char **argv ) {
+ return set_core_exec ( argc, argv, &clear_read_cmd, clear_value );
+}
+
+/**
+ * Get setting value for "read" command
+ *
+ * @v setting Named setting
+ * @v args Remaining arguments
+ * @ret value Setting value
+ * @ret rc Return status code
+ */
+static int read_value ( struct named_setting *setting, char **args __unused,
+ char **value ) {
+ char *existing;
+ int rc;
+
+ /* Read existing value, treating errors as equivalent to an
+ * empty initial setting.
+ */
+ fetchf_setting_copy ( setting->settings, &setting->setting,
+ NULL, &setting->setting, &existing );
+
+ /* Read new value */
+ if ( ( rc = readline_history ( NULL, existing, NULL, value ) ) != 0 )
+ goto err_readline;
+
+ err_readline:
+ free ( existing );
+ return rc;
+}
+
+/**
+ * "read" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int read_exec ( int argc, char **argv ) {
+ return set_core_exec ( argc, argv, &clear_read_cmd, read_value );
+}
+
+/** "inc" options */
+struct inc_options {};
+
+/** "inc" option list */
+static struct option_descriptor inc_opts[] = {};
+
+/** "inc" command descriptor */
+static struct command_descriptor inc_cmd =
+ COMMAND_DESC ( struct inc_options, inc_opts, 1, 2,
+ "<setting> [<increment>]" );
+
+/**
+ * "inc" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int inc_exec ( int argc, char **argv ) {
+ struct inc_options opts;
+ struct named_setting setting;
+ unsigned int increment = 1;
+ unsigned long value;
+ int rc;
+
+ /* Parse options */
+ if ( ( rc = parse_options ( argc, argv, &inc_cmd, &opts ) ) != 0 )
+ goto err_parse_options;
+
+ /* Parse setting name */
+ if ( ( rc = parse_existing_setting ( argv[optind], &setting ) ) != 0 )
+ goto err_parse_setting;
+
+ /* Parse increment (if present) */
+ if ( ( ( optind + 1 ) < argc ) &&
+ ( ( rc = parse_integer ( argv[ optind + 1 ], &increment ) ) != 0))
+ goto err_parse_increment;
+
+ /* Read existing value, treating errors as equivalent to a
+ * zero-valued :int32 initial setting.
+ */
+ if ( ( rc = fetchn_setting ( setting.settings, &setting.setting,
+ NULL, &setting.setting, &value ) ) != 0 ) {
+ value = 0;
+ if ( ! setting.setting.type )
+ setting.setting.type = &setting_type_int32;
+ }
+
+ /* Increment value */
+ value += increment;
+
+ /* Store updated setting value */
+ if ( ( rc = storen_setting ( setting.settings, &setting.setting,
+ value ) ) != 0 ) {
+ printf ( "Could not store \"%s\": %s\n",
+ setting.setting.name, strerror ( rc ) );
+ goto err_store;
+ }
+
+ err_store:
+ err_parse_increment:
+ err_parse_setting:
+ err_parse_options:
+ return rc;
+}
+
+/** Non-volatile option commands */
+struct command nvo_commands[] __command = {
+ {
+ .name = "show",
+ .exec = show_exec,
+ },
+ {
+ .name = "set",
+ .exec = set_exec,
+ },
+ {
+ .name = "clear",
+ .exec = clear_exec,
+ },
+ {
+ .name = "read",
+ .exec = read_exec,
+ },
+ {
+ .name = "inc",
+ .exec = inc_exec,
+ },
+};
diff --git a/qemu/roms/ipxe/src/hci/commands/param_cmd.c b/qemu/roms/ipxe/src/hci/commands/param_cmd.c
new file mode 100644
index 000000000..6cf096d00
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/commands/param_cmd.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2013 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+/** @file
+ *
+ * Form parameter commands
+ *
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <getopt.h>
+#include <ipxe/params.h>
+#include <ipxe/parseopt.h>
+#include <ipxe/command.h>
+
+/** "params" options */
+struct params_options {
+ /** Name */
+ char *name;
+ /** Delete */
+ int delete;
+};
+
+/** "params" option list */
+static struct option_descriptor params_opts[] = {
+ OPTION_DESC ( "name", 'n', required_argument,
+ struct params_options, name, parse_string ),
+ OPTION_DESC ( "delete", 'd', no_argument,
+ struct params_options, delete, parse_flag ),
+};
+
+/** "params" command descriptor */
+static struct command_descriptor params_cmd =
+ COMMAND_DESC ( struct params_options, params_opts, 0, 0, NULL );
+
+/**
+ * The "params" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int params_exec ( int argc, char **argv ) {
+ struct params_options opts;
+ struct parameters *params;
+ int rc;
+
+ /* Parse options */
+ if ( ( rc = parse_options ( argc, argv, &params_cmd, &opts ) ) != 0)
+ return rc;
+
+ /* Create parameter list */
+ params = create_parameters ( opts.name );
+ if ( ! params )
+ return -ENOMEM;
+
+ /* Destroy parameter list, if applicable */
+ if ( opts.delete ) {
+ claim_parameters ( params );
+ params_put ( params );
+ }
+
+ return 0;
+}
+
+/** "param" options */
+struct param_options {
+ /** Parameter list name */
+ char *params;
+};
+
+/** "param" option list */
+static struct option_descriptor param_opts[] = {
+ OPTION_DESC ( "params", 'p', required_argument,
+ struct param_options, params, parse_string ),
+};
+
+/** "param" command descriptor */
+static struct command_descriptor param_cmd =
+ COMMAND_DESC ( struct param_options, param_opts, 1, MAX_ARGUMENTS,
+ "<key> [<value>]" );
+
+/**
+ * The "param" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int param_exec ( int argc, char **argv ) {
+ struct param_options opts;
+ char *key;
+ char *value;
+ struct parameters *params;
+ struct parameter *param;
+ int rc;
+
+ /* Parse options */
+ if ( ( rc = parse_options ( argc, argv, &param_cmd, &opts ) ) != 0 )
+ goto err_parse_options;
+
+ /* Parse key */
+ key = argv[optind];
+
+ /* Parse value */
+ value = concat_args ( &argv[ optind + 1 ] );
+ if ( ! value ) {
+ rc = -ENOMEM;
+ goto err_parse_value;
+ }
+
+ /* Identify parameter list */
+ if ( ( rc = parse_parameters ( opts.params, &params ) ) != 0 )
+ goto err_parse_parameters;
+
+ /* Add parameter */
+ param = add_parameter ( params, key, value );
+ if ( ! param ) {
+ rc = -ENOMEM;
+ goto err_add_parameter;
+ }
+
+ /* Success */
+ rc = 0;
+
+ err_add_parameter:
+ err_parse_parameters:
+ free ( value );
+ err_parse_value:
+ err_parse_options:
+ return rc;
+}
+
+/** Form parameter commands */
+struct command param_commands[] __command = {
+ {
+ .name = "params",
+ .exec = params_exec,
+ },
+ {
+ .name = "param",
+ .exec = param_exec,
+ },
+};
diff --git a/qemu/roms/ipxe/src/hci/commands/pci_cmd.c b/qemu/roms/ipxe/src/hci/commands/pci_cmd.c
new file mode 100644
index 000000000..f5145fb35
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/commands/pci_cmd.c
@@ -0,0 +1,114 @@
+/*
+ * 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.
+ */
+
+#include <stdio.h>
+#include <getopt.h>
+#include <ipxe/pci.h>
+#include <ipxe/command.h>
+#include <ipxe/parseopt.h>
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+/** @file
+ *
+ * PCI commands
+ *
+ */
+
+/** "pciscan" options */
+struct pciscan_options {};
+
+/** "pciscan" option list */
+static struct option_descriptor pciscan_opts[] = {};
+
+/** "pciscan" command descriptor */
+static struct command_descriptor pciscan_cmd =
+ COMMAND_DESC ( struct pciscan_options, pciscan_opts, 1, 1,
+ "<setting>" );
+
+/**
+ * "pciscan" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int pciscan_exec ( int argc, char **argv ) {
+ struct pciscan_options opts;
+ struct named_setting setting;
+ struct pci_device pci;
+ unsigned long prev;
+ int next;
+ int len;
+ int rc;
+
+ /* Parse options */
+ if ( ( rc = parse_options ( argc, argv, &pciscan_cmd, &opts ) ) != 0 )
+ goto err_parse_options;
+
+ /* Parse setting name */
+ if ( ( rc = parse_autovivified_setting ( argv[optind],
+ &setting ) ) != 0 )
+ goto err_parse_setting;
+
+ /* Determine starting bus:dev.fn address */
+ if ( ( len = fetchn_setting ( setting.settings, &setting.setting,
+ NULL, &setting.setting, &prev ) ) < 0 ) {
+ /* Setting not yet defined: start searching from 00:00.0 */
+ prev = 0;
+ } else {
+ /* Setting is defined: start searching from next location */
+ prev++;
+ }
+
+ /* Find next existent PCI device */
+ if ( ( next = pci_find_next ( &pci, prev ) ) < 0 ) {
+ rc = next;
+ goto err_find_next;
+ }
+
+ /* Apply default type if necessary. Use ":uint16" rather than
+ * ":busdevfn" to allow for easy inclusion within a
+ * "${pci/${location}.x.y}" constructed setting.
+ */
+ if ( ! setting.setting.type )
+ setting.setting.type = &setting_type_uint16;
+
+ /* Store setting */
+ if ( ( rc = storen_setting ( setting.settings, &setting.setting,
+ next ) ) != 0 ) {
+ printf ( "Could not store \"%s\": %s\n",
+ setting.setting.name, strerror ( rc ) );
+ goto err_store;
+ }
+
+ err_store:
+ err_find_next:
+ err_parse_setting:
+ err_parse_options:
+ return rc;
+}
+
+/** PCI commands */
+struct command pci_commands[] __command = {
+ {
+ .name = "pciscan",
+ .exec = pciscan_exec,
+ },
+};
diff --git a/qemu/roms/ipxe/src/hci/commands/ping_cmd.c b/qemu/roms/ipxe/src/hci/commands/ping_cmd.c
new file mode 100644
index 000000000..34807696f
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/commands/ping_cmd.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2013 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <getopt.h>
+#include <ipxe/command.h>
+#include <ipxe/parseopt.h>
+#include <ipxe/timer.h>
+#include <usr/pingmgmt.h>
+
+/** @file
+ *
+ * Ping command
+ *
+ */
+
+/** Default payload length */
+#define PING_DEFAULT_SIZE 64
+
+/** Default timeout */
+#define PING_DEFAULT_TIMEOUT TICKS_PER_SEC
+
+/** "ping" options */
+struct ping_options {
+ /** Payload length */
+ unsigned int size;
+ /** Timeout (in ms) */
+ unsigned long timeout;
+ /** Number of packets to send (or zero for no limit) */
+ unsigned int count;
+ /** Inhibit output */
+ int quiet;
+};
+
+/** "ping" option list */
+static struct option_descriptor ping_opts[] = {
+ OPTION_DESC ( "size", 's', required_argument,
+ struct ping_options, size, parse_integer ),
+ OPTION_DESC ( "timeout", 't', required_argument,
+ struct ping_options, timeout, parse_timeout ),
+ OPTION_DESC ( "count", 'c', required_argument,
+ struct ping_options, count, parse_integer ),
+ OPTION_DESC ( "quiet", 'q', no_argument,
+ struct ping_options, quiet, parse_flag ),
+};
+
+/** "ping" command descriptor */
+static struct command_descriptor ping_cmd =
+ COMMAND_DESC ( struct ping_options, ping_opts, 1, 1, "<host>" );
+
+/**
+ * The "ping" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int ping_exec ( int argc, char **argv ) {
+ struct ping_options opts;
+ const char *hostname;
+ int rc;
+
+ /* Initialise options */
+ memset ( &opts, 0, sizeof ( opts ) );
+ opts.size = PING_DEFAULT_SIZE;
+ opts.timeout = PING_DEFAULT_TIMEOUT;
+
+ /* Parse options */
+ if ( ( rc = reparse_options ( argc, argv, &ping_cmd, &opts ) ) != 0 )
+ return rc;
+
+ /* Parse hostname */
+ hostname = argv[optind];
+
+ /* Ping */
+ if ( ( rc = ping ( hostname, opts.timeout, opts.size,
+ opts.count, opts.quiet ) ) != 0 )
+ return rc;
+
+ return 0;
+}
+
+/** Ping command */
+struct command ping_command __command = {
+ .name = "ping",
+ .exec = ping_exec,
+};
diff --git a/qemu/roms/ipxe/src/hci/commands/poweroff_cmd.c b/qemu/roms/ipxe/src/hci/commands/poweroff_cmd.c
new file mode 100644
index 000000000..9d487d330
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/commands/poweroff_cmd.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2013 Marin Hannache <ipxe@mareo.fr>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <getopt.h>
+#include <ipxe/command.h>
+#include <ipxe/parseopt.h>
+#include <ipxe/reboot.h>
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+/** @file
+ *
+ * Power off command
+ *
+ */
+
+/** "poweroff" options */
+struct poweroff_options {};
+
+/** "poweroff" option list */
+static struct option_descriptor poweroff_opts[] = {};
+
+/** "poweroff" command descriptor */
+static struct command_descriptor poweroff_cmd =
+ COMMAND_DESC ( struct poweroff_options, poweroff_opts, 0, 0, NULL );
+
+/**
+ * The "poweroff" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int poweroff_exec ( int argc, char **argv ) {
+ struct poweroff_options opts;
+ int rc;
+
+ /* Parse options */
+ if ( ( rc = parse_options ( argc, argv, &poweroff_cmd, &opts ) ) != 0 )
+ return rc;
+
+ /* Power off system */
+ rc = poweroff();
+ if ( rc != 0 )
+ printf ( "Could not power off: %s\n", strerror ( rc ) );
+
+ return rc;
+}
+
+/** "poweroff" command */
+struct command poweroff_command __command = {
+ .name = "poweroff",
+ .exec = poweroff_exec,
+};
diff --git a/qemu/roms/ipxe/src/hci/commands/profstat_cmd.c b/qemu/roms/ipxe/src/hci/commands/profstat_cmd.c
new file mode 100644
index 000000000..e4c9e5a24
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/commands/profstat_cmd.c
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <stdio.h>
+#include <getopt.h>
+#include <ipxe/command.h>
+#include <ipxe/parseopt.h>
+#include <usr/profstat.h>
+
+/** @file
+ *
+ * Profiling commands
+ *
+ */
+
+/** "profstat" options */
+struct profstat_options {};
+
+/** "profstat" option list */
+static struct option_descriptor profstat_opts[] = {};
+
+/** "profstat" command descriptor */
+static struct command_descriptor profstat_cmd =
+ COMMAND_DESC ( struct profstat_options, profstat_opts, 0, 0, NULL );
+
+/**
+ * The "profstat" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int profstat_exec ( int argc, char **argv ) {
+ struct profstat_options opts;
+ int rc;
+
+ /* Parse options */
+ if ( ( rc = parse_options ( argc, argv, &profstat_cmd, &opts ) ) != 0 )
+ return rc;
+
+ profstat();
+
+ return 0;
+}
+
+/** Profiling commands */
+struct command profstat_commands[] __command = {
+ {
+ .name = "profstat",
+ .exec = profstat_exec,
+ },
+};
diff --git a/qemu/roms/ipxe/src/hci/commands/reboot_cmd.c b/qemu/roms/ipxe/src/hci/commands/reboot_cmd.c
new file mode 100644
index 000000000..485939e42
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/commands/reboot_cmd.c
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+#include <getopt.h>
+#include <ipxe/command.h>
+#include <ipxe/parseopt.h>
+#include <ipxe/reboot.h>
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+/** @file
+ *
+ * Reboot command
+ *
+ */
+
+/** "reboot" options */
+struct reboot_options {
+ /** Perform a warm reboot */
+ int warm;
+};
+
+/** "reboot" option list */
+static struct option_descriptor reboot_opts[] = {
+ OPTION_DESC ( "warm", 'w', no_argument,
+ struct reboot_options, warm, parse_flag ),
+};
+
+/** "reboot" command descriptor */
+static struct command_descriptor reboot_cmd =
+ COMMAND_DESC ( struct reboot_options, reboot_opts, 0, 0, NULL );
+
+/**
+ * The "reboot" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int reboot_exec ( int argc, char **argv ) {
+ struct reboot_options opts;
+ int rc;
+
+ /* Parse options */
+ if ( ( rc = parse_options ( argc, argv, &reboot_cmd, &opts ) ) != 0 )
+ return rc;
+
+ /* Reboot system */
+ reboot ( opts.warm );
+
+ return 0;
+}
+
+/** "reboot" command */
+struct command reboot_command __command = {
+ .name = "reboot",
+ .exec = reboot_exec,
+};
diff --git a/qemu/roms/ipxe/src/hci/commands/route_cmd.c b/qemu/roms/ipxe/src/hci/commands/route_cmd.c
new file mode 100644
index 000000000..cc5ffc2f2
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/commands/route_cmd.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <stdio.h>
+#include <getopt.h>
+#include <ipxe/command.h>
+#include <ipxe/parseopt.h>
+#include <usr/route.h>
+
+/** @file
+ *
+ * Routing table management commands
+ *
+ */
+
+/** "route" options */
+struct route_options {};
+
+/** "route" option list */
+static struct option_descriptor route_opts[] = {};
+
+/** "route" command descriptor */
+static struct command_descriptor route_cmd =
+ COMMAND_DESC ( struct route_options, route_opts, 0, 0, NULL );
+
+/**
+ * The "route" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int route_exec ( int argc, char **argv ) {
+ struct route_options opts;
+ int rc;
+
+ /* Parse options */
+ if ( ( rc = parse_options ( argc, argv, &route_cmd, &opts ) ) != 0 )
+ return rc;
+
+ route();
+
+ return 0;
+}
+
+/** Routing table management commands */
+struct command route_commands[] __command = {
+ {
+ .name = "route",
+ .exec = route_exec,
+ },
+};
diff --git a/qemu/roms/ipxe/src/hci/commands/sanboot_cmd.c b/qemu/roms/ipxe/src/hci/commands/sanboot_cmd.c
new file mode 100644
index 000000000..5954b6326
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/commands/sanboot_cmd.c
@@ -0,0 +1,193 @@
+/*
+ * 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.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <getopt.h>
+#include <ipxe/command.h>
+#include <ipxe/parseopt.h>
+#include <ipxe/uri.h>
+#include <ipxe/sanboot.h>
+#include <usr/autoboot.h>
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+/** @file
+ *
+ * SAN commands
+ *
+ */
+
+/** "sanboot" options */
+struct sanboot_options {
+ /** Drive number */
+ unsigned int drive;
+ /** Do not describe SAN device */
+ int no_describe;
+ /** Keep SAN device */
+ int keep;
+};
+
+/** "sanboot" option list */
+static union {
+ /* "sanboot" takes all three options */
+ struct option_descriptor sanboot[3];
+ /* "sanhook" takes only --drive and --no-describe */
+ struct option_descriptor sanhook[2];
+ /* "sanunhook" takes only --drive */
+ struct option_descriptor sanunhook[1];
+} opts = {
+ .sanboot = {
+ OPTION_DESC ( "drive", 'd', required_argument,
+ struct sanboot_options, drive, parse_integer ),
+ OPTION_DESC ( "no-describe", 'n', no_argument,
+ struct sanboot_options, no_describe, parse_flag ),
+ OPTION_DESC ( "keep", 'k', no_argument,
+ struct sanboot_options, keep, parse_flag ),
+ },
+};
+
+
+/** "sanhook" command descriptor */
+static struct command_descriptor sanhook_cmd =
+ COMMAND_DESC ( struct sanboot_options, opts.sanhook, 1, 1,
+ "<root-path>" );
+
+/** "sanboot" command descriptor */
+static struct command_descriptor sanboot_cmd =
+ COMMAND_DESC ( struct sanboot_options, opts.sanboot, 0, 1,
+ "[<root-path>]" );
+
+/** "sanunhook" command descriptor */
+static struct command_descriptor sanunhook_cmd =
+ COMMAND_DESC ( struct sanboot_options, opts.sanunhook, 0, 0, NULL );
+
+/**
+ * The "sanboot", "sanhook" and "sanunhook" commands
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @v default_flags Default set of flags for uriboot()
+ * @v no_root_path_flags Additional flags to apply if no root path is present
+ * @ret rc Return status code
+ */
+static int sanboot_core_exec ( int argc, char **argv,
+ struct command_descriptor *cmd,
+ int default_flags, int no_root_path_flags ) {
+ struct sanboot_options opts;
+ const char *root_path;
+ struct uri *uri;
+ int flags;
+ int rc;
+
+ /* Initialise options */
+ memset ( &opts, 0, sizeof ( opts ) );
+ opts.drive = san_default_drive();
+
+ /* Parse options */
+ if ( ( rc = reparse_options ( argc, argv, cmd, &opts ) ) != 0 )
+ goto err_parse_options;
+
+ /* Parse root path, if present */
+ if ( argc > optind ) {
+ root_path = argv[optind];
+ uri = parse_uri ( root_path );
+ if ( ! uri ) {
+ rc = -ENOMEM;
+ goto err_parse_uri;
+ }
+ } else {
+ root_path = NULL;
+ uri = NULL;
+ }
+
+ /* Construct flags */
+ flags = default_flags;
+ if ( opts.no_describe )
+ flags |= URIBOOT_NO_SAN_DESCRIBE;
+ if ( opts.keep )
+ flags |= URIBOOT_NO_SAN_UNHOOK;
+ if ( ! root_path )
+ flags |= no_root_path_flags;
+
+ /* Boot from root path */
+ if ( ( rc = uriboot ( NULL, uri, opts.drive, flags ) ) != 0 )
+ goto err_uriboot;
+
+ err_uriboot:
+ uri_put ( uri );
+ err_parse_uri:
+ err_parse_options:
+ return rc;
+}
+
+/**
+ * The "sanhook" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int sanhook_exec ( int argc, char **argv ) {
+ return sanboot_core_exec ( argc, argv, &sanhook_cmd,
+ ( URIBOOT_NO_SAN_BOOT |
+ URIBOOT_NO_SAN_UNHOOK ), 0 );
+}
+
+/**
+ * The "sanboot" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int sanboot_exec ( int argc, char **argv ) {
+ return sanboot_core_exec ( argc, argv, &sanboot_cmd,
+ 0, URIBOOT_NO_SAN_UNHOOK );
+}
+
+/**
+ * The "sanunhook" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int sanunhook_exec ( int argc, char **argv ) {
+ return sanboot_core_exec ( argc, argv, &sanunhook_cmd,
+ ( URIBOOT_NO_SAN_DESCRIBE |
+ URIBOOT_NO_SAN_BOOT ), 0 );
+}
+
+/** SAN commands */
+struct command sanboot_commands[] __command = {
+ {
+ .name = "sanhook",
+ .exec = sanhook_exec,
+ },
+ {
+ .name = "sanboot",
+ .exec = sanboot_exec,
+ },
+ {
+ .name = "sanunhook",
+ .exec = sanunhook_exec,
+ },
+};
diff --git a/qemu/roms/ipxe/src/hci/commands/sync_cmd.c b/qemu/roms/ipxe/src/hci/commands/sync_cmd.c
new file mode 100644
index 000000000..adf7e3cc6
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/commands/sync_cmd.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <string.h>
+#include <stdio.h>
+#include <getopt.h>
+#include <ipxe/command.h>
+#include <ipxe/parseopt.h>
+#include <usr/sync.h>
+
+/** @file
+ *
+ * "sync" command
+ *
+ */
+
+/** "sync" options */
+struct sync_options {
+ /** Timeout */
+ unsigned long timeout;
+};
+
+/** "sync" option list */
+static struct option_descriptor sync_opts[] = {
+ OPTION_DESC ( "timeout", 't', required_argument,
+ struct sync_options, timeout, parse_timeout ),
+};
+
+/** "sync" command descriptor */
+static struct command_descriptor sync_cmd =
+ COMMAND_DESC ( struct sync_options, sync_opts, 0, 0, NULL );
+
+/**
+ * "sync" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int sync_exec ( int argc, char **argv ) {
+ struct sync_options opts;
+ int rc;
+
+ /* Parse options */
+ if ( ( rc = parse_options ( argc, argv, &sync_cmd, &opts ) ) != 0 )
+ return rc;
+
+ /* Wait for pending operations to complete */
+ if ( ( rc = sync ( opts.timeout ) ) != 0 ) {
+ printf ( "Operations did not complete: %s\n", strerror ( rc ) );
+ return rc;
+ }
+
+ return 0;
+}
+
+/** Sync commands */
+struct command sync_command __command = {
+ .name = "sync",
+ .exec = sync_exec,
+};
diff --git a/qemu/roms/ipxe/src/hci/commands/time_cmd.c b/qemu/roms/ipxe/src/hci/commands/time_cmd.c
new file mode 100644
index 000000000..d1dd49caf
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/commands/time_cmd.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2009 Daniel Verkamp <daniel@drv.nu>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * March-19-2009 @ 02:44: Added sleep command.
+ * Shao Miller <shao.miller@yrdsb.edu.on.ca>.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <ipxe/command.h>
+#include <ipxe/parseopt.h>
+#include <ipxe/timer.h>
+
+/** @file
+ *
+ * Time commands
+ *
+ */
+
+/** "time" options */
+struct time_options {};
+
+/** "time" option list */
+static struct option_descriptor time_opts[] = {};
+
+/** "time" command descriptor */
+static struct command_descriptor time_cmd =
+ COMMAND_DESC ( struct time_options, time_opts, 1, MAX_ARGUMENTS,
+ "<command>" );
+
+/**
+ * "time" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int time_exec ( int argc, char **argv ) {
+ struct time_options opts;
+ unsigned long start;
+ unsigned long elapsed;
+ int decisecs;
+ int rc;
+
+ /* Parse options */
+ if ( ( rc = parse_options ( argc, argv, &time_cmd, &opts ) ) != 0 )
+ return rc;
+
+ start = currticks();
+ rc = execv ( argv[1], argv + 1 );
+ elapsed = ( currticks() - start );
+ decisecs = ( 10 * elapsed / ticks_per_sec() );
+
+ printf ( "%s: %d.%ds\n", argv[0],
+ ( decisecs / 10 ), ( decisecs % 10 ) );
+
+ return rc;
+}
+
+/** "time" command */
+struct command time_command __command = {
+ .name = "time",
+ .exec = time_exec,
+};
diff --git a/qemu/roms/ipxe/src/hci/commands/vlan_cmd.c b/qemu/roms/ipxe/src/hci/commands/vlan_cmd.c
new file mode 100644
index 000000000..5d7298220
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/commands/vlan_cmd.c
@@ -0,0 +1,139 @@
+/*
+ * 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.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <ipxe/netdevice.h>
+#include <ipxe/command.h>
+#include <ipxe/parseopt.h>
+#include <ipxe/vlan.h>
+
+/** @file
+ *
+ * VLAN commands
+ *
+ */
+
+/** "vcreate" options */
+struct vcreate_options {
+ /** VLAN tag */
+ unsigned int tag;
+ /** VLAN default priority */
+ unsigned int priority;
+};
+
+/** "vcreate" option list */
+static struct option_descriptor vcreate_opts[] = {
+ OPTION_DESC ( "tag", 't', required_argument,
+ struct vcreate_options, tag, parse_integer ),
+ OPTION_DESC ( "priority", 'p', required_argument,
+ struct vcreate_options, priority, parse_integer ),
+};
+
+/** "vcreate" command descriptor */
+static struct command_descriptor vcreate_cmd =
+ COMMAND_DESC ( struct vcreate_options, vcreate_opts, 1, 1,
+ "<trunk interface>" );
+
+/**
+ * "vcreate" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int vcreate_exec ( int argc, char **argv ) {
+ struct vcreate_options opts;
+ struct net_device *trunk;
+ int rc;
+
+ /* Parse options */
+ if ( ( rc = parse_options ( argc, argv, &vcreate_cmd, &opts ) ) != 0 )
+ return rc;
+
+ /* Parse trunk interface */
+ if ( ( rc = parse_netdev ( argv[optind], &trunk ) ) != 0 )
+ return rc;
+
+ /* Create VLAN device */
+ if ( ( rc = vlan_create ( trunk, opts.tag, opts.priority ) ) != 0 ) {
+ printf ( "Could not create VLAN device: %s\n",
+ strerror ( rc ) );
+ return rc;
+ }
+
+ return 0;
+}
+
+/** "vdestroy" options */
+struct vdestroy_options {};
+
+/** "vdestroy" option list */
+static struct option_descriptor vdestroy_opts[] = {};
+
+/** "vdestroy" command descriptor */
+static struct command_descriptor vdestroy_cmd =
+ COMMAND_DESC ( struct vdestroy_options, vdestroy_opts, 1, 1,
+ "<VLAN interface>" );
+
+/**
+ * "vdestroy" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int vdestroy_exec ( int argc, char **argv ) {
+ struct vdestroy_options opts;
+ struct net_device *netdev;
+ int rc;
+
+ /* Parse options */
+ if ( ( rc = parse_options ( argc, argv, &vdestroy_cmd, &opts ) ) != 0 )
+ return rc;
+
+ /* Parse trunk interface */
+ if ( ( rc = parse_netdev ( argv[optind], &netdev ) ) != 0 )
+ return rc;
+
+ /* Destroy VLAN device */
+ if ( ( rc = vlan_destroy ( netdev ) ) != 0 ) {
+ printf ( "Could not destroy VLAN device: %s\n",
+ strerror ( rc ) );
+ return rc;
+ }
+
+ return 0;
+}
+
+/** VLAN commands */
+struct command vlan_commands[] __command = {
+ {
+ .name = "vcreate",
+ .exec = vcreate_exec,
+ },
+ {
+ .name = "vdestroy",
+ .exec = vdestroy_exec,
+ },
+};
diff --git a/qemu/roms/ipxe/src/hci/editstring.c b/qemu/roms/ipxe/src/hci/editstring.c
new file mode 100644
index 000000000..5f6f04d51
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/editstring.c
@@ -0,0 +1,254 @@
+/*
+ * 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.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <ipxe/keys.h>
+#include <ipxe/editstring.h>
+
+/** @file
+ *
+ * Editable strings
+ *
+ */
+
+static void insert_delete ( struct edit_string *string, size_t delete_len,
+ const char *insert_text )
+ __attribute__ (( nonnull (1) ));
+static void insert_character ( struct edit_string *string,
+ unsigned int character ) __nonnull;
+static void delete_character ( struct edit_string *string ) __nonnull;
+static void backspace ( struct edit_string *string ) __nonnull;
+static void previous_word ( struct edit_string *string ) __nonnull;
+static void kill_word ( struct edit_string *string ) __nonnull;
+static void kill_sol ( struct edit_string *string ) __nonnull;
+static void kill_eol ( struct edit_string *string ) __nonnull;
+
+/**
+ * Insert and/or delete text within an editable string
+ *
+ * @v string Editable string
+ * @v delete_len Length of text to delete from current cursor position
+ * @v insert_text Text to insert at current cursor position, or NULL
+ */
+static void insert_delete ( struct edit_string *string, size_t delete_len,
+ const char *insert_text ) {
+ size_t old_len, max_delete_len, insert_len, max_insert_len, new_len;
+
+ /* Calculate lengths */
+ old_len = strlen ( string->buf );
+ assert ( string->cursor <= old_len );
+ max_delete_len = ( old_len - string->cursor );
+ if ( delete_len > max_delete_len )
+ delete_len = max_delete_len;
+ insert_len = ( insert_text ? strlen ( insert_text ) : 0 );
+ max_insert_len = ( ( string->len - 1 ) - ( old_len - delete_len ) );
+ if ( insert_len > max_insert_len )
+ insert_len = max_insert_len;
+ new_len = ( old_len - delete_len + insert_len );
+
+ /* Fill in edit history */
+ string->mod_start = string->cursor;
+ string->mod_end = ( ( new_len > old_len ) ? new_len : old_len );
+
+ /* Move data following the cursor */
+ memmove ( ( string->buf + string->cursor + insert_len ),
+ ( string->buf + string->cursor + delete_len ),
+ ( max_delete_len + 1 - delete_len ) );
+
+ /* Copy inserted text to cursor position */
+ memcpy ( ( string->buf + string->cursor ), insert_text, insert_len );
+ string->cursor += insert_len;
+}
+
+/**
+ * Insert character at current cursor position
+ *
+ * @v string Editable string
+ * @v character Character to insert
+ */
+static void insert_character ( struct edit_string *string,
+ unsigned int character ) {
+ char insert_text[2] = { character, '\0' };
+ insert_delete ( string, 0, insert_text );
+}
+
+/**
+ * Delete character at current cursor position
+ *
+ * @v string Editable string
+ */
+static void delete_character ( struct edit_string *string ) {
+ insert_delete ( string, 1, NULL );
+}
+
+/**
+ * Delete character to left of current cursor position
+ *
+ * @v string Editable string
+ */
+static void backspace ( struct edit_string *string ) {
+ if ( string->cursor > 0 ) {
+ string->cursor--;
+ delete_character ( string );
+ }
+}
+
+/**
+ * Move to start of previous word
+ *
+ * @v string Editable string
+ */
+static void previous_word ( struct edit_string *string ) {
+ while ( string->cursor &&
+ isspace ( string->buf[ string->cursor - 1 ] ) ) {
+ string->cursor--;
+ }
+ while ( string->cursor &&
+ ( ! isspace ( string->buf[ string->cursor - 1 ] ) ) ) {
+ string->cursor--;
+ }
+}
+
+/**
+ * Delete to end of previous word
+ *
+ * @v string Editable string
+ */
+static void kill_word ( struct edit_string *string ) {
+ size_t old_cursor = string->cursor;
+ previous_word ( string );
+ insert_delete ( string, ( old_cursor - string->cursor ), NULL );
+}
+
+/**
+ * Delete to start of line
+ *
+ * @v string Editable string
+ */
+static void kill_sol ( struct edit_string *string ) {
+ size_t old_cursor = string->cursor;
+ string->cursor = 0;
+ insert_delete ( string, old_cursor, NULL );
+}
+
+/**
+ * Delete to end of line
+ *
+ * @v string Editable string
+ */
+static void kill_eol ( struct edit_string *string ) {
+ insert_delete ( string, ~( ( size_t ) 0 ), NULL );
+}
+
+/**
+ * Replace editable string
+ *
+ * @v string Editable string
+ * @v replacement Replacement string
+ */
+void replace_string ( struct edit_string *string, const char *replacement ) {
+ string->cursor = 0;
+ insert_delete ( string, ~( ( size_t ) 0 ), replacement );
+}
+
+/**
+ * Edit editable string
+ *
+ * @v string Editable string
+ * @v key Key pressed by user
+ * @ret key Key returned to application, or zero
+ *
+ * Handles keypresses and updates the content of the editable string.
+ * Basic line editing facilities (delete/insert/cursor) are supported.
+ * If edit_string() understands and uses the keypress it will return
+ * zero, otherwise it will return the original key.
+ *
+ * This function does not update the display in any way.
+ *
+ * The string's edit history will be updated to allow the caller to
+ * efficiently bring the display into sync with the string content.
+ */
+int edit_string ( struct edit_string *string, int key ) {
+ int retval = 0;
+ size_t len = strlen ( string->buf );
+
+ /* Prepare edit history */
+ string->last_cursor = string->cursor;
+ string->mod_start = string->cursor;
+ string->mod_end = string->cursor;
+
+ /* Interpret key */
+ if ( ( key >= 0x20 ) && ( key <= 0x7e ) ) {
+ /* Printable character; insert at current position */
+ insert_character ( string, key );
+ } else switch ( key ) {
+ case KEY_BACKSPACE:
+ /* Backspace */
+ backspace ( string );
+ break;
+ case KEY_DC:
+ case CTRL_D:
+ /* Delete character */
+ delete_character ( string );
+ break;
+ case CTRL_W:
+ /* Delete word */
+ kill_word ( string );
+ break;
+ case CTRL_U:
+ /* Delete to start of line */
+ kill_sol ( string );
+ break;
+ case CTRL_K:
+ /* Delete to end of line */
+ kill_eol ( string );
+ break;
+ case KEY_HOME:
+ case CTRL_A:
+ /* Start of line */
+ string->cursor = 0;
+ break;
+ case KEY_END:
+ case CTRL_E:
+ /* End of line */
+ string->cursor = len;
+ break;
+ case KEY_LEFT:
+ case CTRL_B:
+ /* Cursor left */
+ if ( string->cursor > 0 )
+ string->cursor--;
+ break;
+ case KEY_RIGHT:
+ case CTRL_F:
+ /* Cursor right */
+ if ( string->cursor < len )
+ string->cursor++;
+ break;
+ default:
+ retval = key;
+ break;
+ }
+
+ return retval;
+}
diff --git a/qemu/roms/ipxe/src/hci/keymap/keymap_al.c b/qemu/roms/ipxe/src/hci/keymap/keymap_al.c
new file mode 100644
index 000000000..caf295e8e
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/keymap/keymap_al.c
@@ -0,0 +1,32 @@
+/** @file
+ *
+ * "al" keyboard mapping
+ *
+ * This file is automatically generated; do not edit
+ *
+ */
+
+FILE_LICENCE ( PUBLIC_DOMAIN );
+
+#include <ipxe/keymap.h>
+
+/** "al" keyboard mapping */
+struct key_mapping al_mapping[] __keymap = {
+ { 0x19, 0x1a }, /* Ctrl-Y => Ctrl-Z */
+ { 0x1a, 0x19 }, /* Ctrl-Z => Ctrl-Y */
+ { 0x22, 0x7b }, /* '"' => '{' */
+ { 0x27, 0x5b }, /* '\'' => '[' */
+ { 0x3c, 0x3b }, /* '<' => ';' */
+ { 0x3e, 0x3a }, /* '>' => ':' */
+ { 0x40, 0x22 }, /* '@' => '"' */
+ { 0x59, 0x5a }, /* 'Y' => 'Z' */
+ { 0x5a, 0x59 }, /* 'Z' => 'Y' */
+ { 0x5c, 0x5d }, /* '\\' => ']' */
+ { 0x5d, 0x40 }, /* ']' => '@' */
+ { 0x60, 0x5c }, /* '`' => '\\' */
+ { 0x79, 0x7a }, /* 'y' => 'z' */
+ { 0x7a, 0x79 }, /* 'z' => 'y' */
+ { 0x7c, 0x7d }, /* '|' => '}' */
+ { 0x7d, 0x27 }, /* '}' => '\'' */
+ { 0x7e, 0x7c }, /* '~' => '|' */
+};
diff --git a/qemu/roms/ipxe/src/hci/keymap/keymap_az.c b/qemu/roms/ipxe/src/hci/keymap/keymap_az.c
new file mode 100644
index 000000000..27ce91e7d
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/keymap/keymap_az.c
@@ -0,0 +1,24 @@
+/** @file
+ *
+ * "az" keyboard mapping
+ *
+ * This file is automatically generated; do not edit
+ *
+ */
+
+FILE_LICENCE ( PUBLIC_DOMAIN );
+
+#include <ipxe/keymap.h>
+
+/** "az" keyboard mapping */
+struct key_mapping az_mapping[] __keymap = {
+ { 0x23, 0x27 }, /* '#' => '\'' */
+ { 0x24, 0x3b }, /* '$' => ';' */
+ { 0x26, 0x3f }, /* '&' => '?' */
+ { 0x2f, 0x2e }, /* '/' => '.' */
+ { 0x3a, 0x49 }, /* ':' => 'I' */
+ { 0x3f, 0x2c }, /* '?' => ',' */
+ { 0x40, 0x22 }, /* '@' => '"' */
+ { 0x5e, 0x3a }, /* '^' => ':' */
+ { 0x7c, 0x2f }, /* '|' => '/' */
+};
diff --git a/qemu/roms/ipxe/src/hci/keymap/keymap_bg.c b/qemu/roms/ipxe/src/hci/keymap/keymap_bg.c
new file mode 100644
index 000000000..62b6baeac
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/keymap/keymap_bg.c
@@ -0,0 +1,15 @@
+/** @file
+ *
+ * "bg" keyboard mapping
+ *
+ * This file is automatically generated; do not edit
+ *
+ */
+
+FILE_LICENCE ( PUBLIC_DOMAIN );
+
+#include <ipxe/keymap.h>
+
+/** "bg" keyboard mapping */
+struct key_mapping bg_mapping[] __keymap = {
+};
diff --git a/qemu/roms/ipxe/src/hci/keymap/keymap_by.c b/qemu/roms/ipxe/src/hci/keymap/keymap_by.c
new file mode 100644
index 000000000..514d0b532
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/keymap/keymap_by.c
@@ -0,0 +1,15 @@
+/** @file
+ *
+ * "by" keyboard mapping
+ *
+ * This file is automatically generated; do not edit
+ *
+ */
+
+FILE_LICENCE ( PUBLIC_DOMAIN );
+
+#include <ipxe/keymap.h>
+
+/** "by" keyboard mapping */
+struct key_mapping by_mapping[] __keymap = {
+};
diff --git a/qemu/roms/ipxe/src/hci/keymap/keymap_cf.c b/qemu/roms/ipxe/src/hci/keymap/keymap_cf.c
new file mode 100644
index 000000000..d7e63b9b1
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/keymap/keymap_cf.c
@@ -0,0 +1,24 @@
+/** @file
+ *
+ * "cf" keyboard mapping
+ *
+ * This file is automatically generated; do not edit
+ *
+ */
+
+FILE_LICENCE ( PUBLIC_DOMAIN );
+
+#include <ipxe/keymap.h>
+
+/** "cf" keyboard mapping */
+struct key_mapping cf_mapping[] __keymap = {
+ { 0x23, 0x2f }, /* '#' => '/' */
+ { 0x3c, 0x27 }, /* '<' => '\'' */
+ { 0x3e, 0x2e }, /* '>' => '.' */
+ { 0x40, 0x22 }, /* '@' => '"' */
+ { 0x5c, 0x3c }, /* '\\' => '<' */
+ { 0x5e, 0x3f }, /* '^' => '?' */
+ { 0x60, 0x23 }, /* '`' => '#' */
+ { 0x7c, 0x3e }, /* '|' => '>' */
+ { 0x7e, 0x7c }, /* '~' => '|' */
+};
diff --git a/qemu/roms/ipxe/src/hci/keymap/keymap_cz.c b/qemu/roms/ipxe/src/hci/keymap/keymap_cz.c
new file mode 100644
index 000000000..9280f84fd
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/keymap/keymap_cz.c
@@ -0,0 +1,27 @@
+/** @file
+ *
+ * "cz" keyboard mapping
+ *
+ * This file is automatically generated; do not edit
+ *
+ */
+
+FILE_LICENCE ( PUBLIC_DOMAIN );
+
+#include <ipxe/keymap.h>
+
+/** "cz" keyboard mapping */
+struct key_mapping cz_mapping[] __keymap = {
+ { 0x21, 0x2b }, /* '!' => '+' */
+ { 0x2d, 0x3d }, /* '-' => '=' */
+ { 0x2f, 0x2d }, /* '/' => '-' */
+ { 0x31, 0x2b }, /* '1' => '+' */
+ { 0x3c, 0x2c }, /* '<' => ',' */
+ { 0x3e, 0x2e }, /* '>' => '.' */
+ { 0x3f, 0x2d }, /* '?' => '-' */
+ { 0x5d, 0x29 }, /* ']' => ')' */
+ { 0x5f, 0x3d }, /* '_' => '=' */
+ { 0x60, 0x3b }, /* '`' => ';' */
+ { 0x7d, 0x29 }, /* '}' => ')' */
+ { 0x7e, 0x3b }, /* '~' => ';' */
+};
diff --git a/qemu/roms/ipxe/src/hci/keymap/keymap_de.c b/qemu/roms/ipxe/src/hci/keymap/keymap_de.c
new file mode 100644
index 000000000..ffcf912f1
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/keymap/keymap_de.c
@@ -0,0 +1,46 @@
+/** @file
+ *
+ * "de" keyboard mapping
+ *
+ * This file is automatically generated; do not edit
+ *
+ */
+
+FILE_LICENCE ( PUBLIC_DOMAIN );
+
+#include <ipxe/keymap.h>
+
+/** "de" keyboard mapping */
+struct key_mapping de_mapping[] __keymap = {
+ { 0x19, 0x1a }, /* Ctrl-Y => Ctrl-Z */
+ { 0x1a, 0x19 }, /* Ctrl-Z => Ctrl-Y */
+ { 0x22, 0x7d }, /* '"' => '}' */
+ { 0x26, 0x2f }, /* '&' => '/' */
+ { 0x27, 0x5d }, /* '\'' => ']' */
+ { 0x28, 0x29 }, /* '(' => ')' */
+ { 0x29, 0x3d }, /* ')' => '=' */
+ { 0x2a, 0x28 }, /* '*' => '(' */
+ { 0x2b, 0x60 }, /* '+' => '`' */
+ { 0x2d, 0x5c }, /* '-' => '\\' */
+ { 0x2f, 0x2d }, /* '/' => '-' */
+ { 0x3a, 0x7b }, /* ':' => '{' */
+ { 0x3b, 0x5b }, /* ';' => '[' */
+ { 0x3c, 0x3b }, /* '<' => ';' */
+ { 0x3d, 0x27 }, /* '=' => '\'' */
+ { 0x3e, 0x3a }, /* '>' => ':' */
+ { 0x3f, 0x5f }, /* '?' => '_' */
+ { 0x40, 0x22 }, /* '@' => '"' */
+ { 0x59, 0x5a }, /* 'Y' => 'Z' */
+ { 0x5a, 0x59 }, /* 'Z' => 'Y' */
+ { 0x5b, 0x40 }, /* '[' => '@' */
+ { 0x5c, 0x23 }, /* '\\' => '#' */
+ { 0x5d, 0x2b }, /* ']' => '+' */
+ { 0x5e, 0x26 }, /* '^' => '&' */
+ { 0x5f, 0x3f }, /* '_' => '?' */
+ { 0x60, 0x5e }, /* '`' => '^' */
+ { 0x79, 0x7a }, /* 'y' => 'z' */
+ { 0x7a, 0x79 }, /* 'z' => 'y' */
+ { 0x7b, 0x5c }, /* '{' => '\\' */
+ { 0x7c, 0x27 }, /* '|' => '\'' */
+ { 0x7d, 0x2a }, /* '}' => '*' */
+};
diff --git a/qemu/roms/ipxe/src/hci/keymap/keymap_dk.c b/qemu/roms/ipxe/src/hci/keymap/keymap_dk.c
new file mode 100644
index 000000000..e409018c8
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/keymap/keymap_dk.c
@@ -0,0 +1,31 @@
+/** @file
+ *
+ * "dk" keyboard mapping
+ *
+ * This file is automatically generated; do not edit
+ *
+ */
+
+FILE_LICENCE ( PUBLIC_DOMAIN );
+
+#include <ipxe/keymap.h>
+
+/** "dk" keyboard mapping */
+struct key_mapping dk_mapping[] __keymap = {
+ { 0x26, 0x2f }, /* '&' => '/' */
+ { 0x28, 0x29 }, /* '(' => ')' */
+ { 0x29, 0x3d }, /* ')' => '=' */
+ { 0x2a, 0x28 }, /* '*' => '(' */
+ { 0x2b, 0x60 }, /* '+' => '`' */
+ { 0x2d, 0x2b }, /* '-' => '+' */
+ { 0x2f, 0x2d }, /* '/' => '-' */
+ { 0x3c, 0x3b }, /* '<' => ';' */
+ { 0x3e, 0x3a }, /* '>' => ':' */
+ { 0x3f, 0x5f }, /* '?' => '_' */
+ { 0x40, 0x22 }, /* '@' => '"' */
+ { 0x5c, 0x27 }, /* '\\' => '\'' */
+ { 0x5e, 0x26 }, /* '^' => '&' */
+ { 0x5f, 0x3f }, /* '_' => '?' */
+ { 0x7c, 0x2a }, /* '|' => '*' */
+ { 0x7d, 0x5e }, /* '}' => '^' */
+};
diff --git a/qemu/roms/ipxe/src/hci/keymap/keymap_es.c b/qemu/roms/ipxe/src/hci/keymap/keymap_es.c
new file mode 100644
index 000000000..c1fe013a9
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/keymap/keymap_es.c
@@ -0,0 +1,29 @@
+/** @file
+ *
+ * "es" keyboard mapping
+ *
+ * This file is automatically generated; do not edit
+ *
+ */
+
+FILE_LICENCE ( PUBLIC_DOMAIN );
+
+#include <ipxe/keymap.h>
+
+/** "es" keyboard mapping */
+struct key_mapping es_mapping[] __keymap = {
+ { 0x26, 0x2f }, /* '&' => '/' */
+ { 0x28, 0x29 }, /* '(' => ')' */
+ { 0x29, 0x3d }, /* ')' => '=' */
+ { 0x2a, 0x28 }, /* '*' => '(' */
+ { 0x2d, 0x27 }, /* '-' => '\'' */
+ { 0x2f, 0x2d }, /* '/' => '-' */
+ { 0x3c, 0x3b }, /* '<' => ';' */
+ { 0x3e, 0x3a }, /* '>' => ':' */
+ { 0x3f, 0x5f }, /* '?' => '_' */
+ { 0x40, 0x22 }, /* '@' => '"' */
+ { 0x5d, 0x2b }, /* ']' => '+' */
+ { 0x5e, 0x26 }, /* '^' => '&' */
+ { 0x5f, 0x3f }, /* '_' => '?' */
+ { 0x7d, 0x2a }, /* '}' => '*' */
+};
diff --git a/qemu/roms/ipxe/src/hci/keymap/keymap_et.c b/qemu/roms/ipxe/src/hci/keymap/keymap_et.c
new file mode 100644
index 000000000..ad88cecc1
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/keymap/keymap_et.c
@@ -0,0 +1,30 @@
+/** @file
+ *
+ * "et" keyboard mapping
+ *
+ * This file is automatically generated; do not edit
+ *
+ */
+
+FILE_LICENCE ( PUBLIC_DOMAIN );
+
+#include <ipxe/keymap.h>
+
+/** "et" keyboard mapping */
+struct key_mapping et_mapping[] __keymap = {
+ { 0x26, 0x2f }, /* '&' => '/' */
+ { 0x28, 0x29 }, /* '(' => ')' */
+ { 0x29, 0x3d }, /* ')' => '=' */
+ { 0x2a, 0x28 }, /* '*' => '(' */
+ { 0x2d, 0x2b }, /* '-' => '+' */
+ { 0x2f, 0x2d }, /* '/' => '-' */
+ { 0x3c, 0x3b }, /* '<' => ';' */
+ { 0x3e, 0x3a }, /* '>' => ':' */
+ { 0x3f, 0x5f }, /* '?' => '_' */
+ { 0x40, 0x22 }, /* '@' => '"' */
+ { 0x5c, 0x27 }, /* '\\' => '\'' */
+ { 0x5e, 0x26 }, /* '^' => '&' */
+ { 0x5f, 0x3f }, /* '_' => '?' */
+ { 0x7c, 0x2a }, /* '|' => '*' */
+ { 0x7f, 0x1b }, /* 0x7f => 0x1b */
+};
diff --git a/qemu/roms/ipxe/src/hci/keymap/keymap_fi.c b/qemu/roms/ipxe/src/hci/keymap/keymap_fi.c
new file mode 100644
index 000000000..c8f6c3a06
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/keymap/keymap_fi.c
@@ -0,0 +1,38 @@
+/** @file
+ *
+ * "fi" keyboard mapping
+ *
+ * This file is automatically generated; do not edit
+ *
+ */
+
+FILE_LICENCE ( PUBLIC_DOMAIN );
+
+#include <ipxe/keymap.h>
+
+/** "fi" keyboard mapping */
+struct key_mapping fi_mapping[] __keymap = {
+ { 0x22, 0x5b }, /* '"' => '[' */
+ { 0x26, 0x2f }, /* '&' => '/' */
+ { 0x27, 0x7b }, /* '\'' => '{' */
+ { 0x28, 0x29 }, /* '(' => ')' */
+ { 0x29, 0x3d }, /* ')' => '=' */
+ { 0x2a, 0x28 }, /* '*' => '(' */
+ { 0x2b, 0x60 }, /* '+' => '`' */
+ { 0x2d, 0x2b }, /* '-' => '+' */
+ { 0x2f, 0x2d }, /* '/' => '-' */
+ { 0x3a, 0x5c }, /* ':' => '\\' */
+ { 0x3b, 0x7c }, /* ';' => '|' */
+ { 0x3c, 0x3b }, /* '<' => ';' */
+ { 0x3d, 0x27 }, /* '=' => '\'' */
+ { 0x3e, 0x3a }, /* '>' => ':' */
+ { 0x3f, 0x5f }, /* '?' => '_' */
+ { 0x40, 0x22 }, /* '@' => '"' */
+ { 0x5b, 0x7d }, /* '[' => '}' */
+ { 0x5c, 0x27 }, /* '\\' => '\'' */
+ { 0x5e, 0x26 }, /* '^' => '&' */
+ { 0x5f, 0x3f }, /* '_' => '?' */
+ { 0x7b, 0x5d }, /* '{' => ']' */
+ { 0x7c, 0x2a }, /* '|' => '*' */
+ { 0x7d, 0x5e }, /* '}' => '^' */
+};
diff --git a/qemu/roms/ipxe/src/hci/keymap/keymap_fr.c b/qemu/roms/ipxe/src/hci/keymap/keymap_fr.c
new file mode 100644
index 000000000..fd615a456
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/keymap/keymap_fr.c
@@ -0,0 +1,68 @@
+/** @file
+ *
+ * "fr" keyboard mapping
+ *
+ * This file is automatically generated; do not edit
+ *
+ */
+
+FILE_LICENCE ( PUBLIC_DOMAIN );
+
+#include <ipxe/keymap.h>
+
+/** "fr" keyboard mapping */
+struct key_mapping fr_mapping[] __keymap = {
+ { 0x01, 0x11 }, /* Ctrl-A => Ctrl-Q */
+ { 0x11, 0x01 }, /* Ctrl-Q => Ctrl-A */
+ { 0x17, 0x1a }, /* Ctrl-W => Ctrl-Z */
+ { 0x1a, 0x17 }, /* Ctrl-Z => Ctrl-W */
+ { 0x21, 0x31 }, /* '!' => '1' */
+ { 0x22, 0x25 }, /* '"' => '%' */
+ { 0x23, 0x33 }, /* '#' => '3' */
+ { 0x24, 0x34 }, /* '$' => '4' */
+ { 0x25, 0x35 }, /* '%' => '5' */
+ { 0x26, 0x37 }, /* '&' => '7' */
+ { 0x27, 0x7c }, /* '\'' => '|' */
+ { 0x28, 0x39 }, /* '(' => '9' */
+ { 0x29, 0x30 }, /* ')' => '0' */
+ { 0x2a, 0x38 }, /* '*' => '8' */
+ { 0x2c, 0x3b }, /* ',' => ';' */
+ { 0x2d, 0x29 }, /* '-' => ')' */
+ { 0x2e, 0x3a }, /* '.' => ':' */
+ { 0x2f, 0x21 }, /* '/' => '!' */
+ { 0x30, 0x40 }, /* '0' => '@' */
+ { 0x31, 0x26 }, /* '1' => '&' */
+ { 0x32, 0x7b }, /* '2' => '{' */
+ { 0x33, 0x22 }, /* '3' => '"' */
+ { 0x34, 0x27 }, /* '4' => '\'' */
+ { 0x35, 0x28 }, /* '5' => '(' */
+ { 0x36, 0x2d }, /* '6' => '-' */
+ { 0x37, 0x7d }, /* '7' => '}' */
+ { 0x38, 0x5f }, /* '8' => '_' */
+ { 0x39, 0x2f }, /* '9' => '/' */
+ { 0x3a, 0x4d }, /* ':' => 'M' */
+ { 0x3b, 0x6d }, /* ';' => 'm' */
+ { 0x3c, 0x2e }, /* '<' => '.' */
+ { 0x3e, 0x2f }, /* '>' => '/' */
+ { 0x3f, 0x5c }, /* '?' => '\\' */
+ { 0x40, 0x32 }, /* '@' => '2' */
+ { 0x41, 0x51 }, /* 'A' => 'Q' */
+ { 0x4d, 0x3f }, /* 'M' => '?' */
+ { 0x51, 0x41 }, /* 'Q' => 'A' */
+ { 0x57, 0x5a }, /* 'W' => 'Z' */
+ { 0x5a, 0x57 }, /* 'Z' => 'W' */
+ { 0x5b, 0x5e }, /* '[' => '^' */
+ { 0x5c, 0x2a }, /* '\\' => '*' */
+ { 0x5d, 0x24 }, /* ']' => '$' */
+ { 0x5e, 0x36 }, /* '^' => '6' */
+ { 0x5f, 0x5d }, /* '_' => ']' */
+ { 0x60, 0x2a }, /* '`' => '*' */
+ { 0x61, 0x71 }, /* 'a' => 'q' */
+ { 0x6d, 0x2c }, /* 'm' => ',' */
+ { 0x71, 0x61 }, /* 'q' => 'a' */
+ { 0x77, 0x7a }, /* 'w' => 'z' */
+ { 0x7a, 0x77 }, /* 'z' => 'w' */
+ { 0x7b, 0x3c }, /* '{' => '<' */
+ { 0x7c, 0x23 }, /* '|' => '#' */
+ { 0x7d, 0x3e }, /* '}' => '>' */
+};
diff --git a/qemu/roms/ipxe/src/hci/keymap/keymap_gr.c b/qemu/roms/ipxe/src/hci/keymap/keymap_gr.c
new file mode 100644
index 000000000..42b6418e8
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/keymap/keymap_gr.c
@@ -0,0 +1,15 @@
+/** @file
+ *
+ * "gr" keyboard mapping
+ *
+ * This file is automatically generated; do not edit
+ *
+ */
+
+FILE_LICENCE ( PUBLIC_DOMAIN );
+
+#include <ipxe/keymap.h>
+
+/** "gr" keyboard mapping */
+struct key_mapping gr_mapping[] __keymap = {
+};
diff --git a/qemu/roms/ipxe/src/hci/keymap/keymap_hu.c b/qemu/roms/ipxe/src/hci/keymap/keymap_hu.c
new file mode 100644
index 000000000..68eff2f4c
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/keymap/keymap_hu.c
@@ -0,0 +1,34 @@
+/** @file
+ *
+ * "hu" keyboard mapping
+ *
+ * This file is automatically generated; do not edit
+ *
+ */
+
+FILE_LICENCE ( PUBLIC_DOMAIN );
+
+#include <ipxe/keymap.h>
+
+/** "hu" keyboard mapping */
+struct key_mapping hu_mapping[] __keymap = {
+ { 0x19, 0x1a }, /* Ctrl-Y => Ctrl-Z */
+ { 0x1a, 0x19 }, /* Ctrl-Z => Ctrl-Y */
+ { 0x21, 0x27 }, /* '!' => '\'' */
+ { 0x23, 0x2b }, /* '#' => '+' */
+ { 0x24, 0x21 }, /* '$' => '!' */
+ { 0x26, 0x3d }, /* '&' => '=' */
+ { 0x28, 0x29 }, /* '(' => ')' */
+ { 0x2a, 0x28 }, /* '*' => '(' */
+ { 0x2f, 0x2d }, /* '/' => '-' */
+ { 0x3c, 0x3f }, /* '<' => '?' */
+ { 0x3e, 0x3a }, /* '>' => ':' */
+ { 0x3f, 0x5f }, /* '?' => '_' */
+ { 0x40, 0x22 }, /* '@' => '"' */
+ { 0x59, 0x5a }, /* 'Y' => 'Z' */
+ { 0x5a, 0x59 }, /* 'Z' => 'Y' */
+ { 0x5e, 0x2f }, /* '^' => '/' */
+ { 0x60, 0x30 }, /* '`' => '0' */
+ { 0x79, 0x7a }, /* 'y' => 'z' */
+ { 0x7a, 0x79 }, /* 'z' => 'y' */
+};
diff --git a/qemu/roms/ipxe/src/hci/keymap/keymap_il.c b/qemu/roms/ipxe/src/hci/keymap/keymap_il.c
new file mode 100644
index 000000000..478330c0c
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/keymap/keymap_il.c
@@ -0,0 +1,15 @@
+/** @file
+ *
+ * "il" keyboard mapping
+ *
+ * This file is automatically generated; do not edit
+ *
+ */
+
+FILE_LICENCE ( PUBLIC_DOMAIN );
+
+#include <ipxe/keymap.h>
+
+/** "il" keyboard mapping */
+struct key_mapping il_mapping[] __keymap = {
+};
diff --git a/qemu/roms/ipxe/src/hci/keymap/keymap_it.c b/qemu/roms/ipxe/src/hci/keymap/keymap_it.c
new file mode 100644
index 000000000..5bb05471c
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/keymap/keymap_it.c
@@ -0,0 +1,32 @@
+/** @file
+ *
+ * "it" keyboard mapping
+ *
+ * This file is automatically generated; do not edit
+ *
+ */
+
+FILE_LICENCE ( PUBLIC_DOMAIN );
+
+#include <ipxe/keymap.h>
+
+/** "it" keyboard mapping */
+struct key_mapping it_mapping[] __keymap = {
+ { 0x26, 0x2f }, /* '&' => '/' */
+ { 0x28, 0x29 }, /* '(' => ')' */
+ { 0x29, 0x3d }, /* ')' => '=' */
+ { 0x2a, 0x28 }, /* '*' => '(' */
+ { 0x2b, 0x5e }, /* '+' => '^' */
+ { 0x2d, 0x27 }, /* '-' => '\'' */
+ { 0x2f, 0x2d }, /* '/' => '-' */
+ { 0x3c, 0x3b }, /* '<' => ';' */
+ { 0x3e, 0x3a }, /* '>' => ':' */
+ { 0x3f, 0x5f }, /* '?' => '_' */
+ { 0x40, 0x22 }, /* '@' => '"' */
+ { 0x5d, 0x2b }, /* ']' => '+' */
+ { 0x5e, 0x26 }, /* '^' => '&' */
+ { 0x5f, 0x3f }, /* '_' => '?' */
+ { 0x60, 0x5c }, /* '`' => '\\' */
+ { 0x7d, 0x2a }, /* '}' => '*' */
+ { 0x7e, 0x7c }, /* '~' => '|' */
+};
diff --git a/qemu/roms/ipxe/src/hci/keymap/keymap_lt.c b/qemu/roms/ipxe/src/hci/keymap/keymap_lt.c
new file mode 100644
index 000000000..3e99d8c6c
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/keymap/keymap_lt.c
@@ -0,0 +1,15 @@
+/** @file
+ *
+ * "lt" keyboard mapping
+ *
+ * This file is automatically generated; do not edit
+ *
+ */
+
+FILE_LICENCE ( PUBLIC_DOMAIN );
+
+#include <ipxe/keymap.h>
+
+/** "lt" keyboard mapping */
+struct key_mapping lt_mapping[] __keymap = {
+};
diff --git a/qemu/roms/ipxe/src/hci/keymap/keymap_mk.c b/qemu/roms/ipxe/src/hci/keymap/keymap_mk.c
new file mode 100644
index 000000000..8f5060778
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/keymap/keymap_mk.c
@@ -0,0 +1,15 @@
+/** @file
+ *
+ * "mk" keyboard mapping
+ *
+ * This file is automatically generated; do not edit
+ *
+ */
+
+FILE_LICENCE ( PUBLIC_DOMAIN );
+
+#include <ipxe/keymap.h>
+
+/** "mk" keyboard mapping */
+struct key_mapping mk_mapping[] __keymap = {
+};
diff --git a/qemu/roms/ipxe/src/hci/keymap/keymap_mt.c b/qemu/roms/ipxe/src/hci/keymap/keymap_mt.c
new file mode 100644
index 000000000..094a6fc60
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/keymap/keymap_mt.c
@@ -0,0 +1,20 @@
+/** @file
+ *
+ * "mt" keyboard mapping
+ *
+ * This file is automatically generated; do not edit
+ *
+ */
+
+FILE_LICENCE ( PUBLIC_DOMAIN );
+
+#include <ipxe/keymap.h>
+
+/** "mt" keyboard mapping */
+struct key_mapping mt_mapping[] __keymap = {
+ { 0x22, 0x40 }, /* '"' => '@' */
+ { 0x23, 0x04 }, /* '#' => Ctrl-D */
+ { 0x40, 0x22 }, /* '@' => '"' */
+ { 0x5c, 0x23 }, /* '\\' => '#' */
+ { 0x7c, 0x7e }, /* '|' => '~' */
+};
diff --git a/qemu/roms/ipxe/src/hci/keymap/keymap_nl.c b/qemu/roms/ipxe/src/hci/keymap/keymap_nl.c
new file mode 100644
index 000000000..ba051705e
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/keymap/keymap_nl.c
@@ -0,0 +1,34 @@
+/** @file
+ *
+ * "nl" keyboard mapping
+ *
+ * This file is automatically generated; do not edit
+ *
+ */
+
+FILE_LICENCE ( PUBLIC_DOMAIN );
+
+#include <ipxe/keymap.h>
+
+/** "nl" keyboard mapping */
+struct key_mapping nl_mapping[] __keymap = {
+ { 0x26, 0x5f }, /* '&' => '_' */
+ { 0x28, 0x29 }, /* '(' => ')' */
+ { 0x29, 0x27 }, /* ')' => '\'' */
+ { 0x2a, 0x28 }, /* '*' => '(' */
+ { 0x2b, 0x7e }, /* '+' => '~' */
+ { 0x2d, 0x2f }, /* '-' => '/' */
+ { 0x2f, 0x2d }, /* '/' => '-' */
+ { 0x3b, 0x2b }, /* ';' => '+' */
+ { 0x3c, 0x3b }, /* '<' => ';' */
+ { 0x3e, 0x3a }, /* '>' => ':' */
+ { 0x3f, 0x3d }, /* '?' => '=' */
+ { 0x40, 0x22 }, /* '@' => '"' */
+ { 0x5c, 0x3c }, /* '\\' => '<' */
+ { 0x5d, 0x2a }, /* ']' => '*' */
+ { 0x5e, 0x26 }, /* '^' => '&' */
+ { 0x5f, 0x3f }, /* '_' => '?' */
+ { 0x60, 0x40 }, /* '`' => '@' */
+ { 0x7c, 0x3e }, /* '|' => '>' */
+ { 0x7d, 0x7c }, /* '}' => '|' */
+};
diff --git a/qemu/roms/ipxe/src/hci/keymap/keymap_no-latin1.c b/qemu/roms/ipxe/src/hci/keymap/keymap_no-latin1.c
new file mode 100644
index 000000000..8c3e81b31
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/keymap/keymap_no-latin1.c
@@ -0,0 +1,34 @@
+/** @file
+ *
+ * "no-latin1" keyboard mapping
+ *
+ * This file is automatically generated; do not edit
+ *
+ */
+
+FILE_LICENCE ( PUBLIC_DOMAIN );
+
+#include <ipxe/keymap.h>
+
+/** "no-latin1" keyboard mapping */
+struct key_mapping no_latin1_mapping[] __keymap = {
+ { 0x26, 0x2f }, /* '&' => '/' */
+ { 0x28, 0x29 }, /* '(' => ')' */
+ { 0x29, 0x3d }, /* ')' => '=' */
+ { 0x2a, 0x28 }, /* '*' => '(' */
+ { 0x2b, 0x60 }, /* '+' => '`' */
+ { 0x2d, 0x2b }, /* '-' => '+' */
+ { 0x2f, 0x2d }, /* '/' => '-' */
+ { 0x3c, 0x3b }, /* '<' => ';' */
+ { 0x3d, 0x5c }, /* '=' => '\\' */
+ { 0x3e, 0x3a }, /* '>' => ':' */
+ { 0x3f, 0x5f }, /* '?' => '_' */
+ { 0x40, 0x22 }, /* '@' => '"' */
+ { 0x5c, 0x27 }, /* '\\' => '\'' */
+ { 0x5d, 0x7e }, /* ']' => '~' */
+ { 0x5e, 0x26 }, /* '^' => '&' */
+ { 0x5f, 0x3f }, /* '_' => '?' */
+ { 0x60, 0x7c }, /* '`' => '|' */
+ { 0x7c, 0x2a }, /* '|' => '*' */
+ { 0x7d, 0x5e }, /* '}' => '^' */
+};
diff --git a/qemu/roms/ipxe/src/hci/keymap/keymap_no.c b/qemu/roms/ipxe/src/hci/keymap/keymap_no.c
new file mode 100644
index 000000000..45cf9e847
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/keymap/keymap_no.c
@@ -0,0 +1,105 @@
+/** @file
+ *
+ * "no" keyboard mapping
+ *
+ * This file is automatically generated; do not edit
+ *
+ */
+
+FILE_LICENCE ( PUBLIC_DOMAIN );
+
+#include <ipxe/keymap.h>
+
+/** "no" keyboard mapping */
+struct key_mapping no_mapping[] __keymap = {
+ { 0x02, 0x18 }, /* Ctrl-B => Ctrl-X */
+ { 0x03, 0x0a }, /* Ctrl-C => Ctrl-J */
+ { 0x04, 0x05 }, /* Ctrl-D => Ctrl-E */
+ { 0x06, 0x15 }, /* Ctrl-F => Ctrl-U */
+ { 0x07, 0x09 }, /* Ctrl-G => Ctrl-I */
+ { 0x08, 0x04 }, /* Ctrl-H => Ctrl-D */
+ { 0x0a, 0x08 }, /* Ctrl-J => Ctrl-H */
+ { 0x0b, 0x14 }, /* Ctrl-K => Ctrl-T */
+ { 0x0c, 0x0e }, /* Ctrl-L => Ctrl-N */
+ { 0x0e, 0x02 }, /* Ctrl-N => Ctrl-B */
+ { 0x0f, 0x12 }, /* Ctrl-O => Ctrl-R */
+ { 0x10, 0x0c }, /* Ctrl-P => Ctrl-L */
+ { 0x12, 0x10 }, /* Ctrl-R => Ctrl-P */
+ { 0x13, 0x0f }, /* Ctrl-S => Ctrl-O */
+ { 0x14, 0x19 }, /* Ctrl-T => Ctrl-Y */
+ { 0x15, 0x07 }, /* Ctrl-U => Ctrl-G */
+ { 0x16, 0x0b }, /* Ctrl-V => Ctrl-K */
+ { 0x18, 0x11 }, /* Ctrl-X => Ctrl-Q */
+ { 0x19, 0x06 }, /* Ctrl-Y => Ctrl-F */
+ { 0x22, 0x5f }, /* '"' => '_' */
+ { 0x26, 0x2f }, /* '&' => '/' */
+ { 0x27, 0x2d }, /* '\'' => '-' */
+ { 0x28, 0x29 }, /* '(' => ')' */
+ { 0x29, 0x3d }, /* ')' => '=' */
+ { 0x2a, 0x28 }, /* '*' => '(' */
+ { 0x2b, 0x60 }, /* '+' => '`' */
+ { 0x2c, 0x77 }, /* ',' => 'w' */
+ { 0x2d, 0x2b }, /* '-' => '+' */
+ { 0x2e, 0x76 }, /* '.' => 'v' */
+ { 0x2f, 0x7a }, /* '/' => 'z' */
+ { 0x3a, 0x53 }, /* ':' => 'S' */
+ { 0x3b, 0x73 }, /* ';' => 's' */
+ { 0x3c, 0x57 }, /* '<' => 'W' */
+ { 0x3d, 0x5c }, /* '=' => '\\' */
+ { 0x3e, 0x56 }, /* '>' => 'V' */
+ { 0x3f, 0x5a }, /* '?' => 'Z' */
+ { 0x40, 0x22 }, /* '@' => '"' */
+ { 0x42, 0x58 }, /* 'B' => 'X' */
+ { 0x43, 0x4a }, /* 'C' => 'J' */
+ { 0x44, 0x45 }, /* 'D' => 'E' */
+ { 0x45, 0x3a }, /* 'E' => ':' */
+ { 0x46, 0x55 }, /* 'F' => 'U' */
+ { 0x47, 0x49 }, /* 'G' => 'I' */
+ { 0x48, 0x44 }, /* 'H' => 'D' */
+ { 0x49, 0x43 }, /* 'I' => 'C' */
+ { 0x4a, 0x48 }, /* 'J' => 'H' */
+ { 0x4b, 0x54 }, /* 'K' => 'T' */
+ { 0x4c, 0x4e }, /* 'L' => 'N' */
+ { 0x4e, 0x42 }, /* 'N' => 'B' */
+ { 0x4f, 0x52 }, /* 'O' => 'R' */
+ { 0x50, 0x4c }, /* 'P' => 'L' */
+ { 0x52, 0x50 }, /* 'R' => 'P' */
+ { 0x53, 0x4f }, /* 'S' => 'O' */
+ { 0x54, 0x59 }, /* 'T' => 'Y' */
+ { 0x55, 0x47 }, /* 'U' => 'G' */
+ { 0x56, 0x4b }, /* 'V' => 'K' */
+ { 0x57, 0x3b }, /* 'W' => ';' */
+ { 0x58, 0x51 }, /* 'X' => 'Q' */
+ { 0x59, 0x46 }, /* 'Y' => 'F' */
+ { 0x5b, 0x27 }, /* '[' => '\'' */
+ { 0x5c, 0x3c }, /* '\\' => '<' */
+ { 0x5d, 0x7e }, /* ']' => '~' */
+ { 0x5e, 0x26 }, /* '^' => '&' */
+ { 0x5f, 0x3f }, /* '_' => '?' */
+ { 0x60, 0x7c }, /* '`' => '|' */
+ { 0x62, 0x78 }, /* 'b' => 'x' */
+ { 0x63, 0x6a }, /* 'c' => 'j' */
+ { 0x64, 0x65 }, /* 'd' => 'e' */
+ { 0x65, 0x2e }, /* 'e' => '.' */
+ { 0x66, 0x75 }, /* 'f' => 'u' */
+ { 0x67, 0x69 }, /* 'g' => 'i' */
+ { 0x68, 0x64 }, /* 'h' => 'd' */
+ { 0x69, 0x63 }, /* 'i' => 'c' */
+ { 0x6a, 0x68 }, /* 'j' => 'h' */
+ { 0x6b, 0x74 }, /* 'k' => 't' */
+ { 0x6c, 0x6e }, /* 'l' => 'n' */
+ { 0x6e, 0x62 }, /* 'n' => 'b' */
+ { 0x6f, 0x72 }, /* 'o' => 'r' */
+ { 0x70, 0x6c }, /* 'p' => 'l' */
+ { 0x72, 0x70 }, /* 'r' => 'p' */
+ { 0x73, 0x6f }, /* 's' => 'o' */
+ { 0x74, 0x79 }, /* 't' => 'y' */
+ { 0x75, 0x67 }, /* 'u' => 'g' */
+ { 0x76, 0x6b }, /* 'v' => 'k' */
+ { 0x77, 0x2c }, /* 'w' => ',' */
+ { 0x78, 0x71 }, /* 'x' => 'q' */
+ { 0x79, 0x66 }, /* 'y' => 'f' */
+ { 0x7b, 0x2a }, /* '{' => '*' */
+ { 0x7c, 0x3e }, /* '|' => '>' */
+ { 0x7d, 0x5e }, /* '}' => '^' */
+};
diff --git a/qemu/roms/ipxe/src/hci/keymap/keymap_pl.c b/qemu/roms/ipxe/src/hci/keymap/keymap_pl.c
new file mode 100644
index 000000000..51822e072
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/keymap/keymap_pl.c
@@ -0,0 +1,15 @@
+/** @file
+ *
+ * "pl" keyboard mapping
+ *
+ * This file is automatically generated; do not edit
+ *
+ */
+
+FILE_LICENCE ( PUBLIC_DOMAIN );
+
+#include <ipxe/keymap.h>
+
+/** "pl" keyboard mapping */
+struct key_mapping pl_mapping[] __keymap = {
+};
diff --git a/qemu/roms/ipxe/src/hci/keymap/keymap_pt.c b/qemu/roms/ipxe/src/hci/keymap/keymap_pt.c
new file mode 100644
index 000000000..a8e44b6a3
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/keymap/keymap_pt.c
@@ -0,0 +1,29 @@
+/** @file
+ *
+ * "pt" keyboard mapping
+ *
+ * This file is automatically generated; do not edit
+ *
+ */
+
+FILE_LICENCE ( PUBLIC_DOMAIN );
+
+#include <ipxe/keymap.h>
+
+/** "pt" keyboard mapping */
+struct key_mapping pt_mapping[] __keymap = {
+ { 0x1c, 0x1d }, /* 0x1c => 0x1d */
+ { 0x1d, 0x1b }, /* 0x1d => 0x1b */
+ { 0x22, 0x5e }, /* '"' => '^' */
+ { 0x27, 0x7e }, /* '\'' => '~' */
+ { 0x2f, 0x3b }, /* '/' => ';' */
+ { 0x3f, 0x3a }, /* '?' => ':' */
+ { 0x5b, 0x27 }, /* '[' => '\'' */
+ { 0x5c, 0x5d }, /* '\\' => ']' */
+ { 0x5d, 0x5b }, /* ']' => '[' */
+ { 0x60, 0x27 }, /* '`' => '\'' */
+ { 0x7b, 0x60 }, /* '{' => '`' */
+ { 0x7c, 0x7d }, /* '|' => '}' */
+ { 0x7d, 0x7b }, /* '}' => '{' */
+ { 0x7e, 0x22 }, /* '~' => '"' */
+};
diff --git a/qemu/roms/ipxe/src/hci/keymap/keymap_ro.c b/qemu/roms/ipxe/src/hci/keymap/keymap_ro.c
new file mode 100644
index 000000000..0eef7d534
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/keymap/keymap_ro.c
@@ -0,0 +1,15 @@
+/** @file
+ *
+ * "ro" keyboard mapping
+ *
+ * This file is automatically generated; do not edit
+ *
+ */
+
+FILE_LICENCE ( PUBLIC_DOMAIN );
+
+#include <ipxe/keymap.h>
+
+/** "ro" keyboard mapping */
+struct key_mapping ro_mapping[] __keymap = {
+};
diff --git a/qemu/roms/ipxe/src/hci/keymap/keymap_ru.c b/qemu/roms/ipxe/src/hci/keymap/keymap_ru.c
new file mode 100644
index 000000000..422b6c69f
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/keymap/keymap_ru.c
@@ -0,0 +1,15 @@
+/** @file
+ *
+ * "ru" keyboard mapping
+ *
+ * This file is automatically generated; do not edit
+ *
+ */
+
+FILE_LICENCE ( PUBLIC_DOMAIN );
+
+#include <ipxe/keymap.h>
+
+/** "ru" keyboard mapping */
+struct key_mapping ru_mapping[] __keymap = {
+};
diff --git a/qemu/roms/ipxe/src/hci/keymap/keymap_sg.c b/qemu/roms/ipxe/src/hci/keymap/keymap_sg.c
new file mode 100644
index 000000000..0b0820929
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/keymap/keymap_sg.c
@@ -0,0 +1,41 @@
+/** @file
+ *
+ * "sg" keyboard mapping
+ *
+ * This file is automatically generated; do not edit
+ *
+ */
+
+FILE_LICENCE ( PUBLIC_DOMAIN );
+
+#include <ipxe/keymap.h>
+
+/** "sg" keyboard mapping */
+struct key_mapping sg_mapping[] __keymap = {
+ { 0x19, 0x1a }, /* Ctrl-Y => Ctrl-Z */
+ { 0x1a, 0x19 }, /* Ctrl-Z => Ctrl-Y */
+ { 0x21, 0x2b }, /* '!' => '+' */
+ { 0x23, 0x2a }, /* '#' => '*' */
+ { 0x24, 0x34 }, /* '$' => '4' */
+ { 0x26, 0x2f }, /* '&' => '/' */
+ { 0x28, 0x29 }, /* '(' => ')' */
+ { 0x29, 0x3d }, /* ')' => '=' */
+ { 0x2a, 0x28 }, /* '*' => '(' */
+ { 0x2b, 0x60 }, /* '+' => '`' */
+ { 0x2d, 0x27 }, /* '-' => '\'' */
+ { 0x2f, 0x2d }, /* '/' => '-' */
+ { 0x3c, 0x3b }, /* '<' => ';' */
+ { 0x3d, 0x5e }, /* '=' => '^' */
+ { 0x3e, 0x3a }, /* '>' => ':' */
+ { 0x3f, 0x5f }, /* '?' => '_' */
+ { 0x40, 0x22 }, /* '@' => '"' */
+ { 0x59, 0x5a }, /* 'Y' => 'Z' */
+ { 0x5a, 0x59 }, /* 'Z' => 'Y' */
+ { 0x5c, 0x24 }, /* '\\' => '$' */
+ { 0x5e, 0x26 }, /* '^' => '&' */
+ { 0x5f, 0x3f }, /* '_' => '?' */
+ { 0x79, 0x7a }, /* 'y' => 'z' */
+ { 0x7a, 0x79 }, /* 'z' => 'y' */
+ { 0x7c, 0x24 }, /* '|' => '$' */
+ { 0x7d, 0x21 }, /* '}' => '!' */
+};
diff --git a/qemu/roms/ipxe/src/hci/keymap/keymap_sr.c b/qemu/roms/ipxe/src/hci/keymap/keymap_sr.c
new file mode 100644
index 000000000..0552f4d90
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/keymap/keymap_sr.c
@@ -0,0 +1,35 @@
+/** @file
+ *
+ * "sr" keyboard mapping
+ *
+ * This file is automatically generated; do not edit
+ *
+ */
+
+FILE_LICENCE ( PUBLIC_DOMAIN );
+
+#include <ipxe/keymap.h>
+
+/** "sr" keyboard mapping */
+struct key_mapping sr_mapping[] __keymap = {
+ { 0x19, 0x1a }, /* Ctrl-Y => Ctrl-Z */
+ { 0x1a, 0x19 }, /* Ctrl-Z => Ctrl-Y */
+ { 0x26, 0x2f }, /* '&' => '/' */
+ { 0x28, 0x29 }, /* '(' => ')' */
+ { 0x29, 0x3d }, /* ')' => '=' */
+ { 0x2a, 0x28 }, /* '*' => '(' */
+ { 0x2b, 0x2a }, /* '+' => '*' */
+ { 0x2d, 0x27 }, /* '-' => '\'' */
+ { 0x2f, 0x2d }, /* '/' => '-' */
+ { 0x3c, 0x3b }, /* '<' => ';' */
+ { 0x3d, 0x2b }, /* '=' => '+' */
+ { 0x3e, 0x3a }, /* '>' => ':' */
+ { 0x3f, 0x5f }, /* '?' => '_' */
+ { 0x40, 0x22 }, /* '@' => '"' */
+ { 0x59, 0x5a }, /* 'Y' => 'Z' */
+ { 0x5a, 0x59 }, /* 'Z' => 'Y' */
+ { 0x5e, 0x26 }, /* '^' => '&' */
+ { 0x5f, 0x3f }, /* '_' => '?' */
+ { 0x79, 0x7a }, /* 'y' => 'z' */
+ { 0x7a, 0x79 }, /* 'z' => 'y' */
+};
diff --git a/qemu/roms/ipxe/src/hci/keymap/keymap_th.c b/qemu/roms/ipxe/src/hci/keymap/keymap_th.c
new file mode 100644
index 000000000..e8b44d1ed
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/keymap/keymap_th.c
@@ -0,0 +1,15 @@
+/** @file
+ *
+ * "th" keyboard mapping
+ *
+ * This file is automatically generated; do not edit
+ *
+ */
+
+FILE_LICENCE ( PUBLIC_DOMAIN );
+
+#include <ipxe/keymap.h>
+
+/** "th" keyboard mapping */
+struct key_mapping th_mapping[] __keymap = {
+};
diff --git a/qemu/roms/ipxe/src/hci/keymap/keymap_ua.c b/qemu/roms/ipxe/src/hci/keymap/keymap_ua.c
new file mode 100644
index 000000000..1106a8b28
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/keymap/keymap_ua.c
@@ -0,0 +1,15 @@
+/** @file
+ *
+ * "ua" keyboard mapping
+ *
+ * This file is automatically generated; do not edit
+ *
+ */
+
+FILE_LICENCE ( PUBLIC_DOMAIN );
+
+#include <ipxe/keymap.h>
+
+/** "ua" keyboard mapping */
+struct key_mapping ua_mapping[] __keymap = {
+};
diff --git a/qemu/roms/ipxe/src/hci/keymap/keymap_uk.c b/qemu/roms/ipxe/src/hci/keymap/keymap_uk.c
new file mode 100644
index 000000000..6550d8ee5
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/keymap/keymap_uk.c
@@ -0,0 +1,19 @@
+/** @file
+ *
+ * "uk" keyboard mapping
+ *
+ * This file is automatically generated; do not edit
+ *
+ */
+
+FILE_LICENCE ( PUBLIC_DOMAIN );
+
+#include <ipxe/keymap.h>
+
+/** "uk" keyboard mapping */
+struct key_mapping uk_mapping[] __keymap = {
+ { 0x22, 0x40 }, /* '"' => '@' */
+ { 0x40, 0x22 }, /* '@' => '"' */
+ { 0x5c, 0x23 }, /* '\\' => '#' */
+ { 0x7c, 0x7e }, /* '|' => '~' */
+};
diff --git a/qemu/roms/ipxe/src/hci/keymap/keymap_us.c b/qemu/roms/ipxe/src/hci/keymap/keymap_us.c
new file mode 100644
index 000000000..73d01a30a
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/keymap/keymap_us.c
@@ -0,0 +1,15 @@
+/** @file
+ *
+ * "us" keyboard mapping
+ *
+ * This file is automatically generated; do not edit
+ *
+ */
+
+FILE_LICENCE ( PUBLIC_DOMAIN );
+
+#include <ipxe/keymap.h>
+
+/** "us" keyboard mapping */
+struct key_mapping us_mapping[] __keymap = {
+};
diff --git a/qemu/roms/ipxe/src/hci/keymap/keymap_wo.c b/qemu/roms/ipxe/src/hci/keymap/keymap_wo.c
new file mode 100644
index 000000000..b45357612
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/keymap/keymap_wo.c
@@ -0,0 +1,55 @@
+/** @file
+ *
+ * "wo" keyboard mapping
+ *
+ * This file is automatically generated; do not edit
+ *
+ */
+
+FILE_LICENCE ( PUBLIC_DOMAIN );
+
+#include <ipxe/keymap.h>
+
+/** "wo" keyboard mapping */
+struct key_mapping wo_mapping[] __keymap = {
+ { 0x01, 0x11 }, /* Ctrl-A => Ctrl-Q */
+ { 0x11, 0x01 }, /* Ctrl-Q => Ctrl-A */
+ { 0x17, 0x1a }, /* Ctrl-W => Ctrl-Z */
+ { 0x1a, 0x17 }, /* Ctrl-Z => Ctrl-W */
+ { 0x21, 0x31 }, /* '!' => '1' */
+ { 0x23, 0x33 }, /* '#' => '3' */
+ { 0x24, 0x34 }, /* '$' => '4' */
+ { 0x25, 0x35 }, /* '%' => '5' */
+ { 0x26, 0x37 }, /* '&' => '7' */
+ { 0x28, 0x39 }, /* '(' => '9' */
+ { 0x29, 0x30 }, /* ')' => '0' */
+ { 0x2a, 0x38 }, /* '*' => '8' */
+ { 0x2c, 0x3b }, /* ',' => ';' */
+ { 0x2d, 0x29 }, /* '-' => ')' */
+ { 0x2e, 0x3a }, /* '.' => ':' */
+ { 0x2f, 0x21 }, /* '/' => '!' */
+ { 0x31, 0x26 }, /* '1' => '&' */
+ { 0x33, 0x22 }, /* '3' => '"' */
+ { 0x34, 0x27 }, /* '4' => '\'' */
+ { 0x35, 0x28 }, /* '5' => '(' */
+ { 0x36, 0x2d }, /* '6' => '-' */
+ { 0x38, 0x5f }, /* '8' => '_' */
+ { 0x3a, 0x4d }, /* ':' => 'M' */
+ { 0x3b, 0x6d }, /* ';' => 'm' */
+ { 0x3c, 0x2e }, /* '<' => '.' */
+ { 0x3e, 0x2f }, /* '>' => '/' */
+ { 0x40, 0x32 }, /* '@' => '2' */
+ { 0x41, 0x51 }, /* 'A' => 'Q' */
+ { 0x4d, 0x3f }, /* 'M' => '?' */
+ { 0x51, 0x41 }, /* 'Q' => 'A' */
+ { 0x57, 0x5a }, /* 'W' => 'Z' */
+ { 0x5a, 0x57 }, /* 'Z' => 'W' */
+ { 0x5d, 0x24 }, /* ']' => '$' */
+ { 0x5e, 0x36 }, /* '^' => '6' */
+ { 0x61, 0x71 }, /* 'a' => 'q' */
+ { 0x6d, 0x2c }, /* 'm' => ',' */
+ { 0x71, 0x61 }, /* 'q' => 'a' */
+ { 0x77, 0x7a }, /* 'w' => 'z' */
+ { 0x7a, 0x77 }, /* 'z' => 'w' */
+ { 0x7e, 0x25 }, /* '~' => '%' */
+};
diff --git a/qemu/roms/ipxe/src/hci/linux_args.c b/qemu/roms/ipxe/src/hci/linux_args.c
new file mode 100644
index 000000000..58eeb063e
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/linux_args.c
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2010 Piotr Jaroszyński <p.jaroszynski@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+FILE_LICENCE(GPL2_OR_LATER);
+
+#include <hci/linux_args.h>
+#include <getopt.h>
+#include <string.h>
+#include <stdio.h>
+#include <ipxe/settings.h>
+#include <ipxe/linux.h>
+#include <ipxe/malloc.h>
+#include <ipxe/init.h>
+
+/** Saved argc */
+static int saved_argc = 0;
+/** Saved argv */
+static char ** saved_argv;
+
+/**
+ * Save argc and argv for later access.
+ *
+ * To be called by linuxprefix
+ */
+__asmcall void save_args(int argc, char **argv)
+{
+ saved_argc = argc;
+ saved_argv = argv;
+}
+
+/** Supported command-line options */
+static struct option options[] = {
+ {"net", 1, NULL, 'n'},
+ {"settings", 1, NULL, 's'},
+ {NULL, 0, NULL, 0}
+};
+
+/**
+ * Parse k1=v1[,k2=v2]* into linux_settings
+ */
+static int parse_kv(char *kv, struct list_head *list)
+{
+ char *token;
+ char *name;
+ char *value;
+ struct linux_setting *setting;
+
+ while ((token = strsep(&kv, ",")) != NULL) {
+ name = strsep(&token, "=");
+ if (name == NULL)
+ continue;
+ value = token;
+ if (value == NULL) {
+ DBG("Bad parameter: '%s'\n", name);
+ continue;
+ }
+
+ setting = malloc(sizeof(*setting));
+
+ if (! setting)
+ return -1;
+
+ setting->name = name;
+ setting->value = value;
+ setting->applied = 0;
+ list_add(&setting->list, list);
+ }
+
+ return 0;
+}
+
+/**
+ * Parse --net arguments
+ *
+ * Format is --net driver_name[,name=value]*
+ */
+static int parse_net_args(char *args)
+{
+ char *driver;
+ struct linux_device_request *dev_request;
+ int rc;
+
+ driver = strsep(&args, ",");
+
+ if (strlen(driver) == 0) {
+ printf("Missing driver name");
+ return -1;
+ }
+
+ dev_request = malloc(sizeof(*dev_request));
+
+ dev_request->driver = driver;
+ INIT_LIST_HEAD(&dev_request->settings);
+ list_add_tail(&dev_request->list, &linux_device_requests);
+
+ /* Parse rest of the settings */
+ rc = parse_kv(args, &dev_request->settings);
+
+ if (rc)
+ printf("Parsing net settings failed");
+
+ return rc;
+}
+
+/**
+ * Parse --settings arguments
+ *
+ * Format is --settings name=value[,name=value]*
+ */
+static int parse_settings_args(char *args)
+{
+ return parse_kv(args, &linux_global_settings);
+}
+
+
+/** Parse passed command-line arguments */
+void linux_args_parse()
+{
+ int c;
+ int rc;
+
+ reset_getopt();
+ while (1) {
+ int option_index = 0;
+
+ c = getopt_long(saved_argc, saved_argv, "", options, &option_index);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'n':
+ if ((rc = parse_net_args(optarg)) != 0)
+ return;
+ break;
+ case 's':
+ if ((rc = parse_settings_args(optarg)) != 0)
+ return;
+ break;
+ default:
+ return;
+ }
+ }
+
+ return;
+}
+
+/** Clean up requests and settings */
+void linux_args_cleanup(int flags __unused)
+{
+ struct linux_device_request *request;
+ struct linux_device_request *rtmp;
+ struct linux_setting *setting;
+ struct linux_setting *stmp;
+
+ /* Clean up requests and their settings */
+ list_for_each_entry_safe(request, rtmp, &linux_device_requests, list) {
+ list_for_each_entry_safe(setting, stmp, &request->settings, list) {
+ list_del(&setting->list);
+ free(setting);
+ }
+ list_del(&request->list);
+ free(request);
+ }
+
+ /* Clean up global settings */
+ list_for_each_entry_safe(setting, stmp, &linux_global_settings, list) {
+ list_del(&setting->list);
+ free(setting);
+ }
+}
+
+struct startup_fn startup_linux_args __startup_fn(STARTUP_EARLY) = {
+ .startup = linux_args_parse,
+ .shutdown = linux_args_cleanup,
+};
diff --git a/qemu/roms/ipxe/src/hci/mucurses/alert.c b/qemu/roms/ipxe/src/hci/mucurses/alert.c
new file mode 100644
index 000000000..00e959a89
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/mucurses/alert.c
@@ -0,0 +1,18 @@
+#include <curses.h>
+#include <stdio.h>
+
+/** @file
+ *
+ * MuCurses alert functions
+ *
+ */
+
+/**
+ * Audible signal
+ *
+ * @ret rc return status code
+ */
+int beep ( void ) {
+ printf("\a");
+ return OK;
+}
diff --git a/qemu/roms/ipxe/src/hci/mucurses/ansi_screen.c b/qemu/roms/ipxe/src/hci/mucurses/ansi_screen.c
new file mode 100644
index 000000000..1d3143f89
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/mucurses/ansi_screen.c
@@ -0,0 +1,102 @@
+#include <stdio.h>
+#include <curses.h>
+#include <ipxe/ansicol.h>
+#include <ipxe/console.h>
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+static void ansiscr_reset(struct _curses_screen *scr) __nonnull;
+static void ansiscr_movetoyx(struct _curses_screen *scr,
+ unsigned int y, unsigned int x) __nonnull;
+static void ansiscr_putc(struct _curses_screen *scr, chtype c) __nonnull;
+
+static unsigned int saved_usage;
+
+static void ansiscr_attrs ( struct _curses_screen *scr, attr_t attrs ) {
+ int bold = ( attrs & A_BOLD );
+ attr_t cpair = PAIR_NUMBER ( attrs );
+
+ if ( scr->attrs != attrs ) {
+ scr->attrs = attrs;
+ /* Reset attributes and set/clear bold as appropriate */
+ printf ( "\033[0;%dm", ( bold ? 1 : 22 ) );
+ /* Set foreground and background colours */
+ ansicol_set_pair ( cpair );
+ }
+}
+
+static void ansiscr_reset ( struct _curses_screen *scr ) {
+ /* Reset terminal attributes and clear screen */
+ scr->attrs = 0;
+ scr->curs_x = 0;
+ scr->curs_y = 0;
+ printf ( "\0330m" );
+ ansicol_set_pair ( CPAIR_DEFAULT );
+ printf ( "\033[2J" );
+}
+
+static void ansiscr_init ( struct _curses_screen *scr ) {
+ saved_usage = console_set_usage ( CONSOLE_USAGE_TUI );
+ ansiscr_reset ( scr );
+}
+
+static void ansiscr_exit ( struct _curses_screen *scr ) {
+ ansiscr_reset ( scr );
+ console_set_usage ( saved_usage );
+}
+
+static void ansiscr_erase ( struct _curses_screen *scr, attr_t attrs ) {
+ ansiscr_attrs ( scr, attrs );
+ printf ( "\033[2J" );
+}
+
+static void ansiscr_movetoyx ( struct _curses_screen *scr,
+ unsigned int y, unsigned int x ) {
+ if ( ( x != scr->curs_x ) || ( y != scr->curs_y ) ) {
+ /* ANSI escape sequence to update cursor position */
+ printf ( "\033[%d;%dH", ( y + 1 ), ( x + 1 ) );
+ scr->curs_x = x;
+ scr->curs_y = y;
+ }
+}
+
+static void ansiscr_putc ( struct _curses_screen *scr, chtype c ) {
+ unsigned int character = ( c & A_CHARTEXT );
+ attr_t attrs = ( c & ( A_ATTRIBUTES | A_COLOR ) );
+
+ /* Update attributes if changed */
+ ansiscr_attrs ( scr, attrs );
+
+ /* Print the actual character */
+ putchar ( character );
+
+ /* Update expected cursor position */
+ if ( ++(scr->curs_x) == COLS ) {
+ scr->curs_x = 0;
+ ++scr->curs_y;
+ }
+}
+
+static int ansiscr_getc ( struct _curses_screen *scr __unused ) {
+ return getchar();
+}
+
+static bool ansiscr_peek ( struct _curses_screen *scr __unused ) {
+ return iskey();
+}
+
+static void ansiscr_cursor ( struct _curses_screen *scr __unused,
+ int visibility ) {
+ printf ( "\033[?25%c", ( visibility ? 'h' : 'l' ) );
+}
+
+SCREEN _ansi_screen = {
+ .init = ansiscr_init,
+ .exit = ansiscr_exit,
+ .erase = ansiscr_erase,
+ .movetoyx = ansiscr_movetoyx,
+ .putc = ansiscr_putc,
+ .getc = ansiscr_getc,
+ .peek = ansiscr_peek,
+ .cursor = ansiscr_cursor,
+};
diff --git a/qemu/roms/ipxe/src/hci/mucurses/clear.c b/qemu/roms/ipxe/src/hci/mucurses/clear.c
new file mode 100644
index 000000000..f5e52ca20
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/mucurses/clear.c
@@ -0,0 +1,100 @@
+#include <curses.h>
+#include "mucurses.h"
+#include "cursor.h"
+
+/** @file
+ *
+ * MuCurses clearing functions
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+/**
+ * Clear a window to the bottom from current cursor position
+ *
+ * @v *win subject window
+ * @ret rc return status code
+ */
+int wclrtobot ( WINDOW *win ) {
+ struct cursor_pos pos;
+
+ _store_curs_pos( win, &pos );
+ do {
+ _wputc( win, ' ', WRAP );
+ } while ( win->curs_y + win->curs_x );
+ _restore_curs_pos( win, &pos );
+
+ return OK;
+}
+
+/**
+ * Clear a window to the end of the current line
+ *
+ * @v *win subject window
+ * @ret rc return status code
+ */
+int wclrtoeol ( WINDOW *win ) {
+ struct cursor_pos pos;
+
+ _store_curs_pos( win, &pos );
+ while ( ( win->curs_y - pos.y ) == 0 ) {
+ _wputc( win, ' ', WRAP );
+ }
+ _restore_curs_pos( win, &pos );
+
+ return OK;
+}
+
+/**
+ * Delete character under the cursor in a window
+ *
+ * @v *win subject window
+ * @ret rc return status code
+ */
+int wdelch ( WINDOW *win ) {
+ _wputc( win, ' ', NOWRAP );
+ _wcursback( win );
+
+ return OK;
+}
+
+/**
+ * Delete line under a window's cursor
+ *
+ * @v *win subject window
+ * @ret rc return status code
+ */
+int wdeleteln ( WINDOW *win ) {
+ struct cursor_pos pos;
+
+ _store_curs_pos( win, &pos );
+ /* let's just set the cursor to the beginning of the line and
+ let wclrtoeol do the work :) */
+ wmove( win, win->curs_y, 0 );
+ wclrtoeol( win );
+ _restore_curs_pos( win, &pos );
+ return OK;
+}
+
+/**
+ * Completely clear a window
+ *
+ * @v *win subject window
+ * @ret rc return status code
+ */
+int werase ( WINDOW *win ) {
+ wmove( win, 0, 0 );
+ wclrtobot( win );
+ return OK;
+}
+
+/**
+ * Completely clear the screen
+ *
+ * @ret rc return status code
+ */
+int erase ( void ) {
+ stdscr->scr->erase( stdscr->scr, stdscr->attrs );
+ return OK;
+}
diff --git a/qemu/roms/ipxe/src/hci/mucurses/colour.c b/qemu/roms/ipxe/src/hci/mucurses/colour.c
new file mode 100644
index 000000000..c1359c868
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/mucurses/colour.c
@@ -0,0 +1,66 @@
+#include <curses.h>
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+struct colour_pair {
+ short fcol;
+ short bcol;
+};
+
+static struct colour_pair cpairs[COLOUR_PAIRS] = {
+ [0] = { COLOUR_WHITE, COLOUR_BLACK },
+};
+
+/**
+ * Identify the RGB components of a given colour value
+ *
+ * @v colour colour value
+ * @v *red address to store red component
+ * @v *green address to store green component
+ * @v *blue address to store blue component
+ * @ret rc return status code
+ */
+int colour_content ( short colour, short *red, short *green, short *blue ) {
+ *red = ( ( colour & COLOUR_RED ) ? 1 : 0 );
+ *green = ( ( colour & COLOUR_GREEN ) ? 1 : 0 );
+ *blue = ( ( colour & COLOUR_BLUE ) ? 1 : 0 );
+ return OK;
+}
+
+/**
+ * Initialise colour pair
+ *
+ * @v pair colour pair number
+ * @v fcol foreground colour
+ * @v bcol background colour
+ */
+int init_pair ( short pair, short fcol, short bcol ) {
+ struct colour_pair *cpair;
+
+ if ( ( pair < 1 ) || ( pair >= COLOUR_PAIRS ) )
+ return ERR;
+
+ cpair = &cpairs[pair];
+ cpair->fcol = fcol;
+ cpair->bcol = bcol;
+ return OK;
+}
+
+/**
+ * Get colours of colour pair
+ *
+ * @v pair colour pair number
+ * @ret fcol foreground colour
+ * @ret bcol background colour
+ */
+int pair_content ( short pair, short *fcol, short *bcol ) {
+ struct colour_pair *cpair;
+
+ if ( ( pair < 0 ) || ( pair >= COLOUR_PAIRS ) )
+ return ERR;
+
+ cpair = &cpairs[pair];
+ *fcol = cpair->fcol;
+ *bcol = cpair->bcol;
+ return OK;
+}
diff --git a/qemu/roms/ipxe/src/hci/mucurses/cursor.h b/qemu/roms/ipxe/src/hci/mucurses/cursor.h
new file mode 100644
index 000000000..16b7d27c2
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/mucurses/cursor.h
@@ -0,0 +1,37 @@
+#ifndef CURSOR_H
+#define CURSOR_H
+
+/** @file
+ *
+ * MuCurses cursor implementation specific header file
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+struct cursor_pos {
+ unsigned int y, x;
+};
+
+/**
+ * Restore cursor position from encoded backup variable
+ *
+ * @v *win window on which to operate
+ * @v *pos pointer to struct in which original cursor position is stored
+ */
+static inline void _restore_curs_pos ( WINDOW *win, struct cursor_pos *pos ) {
+ wmove ( win, pos->y, pos->x );
+}
+
+/**
+ * Store cursor position for later restoration
+ *
+ * @v *win window on which to operate
+ * @v *pos pointer to struct in which to store cursor position
+ */
+static inline void _store_curs_pos ( WINDOW *win, struct cursor_pos *pos ) {
+ pos->y = win->curs_y;
+ pos->x = win->curs_x;
+}
+
+#endif /* CURSOR_H */
diff --git a/qemu/roms/ipxe/src/hci/mucurses/edging.c b/qemu/roms/ipxe/src/hci/mucurses/edging.c
new file mode 100644
index 000000000..eccd32422
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/mucurses/edging.c
@@ -0,0 +1,111 @@
+#include <curses.h>
+#include "mucurses.h"
+#include "cursor.h"
+
+/** @file
+ *
+ * MuCurses edging functions
+ *
+ */
+
+/**
+ * Draw borders from single-byte characters and renditions around a
+ * window
+ *
+ * @v *win window to be bordered
+ * @v verch vertical chtype
+ * @v horch horizontal chtype
+ * @ret rc return status code
+ */
+int box ( WINDOW *win, chtype verch, chtype horch ) {
+ chtype corner = '+' | win->attrs; /* default corner character */
+ return wborder( win, verch, verch, horch, horch,
+ corner, corner, corner, corner );
+}
+
+/**
+ * Draw borders from single-byte characters and renditions around a
+ * window
+ *
+ * @v *win window to be bordered
+ * @v ls left side
+ * @v rs right side
+ * @v ts top
+ * @v bs bottom
+ * @v tl top left corner
+ * @v tr top right corner
+ * @v bl bottom left corner
+ * @v br bottom right corner
+ * @ret rc return status code
+ */
+int wborder ( WINDOW *win, chtype ls, chtype rs,
+ chtype ts, chtype bs, chtype tl,
+ chtype tr, chtype bl, chtype br ) {
+ struct cursor_pos pos;
+
+ _store_curs_pos( win, &pos );
+ wmove(win,0,0);
+
+ _wputch(win,tl,WRAP);
+ while ( ( win->width - 1 ) - win->curs_x ) {
+ _wputch(win,ts,WRAP);
+ }
+ _wputch(win,tr,WRAP);
+
+ while ( ( win->height - 1 ) - win->curs_y ) {
+ _wputch(win,ls,WRAP);
+ wmove(win,win->curs_y,(win->width)-1);
+ _wputch(win,rs,WRAP);
+ }
+
+ _wputch(win,bl,WRAP);
+ while ( ( win->width -1 ) - win->curs_x ) {
+ _wputch(win,bs,WRAP);
+ }
+ _wputch(win,br,NOWRAP); /* do not wrap last char to leave
+ cursor in last position */
+ _restore_curs_pos( win, &pos );
+
+ return OK;
+}
+
+/**
+ * Create a horizontal line in a window
+ *
+ * @v *win subject window
+ * @v ch rendition and character
+ * @v n max number of chars (wide) to render
+ * @ret rc return status code
+ */
+int whline ( WINDOW *win, chtype ch, int n ) {
+ struct cursor_pos pos;
+
+ _store_curs_pos ( win, &pos );
+ while ( ( win->curs_x - win->width ) && n-- ) {
+ _wputch ( win, ch, NOWRAP );
+ }
+ _restore_curs_pos ( win, &pos );
+
+ return OK;
+}
+
+/**
+ * Create a vertical line in a window
+ *
+ * @v *win subject window
+ * @v ch rendition and character
+ * @v n max number of chars (high) to render
+ * @ret rc return status code
+ */
+int wvline ( WINDOW *win, chtype ch, int n ) {
+ struct cursor_pos pos;
+
+ _store_curs_pos ( win, &pos );
+ while ( ( win->curs_y - win->height ) && n-- ) {
+ _wputch ( win, ch, NOWRAP );
+ wmove( win, ++(win->curs_y), pos.x);
+ }
+ _restore_curs_pos ( win, &pos );
+
+ return OK;
+}
diff --git a/qemu/roms/ipxe/src/hci/mucurses/kb.c b/qemu/roms/ipxe/src/hci/mucurses/kb.c
new file mode 100644
index 000000000..b38c8c146
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/mucurses/kb.c
@@ -0,0 +1,143 @@
+#include <curses.h>
+#include <stddef.h>
+#include <unistd.h>
+#include "mucurses.h"
+
+/** @file
+ *
+ * MuCurses keyboard input handling functions
+ */
+
+#define INPUT_DELAY 200 // half-blocking delay timer resolution (ms)
+#define INPUT_DELAY_TIMEOUT 1000 // half-blocking delay timeout
+
+int m_delay; /*
+ < 0 : blocking read
+ 0 : non-blocking read
+ > 0 : timed blocking read
+ */
+bool m_echo;
+bool m_cbreak;
+
+static int _wgetc ( WINDOW *win ) {
+ int timer, c;
+
+ if ( win == NULL )
+ return ERR;
+
+ timer = INPUT_DELAY_TIMEOUT;
+ while ( ! win->scr->peek( win->scr ) ) {
+ if ( m_delay == 0 ) // non-blocking read
+ return ERR;
+ if ( timer > 0 ) { // time-limited blocking read
+ if ( m_delay > 0 )
+ timer -= INPUT_DELAY;
+ mdelay( INPUT_DELAY );
+ } else { return ERR; } // non-blocking read
+ }
+
+ c = win->scr->getc( win->scr );
+
+ if ( m_echo && ( c >= 32 && c <= 126 ) ) // printable ASCII characters
+ _wputch( win, (chtype) ( c | win->attrs ), WRAP );
+
+ return c;
+}
+
+/**
+ * Pop a character from the FIFO into a window
+ *
+ * @v *win window in which to echo input
+ * @ret c char from input stream
+ */
+int wgetch ( WINDOW *win ) {
+ int c;
+
+ c = _wgetc( win );
+
+ if ( m_echo ) {
+ if ( c >= KEY_MIN ) {
+ switch(c) {
+ case KEY_LEFT :
+ case KEY_BACKSPACE :
+ _wcursback( win );
+ wdelch( win );
+ break;
+ default :
+ beep();
+ break;
+ }
+ } else {
+ _wputch( win, (chtype)( c | win->attrs ), WRAP );
+ }
+ }
+
+ return c;
+}
+
+/**
+ * Read at most n characters from the FIFO into a window
+ *
+ * @v *win window in which to echo input
+ * @v *str pointer to string in which to store result
+ * @v n maximum number of characters to read into string (inc. NUL)
+ * @ret rc return status code
+ */
+int wgetnstr ( WINDOW *win, char *str, int n ) {
+ char *_str;
+ int c;
+
+ if ( n == 0 ) {
+ *str = '\0';
+ return OK;
+ }
+
+ _str = str;
+
+ while ( ( c = _wgetc( win ) ) != ERR ) {
+ /* termination enforcement - don't let us go past the
+ end of the allocated buffer... */
+ if ( n == 0 && ( c >= 32 && c <= 126 ) ) {
+ _wcursback( win );
+ wdelch( win );
+ } else {
+ if ( c >= KEY_MIN ) {
+ switch(c) {
+ case KEY_LEFT :
+ case KEY_BACKSPACE :
+ _wcursback( win );
+ wdelch( win );
+ break;
+ case KEY_ENTER :
+ *_str = '\0';
+ return OK;
+ default :
+ beep();
+ break;
+ }
+ }
+ if ( c >= 32 && c <= 126 ) {
+ *(_str++) = c; n--;
+ }
+ }
+ }
+
+ return ERR;
+}
+
+
+/**
+ *
+ */
+int echo ( void ) {
+ m_echo = TRUE;
+ return OK;
+}
+
+/**
+ *
+ */
+int noecho ( void ) {
+ m_echo = FALSE;
+ return OK;
+}
diff --git a/qemu/roms/ipxe/src/hci/mucurses/mucurses.c b/qemu/roms/ipxe/src/hci/mucurses/mucurses.c
new file mode 100644
index 000000000..b67445baf
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/mucurses/mucurses.c
@@ -0,0 +1,156 @@
+#include <curses.h>
+#include "mucurses.h"
+
+/** @file
+ *
+ * MuCurses core functions
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+static void _wupdcurs ( WINDOW *win ) __nonnull;
+void _wputch ( WINDOW *win, chtype ch, int wrap ) __nonnull;
+void _wputc ( WINDOW *win, char c, int wrap ) __nonnull;
+void _wcursback ( WINDOW *win ) __nonnull;
+void _wputchstr ( WINDOW *win, const chtype *chstr, int wrap, int n ) __nonnull;
+void _wputstr ( WINDOW *win, const char *str, int wrap, int n ) __nonnull;
+int wmove ( WINDOW *win, int y, int x ) __nonnull;
+
+WINDOW _stdscr = {
+ .attrs = A_DEFAULT,
+ .ori_y = 0,
+ .ori_x = 0,
+ .curs_y = 0,
+ .curs_x = 0,
+ .scr = &_ansi_screen,
+};
+
+/*
+ * Primitives
+ */
+
+/**
+ * Update cursor position
+ *
+ * @v *win window in which to update position
+ */
+static void _wupdcurs ( WINDOW *win ) {
+ win->scr->movetoyx ( win->scr, win->ori_y + win->curs_y,
+ win->ori_x + win->curs_x );
+}
+
+/**
+ * Write a single character rendition to a window
+ *
+ * @v *win window in which to write
+ * @v ch character rendition to write
+ * @v wrap wrap "switch"
+ */
+void _wputch ( WINDOW *win, chtype ch, int wrap ) {
+ /* make sure we set the screen cursor to the right position
+ first! */
+ _wupdcurs(win);
+ win->scr->putc(win->scr, ch);
+ if ( ++(win->curs_x) - win->width == 0 ) {
+ if ( wrap == WRAP ) {
+ win->curs_x = 0;
+ /* specification says we should really scroll,
+ but we have no buffer to scroll with, so we
+ can only overwrite back at the beginning of
+ the window */
+ if ( ++(win->curs_y) - win->height == 0 )
+ win->curs_y = 0;
+ } else {
+ (win->curs_x)--;
+ }
+ }
+}
+
+/**
+ * Write a single character to a window
+ *
+ * @v *win window in which to write
+ * @v c character rendition to write
+ * @v wrap wrap "switch"
+ */
+void _wputc ( WINDOW *win, char c, int wrap ) {
+ _wputch ( win, ( ( ( unsigned char ) c ) | win->attrs ), wrap );
+}
+
+/**
+ * Retreat the cursor back one position (useful for a whole host of
+ * ops)
+ *
+ * @v *win window in which to retreat
+ */
+void _wcursback ( WINDOW *win ) {
+ if ( win->curs_x == 0 ) {
+ if ( win->curs_y == 0 )
+ win->curs_y = win->height - 1;
+ win->curs_x = win->width = 1;
+ } else {
+ win->curs_x--;
+ }
+
+ _wupdcurs(win);
+}
+
+/**
+ * Write a chtype string to a window
+ *
+ * @v *win window in which to write
+ * @v *chstr chtype string
+ * @v wrap wrap "switch"
+ * @v n write at most n chtypes
+ */
+void _wputchstr ( WINDOW *win, const chtype *chstr, int wrap, int n ) {
+ for ( ; *chstr && n-- ; chstr++ ) {
+ _wputch(win,*chstr,wrap);
+ }
+}
+
+/**
+ * Write a standard c-style string to a window
+ *
+ * @v *win window in which to write
+ * @v *str string
+ * @v wrap wrap "switch"
+ * @v n write at most n chars from *str
+ */
+void _wputstr ( WINDOW *win, const char *str, int wrap, int n ) {
+ for ( ; *str && n-- ; str++ ) {
+ _wputc ( win, *str, wrap );
+ }
+}
+
+/**
+ * Move a window's cursor to the specified position
+ *
+ * @v *win window to be operated on
+ * @v y Y position
+ * @v x X position
+ * @ret rc return status code
+ */
+int wmove ( WINDOW *win, int y, int x ) {
+ /* chech for out-of-bounds errors */
+ if ( ( (unsigned)y >= win->height ) ||
+ ( (unsigned)x >= win->width ) ) {
+ return ERR;
+ }
+
+ win->curs_y = y;
+ win->curs_x = x;
+ _wupdcurs(win);
+ return OK;
+}
+
+/**
+ * Set cursor visibility
+ *
+ * @v visibility cursor visibility
+ */
+int curs_set ( int visibility ) {
+ stdscr->scr->cursor ( stdscr->scr, visibility );
+ return OK;
+}
diff --git a/qemu/roms/ipxe/src/hci/mucurses/mucurses.h b/qemu/roms/ipxe/src/hci/mucurses/mucurses.h
new file mode 100644
index 000000000..7ac1086ac
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/mucurses/mucurses.h
@@ -0,0 +1,23 @@
+#ifndef _MUCURSES_H
+#define _MUCURSES_H
+
+/** @file
+ *
+ * MuCurses core implementation specific header file
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#define WRAP 0
+#define NOWRAP 1
+
+extern SCREEN _ansi_screen;
+
+extern void _wputch ( WINDOW *win, chtype ch, int wrap ) __nonnull;
+extern void _wputc ( WINDOW *win, char c, int wrap ) __nonnull;
+extern void _wputchstr ( WINDOW *win, const chtype *chstr, int wrap, int n ) __nonnull;
+extern void _wputstr ( WINDOW *win, const char *str, int wrap, int n ) __nonnull;
+extern void _wcursback ( WINDOW *win ) __nonnull;
+
+#endif /* _MUCURSES_H */
diff --git a/qemu/roms/ipxe/src/hci/mucurses/print.c b/qemu/roms/ipxe/src/hci/mucurses/print.c
new file mode 100644
index 000000000..9c682588b
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/mucurses/print.c
@@ -0,0 +1,86 @@
+#include <curses.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <ipxe/vsprintf.h>
+#include "mucurses.h"
+
+/** @file
+ *
+ * MuCurses printing functions
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+/**
+ * Add a single-byte character and rendition to a window and advance
+ * the cursor
+ *
+ * @v *win window to be rendered in
+ * @v ch character to be added at cursor
+ * @ret rc return status code
+ */
+int waddch ( WINDOW *win, const chtype ch ) {
+ _wputch( win, ch, WRAP );
+ return OK;
+}
+
+/**
+ * Add string of single-byte characters to a window
+ *
+ * @v *win window to be rendered in
+ * @v *str standard c-style string
+ * @v n max number of chars from string to render
+ * @ret rc return status code
+ */
+int waddnstr ( WINDOW *win, const char *str, int n ) {
+ _wputstr( win, str, WRAP, n );
+ return OK;
+}
+
+struct printw_context {
+ struct printf_context ctx;
+ WINDOW *win;
+};
+
+static void _printw_handler ( struct printf_context *ctx, unsigned int c ) {
+ struct printw_context *wctx =
+ container_of ( ctx, struct printw_context, ctx );
+
+ _wputch( wctx->win, c | wctx->win->attrs, WRAP );
+}
+
+/**
+ * Print formatted output in a window
+ *
+ * @v *win subject window
+ * @v *fmt formatted string
+ * @v varglist argument list
+ * @ret rc return status code
+ */
+int vw_printw ( WINDOW *win, const char *fmt, va_list varglist ) {
+ struct printw_context wctx;
+
+ wctx.win = win;
+ wctx.ctx.handler = _printw_handler;
+ vcprintf ( &(wctx.ctx), fmt, varglist );
+ return OK;
+}
+
+/**
+ * Print formatted output to a window
+ *
+ * @v *win subject window
+ * @v *fmt formatted string
+ * @v ... string arguments
+ * @ret rc return status code
+ */
+int wprintw ( WINDOW *win, const char *fmt, ... ) {
+ va_list args;
+ int i;
+
+ va_start ( args, fmt );
+ i = vw_printw ( win, fmt, args );
+ va_end ( args );
+ return i;
+}
diff --git a/qemu/roms/ipxe/src/hci/mucurses/print_nadv.c b/qemu/roms/ipxe/src/hci/mucurses/print_nadv.c
new file mode 100644
index 000000000..ee472e685
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/mucurses/print_nadv.c
@@ -0,0 +1,26 @@
+#include <curses.h>
+#include "mucurses.h"
+#include "cursor.h"
+
+/** @file
+ *
+ * MuCurses printing functions (no cursor advance)
+ *
+ */
+
+/**
+ * Add string of single-byte characters and renditions to a window
+ *
+ * @v *win window to be rendered in
+ * @v *chstr pointer to first chtype in "string"
+ * @v n max number of chars from chstr to render
+ * @ret rc return status code
+ */
+int waddchnstr ( WINDOW *win, const chtype *chstr, int n ) {
+ struct cursor_pos pos;
+
+ _store_curs_pos( win, &pos );
+ _wputchstr( win, chstr, NOWRAP, n );
+ _restore_curs_pos( win, &pos );
+ return OK;
+}
diff --git a/qemu/roms/ipxe/src/hci/mucurses/slk.c b/qemu/roms/ipxe/src/hci/mucurses/slk.c
new file mode 100644
index 000000000..600658e75
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/mucurses/slk.c
@@ -0,0 +1,363 @@
+#include <curses.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include "mucurses.h"
+#include "cursor.h"
+
+/** @file
+ *
+ * Soft label key functions
+ */
+
+#define MIN_SPACE_SIZE 2
+
+#define SLK_MAX_LABEL_LEN 8
+
+#define SLK_MAX_NUM_LABELS 12
+
+#define SLK_MAX_NUM_SPACES 2
+
+struct _softlabel {
+ // label string
+ char label[SLK_MAX_LABEL_LEN];
+ /* Format of soft label
+ 0: left justify
+ 1: centre justify
+ 2: right justify
+ */
+ unsigned int fmt;
+};
+
+struct _softlabelkeys {
+ struct _softlabel fkeys[SLK_MAX_NUM_LABELS];
+ attr_t attrs;
+ /* Soft label layout format
+ 0: 3-2-3
+ 1: 4-4
+ 2: 4-4-4
+ 3: 4-4-4 with index line
+ */
+ unsigned int fmt;
+ unsigned int max_label_len;
+ unsigned int maj_space_len;
+ unsigned int num_labels;
+ unsigned int num_spaces;
+ unsigned int spaces[SLK_MAX_NUM_SPACES];
+ struct cursor_pos saved_cursor;
+ attr_t saved_attrs;
+ short saved_pair;
+};
+
+static struct _softlabelkeys *slks;
+
+/*
+ I either need to break the primitives here, or write a collection of
+ functions specifically for SLKs that directly access the screen
+ functions - since this technically isn't part of stdscr, I think
+ this should be ok...
+ */
+
+static void _enter_slk ( void ) {
+ _store_curs_pos ( stdscr, &slks->saved_cursor );
+ wattr_get ( stdscr, &slks->saved_attrs, &slks->saved_pair, NULL );
+ LINES++;
+ wmove ( stdscr, LINES, 0 );
+ wattrset ( stdscr, slks->attrs );
+}
+
+static void _leave_slk ( void ) {
+ LINES--;
+ wattr_set ( stdscr, slks->saved_attrs, slks->saved_pair, NULL );
+ _restore_curs_pos ( stdscr, &slks->saved_cursor );
+}
+
+static void _print_label ( struct _softlabel sl ) {
+ int space_ch;
+ char str[SLK_MAX_LABEL_LEN + 1];
+
+ assert ( slks->max_label_len <= SLK_MAX_LABEL_LEN );
+ space_ch = ' ';
+
+ // protect against gaps in the soft label keys array
+ if ( sl.label == NULL ) {
+ memset( str, space_ch, (size_t)(slks->max_label_len) );
+ } else {
+ /* we need to pad the label with varying amounts of leading
+ pad depending on the format of the label */
+ if ( sl.fmt == 1 ) {
+ memset( str, space_ch,
+ (size_t)(slks->max_label_len
+ - strlen(sl.label)) / 2 );
+ }
+ if ( sl.fmt == 2 ) {
+ memset( str, space_ch,
+ (size_t)(slks->max_label_len
+ - strlen(sl.label)) );
+ }
+ strcat(str,sl.label);
+
+ // post-padding
+ memset(str+strlen(str), space_ch,
+ (size_t)(slks->max_label_len - strlen(str)) );
+ }
+
+ // print the formatted label
+ _wputstr ( stdscr, str, NOWRAP, slks->max_label_len );
+}
+
+/**
+ * Return the attribute used for the soft function keys
+ *
+ * @ret attrs the current attributes of the soft function keys
+ */
+attr_t slk_attr ( void ) {
+ return ( slks == NULL ? 0 : slks->attrs );
+}
+
+/**
+ * Turn off soft function key attributes
+ *
+ * @v attrs attribute bit mask
+ * @ret rc return status code
+ */
+int slk_attroff ( const chtype attrs ) {
+ if ( slks == NULL )
+ return ERR;
+ slks->attrs &= ~( attrs & A_ATTRIBUTES );
+ return OK;
+}
+
+/**
+ * Turn on soft function key attributes
+ *
+ * @v attrs attribute bit mask
+ * @ret rc return status code
+ */
+int slk_attron ( const chtype attrs ) {
+ if ( slks == NULL )
+ return ERR;
+ slks->attrs |= ( attrs & A_ATTRIBUTES );
+ return OK;
+}
+
+/**
+ * Set soft function key attributes
+ *
+ * @v attrs attribute bit mask
+ * @ret rc return status code
+ */
+int slk_attrset ( const chtype attrs ) {
+ if ( slks == NULL )
+ return ERR;
+ slks->attrs = ( attrs & A_ATTRIBUTES );
+ return OK;
+}
+
+/**
+ * Turn off soft function key attributes
+ *
+ * @v attrs attribute bit mask
+ * @v *opts undefined (for future implementation)
+ * @ret rc return status code
+ */
+int slk_attr_off ( const attr_t attrs, void *opts __unused ) {
+ return slk_attroff( attrs );
+}
+
+/**
+ * Turn on soft function key attributes
+ *
+ * @v attrs attribute bit mask
+ * @v *opts undefined (for future implementation)
+ * @ret rc return status code
+ */
+int slk_attr_on ( attr_t attrs, void *opts __unused ) {
+ return slk_attron( attrs );
+}
+
+/**
+ * Set soft function key attributes
+ *
+ * @v attrs attribute bit mask
+ * @v colour_pair_number colour pair integer
+ * @v *opts undefined (for future implementation)
+ * @ret rc return status code
+ */
+int slk_attr_set ( const attr_t attrs, short colour_pair_number,
+ void *opts __unused ) {
+ if ( slks == NULL )
+ return ERR;
+
+ if ( ( unsigned short )colour_pair_number > COLORS )
+ return ERR;
+
+ slks->attrs = ( (unsigned short)colour_pair_number << CPAIR_SHIFT ) |
+ ( attrs & A_ATTRIBUTES );
+ return OK;
+}
+
+/**
+ * Clear the soft function key labels from the screen
+ *
+ * @ret rc return status code
+ */
+int slk_clear ( void ) {
+ if ( slks == NULL )
+ return ERR;
+
+ _enter_slk();
+ wclrtoeol ( stdscr );
+ _leave_slk();
+
+ return OK;
+}
+
+/**
+ * Set soft label colour pair
+ */
+int slk_colour ( short colour_pair_number ) {
+ if ( slks == NULL )
+ return ERR;
+ if ( ( unsigned short )colour_pair_number > COLORS )
+ return ERR;
+
+ slks->attrs = ( (unsigned short)colour_pair_number << CPAIR_SHIFT )
+ | ( slks->attrs & A_ATTRIBUTES );
+
+ return OK;
+}
+
+/**
+ * Initialise the soft function keys
+ *
+ * @v fmt format of keys
+ * @ret rc return status code
+ */
+int slk_init ( int fmt ) {
+ unsigned short nmaj, nmin, nblocks, available_width;
+
+ if ( (unsigned)fmt > 3 ) {
+ return ERR;
+ }
+
+ /* There seems to be no API call to free this data structure... */
+ if ( ! slks )
+ slks = calloc(1,sizeof(*slks));
+ if ( ! slks )
+ return ERR;
+
+ slks->attrs = A_DEFAULT;
+ slks->fmt = fmt;
+ switch(fmt) {
+ case 0:
+ nblocks = 8; nmaj = 2; nmin = 5;
+ slks->spaces[0] = 2; slks->spaces[1] = 4;
+ break;
+ case 1:
+ nblocks = 8; nmaj = 1; nmin = 6;
+ slks->spaces[0] = 3;
+ break;
+ case 2:
+ // same allocations as format 3
+ case 3:
+ nblocks = 12; nmaj = 2; nmin = 9;
+ slks->spaces[0] = 3; slks->spaces[1] = 7;
+ break;
+ default:
+ nblocks = 0; nmaj = 0; nmin = 0;
+ break;
+ }
+
+ // determine maximum label length and major space size
+ available_width = COLS - ( ( MIN_SPACE_SIZE * nmaj ) + nmin );
+ slks->max_label_len = available_width / nblocks;
+ slks->maj_space_len = MIN_SPACE_SIZE +
+ ( available_width % nblocks ) / nmaj;
+ slks->num_spaces = nmaj;
+ slks->num_labels = nblocks;
+
+ // strip a line from the screen
+ LINES -= 1;
+
+ return OK;
+}
+
+/**
+ * Return the label for the specified soft key
+ *
+ * @v labnum soft key identifier
+ * @ret label return label
+ */
+char* slk_label ( int labnum ) {
+ if ( slks == NULL )
+ return NULL;
+
+ return slks->fkeys[labnum].label;
+}
+
+/**
+ * Restore soft function key labels to the screen
+ *
+ * @ret rc return status code
+ */
+int slk_restore ( void ) {
+ unsigned int i, j, pos_x,
+ *next_space, *last_space;
+ chtype space_ch;
+
+ if ( slks == NULL )
+ return ERR;
+
+ pos_x = 0;
+
+ _enter_slk();
+
+ space_ch = (chtype)' ' | slks->attrs;
+ next_space = &(slks->spaces[0]);
+ last_space = &(slks->spaces[slks->num_spaces-1]);
+
+ for ( i = 0; i < slks->num_labels ; i++ ) {
+ _print_label( slks->fkeys[i] );
+ pos_x += slks->max_label_len;
+
+ if ( i == *next_space ) {
+ for ( j = 0; j < slks->maj_space_len; j++, pos_x++ )
+ _wputch ( stdscr, space_ch, NOWRAP );
+ if ( next_space < last_space )
+ next_space++;
+ } else {
+ if ( pos_x < COLS )
+ _wputch ( stdscr, space_ch, NOWRAP );
+ pos_x++;
+ }
+ }
+
+ _leave_slk();
+
+ return OK;
+}
+
+/**
+ * Configure specified soft key
+ *
+ * @v labnum soft label position to configure
+ * @v *label string to use as soft key label
+ * @v fmt justification format of label
+ * @ret rc return status code
+ */
+int slk_set ( int labnum, const char *label, int fmt ) {
+ if ( slks == NULL )
+ return ERR;
+ if ( (unsigned short)labnum >= slks->num_labels )
+ return ERR;
+ if ( (unsigned short)fmt >= 3 )
+ return ERR;
+
+ strncpy(slks->fkeys[labnum].label, label,
+ sizeof(slks->fkeys[labnum].label));
+ slks->fkeys[labnum].fmt = fmt;
+
+ return OK;
+}
diff --git a/qemu/roms/ipxe/src/hci/mucurses/widgets/editbox.c b/qemu/roms/ipxe/src/hci/mucurses/widgets/editbox.c
new file mode 100644
index 000000000..630a66e0b
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/mucurses/widgets/editbox.c
@@ -0,0 +1,103 @@
+/*
+ * 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.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <string.h>
+#include <assert.h>
+#include <ipxe/editbox.h>
+
+/** @file
+ *
+ * Editable text box widget
+ *
+ */
+
+#define EDITBOX_MIN_CHARS 3
+
+/**
+ * Initialise text box widget
+ *
+ * @v box Editable text box widget
+ * @v buf Text buffer
+ * @v len Size of text buffer
+ * @v win Containing window
+ * @v row Row
+ * @v col Starting column
+ * @v width Width
+ * @v flags Flags
+ */
+void init_editbox ( struct edit_box *box, char *buf, size_t len,
+ WINDOW *win, unsigned int row, unsigned int col,
+ unsigned int width, unsigned int flags ) {
+ memset ( box, 0, sizeof ( *box ) );
+ init_editstring ( &box->string, buf, len );
+ box->string.cursor = strlen ( buf );
+ box->win = ( win ? win : stdscr );
+ box->row = row;
+ box->col = col;
+ box->width = width;
+ box->flags = flags;
+}
+
+/**
+ * Draw text box widget
+ *
+ * @v box Editable text box widget
+ *
+ */
+void draw_editbox ( struct edit_box *box ) {
+ size_t width = box->width;
+ char buf[ width + 1 ];
+ signed int cursor_offset, underflow, overflow, first;
+ size_t len;
+
+ /* Adjust starting offset so that cursor remains within box */
+ cursor_offset = ( box->string.cursor - box->first );
+ underflow = ( EDITBOX_MIN_CHARS - cursor_offset );
+ overflow = ( cursor_offset - ( width - 1 ) );
+ first = box->first;
+ if ( underflow > 0 ) {
+ first -= underflow;
+ if ( first < 0 )
+ first = 0;
+ } else if ( overflow > 0 ) {
+ first += overflow;
+ }
+ box->first = first;
+ cursor_offset = ( box->string.cursor - first );
+
+ /* Construct underscore-padded string portion */
+ memset ( buf, '_', width );
+ buf[width] = '\0';
+ len = ( strlen ( box->string.buf ) - first );
+ if ( len > width )
+ len = width;
+ if ( box->flags & EDITBOX_STARS ) {
+ memset ( buf, '*', len );
+ } else {
+ memcpy ( buf, ( box->string.buf + first ), len );
+ }
+
+ /* Print box content and move cursor */
+ if ( ! box->win )
+ box->win = stdscr;
+ mvwprintw ( box->win, box->row, box->col, "%s", buf );
+ wmove ( box->win, box->row, ( box->col + cursor_offset ) );
+}
diff --git a/qemu/roms/ipxe/src/hci/mucurses/winattrs.c b/qemu/roms/ipxe/src/hci/mucurses/winattrs.c
new file mode 100644
index 000000000..f549d7519
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/mucurses/winattrs.c
@@ -0,0 +1,133 @@
+#include <curses.h>
+
+/** @file
+ *
+ * MuCurses window attribute functions
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+/**
+ * Get the background rendition attributes for a window
+ *
+ * @v *win subject window
+ * @ret ch chtype rendition representation
+ */
+inline chtype getbkgd ( WINDOW *win ) {
+ return win->attrs;
+}
+
+/**
+ * Turn off attributes in a window
+ *
+ * @v win subject window
+ * @v attrs attributes to enable
+ * @ret rc return status code
+ */
+int wattroff ( WINDOW *win, int attrs ) {
+ win->attrs &= ~attrs;
+ return OK;
+}
+
+/**
+ * Turn on attributes in a window
+ *
+ * @v win subject window
+ * @v attrs attributes to enable
+ * @ret rc return status code
+ */
+int wattron ( WINDOW *win, int attrs ) {
+ win->attrs |= attrs;
+ return OK;
+}
+
+/**
+ * Set attributes in a window
+ *
+ * @v win subject window
+ * @v attrs attributes to enable
+ * @ret rc return status code
+ */
+int wattrset ( WINDOW *win, int attrs ) {
+ win->attrs = ( attrs | ( win->attrs & A_COLOR ) );
+ return OK;
+}
+
+/**
+ * Get attributes and colour pair information
+ *
+ * @v *win window to obtain information from
+ * @v *attrs address in which to store attributes
+ * @v *pair address in which to store colour pair
+ * @v *opts undefined (for future implementation)
+ * @ret rc return status cude
+ */
+int wattr_get ( WINDOW *win, attr_t *attrs, short *pair,
+ void *opts __unused ) {
+ *attrs = win->attrs & A_ATTRIBUTES;
+ *pair = PAIR_NUMBER ( win->attrs );
+ return OK;
+}
+
+/**
+ * Turn off attributes in a window
+ *
+ * @v *win subject window
+ * @v attrs attributes to toggle
+ * @v *opts undefined (for future implementation)
+ * @ret rc return status code
+ */
+int wattr_off ( WINDOW *win, attr_t attrs,
+ void *opts __unused ) {
+ wattroff( win, attrs );
+ return OK;
+}
+
+/**
+ * Turn on attributes in a window
+ *
+ * @v *win subject window
+ * @v attrs attributes to toggle
+ * @v *opts undefined (for future implementation)
+ * @ret rc return status code
+ */
+int wattr_on ( WINDOW *win, attr_t attrs,
+ void *opts __unused ) {
+ wattron( win, attrs );
+ return OK;
+}
+
+/**
+ * Set attributes and colour pair information in a window
+ *
+ * @v *win subject window
+ * @v attrs attributes to set
+ * @v cpair colour pair to set
+ * @v *opts undefined (for future implementation)
+ * @ret rc return status code
+ */
+int wattr_set ( WINDOW *win, attr_t attrs, short cpair,
+ void *opts __unused ) {
+ wattrset( win, attrs | COLOUR_PAIR ( cpair ) );
+ return OK;
+}
+
+/**
+ * Set colour pair for a window
+ *
+ * @v *win subject window
+ * @v colour_pair_number colour pair integer
+ * @v *opts undefined (for future implementation)
+ * @ret rc return status code
+ */
+int wcolour_set ( WINDOW *win, short colour_pair_number,
+ void *opts __unused ) {
+ if ( ( unsigned short )colour_pair_number > COLOUR_PAIRS )
+ return ERR;
+
+ win->attrs = ( ( win->attrs & A_ATTRIBUTES ) |
+ COLOUR_PAIR ( colour_pair_number ) );
+ return OK;
+}
+
diff --git a/qemu/roms/ipxe/src/hci/mucurses/windows.c b/qemu/roms/ipxe/src/hci/mucurses/windows.c
new file mode 100644
index 000000000..63d0af08c
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/mucurses/windows.c
@@ -0,0 +1,158 @@
+#include <curses.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include "mucurses.h"
+
+/** @file
+ *
+ * MuCurses windows instance functions
+ *
+ */
+
+/**
+ * Delete a window
+ *
+ * @v *win pointer to window being deleted
+ * @ret rc return status code
+ */
+int delwin ( WINDOW *win ) {
+ if ( win == NULL )
+ return ERR;
+
+ /* I think we should blank the region covered by the window -
+ ncurses doesn't do this, but they have a buffer, so they
+ may just be deleting from an offscreen context whereas we
+ are guaranteed to be deleting something onscreen */
+ wmove( win, 0, 0 );
+ chtype killch = (chtype)' ';
+ do {
+ _wputch( win, killch, WRAP );
+ } while ( win->curs_x + win->curs_y );
+
+ free( win );
+
+ wmove ( stdscr, 0, 0 );
+
+ return OK;
+}
+
+/**
+ * Create a new derived window
+ *
+ * @v parent parent window
+ * @v nlines window height
+ * @v ncols window width
+ * @v begin_y window y origin (relative to parent)
+ * @v begin_x window x origin (relative to parent)
+ * @ret ptr return pointer to child window
+ */
+WINDOW *derwin ( WINDOW *parent, int nlines, int ncols,
+ int begin_y, int begin_x ) {
+ WINDOW *child;
+ if ( parent == NULL )
+ return NULL;
+ if ( ( child = malloc( sizeof( WINDOW ) ) ) == NULL )
+ return NULL;
+ if ( ( (unsigned)ncols > parent->width ) ||
+ ( (unsigned)nlines > parent->height ) )
+ return NULL;
+ child->ori_y = parent->ori_y + begin_y;
+ child->ori_x = parent->ori_x + begin_x;
+ child->height = nlines;
+ child->width = ncols;
+ child->parent = parent;
+ child->scr = parent->scr;
+ return child;
+}
+
+/**
+ * Create a duplicate of the specified window
+ *
+ * @v orig original window
+ * @ret ptr pointer to duplicate window
+ */
+WINDOW *dupwin ( WINDOW *orig ) {
+ WINDOW *copy;
+ if ( orig == NULL )
+ return NULL;
+ if ( ( copy = malloc( sizeof( WINDOW ) ) ) == NULL )
+ return NULL;
+ copy->scr = orig->scr;
+ copy->attrs = orig->attrs;
+ copy->ori_y = orig->ori_y;
+ copy->ori_x = orig->ori_x;
+ copy->curs_y = orig->curs_y;
+ copy->curs_x = orig->curs_x;
+ copy->height = orig->height;
+ copy->width = orig->width;
+ return copy;
+}
+
+/**
+ * Move window origin to specified coordinates
+ *
+ * @v *win window to move
+ * @v y Y position
+ * @v x X position
+ * @ret rc return status code
+ */
+int mvwin ( WINDOW *win, int y, int x ) {
+ if ( win == NULL )
+ return ERR;
+ if ( ( ( (unsigned)y + win->height ) > LINES ) ||
+ ( ( (unsigned)x + win->width ) > COLS ) )
+ return ERR;
+
+ win->ori_y = y;
+ win->ori_x = x;
+
+ return OK;
+}
+
+/**
+ * Create new WINDOW
+ *
+ * @v nlines number of lines
+ * @v ncols number of columns
+ * @v begin_y column origin
+ * @v begin_x line origin
+ * @ret *win return pointer to new window
+ */
+WINDOW *newwin ( int nlines, int ncols, int begin_y, int begin_x ) {
+ WINDOW *win;
+ if ( ( win = malloc( sizeof(WINDOW) ) ) == NULL )
+ return NULL;
+ if ( ( (unsigned)( begin_y + nlines ) > stdscr->height ) &&
+ ( (unsigned)( begin_x + ncols ) > stdscr->width ) )
+ return NULL;
+ win->ori_y = begin_y;
+ win->ori_x = begin_x;
+ win->height = nlines;
+ win->width = ncols;
+ win->scr = stdscr->scr;
+ win->parent = stdscr;
+ return win;
+}
+
+/**
+ * Create a new sub-window
+ *
+ * @v orig parent window
+ * @v nlines window height
+ * @v ncols window width
+ * @v begin_y window y origin (absolute)
+ * @v begin_x window x origin (absolute)
+ * @ret ptr return pointer to child window
+ */
+WINDOW *subwin ( WINDOW *parent, int nlines, int ncols,
+ int begin_y, int begin_x ) {
+ WINDOW *child;
+ if ( parent == NULL )
+ return NULL;
+ if ( ( child = malloc( sizeof( WINDOW ) ) ) == NULL )
+ return NULL;
+ child = newwin( nlines, ncols, begin_y, begin_x );
+ child->parent = parent;
+ child->scr = parent->scr;
+ return child;
+}
diff --git a/qemu/roms/ipxe/src/hci/mucurses/wininit.c b/qemu/roms/ipxe/src/hci/mucurses/wininit.c
new file mode 100644
index 000000000..b75abba44
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/mucurses/wininit.c
@@ -0,0 +1,38 @@
+#include <stddef.h>
+#include <curses.h>
+
+/** @file
+ *
+ * MuCurses initialisation functions
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+/**
+ * Initialise console environment
+ *
+ * @ret *win return pointer to stdscr
+ */
+WINDOW *initscr ( void ) {
+ /* determine console size */
+ /* initialise screen */
+ stdscr->scr->init( stdscr->scr );
+ stdscr->height = LINES;
+ stdscr->width = COLS;
+ move ( 0, 0 );
+ return stdscr;
+}
+
+/**
+ * Finalise console environment
+ *
+ */
+int endwin ( void ) {
+ attrset ( 0 );
+ color_set ( 0, NULL );
+ curs_set ( 1 );
+ mvprintw ( ( LINES - 1 ), 0, "\n" );
+ stdscr->scr->exit( stdscr->scr );
+ return OK;
+}
diff --git a/qemu/roms/ipxe/src/hci/readline.c b/qemu/roms/ipxe/src/hci/readline.c
new file mode 100644
index 000000000..40aa59787
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/readline.c
@@ -0,0 +1,343 @@
+/*
+ * 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.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <ipxe/console.h>
+#include <ipxe/keys.h>
+#include <ipxe/editstring.h>
+#include <readline/readline.h>
+
+/** @file
+ *
+ * Minimal readline
+ *
+ */
+
+#define READLINE_MAX 256
+
+/**
+ * Synchronise console with edited string
+ *
+ * @v string Editable string
+ */
+static void sync_console ( struct edit_string *string ) {
+ unsigned int mod_start = string->mod_start;
+ unsigned int mod_end = string->mod_end;
+ unsigned int cursor = string->last_cursor;
+ size_t len = strlen ( string->buf );
+
+ /* Expand region back to old cursor position if applicable */
+ if ( mod_start > string->last_cursor )
+ mod_start = string->last_cursor;
+
+ /* Expand region forward to new cursor position if applicable */
+ if ( mod_end < string->cursor )
+ mod_end = string->cursor;
+
+ /* Backspace to start of region */
+ while ( cursor > mod_start ) {
+ putchar ( '\b' );
+ cursor--;
+ }
+
+ /* Print modified region */
+ while ( cursor < mod_end ) {
+ putchar ( ( cursor >= len ) ? ' ' : string->buf[cursor] );
+ cursor++;
+ }
+
+ /* Backspace to new cursor position */
+ while ( cursor > string->cursor ) {
+ putchar ( '\b' );
+ cursor--;
+ }
+}
+
+/**
+ * Locate history entry
+ *
+ * @v history History buffer
+ * @v depth Depth within history buffer
+ * @ret entry History entry
+ */
+static struct readline_history_entry *
+history_entry ( struct readline_history *history, unsigned int depth ) {
+ unsigned int offset;
+
+ offset = ( ( history->next - depth ) %
+ ( sizeof ( history->entries ) /
+ sizeof ( history->entries[0] ) ) );
+ return &history->entries[offset];
+}
+
+/**
+ * Read string from history buffer
+ *
+ * @v history History buffer
+ * @v depth Depth within history buffer
+ * @ret string String
+ */
+static const char * history_fetch ( struct readline_history *history,
+ unsigned int depth ) {
+ struct readline_history_entry *entry;
+
+ /* Return the temporary copy if it exists, otherwise return
+ * the persistent copy.
+ */
+ entry = history_entry ( history, depth );
+ return ( entry->temp ? entry->temp : entry->string );
+}
+
+/**
+ * Write temporary string copy to history buffer
+ *
+ * @v history History buffer
+ * @v depth Depth within history buffer
+ * @v string String
+ */
+static void history_store ( struct readline_history *history,
+ unsigned int depth, const char *string ) {
+ struct readline_history_entry *entry;
+ char *temp;
+
+ /* Create temporary copy of string */
+ temp = strdup ( string );
+ if ( ! temp ) {
+ /* Just discard the string; there's nothing we can do */
+ DBGC ( history, "READLINE %p could not store string\n",
+ history );
+ return;
+ }
+
+ /* Store temporary copy */
+ entry = history_entry ( history, depth );
+ free ( entry->temp );
+ entry->temp = temp;
+}
+
+/**
+ * Move to new history depth
+ *
+ * @v history History buffer
+ * @v offset Offset by which to change depth
+ * @v old_string String (possibly modified) at current depth
+ * @ret new_string String at new depth, or NULL for no movement
+ */
+static const char * history_move ( struct readline_history *history,
+ int offset, const char *old_string ) {
+ unsigned int new_depth = ( history->depth + offset );
+ const char * new_string = history_fetch ( history, new_depth );
+
+ /* Depth checks */
+ if ( new_depth > READLINE_HISTORY_MAX_DEPTH )
+ return NULL;
+ if ( ! new_string )
+ return NULL;
+
+ /* Store temporary copy of old string at current depth */
+ history_store ( history, history->depth, old_string );
+
+ /* Update depth */
+ history->depth = new_depth;
+
+ /* Return new string */
+ return new_string;
+}
+
+/**
+ * Append new history entry
+ *
+ * @v history History buffer
+ * @v string String
+ */
+static void history_append ( struct readline_history *history,
+ const char *string ) {
+ struct readline_history_entry *entry;
+
+ /* Store new entry */
+ entry = history_entry ( history, 0 );
+ assert ( entry->string == NULL );
+ entry->string = strdup ( string );
+ if ( ! entry->string ) {
+ /* Just discard the string; there's nothing we can do */
+ DBGC ( history, "READLINE %p could not append string\n",
+ history );
+ return;
+ }
+
+ /* Increment history position */
+ history->next++;
+
+ /* Prepare empty "next" slot */
+ entry = history_entry ( history, 0 );
+ free ( entry->string );
+ entry->string = NULL;
+}
+
+/**
+ * Clean up history after editing
+ *
+ * @v history History buffer
+ */
+static void history_cleanup ( struct readline_history *history ) {
+ struct readline_history_entry *entry;
+ unsigned int i;
+
+ /* Discard any temporary strings */
+ for ( i = 0 ; i < ( sizeof ( history->entries ) /
+ sizeof ( history->entries[0] ) ) ; i++ ) {
+ entry = &history->entries[i];
+ free ( entry->temp );
+ entry->temp = NULL;
+ }
+
+ /* Reset depth */
+ history->depth = 0;
+
+ /* Sanity check */
+ entry = history_entry ( history, 0 );
+ assert ( entry->string == NULL );
+}
+
+/**
+ * Free history buffer
+ *
+ * @v history History buffer
+ */
+void history_free ( struct readline_history *history ) {
+ struct readline_history_entry *entry;
+ unsigned int i;
+
+ /* Discard any temporary strings */
+ for ( i = 0 ; i < ( sizeof ( history->entries ) /
+ sizeof ( history->entries[0] ) ) ; i++ ) {
+ entry = &history->entries[i];
+ assert ( entry->temp == NULL );
+ free ( entry->string );
+ }
+}
+
+/**
+ * Read line from console (with history)
+ *
+ * @v prompt Prompt string
+ * @v prefill Prefill string, or NULL for no prefill
+ * @v history History buffer, or NULL for no history
+ * @ret line Line read from console (excluding terminating newline)
+ * @ret rc Return status code
+ *
+ * The returned line is allocated with malloc(); the caller must
+ * eventually call free() to release the storage.
+ */
+int readline_history ( const char *prompt, const char *prefill,
+ struct readline_history *history, char **line ) {
+ char buf[READLINE_MAX];
+ struct edit_string string;
+ int key;
+ int move_by;
+ const char *new_string;
+ int rc;
+
+ /* Avoid returning uninitialised data on error */
+ *line = NULL;
+
+ /* Display prompt, if applicable */
+ if ( prompt )
+ printf ( "%s", prompt );
+
+ /* Ensure cursor is visible */
+ printf ( "\033[?25h" );
+
+ /* Initialise editable string */
+ memset ( &string, 0, sizeof ( string ) );
+ init_editstring ( &string, buf, sizeof ( buf ) );
+ buf[0] = '\0';
+
+ /* Prefill string, if applicable */
+ if ( prefill ) {
+ replace_string ( &string, prefill );
+ sync_console ( &string );
+ }
+
+ while ( 1 ) {
+ /* Handle keypress */
+ key = edit_string ( &string, getkey ( 0 ) );
+ sync_console ( &string );
+ move_by = 0;
+ switch ( key ) {
+ case CR:
+ case LF:
+ *line = strdup ( buf );
+ rc = ( ( *line ) ? 0 : -ENOMEM );
+ goto done;
+ case CTRL_C:
+ rc = -ECANCELED;
+ goto done;
+ case KEY_UP:
+ move_by = 1;
+ break;
+ case KEY_DOWN:
+ move_by = -1;
+ break;
+ default:
+ /* Do nothing */
+ break;
+ }
+
+ /* Handle history movement, if applicable */
+ if ( move_by && history ) {
+ new_string = history_move ( history, move_by, buf );
+ if ( new_string ) {
+ replace_string ( &string, new_string );
+ sync_console ( &string );
+ }
+ }
+ }
+
+ done:
+ putchar ( '\n' );
+ if ( history ) {
+ if ( *line && (*line)[0] )
+ history_append ( history, *line );
+ history_cleanup ( history );
+ }
+ assert ( ( rc == 0 ) ^ ( *line == NULL ) );
+ return rc;
+}
+
+/**
+ * Read line from console
+ *
+ * @v prompt Prompt string
+ * @ret line Line read from console (excluding terminating newline)
+ *
+ * The returned line is allocated with malloc(); the caller must
+ * eventually call free() to release the storage.
+ */
+char * readline ( const char *prompt ) {
+ char *line;
+
+ readline_history ( prompt, NULL, NULL, &line );
+ return line;
+}
diff --git a/qemu/roms/ipxe/src/hci/shell.c b/qemu/roms/ipxe/src/hci/shell.c
new file mode 100644
index 000000000..c1a543849
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/shell.c
@@ -0,0 +1,138 @@
+/*
+ * 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.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <getopt.h>
+#include <readline/readline.h>
+#include <ipxe/command.h>
+#include <ipxe/parseopt.h>
+#include <ipxe/shell.h>
+
+/** @file
+ *
+ * Minimal command shell
+ *
+ */
+
+/** The shell prompt string */
+static const char shell_prompt[] = "iPXE> ";
+
+/**
+ * "help" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int help_exec ( int argc __unused, char **argv __unused ) {
+ struct command *command;
+ unsigned int hpos = 0;
+
+ printf ( "\nAvailable commands:\n\n" );
+ for_each_table_entry ( command, COMMANDS ) {
+ hpos += printf ( " %s", command->name );
+ if ( hpos > ( 16 * 4 ) ) {
+ printf ( "\n" );
+ hpos = 0;
+ } else {
+ while ( hpos % 16 ) {
+ printf ( " " );
+ hpos++;
+ }
+ }
+ }
+ printf ( "\n\nType \"<command> --help\" for further information\n\n" );
+ return 0;
+}
+
+/** "help" command */
+struct command help_command __command = {
+ .name = "help",
+ .exec = help_exec,
+};
+
+/**
+ * Start command shell
+ *
+ */
+int shell ( void ) {
+ struct readline_history history;
+ char *line;
+ int rc = 0;
+
+ /* Initialise shell history */
+ memset ( &history, 0, sizeof ( history ) );
+
+ /* Read and execute commands */
+ do {
+ readline_history ( shell_prompt, NULL, &history, &line );
+ if ( line ) {
+ rc = system ( line );
+ free ( line );
+ }
+ } while ( ! shell_stopped ( SHELL_STOP_COMMAND_SEQUENCE ) );
+
+ /* Discard shell history */
+ history_free ( &history );
+
+ return rc;
+}
+
+/** "shell" options */
+struct shell_options {};
+
+/** "shell" option list */
+static struct option_descriptor shell_opts[] = {};
+
+/** "shell" command descriptor */
+static struct command_descriptor shell_cmd =
+ COMMAND_DESC ( struct shell_options, shell_opts, 0, 0, NULL );
+
+/**
+ * "shell" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int shell_exec ( int argc, char **argv ) {
+ struct shell_options opts;
+ int rc;
+
+ /* Parse options */
+ if ( ( rc = parse_options ( argc, argv, &shell_cmd, &opts ) ) != 0 )
+ return rc;
+
+ /* Start shell */
+ if ( ( rc = shell() ) != 0 )
+ return rc;
+
+ return 0;
+}
+
+/** "shell" command */
+struct command shell_command __command = {
+ .name = "shell",
+ .exec = shell_exec,
+};
diff --git a/qemu/roms/ipxe/src/hci/strerror.c b/qemu/roms/ipxe/src/hci/strerror.c
new file mode 100644
index 000000000..9356e9e0a
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/strerror.c
@@ -0,0 +1,125 @@
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <ipxe/errortab.h>
+
+/** @file
+ *
+ * Error descriptions.
+ *
+ * The error numbers used by Etherboot are a superset of those defined
+ * by the PXE specification version 2.1. See errno.h for a listing of
+ * the error values.
+ *
+ * To save space in ROM images, error string tables are optional. Use
+ * the ERRORMSG_XXX options in config.h to select which error string
+ * tables you want to include. If an error string table is omitted,
+ * strerror() will simply return the text "Error 0x<errno>".
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+/**
+ * Find error description
+ *
+ * @v errno Error number
+ * @ret errortab Error description, or NULL
+ */
+static struct errortab * find_error ( int errno ) {
+ struct errortab *errortab;
+
+ for_each_table_entry ( errortab, ERRORTAB ) {
+ if ( errortab->errno == errno )
+ return errortab;
+ }
+
+ return NULL;
+}
+
+/**
+ * Find closest error description
+ *
+ * @v errno Error number
+ * @ret errortab Error description, or NULL
+ *
+ *
+ */
+static struct errortab * find_closest_error ( int errno ) {
+ struct errortab *errortab;
+
+ /* First, look for an exact match */
+ if ( ( errortab = find_error ( errno ) ) != NULL )
+ return errortab;
+
+ /* Second, try masking off the iPXE-specific bit and seeing if
+ * we have an entry for the generic POSIX error message.
+ */
+ if ( ( errortab = find_error ( errno & 0x7f0000ff ) ) != NULL )
+ return errortab;
+
+ return NULL;
+}
+
+/**
+ * Retrieve string representation of error number.
+ *
+ * @v errno/rc Error number or return status code
+ * @ret strerror Pointer to error text
+ *
+ * If the error is not found in the linked-in error tables, generates
+ * a generic "Error 0x<errno>" message.
+ *
+ * The pointer returned by strerror() is valid only until the next
+ * call to strerror().
+ *
+ */
+const char * strerror ( int errno ) {
+ static char errbuf[64];
+ struct errortab *errortab;
+
+ /* Allow for strerror(rc) as well as strerror(errno) */
+ if ( errno < 0 )
+ errno = -errno;
+
+ /* Find the error description, if one exists */
+ errortab = find_closest_error ( errno );
+
+ /* Construct the error message */
+ if ( errortab ) {
+ snprintf ( errbuf, sizeof ( errbuf ),
+ "%s (http://ipxe.org/%08x)",
+ errortab->text, errno );
+ } else {
+ snprintf ( errbuf, sizeof ( errbuf ),
+ "Error %#08x (http://ipxe.org/%08x)",
+ errno, errno );
+ }
+
+ return errbuf;
+}
+
+/* Do not include ERRFILE portion in the numbers in the error table */
+#undef ERRFILE
+#define ERRFILE 0
+
+/** The most common errors */
+struct errortab common_errors[] __errortab = {
+ __einfo_errortab ( EINFO_ENOERR ),
+ __einfo_errortab ( EINFO_EACCES ),
+ __einfo_errortab ( EINFO_ECANCELED ),
+ __einfo_errortab ( EINFO_ECONNRESET ),
+ __einfo_errortab ( EINFO_EINVAL ),
+ __einfo_errortab ( EINFO_EIO ),
+ __einfo_errortab ( EINFO_ENETUNREACH ),
+ __einfo_errortab ( EINFO_ENODEV ),
+ __einfo_errortab ( EINFO_ENOENT ),
+ __einfo_errortab ( EINFO_ENOEXEC ),
+ __einfo_errortab ( EINFO_ENOMEM ),
+ __einfo_errortab ( EINFO_ENOSPC ),
+ __einfo_errortab ( EINFO_ENOTCONN ),
+ __einfo_errortab ( EINFO_ENOTSUP ),
+ __einfo_errortab ( EINFO_EPERM ),
+ __einfo_errortab ( EINFO_ERANGE ),
+ __einfo_errortab ( EINFO_ETIMEDOUT ),
+};
diff --git a/qemu/roms/ipxe/src/hci/tui/login_ui.c b/qemu/roms/ipxe/src/hci/tui/login_ui.c
new file mode 100644
index 000000000..996b68a0a
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/tui/login_ui.c
@@ -0,0 +1,133 @@
+/*
+ * 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.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+/** @file
+ *
+ * Login UI
+ *
+ */
+
+#include <string.h>
+#include <errno.h>
+#include <curses.h>
+#include <ipxe/console.h>
+#include <ipxe/settings.h>
+#include <ipxe/editbox.h>
+#include <ipxe/keys.h>
+#include <ipxe/ansicol.h>
+#include <ipxe/login_ui.h>
+
+/* Screen layout */
+#define USERNAME_LABEL_ROW ( ( LINES / 2U ) - 4U )
+#define USERNAME_ROW ( ( LINES / 2U ) - 2U )
+#define PASSWORD_LABEL_ROW ( ( LINES / 2U ) + 2U )
+#define PASSWORD_ROW ( ( LINES / 2U ) + 4U )
+#define LABEL_COL ( ( COLS / 2U ) - 4U )
+#define EDITBOX_COL ( ( COLS / 2U ) - 10U )
+#define EDITBOX_WIDTH 20U
+
+int login_ui ( void ) {
+ char username[64];
+ char password[64];
+ struct edit_box username_box;
+ struct edit_box password_box;
+ struct edit_box *current_box = &username_box;
+ int key;
+ int rc = -EINPROGRESS;
+
+ /* Fetch current setting values */
+ fetch_string_setting ( NULL, &username_setting, username,
+ sizeof ( username ) );
+ fetch_string_setting ( NULL, &password_setting, password,
+ sizeof ( password ) );
+
+ /* Initialise UI */
+ initscr();
+ start_color();
+ init_editbox ( &username_box, username, sizeof ( username ), NULL,
+ USERNAME_ROW, EDITBOX_COL, EDITBOX_WIDTH, 0 );
+ init_editbox ( &password_box, password, sizeof ( password ), NULL,
+ PASSWORD_ROW, EDITBOX_COL, EDITBOX_WIDTH,
+ EDITBOX_STARS );
+
+ /* Draw initial UI */
+ color_set ( CPAIR_NORMAL, NULL );
+ erase();
+ attron ( A_BOLD );
+ mvprintw ( USERNAME_LABEL_ROW, LABEL_COL, "Username:" );
+ mvprintw ( PASSWORD_LABEL_ROW, LABEL_COL, "Password:" );
+ attroff ( A_BOLD );
+ color_set ( CPAIR_EDIT, NULL );
+ draw_editbox ( &username_box );
+ draw_editbox ( &password_box );
+
+ /* Main loop */
+ while ( rc == -EINPROGRESS ) {
+
+ draw_editbox ( current_box );
+
+ key = getkey ( 0 );
+ switch ( key ) {
+ case KEY_DOWN:
+ current_box = &password_box;
+ break;
+ case KEY_UP:
+ current_box = &username_box;
+ break;
+ case TAB:
+ current_box = ( ( current_box == &username_box ) ?
+ &password_box : &username_box );
+ break;
+ case KEY_ENTER:
+ if ( current_box == &username_box ) {
+ current_box = &password_box;
+ } else {
+ rc = 0;
+ }
+ break;
+ case CTRL_C:
+ case ESC:
+ rc = -ECANCELED;
+ break;
+ default:
+ edit_editbox ( current_box, key );
+ break;
+ }
+ }
+
+ /* Terminate UI */
+ color_set ( CPAIR_NORMAL, NULL );
+ erase();
+ endwin();
+
+ if ( rc != 0 )
+ return rc;
+
+ /* Store settings */
+ if ( ( rc = store_setting ( NULL, &username_setting, username,
+ strlen ( username ) ) ) != 0 )
+ return rc;
+ if ( ( rc = store_setting ( NULL, &password_setting, password,
+ strlen ( password ) ) ) != 0 )
+ return rc;
+
+ return 0;
+}
diff --git a/qemu/roms/ipxe/src/hci/tui/menu_ui.c b/qemu/roms/ipxe/src/hci/tui/menu_ui.c
new file mode 100644
index 000000000..0a9566def
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/tui/menu_ui.c
@@ -0,0 +1,363 @@
+/*
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+/** @file
+ *
+ * Menu interface
+ *
+ */
+
+#include <string.h>
+#include <errno.h>
+#include <curses.h>
+#include <ipxe/keys.h>
+#include <ipxe/timer.h>
+#include <ipxe/console.h>
+#include <ipxe/ansicol.h>
+#include <ipxe/menu.h>
+
+/* Screen layout */
+#define TITLE_ROW 1U
+#define MENU_ROW 3U
+#define MENU_COL 1U
+#define MENU_ROWS ( LINES - 2U - MENU_ROW )
+#define MENU_COLS ( COLS - 2U )
+#define MENU_PAD 2U
+
+/** A menu user interface */
+struct menu_ui {
+ /** Menu */
+ struct menu *menu;
+ /** Number of menu items */
+ unsigned int count;
+ /** Currently selected item */
+ int selected;
+ /** First visible item */
+ int first_visible;
+ /** Timeout (0=indefinite) */
+ unsigned long timeout;
+};
+
+/**
+ * Return a numbered menu item
+ *
+ * @v menu Menu
+ * @v index Index
+ * @ret item Menu item, or NULL
+ */
+static struct menu_item * menu_item ( struct menu *menu, unsigned int index ) {
+ struct menu_item *item;
+
+ list_for_each_entry ( item, &menu->items, list ) {
+ if ( index-- == 0 )
+ return item;
+ }
+
+ return NULL;
+}
+
+/**
+ * Draw a numbered menu item
+ *
+ * @v ui Menu user interface
+ * @v index Index
+ */
+static void draw_menu_item ( struct menu_ui *ui, int index ) {
+ struct menu_item *item;
+ unsigned int row_offset;
+ char buf[ MENU_COLS + 1 /* NUL */ ];
+ char timeout_buf[6]; /* "(xxx)" + NUL */
+ size_t timeout_len;
+ size_t max_len;
+ size_t len;
+
+ /* Move to start of row */
+ row_offset = ( index - ui->first_visible );
+ move ( ( MENU_ROW + row_offset ), MENU_COL );
+
+ /* Get menu item */
+ item = menu_item ( ui->menu, index );
+ if ( item ) {
+
+ /* Draw separators in a different colour */
+ if ( ! item->label )
+ color_set ( CPAIR_SEPARATOR, NULL );
+
+ /* Highlight if this is the selected item */
+ if ( index == ui->selected ) {
+ color_set ( CPAIR_SELECT, NULL );
+ attron ( A_BOLD );
+ }
+
+ /* Construct row */
+ memset ( buf, ' ', ( sizeof ( buf ) - 1 ) );
+ buf[ sizeof ( buf ) -1 ] = '\0';
+ len = strlen ( item->text );
+ max_len = ( sizeof ( buf ) - 1 /* NUL */ - ( 2 * MENU_PAD ) );
+ if ( len > max_len )
+ len = max_len;
+ memcpy ( ( buf + MENU_PAD ), item->text, len );
+
+ /* Add timeout if applicable */
+ timeout_len =
+ snprintf ( timeout_buf, sizeof ( timeout_buf ), "(%ld)",
+ ( ( ui->timeout + TICKS_PER_SEC - 1 ) /
+ TICKS_PER_SEC ) );
+ if ( ( index == ui->selected ) && ( ui->timeout != 0 ) ) {
+ memcpy ( ( buf + MENU_COLS - MENU_PAD - timeout_len ),
+ timeout_buf, timeout_len );
+ }
+
+ /* Print row */
+ printw ( "%s", buf );
+
+ /* Reset attributes */
+ color_set ( CPAIR_NORMAL, NULL );
+ attroff ( A_BOLD );
+
+ } else {
+ /* Clear row if there is no corresponding menu item */
+ clrtoeol();
+ }
+
+ /* Move cursor back to start of row */
+ move ( ( MENU_ROW + row_offset ), MENU_COL );
+}
+
+/**
+ * Draw the current block of menu items
+ *
+ * @v ui Menu user interface
+ */
+static void draw_menu_items ( struct menu_ui *ui ) {
+ unsigned int i;
+
+ /* Jump scroll to correct point in list */
+ while ( ui->first_visible < ui->selected )
+ ui->first_visible += MENU_ROWS;
+ while ( ui->first_visible > ui->selected )
+ ui->first_visible -= MENU_ROWS;
+
+ /* Draw ellipses before and/or after the list as necessary */
+ color_set ( CPAIR_SEPARATOR, NULL );
+ mvaddstr ( ( MENU_ROW - 1 ), ( MENU_COL + MENU_PAD ),
+ ( ( ui->first_visible > 0 ) ? "..." : " " ) );
+ mvaddstr ( ( MENU_ROW + MENU_ROWS ), ( MENU_COL + MENU_PAD ),
+ ( ( ( ui->first_visible + MENU_ROWS ) < ui->count ) ?
+ "..." : " " ) );
+ color_set ( CPAIR_NORMAL, NULL );
+
+ /* Draw visible items */
+ for ( i = 0 ; i < MENU_ROWS ; i++ )
+ draw_menu_item ( ui, ( ui->first_visible + i ) );
+}
+
+/**
+ * Menu main loop
+ *
+ * @v ui Menu user interface
+ * @ret selected Selected item
+ * @ret rc Return status code
+ */
+static int menu_loop ( struct menu_ui *ui, struct menu_item **selected ) {
+ struct menu_item *item;
+ unsigned long timeout;
+ unsigned int delta;
+ int current;
+ int key;
+ int i;
+ int move;
+ int chosen = 0;
+ int rc = 0;
+
+ do {
+ /* Record current selection */
+ current = ui->selected;
+
+ /* Calculate timeout as remainder of current second */
+ timeout = ( ui->timeout % TICKS_PER_SEC );
+ if ( ( timeout == 0 ) && ( ui->timeout != 0 ) )
+ timeout = TICKS_PER_SEC;
+ ui->timeout -= timeout;
+
+ /* Get key */
+ move = 0;
+ key = getkey ( timeout );
+ if ( key < 0 ) {
+ /* Choose default if we finally time out */
+ if ( ui->timeout == 0 )
+ chosen = 1;
+ } else {
+ /* Cancel any timeout */
+ ui->timeout = 0;
+
+ /* Handle key */
+ switch ( key ) {
+ case KEY_UP:
+ move = -1;
+ break;
+ case KEY_DOWN:
+ move = +1;
+ break;
+ case KEY_PPAGE:
+ move = ( ui->first_visible - ui->selected - 1 );
+ break;
+ case KEY_NPAGE:
+ move = ( ui->first_visible - ui->selected
+ + MENU_ROWS );
+ break;
+ case KEY_HOME:
+ move = -ui->count;
+ break;
+ case KEY_END:
+ move = +ui->count;
+ break;
+ case ESC:
+ case CTRL_C:
+ rc = -ECANCELED;
+ break;
+ case CR:
+ case LF:
+ chosen = 1;
+ break;
+ default:
+ i = 0;
+ list_for_each_entry ( item, &ui->menu->items,
+ list ) {
+ if ( ! ( item->shortcut &&
+ ( item->shortcut == key ) ) ) {
+ i++;
+ continue;
+ }
+ ui->selected = i;
+ if ( item->label ) {
+ chosen = 1;
+ } else {
+ move = +1;
+ }
+ }
+ break;
+ }
+ }
+
+ /* Move selection, if applicable */
+ while ( move ) {
+ ui->selected += move;
+ if ( ui->selected < 0 ) {
+ ui->selected = 0;
+ move = +1;
+ } else if ( ui->selected >= ( int ) ui->count ) {
+ ui->selected = ( ui->count - 1 );
+ move = -1;
+ }
+ item = menu_item ( ui->menu, ui->selected );
+ if ( item->label )
+ break;
+ move = ( ( move > 0 ) ? +1 : -1 );
+ }
+
+ /* Redraw selection if necessary */
+ if ( ( ui->selected != current ) || ( timeout != 0 ) ) {
+ draw_menu_item ( ui, current );
+ delta = ( ui->selected - ui->first_visible );
+ if ( delta >= MENU_ROWS )
+ draw_menu_items ( ui );
+ draw_menu_item ( ui, ui->selected );
+ }
+
+ /* Record selection */
+ item = menu_item ( ui->menu, ui->selected );
+ assert ( item != NULL );
+ assert ( item->label != NULL );
+ *selected = item;
+
+ } while ( ( rc == 0 ) && ! chosen );
+
+ return rc;
+}
+
+/**
+ * Show menu
+ *
+ * @v menu Menu
+ * @v timeout Timeout period, in ticks (0=indefinite)
+ * @ret selected Selected item
+ * @ret rc Return status code
+ */
+int show_menu ( struct menu *menu, unsigned long timeout,
+ const char *select, struct menu_item **selected ) {
+ struct menu_item *item;
+ struct menu_ui ui;
+ char buf[ MENU_COLS + 1 /* NUL */ ];
+ int labelled_count = 0;
+ int rc;
+
+ /* Initialise UI */
+ memset ( &ui, 0, sizeof ( ui ) );
+ ui.menu = menu;
+ ui.timeout = timeout;
+ list_for_each_entry ( item, &menu->items, list ) {
+ if ( item->label ) {
+ if ( ! labelled_count )
+ ui.selected = ui.count;
+ labelled_count++;
+ if ( select ) {
+ if ( strcmp ( select, item->label ) == 0 )
+ ui.selected = ui.count;
+ } else {
+ if ( item->is_default )
+ ui.selected = ui.count;
+ }
+ }
+ ui.count++;
+ }
+ if ( ! labelled_count ) {
+ /* Menus with no labelled items cannot be selected
+ * from, and will seriously confuse the navigation
+ * logic. Refuse to display any such menus.
+ */
+ return -ENOENT;
+ }
+
+ /* Initialise screen */
+ initscr();
+ start_color();
+ color_set ( CPAIR_NORMAL, NULL );
+ curs_set ( 0 );
+ erase();
+
+ /* Draw initial content */
+ attron ( A_BOLD );
+ snprintf ( buf, sizeof ( buf ), "%s", ui.menu->title );
+ mvprintw ( TITLE_ROW, ( ( COLS - strlen ( buf ) ) / 2 ), "%s", buf );
+ attroff ( A_BOLD );
+ draw_menu_items ( &ui );
+ draw_menu_item ( &ui, ui.selected );
+
+ /* Enter main loop */
+ rc = menu_loop ( &ui, selected );
+ assert ( *selected );
+
+ /* Clear screen */
+ endwin();
+
+ return rc;
+}
diff --git a/qemu/roms/ipxe/src/hci/tui/settings_ui.c b/qemu/roms/ipxe/src/hci/tui/settings_ui.c
new file mode 100644
index 000000000..221839730
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/tui/settings_ui.c
@@ -0,0 +1,603 @@
+/*
+ * 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.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <string.h>
+#include <curses.h>
+#include <ipxe/console.h>
+#include <ipxe/settings.h>
+#include <ipxe/editbox.h>
+#include <ipxe/keys.h>
+#include <ipxe/ansicol.h>
+#include <ipxe/settings_ui.h>
+
+/** @file
+ *
+ * Option configuration console
+ *
+ */
+
+/* Screen layout */
+#define TITLE_ROW 1U
+#define SETTINGS_LIST_ROW 3U
+#define SETTINGS_LIST_COL 1U
+#define SETTINGS_LIST_ROWS ( LINES - 6U - SETTINGS_LIST_ROW )
+#define INFO_ROW ( LINES - 5U )
+#define ALERT_ROW ( LINES - 2U )
+#define INSTRUCTION_ROW ( LINES - 2U )
+#define INSTRUCTION_PAD " "
+
+/** Layout of text within a setting widget */
+#define SETTING_ROW_TEXT( cols ) struct { \
+ char start[0]; \
+ char pad1[1]; \
+ union { \
+ char settings[ cols - 1 - 1 - 1 - 1 ]; \
+ struct { \
+ char name[15]; \
+ char pad2[1]; \
+ char value[ cols - 1 - 15 - 1 - 1 - 1 - 1 ]; \
+ } setting; \
+ } u; \
+ char pad3[1]; \
+ char nul; \
+} __attribute__ (( packed ))
+
+/** A setting row widget */
+struct setting_row_widget {
+ /** Target configuration settings block
+ *
+ * Valid only for rows that lead to new settings blocks.
+ */
+ struct settings *settings;
+ /** Configuration setting origin
+ *
+ * Valid only for rows that represent individual settings.
+ */
+ struct settings *origin;
+ /** Configuration setting
+ *
+ * Valid only for rows that represent individual settings.
+ */
+ struct setting setting;
+ /** Screen row */
+ unsigned int row;
+ /** Screen column */
+ unsigned int col;
+ /** Edit box widget used for editing setting */
+ struct edit_box editbox;
+ /** Editing in progress flag */
+ int editing;
+ /** Buffer for setting's value */
+ char value[256]; /* enough size for a DHCP string */
+};
+
+/** A settings widget */
+struct setting_widget {
+ /** Settings block */
+ struct settings *settings;
+ /** Number of rows */
+ unsigned int num_rows;
+ /** Current row index */
+ unsigned int current;
+ /** Index of the first visible row, for scrolling. */
+ unsigned int first_visible;
+ /** Active row */
+ struct setting_row_widget row;
+};
+
+/**
+ * Select a setting row
+ *
+ * @v widget Setting widget
+ * @v index Index of setting row
+ * @ret count Number of settings rows
+ */
+static unsigned int select_setting_row ( struct setting_widget *widget,
+ unsigned int index ) {
+ SETTING_ROW_TEXT ( COLS ) *text;
+ struct settings *settings;
+ struct setting *setting;
+ struct setting *previous = NULL;
+ unsigned int count = 0;
+
+ /* Initialise structure */
+ memset ( &widget->row, 0, sizeof ( widget->row ) );
+ widget->current = index;
+ widget->row.row = ( SETTINGS_LIST_ROW + index - widget->first_visible );
+ widget->row.col = SETTINGS_LIST_COL;
+
+ /* Include parent settings block, if applicable */
+ if ( widget->settings->parent && ( count++ == index ) ) {
+ widget->row.settings = widget->settings->parent;
+ snprintf ( widget->row.value, sizeof ( widget->row.value ),
+ "../" );
+ }
+
+ /* Include any child settings blocks, if applicable */
+ list_for_each_entry ( settings, &widget->settings->children, siblings ){
+ if ( count++ == index ) {
+ widget->row.settings = settings;
+ snprintf ( widget->row.value,
+ sizeof ( widget->row.value ), "%s/",
+ settings->name );
+ }
+ }
+
+ /* Include any applicable settings */
+ for_each_table_entry ( setting, SETTINGS ) {
+
+ /* Skip inapplicable settings */
+ if ( ! setting_applies ( widget->settings, setting ) )
+ continue;
+
+ /* Skip duplicate settings */
+ if ( previous && ( setting_cmp ( setting, previous ) == 0 ) )
+ continue;
+ previous = setting;
+
+ /* Read current setting value and origin */
+ if ( count++ == index ) {
+ fetchf_setting ( widget->settings, setting,
+ &widget->row.origin,
+ &widget->row.setting,
+ widget->row.value,
+ sizeof ( widget->row.value ) );
+ }
+ }
+
+ /* Initialise edit box */
+ init_editbox ( &widget->row.editbox, widget->row.value,
+ sizeof ( widget->row.value ), NULL, widget->row.row,
+ ( widget->row.col +
+ offsetof ( typeof ( *text ), u.setting.value ) ),
+ sizeof ( text->u.setting.value ), 0 );
+
+ return count;
+}
+
+/**
+ * Copy string without NUL termination
+ *
+ * @v dest Destination
+ * @v src Source
+ * @v len Maximum length of destination
+ * @ret len Length of (unterminated) string
+ */
+static size_t string_copy ( char *dest, const char *src, size_t len ) {
+ size_t src_len;
+
+ src_len = strlen ( src );
+ if ( len > src_len )
+ len = src_len;
+ memcpy ( dest, src, len );
+ return len;
+}
+
+/**
+ * Draw setting row
+ *
+ * @v widget Setting widget
+ */
+static void draw_setting_row ( struct setting_widget *widget ) {
+ SETTING_ROW_TEXT ( COLS ) text;
+ unsigned int curs_offset;
+ char *value;
+
+ /* Fill row with spaces */
+ memset ( &text, ' ', sizeof ( text ) );
+ text.nul = '\0';
+
+ /* Construct row content */
+ if ( widget->row.settings ) {
+
+ /* Construct space-padded name */
+ curs_offset = ( offsetof ( typeof ( text ), u.settings ) +
+ string_copy ( text.u.settings,
+ widget->row.value,
+ sizeof ( text.u.settings ) ) );
+
+ } else {
+
+ /* Construct dot-padded name */
+ memset ( text.u.setting.name, '.',
+ sizeof ( text.u.setting.name ) );
+ string_copy ( text.u.setting.name, widget->row.setting.name,
+ sizeof ( text.u.setting.name ) );
+
+ /* Construct space-padded value */
+ value = widget->row.value;
+ if ( ! *value )
+ value = "<not specified>";
+ curs_offset = ( offsetof ( typeof ( text ), u.setting.value ) +
+ string_copy ( text.u.setting.value, value,
+ sizeof ( text.u.setting.value )));
+ }
+
+ /* Print row */
+ if ( ( widget->row.origin == widget->settings ) ||
+ ( widget->row.settings != NULL ) ) {
+ attron ( A_BOLD );
+ }
+ mvprintw ( widget->row.row, widget->row.col, "%s", text.start );
+ attroff ( A_BOLD );
+ move ( widget->row.row, widget->row.col + curs_offset );
+}
+
+/**
+ * Edit setting widget
+ *
+ * @v widget Setting widget
+ * @v key Key pressed by user
+ * @ret key Key returned to application, or zero
+ */
+static int edit_setting ( struct setting_widget *widget, int key ) {
+ assert ( widget->row.setting.name != NULL );
+ widget->row.editing = 1;
+ return edit_editbox ( &widget->row.editbox, key );
+}
+
+/**
+ * Save setting widget value back to configuration settings
+ *
+ * @v widget Setting widget
+ */
+static int save_setting ( struct setting_widget *widget ) {
+ assert ( widget->row.setting.name != NULL );
+ return storef_setting ( widget->settings, &widget->row.setting,
+ widget->row.value );
+}
+
+/**
+ * Print message centred on specified row
+ *
+ * @v row Row
+ * @v fmt printf() format string
+ * @v args printf() argument list
+ */
+static void vmsg ( unsigned int row, const char *fmt, va_list args ) {
+ char buf[COLS];
+ size_t len;
+
+ len = vsnprintf ( buf, sizeof ( buf ), fmt, args );
+ mvprintw ( row, ( ( COLS - len ) / 2 ), "%s", buf );
+}
+
+/**
+ * Print message centred on specified row
+ *
+ * @v row Row
+ * @v fmt printf() format string
+ * @v .. printf() arguments
+ */
+static void msg ( unsigned int row, const char *fmt, ... ) {
+ va_list args;
+
+ va_start ( args, fmt );
+ vmsg ( row, fmt, args );
+ va_end ( args );
+}
+
+/**
+ * Clear message on specified row
+ *
+ * @v row Row
+ */
+static void clearmsg ( unsigned int row ) {
+ move ( row, 0 );
+ clrtoeol();
+}
+
+/**
+ * Print alert message
+ *
+ * @v fmt printf() format string
+ * @v args printf() argument list
+ */
+static void valert ( const char *fmt, va_list args ) {
+ clearmsg ( ALERT_ROW );
+ color_set ( CPAIR_ALERT, NULL );
+ vmsg ( ALERT_ROW, fmt, args );
+ sleep ( 2 );
+ color_set ( CPAIR_NORMAL, NULL );
+ clearmsg ( ALERT_ROW );
+}
+
+/**
+ * Print alert message
+ *
+ * @v fmt printf() format string
+ * @v ... printf() arguments
+ */
+static void alert ( const char *fmt, ... ) {
+ va_list args;
+
+ va_start ( args, fmt );
+ valert ( fmt, args );
+ va_end ( args );
+}
+
+/**
+ * Draw title row
+ *
+ * @v widget Setting widget
+ */
+static void draw_title_row ( struct setting_widget *widget ) {
+ const char *name;
+
+ clearmsg ( TITLE_ROW );
+ name = settings_name ( widget->settings );
+ attron ( A_BOLD );
+ msg ( TITLE_ROW, "iPXE configuration settings%s%s",
+ ( name[0] ? " - " : "" ), name );
+ attroff ( A_BOLD );
+}
+
+/**
+ * Draw information row
+ *
+ * @v widget Setting widget
+ */
+static void draw_info_row ( struct setting_widget *widget ) {
+ char buf[32];
+
+ /* Draw nothing unless this row represents a setting */
+ clearmsg ( INFO_ROW );
+ clearmsg ( INFO_ROW + 1 );
+ if ( ! widget->row.setting.name )
+ return;
+
+ /* Determine a suitable setting name */
+ setting_name ( ( widget->row.origin ?
+ widget->row.origin : widget->settings ),
+ &widget->row.setting, buf, sizeof ( buf ) );
+
+ /* Draw row */
+ attron ( A_BOLD );
+ msg ( INFO_ROW, "%s - %s", buf, widget->row.setting.description );
+ attroff ( A_BOLD );
+ color_set ( CPAIR_URL, NULL );
+ msg ( ( INFO_ROW + 1 ), "http://ipxe.org/cfg/%s",
+ widget->row.setting.name );
+ color_set ( CPAIR_NORMAL, NULL );
+}
+
+/**
+ * Draw instruction row
+ *
+ * @v widget Setting widget
+ */
+static void draw_instruction_row ( struct setting_widget *widget ) {
+
+ clearmsg ( INSTRUCTION_ROW );
+ if ( widget->row.editing ) {
+ msg ( INSTRUCTION_ROW,
+ "Enter - accept changes" INSTRUCTION_PAD
+ "Ctrl-C - discard changes" );
+ } else {
+ msg ( INSTRUCTION_ROW,
+ "%sCtrl-X - exit configuration utility",
+ ( ( widget->row.origin == widget->settings ) ?
+ "Ctrl-D - delete setting" INSTRUCTION_PAD : "" ) );
+ }
+}
+
+/**
+ * Reveal setting row
+ *
+ * @v widget Setting widget
+ * @v index Index of setting row
+ */
+static void reveal_setting_row ( struct setting_widget *widget,
+ unsigned int index ) {
+ unsigned int i;
+
+ /* Simply return if setting N is already on-screen. */
+ if ( index - widget->first_visible < SETTINGS_LIST_ROWS )
+ return;
+
+ /* Jump scroll to make the specified setting row visible. */
+ while ( widget->first_visible < index )
+ widget->first_visible += SETTINGS_LIST_ROWS;
+ while ( widget->first_visible > index )
+ widget->first_visible -= SETTINGS_LIST_ROWS;
+
+ /* Draw ellipses before and/or after the settings list to
+ * represent any invisible settings.
+ */
+ mvaddstr ( SETTINGS_LIST_ROW - 1,
+ SETTINGS_LIST_COL + 1,
+ widget->first_visible > 0 ? "..." : " " );
+ mvaddstr ( SETTINGS_LIST_ROW + SETTINGS_LIST_ROWS,
+ SETTINGS_LIST_COL + 1,
+ ( ( widget->first_visible + SETTINGS_LIST_ROWS )
+ < widget->num_rows ? "..." : " " ) );
+
+ /* Draw visible settings. */
+ for ( i = 0; i < SETTINGS_LIST_ROWS; i++ ) {
+ if ( ( widget->first_visible + i ) < widget->num_rows ) {
+ select_setting_row ( widget,
+ widget->first_visible + i );
+ draw_setting_row ( widget );
+ } else {
+ clearmsg ( SETTINGS_LIST_ROW + i );
+ }
+ }
+}
+
+/**
+ * Reveal setting row
+ *
+ * @v widget Setting widget
+ * @v settings Settings block
+ */
+static void init_widget ( struct setting_widget *widget,
+ struct settings *settings ) {
+
+ widget->settings = settings_target ( settings );
+ widget->num_rows = select_setting_row ( widget, 0 );
+ widget->first_visible = SETTINGS_LIST_ROWS;
+ draw_title_row ( widget );
+ reveal_setting_row ( widget, 0 );
+ select_setting_row ( widget, 0 );
+}
+
+static int main_loop ( struct settings *settings ) {
+ struct setting_widget widget;
+ int redraw = 1;
+ int move;
+ unsigned int next;
+ int key;
+ int rc;
+
+ /* Print initial screen content */
+ color_set ( CPAIR_NORMAL, NULL );
+ memset ( &widget, 0, sizeof ( widget ) );
+ init_widget ( &widget, settings );
+
+ while ( 1 ) {
+
+ /* Redraw rows if necessary */
+ if ( redraw ) {
+ draw_info_row ( &widget );
+ draw_instruction_row ( &widget );
+ color_set ( ( widget.row.editing ?
+ CPAIR_EDIT : CPAIR_SELECT ), NULL );
+ draw_setting_row ( &widget );
+ color_set ( CPAIR_NORMAL, NULL );
+ curs_set ( widget.row.editing );
+ redraw = 0;
+ }
+
+ if ( widget.row.editing ) {
+
+ /* Sanity check */
+ assert ( widget.row.setting.name != NULL );
+
+ /* Redraw edit box */
+ color_set ( CPAIR_EDIT, NULL );
+ draw_editbox ( &widget.row.editbox );
+ color_set ( CPAIR_NORMAL, NULL );
+
+ /* Process keypress */
+ key = edit_setting ( &widget, getkey ( 0 ) );
+ switch ( key ) {
+ case CR:
+ case LF:
+ if ( ( rc = save_setting ( &widget ) ) != 0 )
+ alert ( " %s ", strerror ( rc ) );
+ /* Fall through */
+ case CTRL_C:
+ select_setting_row ( &widget, widget.current );
+ redraw = 1;
+ break;
+ default:
+ /* Do nothing */
+ break;
+ }
+
+ } else {
+
+ /* Process keypress */
+ key = getkey ( 0 );
+ move = 0;
+ switch ( key ) {
+ case KEY_UP:
+ move = -1;
+ break;
+ case KEY_DOWN:
+ move = +1;
+ break;
+ case KEY_PPAGE:
+ move = ( widget.first_visible -
+ widget.current - 1 );
+ break;
+ case KEY_NPAGE:
+ move = ( widget.first_visible - widget.current
+ + SETTINGS_LIST_ROWS );
+ break;
+ case KEY_HOME:
+ move = -widget.num_rows;
+ break;
+ case KEY_END:
+ move = +widget.num_rows;
+ break;
+ case CTRL_D:
+ if ( ! widget.row.setting.name )
+ break;
+ if ( ( rc = delete_setting ( widget.settings,
+ &widget.row.setting ) ) != 0 ) {
+ alert ( " %s ", strerror ( rc ) );
+ }
+ select_setting_row ( &widget, widget.current );
+ redraw = 1;
+ break;
+ case CTRL_X:
+ return 0;
+ case CR:
+ case LF:
+ if ( widget.row.settings ) {
+ init_widget ( &widget,
+ widget.row.settings );
+ redraw = 1;
+ }
+ /* Fall through */
+ default:
+ if ( widget.row.setting.name ) {
+ edit_setting ( &widget, key );
+ redraw = 1;
+ }
+ break;
+ }
+ if ( move ) {
+ next = ( widget.current + move );
+ if ( ( int ) next < 0 )
+ next = 0;
+ if ( next >= widget.num_rows )
+ next = ( widget.num_rows - 1 );
+ if ( next != widget.current ) {
+ draw_setting_row ( &widget );
+ redraw = 1;
+ reveal_setting_row ( &widget, next );
+ select_setting_row ( &widget, next );
+ }
+ }
+ }
+ }
+}
+
+int settings_ui ( struct settings *settings ) {
+ int rc;
+
+ initscr();
+ start_color();
+ color_set ( CPAIR_NORMAL, NULL );
+ curs_set ( 0 );
+ erase();
+
+ rc = main_loop ( settings );
+
+ endwin();
+
+ return rc;
+}
diff --git a/qemu/roms/ipxe/src/hci/wireless_errors.c b/qemu/roms/ipxe/src/hci/wireless_errors.c
new file mode 100644
index 000000000..7154df556
--- /dev/null
+++ b/qemu/roms/ipxe/src/hci/wireless_errors.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2009 Joshua Oreman <oremanj@rwcr.net>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <errno.h>
+#include <ipxe/errortab.h>
+#include <ipxe/net80211_err.h>
+
+/* Record errors as though they come from the 802.11 stack */
+#undef ERRFILE
+#define ERRFILE ERRFILE_net80211
+
+/** All 802.11 errors
+ */
+struct errortab wireless_errors[] __errortab = {
+ __einfo_errortab ( EINFO_EINVAL_PKT_TOO_SHORT ),
+ __einfo_errortab ( EINFO_EINVAL_PKT_VERSION ),
+ __einfo_errortab ( EINFO_EINVAL_PKT_NOT_DATA ),
+ __einfo_errortab ( EINFO_EINVAL_PKT_NOT_FROMDS ),
+ __einfo_errortab ( EINFO_EINVAL_PKT_LLC_HEADER ),
+ __einfo_errortab ( EINFO_EINVAL_CRYPTO_REQUEST ),
+ __einfo_errortab ( EINFO_EINVAL_ACTIVE_SCAN ),
+ __einfo_errortab ( EINFO_ECONNREFUSED_FAILURE ),
+ __einfo_errortab ( EINFO_ECONNREFUSED_CAPAB_UNSUPP ),
+ __einfo_errortab ( EINFO_ECONNREFUSED_REASSOC_INVALID ),
+ __einfo_errortab ( EINFO_ECONNREFUSED_ASSOC_DENIED ),
+ __einfo_errortab ( EINFO_ECONNREFUSED_AUTH_ALGO_UNSUPP ),
+ __einfo_errortab ( EINFO_ECONNREFUSED_AUTH_SEQ_INVALID ),
+ __einfo_errortab ( EINFO_ECONNREFUSED_AUTH_CHALL_INVALID ),
+ __einfo_errortab ( EINFO_ECONNREFUSED_AUTH_TIMEOUT ),
+ __einfo_errortab ( EINFO_ECONNREFUSED_ASSOC_NO_ROOM ),
+ __einfo_errortab ( EINFO_ECONNREFUSED_ASSOC_NEED_RATE ),
+ __einfo_errortab ( EINFO_ECONNREFUSED_ASSOC_NEED_SHORT_PMBL ),
+ __einfo_errortab ( EINFO_ECONNREFUSED_ASSOC_NEED_PBCC ),
+ __einfo_errortab ( EINFO_ECONNREFUSED_ASSOC_NEED_CHAN_AGILITY ),
+ __einfo_errortab ( EINFO_ECONNREFUSED_ASSOC_NEED_SPECTRUM_MGMT ),
+ __einfo_errortab ( EINFO_ECONNREFUSED_ASSOC_BAD_POWER ),
+ __einfo_errortab ( EINFO_ECONNREFUSED_ASSOC_BAD_CHANNELS ),
+ __einfo_errortab ( EINFO_ECONNREFUSED_ASSOC_NEED_SHORT_SLOT ),
+ __einfo_errortab ( EINFO_ECONNREFUSED_ASSOC_NEED_DSSS_OFDM ),
+ __einfo_errortab ( EINFO_EHOSTUNREACH_QOS_FAILURE ),
+ __einfo_errortab ( EINFO_EHOSTUNREACH_QOS_NO_ROOM ),
+ __einfo_errortab ( EINFO_EHOSTUNREACH_LINK_IS_HORRIBLE ),
+ __einfo_errortab ( EINFO_EHOSTUNREACH_ASSOC_NEED_QOS ),
+ __einfo_errortab ( EINFO_EHOSTUNREACH_REQUEST_DECLINED ),
+ __einfo_errortab ( EINFO_EHOSTUNREACH_REQUEST_INVALID ),
+ __einfo_errortab ( EINFO_EHOSTUNREACH_TS_NOT_CREATED_AGAIN ),
+ __einfo_errortab ( EINFO_EHOSTUNREACH_INVALID_IE ),
+ __einfo_errortab ( EINFO_EHOSTUNREACH_GROUP_CIPHER_INVALID ),
+ __einfo_errortab ( EINFO_EHOSTUNREACH_PAIR_CIPHER_INVALID ),
+ __einfo_errortab ( EINFO_EHOSTUNREACH_AKMP_INVALID ),
+ __einfo_errortab ( EINFO_EHOSTUNREACH_RSN_VERSION_UNSUPP ),
+ __einfo_errortab ( EINFO_EHOSTUNREACH_RSN_CAPAB_INVALID ),
+ __einfo_errortab ( EINFO_EHOSTUNREACH_CIPHER_REJECTED ),
+ __einfo_errortab ( EINFO_EHOSTUNREACH_TS_NOT_CREATED_WAIT ),
+ __einfo_errortab ( EINFO_EHOSTUNREACH_DIRECT_LINK_FORBIDDEN ),
+ __einfo_errortab ( EINFO_EHOSTUNREACH_DEST_NOT_PRESENT ),
+ __einfo_errortab ( EINFO_EHOSTUNREACH_DEST_NOT_QOS ),
+ __einfo_errortab ( EINFO_EHOSTUNREACH_ASSOC_LISTEN_TOO_HIGH ),
+ __einfo_errortab ( EINFO_ECONNRESET_UNSPECIFIED ),
+ __einfo_errortab ( EINFO_ECONNRESET_AUTH_NO_LONGER_VALID ),
+ __einfo_errortab ( EINFO_ECONNRESET_LEAVING ),
+ __einfo_errortab ( EINFO_ECONNRESET_INACTIVITY ),
+ __einfo_errortab ( EINFO_ECONNRESET_OUT_OF_RESOURCES ),
+ __einfo_errortab ( EINFO_ECONNRESET_NEED_AUTH ),
+ __einfo_errortab ( EINFO_ECONNRESET_NEED_ASSOC ),
+ __einfo_errortab ( EINFO_ECONNRESET_LEAVING_TO_ROAM ),
+ __einfo_errortab ( EINFO_ECONNRESET_REASSOC_INVALID ),
+ __einfo_errortab ( EINFO_ECONNRESET_BAD_POWER ),
+ __einfo_errortab ( EINFO_ECONNRESET_BAD_CHANNELS ),
+ __einfo_errortab ( EINFO_ECONNRESET_INVALID_IE ),
+ __einfo_errortab ( EINFO_ECONNRESET_MIC_FAILURE ),
+ __einfo_errortab ( EINFO_ECONNRESET_4WAY_TIMEOUT ),
+ __einfo_errortab ( EINFO_ECONNRESET_GROUPKEY_TIMEOUT ),
+ __einfo_errortab ( EINFO_ECONNRESET_4WAY_INVALID ),
+ __einfo_errortab ( EINFO_ECONNRESET_GROUP_CIPHER_INVALID ),
+ __einfo_errortab ( EINFO_ECONNRESET_PAIR_CIPHER_INVALID ),
+ __einfo_errortab ( EINFO_ECONNRESET_AKMP_INVALID ),
+ __einfo_errortab ( EINFO_ECONNRESET_RSN_VERSION_INVALID ),
+ __einfo_errortab ( EINFO_ECONNRESET_RSN_CAPAB_INVALID ),
+ __einfo_errortab ( EINFO_ECONNRESET_8021X_FAILURE ),
+ __einfo_errortab ( EINFO_ECONNRESET_CIPHER_REJECTED ),
+ __einfo_errortab ( EINFO_ENETRESET_QOS_UNSPECIFIED ),
+ __einfo_errortab ( EINFO_ENETRESET_QOS_OUT_OF_RESOURCES ),
+ __einfo_errortab ( EINFO_ENETRESET_LINK_IS_HORRIBLE ),
+ __einfo_errortab ( EINFO_ENETRESET_INVALID_TXOP ),
+ __einfo_errortab ( EINFO_ENETRESET_REQUESTED_LEAVING ),
+ __einfo_errortab ( EINFO_ENETRESET_REQUESTED_NO_USE ),
+ __einfo_errortab ( EINFO_ENETRESET_REQUESTED_NEED_SETUP ),
+ __einfo_errortab ( EINFO_ENETRESET_REQUESTED_TIMEOUT ),
+ __einfo_errortab ( EINFO_ENETRESET_CIPHER_UNSUPPORTED ),
+};