Index: AppPkg/Applications/ConsoleIO/ConsoleIO.c
===================================================================
--- AppPkg/Applications/ConsoleIO/ConsoleIO.c	(revision 0)
+++ AppPkg/Applications/ConsoleIO/ConsoleIO.c	(working copy)
@@ -0,0 +1,198 @@
+/** @file
+    Exercise Console I/O functions in several modes.
+
+    Type END in order to exit.
+
+    Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+    This program and the accompanying materials
+    are licensed and made available under the terms and conditions of the BSD License
+    which accompanies this distribution. The full text of the license may be found at
+    http://opensource.org/licenses/bsd-license.
+
+    THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+    WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include  <stdio.h>
+#include  <stdlib.h>
+#include  <string.h>
+#include  <sys/EfiSysCall.h>
+#include  <sys/termios.h>
+#include  "ConsoleIO.h"
+
+const char  Identify[] = "\
+Console I/O Test.  Echos input in several modes.\n\
+Type END to exit.\n";
+
+const char  HelpText[] = "\
+  Syntax:  conio [Options]\n\
+  Options are:\n\
+    -h    Display this Help message.\n\
+    -?    Display this Help message.\n\
+    -s    Stop ignoring function and other special keys.\n\
+    -t    Dump the termios structure for stdin.\n\
+    -v    Verbose output.\n\
+";
+
+/** Remove the trailing newline from a buffered line.
+
+  Finds the first newline in a buffer and replaces it with a NUL character.
+  The buffer is assumed to be MBCS and not UCS2.
+
+  @param[in,out]    Buff    Pointer to the buffer containing the line to modify.
+**/
+VOID
+StripNL( char *Buff)
+{
+  Buff = strchr(Buff, '\n');
+  if(Buff != NULL) {
+    *Buff = 0;
+  }
+}
+
+/** Get and process command line options.
+
+  @param[in]  Argc    Number of arguments pointed to by Argv.
+  @param[in]  Argv    Array of pointers to arguments.
+
+  @return   A bitmapped set of flags identifying the recognized options.
+**/
+UINT32
+GetOptions(
+  int Argc,
+  char  **Argv
+  )
+{
+  char   *Arg;
+  UINT32  Options;
+  int     i;
+
+  Options = 0;
+
+  for (i = 1; i < Argc; ++i) {
+    Arg = Argv[i];
+
+    if (Arg[0] != '-') {
+      continue;
+    }
+    switch (Arg[1]) {
+      case 'd': // Set VEOF to EOT (^D)
+        Options |= FLAG_D;
+        break;
+
+      case 'h':
+      case '?': // Help
+        Options |= FLAG_H;
+        break;
+
+      case 's': // Read Scan Codes
+        Options |= FLAG_S;
+        break;
+
+      case 't': // Dump the termios structure
+        Options |= FLAG_T;
+        break;
+
+      case 'v': // Verbose
+        Options |= FLAG_V;
+        break;
+
+      case 'z': // Set VEOF to SUB (^Z)
+        Options |= FLAG_Z;
+        break;
+
+      default:
+        break;
+    }
+  }
+  return Options;
+}
+
+/** Console I/O exerciser.
+
+  @param[in]  Argc    Number of argument tokens pointed to by Argv.
+  @param[in]  Argv    Array of Argc pointers to command line tokens.
+
+  @retval  0         The application exited normally.
+  @retval  Non-Zero  An error occurred.
+**/
+int
+main (
+  IN int Argc,
+  IN char **Argv
+  )
+{
+  char           *fret;
+  char           *inbuff;
+  UINT32          Options;
+  struct termios  TermConf;
+
+  puts (Identify);
+
+  // Process command-line Options ############################################
+
+  Options = GetOptions (Argc, Argv);
+
+  if (Options & FLAG_H) {
+    puts (HelpText);
+    return 0;
+  }
+
+  if (tcgetattr (STDIN_FILENO, &TermConf) != 0) {
+    perror ("ERROR retrieving terminal attributes");
+    return EXIT_FAILURE;
+  }
+
+  if ((Options & FLAG_D) != 0) {
+    // Set VEOF to ^D (EOT)
+    TermConf.c_cc[VEOF] = CHAR_EOT;
+  }
+
+  if ((Options & FLAG_S) != 0) {
+    // Clear the IGNSPEC flag
+    TermConf.c_iflag &= ~IGNSPEC;
+  }
+
+  if ((Options & FLAG_Z) != 0) {
+    // Set VEOF to ^Z (SUB)
+    TermConf.c_cc[VEOF] = CHAR_SUB;
+  }
+
+  if (Options != 0) {
+    if (tcsetattr (STDIN_FILENO, TCSANOW, &TermConf) != 0) {
+      perror ("ERROR setting terminal attributes");
+      return EXIT_FAILURE;
+    }
+  }
+
+  if (Options & FLAG_T) {
+    DumpTermios (&TermConf);  // Dump the termios structure
+  }
+
+  // Actual work part of the application #####################################
+
+  inbuff = malloc(512);
+  if (inbuff == NULL) {
+    puts("ERROR: Unable to malloc input buffer.");
+    return -1;
+  }
+
+  do {
+    fputs("Type  something: ", stdout);
+    fret = fgets(inbuff, 100, stdin);
+
+    if (fret == NULL) {
+      perror("ERROR!  fgets() failed");
+      break;
+    }
+    else {
+      // Strip trailing line end.
+      StripNL(inbuff);
+      printf("fgets  returned \"%s\"\n", fret);
+      FKprint("buffer contains", inbuff);
+      putchar('\n');
+    }
+  } while(strcmp(inbuff, "END") != 0);
+
+  free (inbuff);
+  return 0;
+}
Index: AppPkg/Applications/ConsoleIO/ConsoleIO.h
===================================================================
--- AppPkg/Applications/ConsoleIO/ConsoleIO.h	(revision 0)
+++ AppPkg/Applications/ConsoleIO/ConsoleIO.h	(working copy)
@@ -0,0 +1,103 @@
+/** @file
+    Private declarations for the ConsoleIO test application.
+
+    Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+    This program and the accompanying materials
+    are licensed and made available under the terms and conditions of the BSD License
+    which accompanies this distribution. The full text of the license may be found at
+    http://opensource.org/licenses/bsd-license.
+
+    THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+    WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#ifndef   CONSOLE_IO_H_
+#define   CONSOLE_IO_H_
+
+#define   NumNames    46    ///< Number of named special non-printing characters
+
+/// Command Line Flags
+/// @{
+#define FLAG_A    0x00000001
+#define FLAG_B    0x00000002
+#define FLAG_C    0x00000004
+#define FLAG_D    0x00000008
+#define FLAG_E    0x00000010
+#define FLAG_F    0x00000020
+#define FLAG_G    0x00000040
+#define FLAG_H    0x00000080    ///< Help
+#define FLAG_I    0x00000100
+#define FLAG_J    0x00000200
+#define FLAG_K    0x00000400
+#define FLAG_L    0x00000800
+#define FLAG_M    0x00001000
+#define FLAG_N    0x00002000
+#define FLAG_O    0x00004000
+#define FLAG_P    0x00008000
+#define FLAG_Q    0x00010000
+#define FLAG_R    0x00020000
+#define FLAG_S    0x00040000    ///< Accept Special characters
+#define FLAG_T    0x00080000    ///< Dump the termios structure for stdin
+#define FLAG_U    0x00100000
+#define FLAG_V    0x00200000    ///< Verbose
+#define FLAG_W    0x00400000
+#define FLAG_X    0x00800000
+#define FLAG_Y    0x01000000
+#define FLAG_Z    0x02000000
+/// @}
+
+/// Number of named flags in each of the flag name tables.
+/// @{
+#define NumInFlags      4
+#define NumOutFlags     8
+#define NumCtrlFlags    0
+#define NumLocalFlags   11
+/// @}
+
+/// An array of pointers to the MBCS names of special non-printing characters.
+extern const char * const FunNames[46];
+
+/// Each entry in the flag name arrays is of this type
+typedef struct FlagEnt {
+  char   *FlagName;
+  UINT32  FlagValue;
+} FlagEnt;
+
+/** Print the name of a key associated with ScanCode.
+
+  @param[in]  ScanCode    Scan code associated with the key to print the name of.
+**/
+VOID
+PrintFunKey (
+  int   ScanCode
+);
+
+/** Print a buffer one character at a time, translating special characters as needed.
+
+  The buffer will be printed after the message pointed to by Msg.  If buffer contains
+  a non-printing character, such as a function key or arrow, a special tag will be
+  printed identifying the character.  e.g.: <F1>, <Pg Up>, <Up>, ^G, ^I, ...
+
+  The input buffer contains MBCS characters which are converted into Wide characters
+  before processing.
+
+  Example:
+    Buff = "AbCdEfG";
+    FKprint ("Buffer contents", Buff)
+  will produce:
+    Buffer contents "AbCdEfG"
+
+  @param[in]  Msg     Message to prefix to Buffer contents
+  @param[in]  Buff    Buffer to be displayed.
+**/
+void FKprint (
+  const char * const Fmt,
+  const char * const Buff
+);
+
+/** Print a description of each element of the termios structure.
+
+  @param[in]  TermInfo  Pointer to the termios structure to dump.
+**/
+void DumpTermios (struct termios *TermStruc);
+
+#endif    // CONSOLE_IO_H_
Index: AppPkg/Applications/ConsoleIO/ConsoleIO.inf
===================================================================
--- AppPkg/Applications/ConsoleIO/ConsoleIO.inf	(revision 0)
+++ AppPkg/Applications/ConsoleIO/ConsoleIO.inf	(working copy)
@@ -0,0 +1,41 @@
+## @file
+#   An application to test Console I/O functionality in several modes.
+#
+#  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution. The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010006
+  BASE_NAME                      = ConsoleIO
+  FILE_GUID                      = 8D559BE2-E6BA-462E-A104-A3818E984F1A
+  MODULE_TYPE                    = UEFI_APPLICATION
+  VERSION_STRING                 = 0.1
+  ENTRY_POINT                    = ShellCEntryLib
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources]
+  ConsoleIO.c
+  FunKey.c
+  FkPrint.c
+  TermInfo.c
+
+[Packages]
+  StdLib/StdLib.dec
+  MdePkg/MdePkg.dec
+  ShellPkg/ShellPkg.dec
+
+[LibraryClasses]
+  LibC
+  LibStdio
+  LibString
+  LibWchar
Index: AppPkg/Applications/ConsoleIO/FkPrint.c
===================================================================
--- AppPkg/Applications/ConsoleIO/FkPrint.c	(revision 0)
+++ AppPkg/Applications/ConsoleIO/FkPrint.c	(working copy)
@@ -0,0 +1,78 @@
+/** @file
+    Print a buffer one character at a time, translating special characters as needed.
+
+    Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+    This program and the accompanying materials
+    are licensed and made available under the terms and conditions of the BSD License
+    which accompanies this distribution. The full text of the license may be found at
+    http://opensource.org/licenses/bsd-license.
+
+    THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+    WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include  <stdio.h>
+#include  <stdlib.h>
+#include  <wchar.h>
+#include  <sys/types.h>
+#include  <sys/termios.h>
+#include  "ConsoleIO.h"
+
+/** Print a buffer one character at a time, translating special characters as needed.
+
+  The buffer will be printed after the message pointed to by Msg.  If buffer contains
+  a non-printing character, such as a function key or arrow, a special tag will be
+  printed identifying the character.  e.g.: <F1>, <Pg Up>, <Up>, ^G, ^I, ...
+
+  The input buffer contains MBCS characters which are converted into Wide characters
+  before processing.
+
+  Example:
+    Buff = "AbCdEfG";
+    FKprint ("Buffer contents", Buff)
+  will produce:
+    Buffer contents "AbCdEfG"
+
+  @param[in]  Msg     Message to prefix to Buffer contents
+  @param[in]  Buff    Buffer to be displayed.
+**/
+void
+FKprint (
+  const char * const Msg,
+  const char * const Buff
+  )
+{
+  wchar_t  *WideBuff;
+  wchar_t  *pWork;
+  ssize_t    Val;
+  wchar_t   CurChar;
+
+  WideBuff = malloc(2048);
+  if (WideBuff != NULL) {
+    Val = (ssize_t)mbstowcs (WideBuff, Buff, 1024);
+    if (Val < 0) {
+      puts("ERROR: Invalid character encountered in buffer.");
+    }
+    else {
+      fputs (Msg, stdout);
+      fputs (" \"", stdout);
+      // Val contains the number of characters in WideBuff
+      pWork = WideBuff;
+      for ( ; Val > 0; --Val) {
+        CurChar = *pWork++;
+        if((CurChar < TtyFunKeyMin) || (CurChar > TtyFunKeyMax)) {
+          // Regular character, just print it.
+          putwchar (CurChar);
+        }
+        else {
+          // Function key or special character
+          PrintFunKey (CurChar);
+        }
+      }
+      fputs ("\"\n", stdout);
+    }
+    free(WideBuff);
+  }
+  else {
+    puts("ERROR: Unable to malloc memory.");
+  }
+}
Index: AppPkg/Applications/ConsoleIO/FunKey.c
===================================================================
--- AppPkg/Applications/ConsoleIO/FunKey.c	(revision 0)
+++ AppPkg/Applications/ConsoleIO/FunKey.c	(working copy)
@@ -0,0 +1,136 @@
+/** @file
+    Defines an array of strings associated with each special/function key.
+    Index 0 corresponds to TtyUpArrow with each increasing index going downward
+    to TtyKeyEject.
+
+    Also defines a function to get the name of a key given its scan code and a
+    function to print the key's name.
+
+    Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+    This program and the accompanying materials
+    are licensed and made available under the terms and conditions of the BSD License
+    which accompanies this distribution. The full text of the license may be found at
+    http://opensource.org/licenses/bsd-license.
+
+    THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+    WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include  <stdio.h>
+#include  <sys/termios.h>
+#include  "ConsoleIO.h"
+
+/// An array of pointers to the MBCS names of special non-printing characters.
+const char * const FunNames[NumNames] = {
+  "Unknown",      //TtyFunKeyMax  = 0xF900    63744 = 0
+  "Up",           //TtyUpArrow    = 0xF8FF,   63743 = 1
+  "Down",         //TtyDownArrow,             63742 = 2
+  "Right",        //TtyRightArrow,            63741 = 3
+  "Left",         //TtyLeftArrow,             63740 = 4
+  "Home",         //TtyHome,                  63739 = 5
+  "End",          //TtyEnd,                   63738 = 6
+  "Insert",       //TtyInsert,                63737 = 7
+  "Delete",       //TtyDelete,                63736 = 8
+  "Pg Up",        //TtyPageUp,                63735 = 9
+  "Pg Down",      //TtyPageDown,              63734 = 10
+  "F1",           //TtyF1,                    63733 = 11
+  "F2",           //TtyF2,                    63732 = 12
+  "F3",           //TtyF3,                    63731 = 13
+  "F4",           //TtyF4,                    63730 = 14
+  "F5",           //TtyF5,                    63729 = 15
+  "F6",           //TtyF6,                    63728 = 16
+  "F7",           //TtyF7,                    63727 = 17
+  "F8",           //TtyF8,                    63726 = 18
+  "F9",           //TtyF9,                    63725 = 19
+  "F10",          //TtyF10,                   63724 = 20
+  "F11",          //TtyF11,                   63723 = 21
+  "F12",          //TtyF12,                   63722 = 22
+  "ESC",          //TtyEscape     = 0xF8E9,   63721 = 23
+
+  "F13",          //TtyF13        = 0xF898,   63640 = 104  = 24    (80)
+  "F14",          //TtyF14,                   63639 = 105  = 25
+  "F15",          //TtyF15,                   63638 = 106  = 26
+  "F16",          //TtyF16,                   63637 = 107  = 27
+  "F17",          //TtyF17,                   63636 = 108  = 28
+  "F18",          //TtyF18,                   63635 = 109  = 29
+  "F19",          //TtyF19,                   63634 = 110  = 30
+  "F20",          //TtyF20,                   63633 = 111  = 31
+  "F21",          //TtyF21,                   63632 = 112  = 32
+  "F22",          //TtyF22,                   63631 = 113  = 33
+  "F23",          //TtyF23,                   63630 = 114  = 34
+  "F24",          //TtyF24        = 0xF88D,   63629 = 115  = 35
+
+  "Mute",         //TtyMute       = 0xF881,   63617 = 127  = 36    (91) (11)
+  "Vol Up",       //TtyVolumeUp,              63616 = 128  = 37
+  "Vol Down",     //TtyVolumeDown = 0xF87F,   63615 = 129  = 38
+
+  "Brighten",     //TtyBrightnessUp = 0xF800, 63488 = 256  = 39    (217) (126)
+  "Dim",          //TtyBrightnessDown,        63487 = 257  = 40
+  "Susp",         //TtySuspend,               63486 = 258  = 41
+  "Hiber",        //TtyHibernate,             63485 = 259  = 42
+  "Display",      //TtyToggleDisplay,         63484 = 260  = 43
+  "Recovery",     //TtyRecovery,              63483 = 261  = 44
+  "Eject"         //TtyKeyEject   = 0xF7FA,   63482 = 262  = 45
+};
+
+/** Given the Scan Code of a special key, retrieve its name.
+  ScanCodes that are within undefined ranges are given the name "Unknown", while
+  ScanCodes that are outside the range of special keys are named "ERROR".
+
+  @param[in]  ScanCode    Key to get the name of.
+
+  @return     A pointer to the name of the key associated with ScanCode.
+**/
+const char *
+FunKeyName (
+  int   ScanCode
+  )
+{
+  const char *Name;
+  int         NameDex;
+
+  NameDex = -1;
+
+  if (ScanCode >= TtyFunKeyMin) {
+    NameDex = TtyFunKeyMax - ScanCode;
+    if (NameDex > 23) {
+      NameDex -= 80;
+      if (NameDex < 24) {
+        NameDex = 0;
+      }
+    }
+    if (NameDex > 35) {
+      NameDex -= 11;
+      if (NameDex < 36) {
+        NameDex = 0;
+      }
+    }
+    if (NameDex > 38) {
+      NameDex -= 126;
+      if (NameDex < 39) {
+        NameDex = 0;
+      }
+    }
+  }
+  if ((NameDex < 0) || (NameDex >= NumNames)) {
+    Name = "ERROR";
+  }
+  else {
+    Name = FunNames[NameDex];
+  }
+  return Name;
+}
+
+/** Print the name of a key associated with ScanCode.
+
+  @param[in]  ScanCode    Scan code associated with the key to print the name of.
+**/
+VOID
+PrintFunKey (
+  int   ScanCode
+  )
+{
+  const char   *Name;
+
+  Name = FunKeyName (ScanCode);
+  printf("<%s>", Name);
+}
Index: AppPkg/Applications/ConsoleIO/TermInfo.c
===================================================================
--- AppPkg/Applications/ConsoleIO/TermInfo.c	(revision 0)
+++ AppPkg/Applications/ConsoleIO/TermInfo.c	(working copy)
@@ -0,0 +1,159 @@
+/** @file
+    Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+    This program and the accompanying materials
+    are licensed and made available under the terms and conditions of the BSD License
+    which accompanies this distribution. The full text of the license may be found at
+    http://opensource.org/licenses/bsd-license.
+
+    THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+    WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include  <stdio.h>
+#include  <sys/termios.h>
+#include  "ConsoleIO.h"
+
+/// Names of input flags from termios.c_iflag
+const FlagEnt InFlags[NumInFlags] = {
+  { "INLCR",    INLCR },
+  { "IGNCR",    IGNCR },
+  { "ICRNL",    ICRNL },
+  { "IGNSPEC",  IGNSPEC }
+};
+
+/// Names of control flags from termios.c_cflag
+const FlagEnt CtrlFlags[] = {
+  { "null",    0 }
+};
+
+/// Names of output flags from termios.c_oflag
+const FlagEnt OutFlags[NumOutFlags] = {
+  { "OPOST",  OPOST },
+  { "ONLCR",  ONLCR },
+  { "OXTABS", OXTABS },
+  { "ONOEOT", ONOEOT },
+  { "OCRNL",  OCRNL },
+  { "ONOCR",  ONOCR },
+  { "ONLRET", ONLRET },
+  { "OCTRL",  OCTRL }
+};
+
+/// Names of local flags from termios.c_lflag
+const FlagEnt LocalFlags[NumLocalFlags] = {
+  { "ECHO",     ECHO },
+  { "ECHOE",    ECHOE },
+  { "ECHOK",    ECHOK },
+  { "ECHONL",   ECHONL },
+  { "ISIG",     ISIG },
+  { "ICANON",   ICANON },
+  { "IEXTEN",   IEXTEN },
+  { "TOSTOP",   TOSTOP },
+  { "PENDIN",   PENDIN },
+  { "NOFLSH",   NOFLSH },
+  { "FLUSHO",   FLUSHO }
+};
+
+/// Names of elements of the c_cc array from termios.c_cc
+const FlagEnt CcNames[NCCS] = {
+  { "VTABLEN",    0 },
+  { "VEOF",       1 },
+  { "VEOL",       1 },
+  { "VERASE",     1 },
+  { "VKILL",      1 },
+  { "VINTR",      1 },
+  { "VQUIT",      1 },
+  { "VMIN",       0 },
+  { "VTIME",      0 },
+  { "VWERASE",    1 },
+  { "VREPRINT",   1 },
+  { "VLNEXT",     1 },
+  { "VDISCARD",   1 }
+};
+
+/** Print the flags given the Flag value and a pointer to an array of possible names.
+
+  @param[in]    Header    Pointer to a string to print before the flag values
+  @param[in]    FlagVal   The bitmapped flags to be identified
+  @param[in]    Table     Pointer to the array of potential flag names
+  @param[in]    NumFlags  Number of names defined in Table
+**/
+void
+ListFlags (
+  const char      * const Header,
+  const tcflag_t          FlagVal,
+  const FlagEnt   * const Table,
+  const UINT32            NumFlags
+  )
+{
+  UINT32 i;
+
+  printf("%8s: [0x%04X] ", Header, FlagVal);
+  for (i = 0; i < NumFlags; ++i) {
+    if ((FlagVal & Table[i].FlagValue) != 0) {
+      printf(" %s", Table[i].FlagName);
+    }
+  }
+  puts("");
+}
+
+/** Print a description of each member of the c_cc array.
+
+  @param[in]  c_cc    Pointer to the c_cc array to dump.
+  @param[in]  Table   Pointer to the table of names for the c_cc members.
+**/
+void
+PrintCCC (
+  cc_t            * const c_cc,
+  const FlagEnt   * const Table
+  )
+{
+  int           i;
+  unsigned char c;
+
+  puts("Control Character array (c_cc):");
+  for (i = 0; i < NCCS; ++i) {
+    c = c_cc[i];
+    printf("  %9s: [0x%02X]", Table[i].FlagName, c);
+    if (Table[i].FlagValue == 1) {
+      if (c < 0x7f) {
+        if (c < ' ') {
+          c += '@';
+          printf("  '^%c'", c);
+        }
+        else {
+          fputs("  '?'", stdout);
+        }
+      }
+      else {
+        fputs("  Disabled", stdout);
+      }
+    }
+    puts("");
+  }
+}
+
+/** Print a description of each element of the termios structure.
+
+  @param[in]  TermInfo  Pointer to the termios structure to dump.
+**/
+void
+DumpTermios (
+  struct termios *TermInfo
+  )
+{
+  puts("termios structure for stdin:");
+  /* input speed    */
+  printf("Input Speed: %d\n", TermInfo->c_ispeed);
+  /* output speed   */
+  printf("Output Speed: %d\n", TermInfo->c_ospeed);
+  /* input flags    */
+  ListFlags ("Input", TermInfo->c_iflag, InFlags, NumInFlags);
+  /* output flags   */
+  ListFlags ("Output", TermInfo->c_oflag, OutFlags, NumOutFlags);
+  /* control flags  */
+  ListFlags ("Control", TermInfo->c_cflag, CtrlFlags, NumCtrlFlags);
+  /* local flags    */
+  ListFlags ("Local", TermInfo->c_lflag, LocalFlags, NumLocalFlags);
+  /* control chars  */
+  PrintCCC (&TermInfo->c_cc[0], CcNames);
+  puts("");
+}
Index: AppPkg/Applications/ConsoleIO/ConsoleIO.c
===================================================================
--- AppPkg/Applications/ConsoleIO/ConsoleIO.c	(revision 0)
+++ AppPkg/Applications/ConsoleIO/ConsoleIO.c	(working copy)
@@ -0,0 +1,198 @@
+/** @file
+    Exercise Console I/O functions in several modes.
+
+    Type END in order to exit.
+
+    Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+    This program and the accompanying materials
+    are licensed and made available under the terms and conditions of the BSD License
+    which accompanies this distribution. The full text of the license may be found at
+    http://opensource.org/licenses/bsd-license.
+
+    THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+    WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include  <stdio.h>
+#include  <stdlib.h>
+#include  <string.h>
+#include  <sys/EfiSysCall.h>
+#include  <sys/termios.h>
+#include  "ConsoleIO.h"
+
+const char  Identify[] = "\
+Console I/O Test.  Echos input in several modes.\n\
+Type END to exit.\n";
+
+const char  HelpText[] = "\
+  Syntax:  conio [Options]\n\
+  Options are:\n\
+    -h    Display this Help message.\n\
+    -?    Display this Help message.\n\
+    -s    Stop ignoring function and other special keys.\n\
+    -t    Dump the termios structure for stdin.\n\
+    -v    Verbose output.\n\
+";
+
+/** Remove the trailing newline from a buffered line.
+
+  Finds the first newline in a buffer and replaces it with a NUL character.
+  The buffer is assumed to be MBCS and not UCS2.
+
+  @param[in,out]    Buff    Pointer to the buffer containing the line to modify.
+**/
+VOID
+StripNL( char *Buff)
+{
+  Buff = strchr(Buff, '\n');
+  if(Buff != NULL) {
+    *Buff = 0;
+  }
+}
+
+/** Get and process command line options.
+
+  @param[in]  Argc    Number of arguments pointed to by Argv.
+  @param[in]  Argv    Array of pointers to arguments.
+
+  @return   A bitmapped set of flags identifying the recognized options.
+**/
+UINT32
+GetOptions(
+  int Argc,
+  char  **Argv
+  )
+{
+  char   *Arg;
+  UINT32  Options;
+  int     i;
+
+  Options = 0;
+
+  for (i = 1; i < Argc; ++i) {
+    Arg = Argv[i];
+
+    if (Arg[0] != '-') {
+      continue;
+    }
+    switch (Arg[1]) {
+      case 'd': // Set VEOF to EOT (^D)
+        Options |= FLAG_D;
+        break;
+
+      case 'h':
+      case '?': // Help
+        Options |= FLAG_H;
+        break;
+
+      case 's': // Read Scan Codes
+        Options |= FLAG_S;
+        break;
+
+      case 't': // Dump the termios structure
+        Options |= FLAG_T;
+        break;
+
+      case 'v': // Verbose
+        Options |= FLAG_V;
+        break;
+
+      case 'z': // Set VEOF to SUB (^Z)
+        Options |= FLAG_Z;
+        break;
+
+      default:
+        break;
+    }
+  }
+  return Options;
+}
+
+/** Console I/O exerciser.
+
+  @param[in]  Argc    Number of argument tokens pointed to by Argv.
+  @param[in]  Argv    Array of Argc pointers to command line tokens.
+
+  @retval  0         The application exited normally.
+  @retval  Non-Zero  An error occurred.
+**/
+int
+main (
+  IN int Argc,
+  IN char **Argv
+  )
+{
+  char           *fret;
+  char           *inbuff;
+  UINT32          Options;
+  struct termios  TermConf;
+
+  puts (Identify);
+
+  // Process command-line Options ############################################
+
+  Options = GetOptions (Argc, Argv);
+
+  if (Options & FLAG_H) {
+    puts (HelpText);
+    return 0;
+  }
+
+  if (tcgetattr (STDIN_FILENO, &TermConf) != 0) {
+    perror ("ERROR retrieving terminal attributes");
+    return EXIT_FAILURE;
+  }
+
+  if ((Options & FLAG_D) != 0) {
+    // Set VEOF to ^D (EOT)
+    TermConf.c_cc[VEOF] = CHAR_EOT;
+  }
+
+  if ((Options & FLAG_S) != 0) {
+    // Clear the IGNSPEC flag
+    TermConf.c_iflag &= ~IGNSPEC;
+  }
+
+  if ((Options & FLAG_Z) != 0) {
+    // Set VEOF to ^Z (SUB)
+    TermConf.c_cc[VEOF] = CHAR_SUB;
+  }
+
+  if (Options != 0) {
+    if (tcsetattr (STDIN_FILENO, TCSANOW, &TermConf) != 0) {
+      perror ("ERROR setting terminal attributes");
+      return EXIT_FAILURE;
+    }
+  }
+
+  if (Options & FLAG_T) {
+    DumpTermios (&TermConf);  // Dump the termios structure
+  }
+
+  // Actual work part of the application #####################################
+
+  inbuff = malloc(512);
+  if (inbuff == NULL) {
+    puts("ERROR: Unable to malloc input buffer.");
+    return -1;
+  }
+
+  do {
+    fputs("Type  something: ", stdout);
+    fret = fgets(inbuff, 100, stdin);
+
+    if (fret == NULL) {
+      perror("ERROR!  fgets() failed");
+      break;
+    }
+    else {
+      // Strip trailing line end.
+      StripNL(inbuff);
+      printf("fgets  returned \"%s\"\n", fret);
+      FKprint("buffer contains", inbuff);
+      putchar('\n');
+    }
+  } while(strcmp(inbuff, "END") != 0);
+
+  free (inbuff);
+  return 0;
+}
Index: AppPkg/Applications/ConsoleIO/ConsoleIO.h
===================================================================
--- AppPkg/Applications/ConsoleIO/ConsoleIO.h	(revision 0)
+++ AppPkg/Applications/ConsoleIO/ConsoleIO.h	(working copy)
@@ -0,0 +1,103 @@
+/** @file
+    Private declarations for the ConsoleIO test application.
+
+    Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+    This program and the accompanying materials
+    are licensed and made available under the terms and conditions of the BSD License
+    which accompanies this distribution. The full text of the license may be found at
+    http://opensource.org/licenses/bsd-license.
+
+    THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+    WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#ifndef   CONSOLE_IO_H_
+#define   CONSOLE_IO_H_
+
+#define   NumNames    46    ///< Number of named special non-printing characters
+
+/// Command Line Flags
+/// @{
+#define FLAG_A    0x00000001
+#define FLAG_B    0x00000002
+#define FLAG_C    0x00000004
+#define FLAG_D    0x00000008
+#define FLAG_E    0x00000010
+#define FLAG_F    0x00000020
+#define FLAG_G    0x00000040
+#define FLAG_H    0x00000080    ///< Help
+#define FLAG_I    0x00000100
+#define FLAG_J    0x00000200
+#define FLAG_K    0x00000400
+#define FLAG_L    0x00000800
+#define FLAG_M    0x00001000
+#define FLAG_N    0x00002000
+#define FLAG_O    0x00004000
+#define FLAG_P    0x00008000
+#define FLAG_Q    0x00010000
+#define FLAG_R    0x00020000
+#define FLAG_S    0x00040000    ///< Accept Special characters
+#define FLAG_T    0x00080000    ///< Dump the termios structure for stdin
+#define FLAG_U    0x00100000
+#define FLAG_V    0x00200000    ///< Verbose
+#define FLAG_W    0x00400000
+#define FLAG_X    0x00800000
+#define FLAG_Y    0x01000000
+#define FLAG_Z    0x02000000
+/// @}
+
+/// Number of named flags in each of the flag name tables.
+/// @{
+#define NumInFlags      4
+#define NumOutFlags     8
+#define NumCtrlFlags    0
+#define NumLocalFlags   11
+/// @}
+
+/// An array of pointers to the MBCS names of special non-printing characters.
+extern const char * const FunNames[46];
+
+/// Each entry in the flag name arrays is of this type
+typedef struct FlagEnt {
+  char   *FlagName;
+  UINT32  FlagValue;
+} FlagEnt;
+
+/** Print the name of a key associated with ScanCode.
+
+  @param[in]  ScanCode    Scan code associated with the key to print the name of.
+**/
+VOID
+PrintFunKey (
+  int   ScanCode
+);
+
+/** Print a buffer one character at a time, translating special characters as needed.
+
+  The buffer will be printed after the message pointed to by Msg.  If buffer contains
+  a non-printing character, such as a function key or arrow, a special tag will be
+  printed identifying the character.  e.g.: <F1>, <Pg Up>, <Up>, ^G, ^I, ...
+
+  The input buffer contains MBCS characters which are converted into Wide characters
+  before processing.
+
+  Example:
+    Buff = "AbCdEfG";
+    FKprint ("Buffer contents", Buff)
+  will produce:
+    Buffer contents "AbCdEfG"
+
+  @param[in]  Msg     Message to prefix to Buffer contents
+  @param[in]  Buff    Buffer to be displayed.
+**/
+void FKprint (
+  const char * const Fmt,
+  const char * const Buff
+);
+
+/** Print a description of each element of the termios structure.
+
+  @param[in]  TermInfo  Pointer to the termios structure to dump.
+**/
+void DumpTermios (struct termios *TermStruc);
+
+#endif    // CONSOLE_IO_H_
Index: AppPkg/Applications/ConsoleIO/ConsoleIO.inf
===================================================================
--- AppPkg/Applications/ConsoleIO/ConsoleIO.inf	(revision 0)
+++ AppPkg/Applications/ConsoleIO/ConsoleIO.inf	(working copy)
@@ -0,0 +1,41 @@
+## @file
+#   An application to test Console I/O functionality in several modes.
+#
+#  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution. The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010006
+  BASE_NAME                      = ConsoleIO
+  FILE_GUID                      = 8D559BE2-E6BA-462E-A104-A3818E984F1A
+  MODULE_TYPE                    = UEFI_APPLICATION
+  VERSION_STRING                 = 0.1
+  ENTRY_POINT                    = ShellCEntryLib
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources]
+  ConsoleIO.c
+  FunKey.c
+  FkPrint.c
+  TermInfo.c
+
+[Packages]
+  StdLib/StdLib.dec
+  MdePkg/MdePkg.dec
+  ShellPkg/ShellPkg.dec
+
+[LibraryClasses]
+  LibC
+  LibStdio
+  LibString
+  LibWchar
Index: AppPkg/Applications/ConsoleIO/FkPrint.c
===================================================================
--- AppPkg/Applications/ConsoleIO/FkPrint.c	(revision 0)
+++ AppPkg/Applications/ConsoleIO/FkPrint.c	(working copy)
@@ -0,0 +1,78 @@
+/** @file
+    Print a buffer one character at a time, translating special characters as needed.
+
+    Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+    This program and the accompanying materials
+    are licensed and made available under the terms and conditions of the BSD License
+    which accompanies this distribution. The full text of the license may be found at
+    http://opensource.org/licenses/bsd-license.
+
+    THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+    WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include  <stdio.h>
+#include  <stdlib.h>
+#include  <wchar.h>
+#include  <sys/types.h>
+#include  <sys/termios.h>
+#include  "ConsoleIO.h"
+
+/** Print a buffer one character at a time, translating special characters as needed.
+
+  The buffer will be printed after the message pointed to by Msg.  If buffer contains
+  a non-printing character, such as a function key or arrow, a special tag will be
+  printed identifying the character.  e.g.: <F1>, <Pg Up>, <Up>, ^G, ^I, ...
+
+  The input buffer contains MBCS characters which are converted into Wide characters
+  before processing.
+
+  Example:
+    Buff = "AbCdEfG";
+    FKprint ("Buffer contents", Buff)
+  will produce:
+    Buffer contents "AbCdEfG"
+
+  @param[in]  Msg     Message to prefix to Buffer contents
+  @param[in]  Buff    Buffer to be displayed.
+**/
+void
+FKprint (
+  const char * const Msg,
+  const char * const Buff
+  )
+{
+  wchar_t  *WideBuff;
+  wchar_t  *pWork;
+  ssize_t    Val;
+  wchar_t   CurChar;
+
+  WideBuff = malloc(2048);
+  if (WideBuff != NULL) {
+    Val = (ssize_t)mbstowcs (WideBuff, Buff, 1024);
+    if (Val < 0) {
+      puts("ERROR: Invalid character encountered in buffer.");
+    }
+    else {
+      fputs (Msg, stdout);
+      fputs (" \"", stdout);
+      // Val contains the number of characters in WideBuff
+      pWork = WideBuff;
+      for ( ; Val > 0; --Val) {
+        CurChar = *pWork++;
+        if((CurChar < TtyFunKeyMin) || (CurChar > TtyFunKeyMax)) {
+          // Regular character, just print it.
+          putwchar (CurChar);
+        }
+        else {
+          // Function key or special character
+          PrintFunKey (CurChar);
+        }
+      }
+      fputs ("\"\n", stdout);
+    }
+    free(WideBuff);
+  }
+  else {
+    puts("ERROR: Unable to malloc memory.");
+  }
+}
Index: AppPkg/Applications/ConsoleIO/FunKey.c
===================================================================
--- AppPkg/Applications/ConsoleIO/FunKey.c	(revision 0)
+++ AppPkg/Applications/ConsoleIO/FunKey.c	(working copy)
@@ -0,0 +1,136 @@
+/** @file
+    Defines an array of strings associated with each special/function key.
+    Index 0 corresponds to TtyUpArrow with each increasing index going downward
+    to TtyKeyEject.
+
+    Also defines a function to get the name of a key given its scan code and a
+    function to print the key's name.
+
+    Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+    This program and the accompanying materials
+    are licensed and made available under the terms and conditions of the BSD License
+    which accompanies this distribution. The full text of the license may be found at
+    http://opensource.org/licenses/bsd-license.
+
+    THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+    WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include  <stdio.h>
+#include  <sys/termios.h>
+#include  "ConsoleIO.h"
+
+/// An array of pointers to the MBCS names of special non-printing characters.
+const char * const FunNames[NumNames] = {
+  "Unknown",      //TtyFunKeyMax  = 0xF900    63744 = 0
+  "Up",           //TtyUpArrow    = 0xF8FF,   63743 = 1
+  "Down",         //TtyDownArrow,             63742 = 2
+  "Right",        //TtyRightArrow,            63741 = 3
+  "Left",         //TtyLeftArrow,             63740 = 4
+  "Home",         //TtyHome,                  63739 = 5
+  "End",          //TtyEnd,                   63738 = 6
+  "Insert",       //TtyInsert,                63737 = 7
+  "Delete",       //TtyDelete,                63736 = 8
+  "Pg Up",        //TtyPageUp,                63735 = 9
+  "Pg Down",      //TtyPageDown,              63734 = 10
+  "F1",           //TtyF1,                    63733 = 11
+  "F2",           //TtyF2,                    63732 = 12
+  "F3",           //TtyF3,                    63731 = 13
+  "F4",           //TtyF4,                    63730 = 14
+  "F5",           //TtyF5,                    63729 = 15
+  "F6",           //TtyF6,                    63728 = 16
+  "F7",           //TtyF7,                    63727 = 17
+  "F8",           //TtyF8,                    63726 = 18
+  "F9",           //TtyF9,                    63725 = 19
+  "F10",          //TtyF10,                   63724 = 20
+  "F11",          //TtyF11,                   63723 = 21
+  "F12",          //TtyF12,                   63722 = 22
+  "ESC",          //TtyEscape     = 0xF8E9,   63721 = 23
+
+  "F13",          //TtyF13        = 0xF898,   63640 = 104  = 24    (80)
+  "F14",          //TtyF14,                   63639 = 105  = 25
+  "F15",          //TtyF15,                   63638 = 106  = 26
+  "F16",          //TtyF16,                   63637 = 107  = 27
+  "F17",          //TtyF17,                   63636 = 108  = 28
+  "F18",          //TtyF18,                   63635 = 109  = 29
+  "F19",          //TtyF19,                   63634 = 110  = 30
+  "F20",          //TtyF20,                   63633 = 111  = 31
+  "F21",          //TtyF21,                   63632 = 112  = 32
+  "F22",          //TtyF22,                   63631 = 113  = 33
+  "F23",          //TtyF23,                   63630 = 114  = 34
+  "F24",          //TtyF24        = 0xF88D,   63629 = 115  = 35
+
+  "Mute",         //TtyMute       = 0xF881,   63617 = 127  = 36    (91) (11)
+  "Vol Up",       //TtyVolumeUp,              63616 = 128  = 37
+  "Vol Down",     //TtyVolumeDown = 0xF87F,   63615 = 129  = 38
+
+  "Brighten",     //TtyBrightnessUp = 0xF800, 63488 = 256  = 39    (217) (126)
+  "Dim",          //TtyBrightnessDown,        63487 = 257  = 40
+  "Susp",         //TtySuspend,               63486 = 258  = 41
+  "Hiber",        //TtyHibernate,             63485 = 259  = 42
+  "Display",      //TtyToggleDisplay,         63484 = 260  = 43
+  "Recovery",     //TtyRecovery,              63483 = 261  = 44
+  "Eject"         //TtyKeyEject   = 0xF7FA,   63482 = 262  = 45
+};
+
+/** Given the Scan Code of a special key, retrieve its name.
+  ScanCodes that are within undefined ranges are given the name "Unknown", while
+  ScanCodes that are outside the range of special keys are named "ERROR".
+
+  @param[in]  ScanCode    Key to get the name of.
+
+  @return     A pointer to the name of the key associated with ScanCode.
+**/
+const char *
+FunKeyName (
+  int   ScanCode
+  )
+{
+  const char *Name;
+  int         NameDex;
+
+  NameDex = -1;
+
+  if (ScanCode >= TtyFunKeyMin) {
+    NameDex = TtyFunKeyMax - ScanCode;
+    if (NameDex > 23) {
+      NameDex -= 80;
+      if (NameDex < 24) {
+        NameDex = 0;
+      }
+    }
+    if (NameDex > 35) {
+      NameDex -= 11;
+      if (NameDex < 36) {
+        NameDex = 0;
+      }
+    }
+    if (NameDex > 38) {
+      NameDex -= 126;
+      if (NameDex < 39) {
+        NameDex = 0;
+      }
+    }
+  }
+  if ((NameDex < 0) || (NameDex >= NumNames)) {
+    Name = "ERROR";
+  }
+  else {
+    Name = FunNames[NameDex];
+  }
+  return Name;
+}
+
+/** Print the name of a key associated with ScanCode.
+
+  @param[in]  ScanCode    Scan code associated with the key to print the name of.
+**/
+VOID
+PrintFunKey (
+  int   ScanCode
+  )
+{
+  const char   *Name;
+
+  Name = FunKeyName (ScanCode);
+  printf("<%s>", Name);
+}
Index: AppPkg/Applications/ConsoleIO/TermInfo.c
===================================================================
--- AppPkg/Applications/ConsoleIO/TermInfo.c	(revision 0)
+++ AppPkg/Applications/ConsoleIO/TermInfo.c	(working copy)
@@ -0,0 +1,159 @@
+/** @file
+    Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+    This program and the accompanying materials
+    are licensed and made available under the terms and conditions of the BSD License
+    which accompanies this distribution. The full text of the license may be found at
+    http://opensource.org/licenses/bsd-license.
+
+    THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+    WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include  <stdio.h>
+#include  <sys/termios.h>
+#include  "ConsoleIO.h"
+
+/// Names of input flags from termios.c_iflag
+const FlagEnt InFlags[NumInFlags] = {
+  { "INLCR",    INLCR },
+  { "IGNCR",    IGNCR },
+  { "ICRNL",    ICRNL },
+  { "IGNSPEC",  IGNSPEC }
+};
+
+/// Names of control flags from termios.c_cflag
+const FlagEnt CtrlFlags[] = {
+  { "null",    0 }
+};
+
+/// Names of output flags from termios.c_oflag
+const FlagEnt OutFlags[NumOutFlags] = {
+  { "OPOST",  OPOST },
+  { "ONLCR",  ONLCR },
+  { "OXTABS", OXTABS },
+  { "ONOEOT", ONOEOT },
+  { "OCRNL",  OCRNL },
+  { "ONOCR",  ONOCR },
+  { "ONLRET", ONLRET },
+  { "OCTRL",  OCTRL }
+};
+
+/// Names of local flags from termios.c_lflag
+const FlagEnt LocalFlags[NumLocalFlags] = {
+  { "ECHO",     ECHO },
+  { "ECHOE",    ECHOE },
+  { "ECHOK",    ECHOK },
+  { "ECHONL",   ECHONL },
+  { "ISIG",     ISIG },
+  { "ICANON",   ICANON },
+  { "IEXTEN",   IEXTEN },
+  { "TOSTOP",   TOSTOP },
+  { "PENDIN",   PENDIN },
+  { "NOFLSH",   NOFLSH },
+  { "FLUSHO",   FLUSHO }
+};
+
+/// Names of elements of the c_cc array from termios.c_cc
+const FlagEnt CcNames[NCCS] = {
+  { "VTABLEN",    0 },
+  { "VEOF",       1 },
+  { "VEOL",       1 },
+  { "VERASE",     1 },
+  { "VKILL",      1 },
+  { "VINTR",      1 },
+  { "VQUIT",      1 },
+  { "VMIN",       0 },
+  { "VTIME",      0 },
+  { "VWERASE",    1 },
+  { "VREPRINT",   1 },
+  { "VLNEXT",     1 },
+  { "VDISCARD",   1 }
+};
+
+/** Print the flags given the Flag value and a pointer to an array of possible names.
+
+  @param[in]    Header    Pointer to a string to print before the flag values
+  @param[in]    FlagVal   The bitmapped flags to be identified
+  @param[in]    Table     Pointer to the array of potential flag names
+  @param[in]    NumFlags  Number of names defined in Table
+**/
+void
+ListFlags (
+  const char      * const Header,
+  const tcflag_t          FlagVal,
+  const FlagEnt   * const Table,
+  const UINT32            NumFlags
+  )
+{
+  UINT32 i;
+
+  printf("%8s: [0x%04X] ", Header, FlagVal);
+  for (i = 0; i < NumFlags; ++i) {
+    if ((FlagVal & Table[i].FlagValue) != 0) {
+      printf(" %s", Table[i].FlagName);
+    }
+  }
+  puts("");
+}
+
+/** Print a description of each member of the c_cc array.
+
+  @param[in]  c_cc    Pointer to the c_cc array to dump.
+  @param[in]  Table   Pointer to the table of names for the c_cc members.
+**/
+void
+PrintCCC (
+  cc_t            * const c_cc,
+  const FlagEnt   * const Table
+  )
+{
+  int           i;
+  unsigned char c;
+
+  puts("Control Character array (c_cc):");
+  for (i = 0; i < NCCS; ++i) {
+    c = c_cc[i];
+    printf("  %9s: [0x%02X]", Table[i].FlagName, c);
+    if (Table[i].FlagValue == 1) {
+      if (c < 0x7f) {
+        if (c < ' ') {
+          c += '@';
+          printf("  '^%c'", c);
+        }
+        else {
+          fputs("  '?'", stdout);
+        }
+      }
+      else {
+        fputs("  Disabled", stdout);
+      }
+    }
+    puts("");
+  }
+}
+
+/** Print a description of each element of the termios structure.
+
+  @param[in]  TermInfo  Pointer to the termios structure to dump.
+**/
+void
+DumpTermios (
+  struct termios *TermInfo
+  )
+{
+  puts("termios structure for stdin:");
+  /* input speed    */
+  printf("Input Speed: %d\n", TermInfo->c_ispeed);
+  /* output speed   */
+  printf("Output Speed: %d\n", TermInfo->c_ospeed);
+  /* input flags    */
+  ListFlags ("Input", TermInfo->c_iflag, InFlags, NumInFlags);
+  /* output flags   */
+  ListFlags ("Output", TermInfo->c_oflag, OutFlags, NumOutFlags);
+  /* control flags  */
+  ListFlags ("Control", TermInfo->c_cflag, CtrlFlags, NumCtrlFlags);
+  /* local flags    */
+  ListFlags ("Local", TermInfo->c_lflag, LocalFlags, NumLocalFlags);
+  /* control chars  */
+  PrintCCC (&TermInfo->c_cc[0], CcNames);
+  puts("");
+}
Index: AppPkg/AppPkg.dsc
===================================================================
--- AppPkg/AppPkg.dsc	(revision 16408)
+++ AppPkg/AppPkg.dsc	(working copy)
@@ -112,6 +112,7 @@
   AppPkg/Applications/Main/Main.inf          # Simple invocation. No other LibC functions.
   AppPkg/Applications/Enquire/Enquire.inf    #
   AppPkg/Applications/ArithChk/ArithChk.inf  #
+  AppPkg/Applications/ConsoleIO/ConsoleIO.inf   # Exercise Console I/O
 
 #### A simple fuzzer for OrderedCollectionLib, in particular for
 #### BaseOrderedCollectionRedBlackTreeLib.
