hikey: Add UEFI sources for reference

UEFI needs to be built outside Android build system.
Please follow the instructions in README.

The sources correspond to:
https://github.com/96boards/edk2/commit/14eae0c12e71fd33c4c0fc51e4475e8db02566cf
https://github.com/96boards/arm-trusted-firmware/commit/e9b4909dcd75fc4ae7041cfb83d28ab9adb7afdf
https://github.com/96boards/l-loader/commit/6b784ad5c4ab00e2b1c6f53cd5f74054e5d00a78
https://git.linaro.org/uefi/uefi-tools.git/commit/abe618f8ab72034fff1ce46c9c006a2c6bd40a7e

Change-Id: Ieeefdb63e673e0c8e64e0a1f02c7bddc63b2c7fb
Signed-off-by: Vishal Bhoj <vishal.bhoj@linaro.org>
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/DataSink/DataSink.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/DataSink/DataSink.c
new file mode 100644
index 0000000..14b2fd1
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/DataSink/DataSink.c
@@ -0,0 +1,1287 @@
+/** @file

+  Data source for network testing.

+

+  Copyright (c) 2011-2012, Intel Corporation

+  All rights reserved. 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.php

+

+  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 <errno.h>

+#include <Uefi.h>

+

+#include <Library/BaseMemoryLib.h>

+#include <Library/DebugLib.h>

+#include <Library/PcdLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/UefiLib.h>

+

+#include <netinet/in.h>

+

+#include <sys/EfiSysCall.h>

+#include <sys/poll.h>

+#include <sys/socket.h>

+

+

+#define DATA_SAMPLE_SHIFT           5       ///<  Shift for number of samples

+#define MAX_CONNECTIONS       ( 1 + 16 )    ///<  Maximum number of client connections

+#define RANGE_SWITCH        ( 1024 * 1024 ) ///<  Switch display ranges

+#define DATA_RATE_UPDATE_SHIFT      2       ///<  2n seconds between updates

+#define AVERAGE_SHIFT_COUNT ( 6 - DATA_RATE_UPDATE_SHIFT )  ///<  2n samples in average

+#define DATA_SAMPLES        ( 1 << DATA_SAMPLE_SHIFT )      ///<  Number of samples

+

+#define TPL_DATASINK        TPL_CALLBACK  ///<  Synchronization TPL

+

+#define PACKET_SIZE                 1448  ///<  Size of data packets

+#define DATA_BUFFER_SIZE    (( 65536 / PACKET_SIZE ) * PACKET_SIZE )  ///<  Buffer size in bytes

+

+typedef struct _DT_PORT {

+  UINT64 BytesTotal;

+  struct sockaddr_in6 IpAddress;

+  UINT32 In;

+  UINT32 Samples;

+  UINT64 BytesReceived[ DATA_SAMPLES ];

+} DT_PORT;

+

+volatile BOOLEAN bTick;

+BOOLEAN bTimerRunning;

+struct sockaddr_in6 LocalAddress;

+EFI_EVENT pTimer;

+int ListenSocket;

+UINT8 Buffer[ DATA_BUFFER_SIZE ];

+struct pollfd PollFd[ MAX_CONNECTIONS ];

+DT_PORT Port[ MAX_CONNECTIONS ];

+nfds_t MaxPort;

+

+

+//

+//  Forward routine declarations

+//

+EFI_STATUS TimerStart ( UINTN Milliseconds );

+

+

+/**

+  Check for control C entered at console

+

+  @retval  EFI_SUCCESS  Control C not entered

+  @retval  EFI_ABORTED  Control C entered

+**/

+EFI_STATUS

+ControlCCheck (

+  )

+{

+  EFI_STATUS Status;

+

+  //

+  //  Assume no user intervention

+  //

+  Status = EFI_SUCCESS;

+

+  //

+  //  Display user stop request

+  //

+  if ( EFI_ERROR ( Status )) {

+    DEBUG (( DEBUG_INFO,

+              "User stop request!\r\n" ));

+  }

+

+  //

+  //  Return the check status

+  //

+  return Status;

+}

+

+

+/**

+  Accept a socket connection

+

+  @retval  EFI_SUCCESS      The application is running normally

+  @retval  EFI_NOT_STARTED  Error with the listen socket

+  @retval  Other            The user stopped the application

+**/

+EFI_STATUS

+SocketAccept (

+  )

+{

+  INT32 SocketStatus;

+  EFI_STATUS Status;

+  INTN Index;

+

+  //

+  //  Assume failure

+  //

+  Status = EFI_DEVICE_ERROR;

+

+  //

+  //  Bind to the local address

+  //

+  SocketStatus = bind ( ListenSocket,

+                        (struct sockaddr *) &LocalAddress,

+                        LocalAddress.sin6_len );

+  if ( 0 == SocketStatus ) {

+    //

+    //  Start listening on the local socket

+    //

+    SocketStatus = listen ( ListenSocket, 5 );

+    if ( 0 == SocketStatus ) {

+      //

+      //  Local socket in the listen state

+      //

+      Status = EFI_SUCCESS;

+

+      //

+      //  Allocate a port

+      //

+      Index = MaxPort++;

+      PollFd[ Index ].fd = ListenSocket;

+      PollFd[ Index ].events = POLLRDNORM | POLLHUP;

+      PollFd[ Index ].revents = 0;

+      ZeroMem ( &Port[ Index ], sizeof ( Port[ Index ]));

+    }

+  }

+

+  //

+  //  Return the operation status

+  //

+  return Status;

+}

+

+

+/**

+  Close the socket

+

+  @retval  EFI_SUCCESS  The application is running normally

+  @retval  Other        The user stopped the application

+**/

+EFI_STATUS

+SocketClose (

+  )

+{

+  INT32 CloseStatus;

+  EFI_STATUS Status;

+

+  //

+  //  Determine if the socket is open

+  //

+  Status = EFI_DEVICE_ERROR;

+  if ( -1 != ListenSocket ) {

+    //

+    //  Attempt to close the socket

+    //

+    CloseStatus = close ( ListenSocket );

+    if ( 0 == CloseStatus ) {

+      DEBUG (( DEBUG_INFO,

+                "0x%08x: Socket closed\r\n",

+                ListenSocket ));

+      ListenSocket = -1;

+      Status = EFI_SUCCESS;

+    }

+    else {

+      DEBUG (( DEBUG_ERROR,

+                "ERROR: Failed to close socket, errno: %d\r\n",

+                errno ));

+    }

+  }

+

+  //

+  //  Return the operation status

+  //

+  return Status;

+}

+

+

+/**

+  Create the socket

+

+  @param [in] Family    Network family, AF_INET or AF_INET6

+

+  @retval  EFI_SUCCESS  The application is running normally

+  @retval  Other        The user stopped the application

+**/

+EFI_STATUS

+SocketNew (

+  sa_family_t Family

+  )

+{

+  EFI_STATUS Status;

+

+  //

+  //  Get the port number

+  //

+  ZeroMem ( &LocalAddress, sizeof ( LocalAddress ));

+  LocalAddress.sin6_len = sizeof ( LocalAddress );

+  LocalAddress.sin6_family = Family;

+  LocalAddress.sin6_port = htons ( PcdGet16 ( DataSource_Port ));

+  

+  //

+  //  Loop creating the socket

+  //

+  DEBUG (( DEBUG_INFO,

+            "Creating the socket\r\n" ));

+

+  //

+  //  Check for user stop request

+  //

+  Status = ControlCCheck ( );

+  if ( !EFI_ERROR ( Status )) {

+    //

+    //  Attempt to create the socket

+    //

+    ListenSocket = socket ( LocalAddress.sin6_family,

+                            SOCK_STREAM,

+                            IPPROTO_TCP );

+    if ( -1 != ListenSocket ) {

+      DEBUG (( DEBUG_INFO,

+                "0x%08x: Socket created\r\n",

+                ListenSocket ));

+    }

+    else {

+      Status = EFI_NOT_STARTED;

+    }

+  }

+

+  //

+  //  Return the operation status

+  //

+  return Status;

+}

+

+

+/**

+  Poll the socket for more work

+

+  @retval  EFI_SUCCESS      The application is running normally

+  @retval  EFI_NOT_STARTED  Listen socket error

+  @retval  Other            The user stopped the application

+**/

+EFI_STATUS

+SocketPoll (

+  )

+{

+  BOOLEAN bRemoveSocket;

+  BOOLEAN bListenError;

+  size_t BytesReceived;

+  int CloseStatus;

+  nfds_t Entry;

+  INTN EntryPrevious;

+  int FdCount;

+  nfds_t Index;

+  socklen_t LengthInBytes;

+  struct sockaddr_in * pPortIpAddress4;

+  struct sockaddr_in6 * pPortIpAddress6;

+  struct sockaddr_in * pRemoteAddress4;

+  struct sockaddr_in6 * pRemoteAddress6;

+  struct sockaddr_in6 RemoteAddress;

+  int Socket;

+  EFI_STATUS Status;

+  EFI_TPL TplPrevious;

+

+  //

+  //  Check for control-C

+  //

+  pRemoteAddress4 = (struct sockaddr_in *)&RemoteAddress;

+  pRemoteAddress6 = (struct sockaddr_in6 *)&RemoteAddress;

+  bListenError = FALSE;

+  Status = ControlCCheck ( );

+  if ( !EFI_ERROR ( Status )) {

+    //

+    //  Poll the sockets

+    //

+    FdCount = poll ( &PollFd[0],

+                     MaxPort,

+                     0 );

+    if ( -1 == FdCount ) {

+      //

+      //  Poll error

+      //

+      DEBUG (( DEBUG_ERROR,

+                "ERROR - Poll error, errno: %d\r\n",

+                errno ));

+      Status = EFI_DEVICE_ERROR;

+    }

+    else {

+      //

+      //  Process the poll output

+      //

+      Index = 0;

+      while ( FdCount ) {

+        bRemoveSocket = FALSE;

+

+        //

+        //  Account for this descriptor

+        //

+        pPortIpAddress4 = (struct sockaddr_in *)&Port[ Index ].IpAddress;

+        pPortIpAddress6 = (struct sockaddr_in6 *)&Port[ Index ].IpAddress;

+        if ( 0 != PollFd[ Index ].revents ) {

+          FdCount -= 1;

+        }

+

+        //

+        //  Check for a broken connection

+        //

+        if ( 0 != ( PollFd[ Index ].revents & POLLHUP )) {

+          bRemoveSocket = TRUE;

+          if ( ListenSocket == PollFd[ Index ].fd ) {

+            bListenError = TRUE;

+            DEBUG (( DEBUG_ERROR,

+                      "ERROR - Network closed on listen socket, errno: %d\r\n",

+                      errno ));

+          }

+          else {

+            if ( AF_INET == pPortIpAddress4->sin_family ) {

+              DEBUG (( DEBUG_ERROR,

+                        "ERROR - Network closed on socket %d.%d.%d.%d:%d, errno: %d\r\n",

+                        pPortIpAddress4->sin_addr.s_addr & 0xff,

+                        ( pPortIpAddress4->sin_addr.s_addr >> 8 ) & 0xff,

+                        ( pPortIpAddress4->sin_addr.s_addr >> 16 ) & 0xff,

+                        ( pPortIpAddress4->sin_addr.s_addr >> 24 ) & 0xff,

+                        ntohs ( pPortIpAddress4->sin_port ),

+                        errno ));

+            }

+            else {

+              DEBUG (( DEBUG_ERROR,

+                        "ERROR - Network closed on socket [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d, errno: %d\r\n",

+                        pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],

+                        pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],

+                        pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],

+                        pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],

+                        pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],

+                        pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],

+                        pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],

+                        pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],

+                        pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],

+                        pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],

+                        pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],

+                        pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],

+                        pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],

+                        pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],

+                        pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],

+                        pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],

+                        ntohs ( pPortIpAddress6->sin6_port ),

+                        errno ));

+            }

+

+            //

+            //  Close the socket

+            //

+            CloseStatus = close ( PollFd[ Index ].fd );

+            if ( 0 == CloseStatus ) {

+              bRemoveSocket = TRUE;

+              if ( AF_INET == pPortIpAddress4->sin_family ) {

+                DEBUG (( DEBUG_INFO,

+                          "0x%08x: Socket closed for %d.%d.%d.%d:%d\r\n",

+                          PollFd[ Index ].fd,

+                          pPortIpAddress4->sin_addr.s_addr & 0xff,

+                          ( pPortIpAddress4->sin_addr.s_addr >> 8 ) & 0xff,

+                          ( pPortIpAddress4->sin_addr.s_addr >> 16 ) & 0xff,

+                          ( pPortIpAddress4->sin_addr.s_addr >> 24 ) & 0xff,

+                          ntohs ( pPortIpAddress4->sin_port )));

+              }

+              else {

+                DEBUG (( DEBUG_INFO,

+                          "0x%08x: Socket closed for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",

+                          PollFd[ Index ].fd,

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],

+                          ntohs ( pPortIpAddress6->sin6_port )));

+              }

+            }

+            else {

+              if ( AF_INET == pPortIpAddress4->sin_family ) {

+                DEBUG (( DEBUG_ERROR,

+                          "ERROR - Failed to close socket 0x%08x for %d.%d.%d.%d:%d, errno: %d\r\n",

+                          PollFd[ Index ].fd,

+                          pPortIpAddress4->sin_addr.s_addr & 0xff,

+                          ( pPortIpAddress4->sin_addr.s_addr >> 8 ) & 0xff,

+                          ( pPortIpAddress4->sin_addr.s_addr >> 16 ) & 0xff,

+                          ( pPortIpAddress4->sin_addr.s_addr >> 24 ) & 0xff,

+                          ntohs ( pPortIpAddress4->sin_port ),

+                          errno ));

+              }

+              else {

+                DEBUG (( DEBUG_ERROR,

+                          "ERROR - Failed to close socket 0x%08x for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d, errno: %d\r\n",

+                          PollFd[ Index ].fd,

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],

+                          ntohs ( pPortIpAddress6->sin6_port ),

+                          errno ));

+              }

+            }

+          }

+        }

+        

+        //

+        //  Check for a connection or read data

+        //

+        if ( 0 != ( PollFd[ Index ].revents & POLLRDNORM )) {

+          //

+          //  Check for a connection

+          //

+          if ( ListenSocket == PollFd[ Index ].fd ) {

+            //

+            //  Another client connection was received

+            //

+            LengthInBytes = sizeof ( RemoteAddress );

+            Socket = accept ( ListenSocket,

+                              (struct sockaddr *) &RemoteAddress,

+                              &LengthInBytes );

+            if ( -1 == Socket ) {

+              //

+              //  Listen socket error

+              //

+              bListenError = TRUE;

+              bRemoveSocket = TRUE;

+              DEBUG (( DEBUG_ERROR,

+                        "ERROR - Listen socket failure, errno: %d\r\n",

+                        errno ));

+            }

+            else {

+              //

+              //  Determine if there is room for this connection

+              //

+              if (( MAX_CONNECTIONS <= MaxPort )

+                || ((( MAX_CONNECTIONS - 1 ) == MaxPort ) && ( -1 == ListenSocket ))) {

+                //

+                //  Display the connection

+                //

+                if ( AF_INET == pRemoteAddress4->sin_family ) {

+                  Print ( L"Rejecting connection to remote system %d.%d.%d.%d:%d\r\n",

+                          pRemoteAddress4->sin_addr.s_addr & 0xff,

+                          ( pRemoteAddress4->sin_addr.s_addr >> 8 ) & 0xff,

+                          ( pRemoteAddress4->sin_addr.s_addr >> 16 ) & 0xff,

+                          ( pRemoteAddress4->sin_addr.s_addr >> 24 ) & 0xff,

+                          ntohs ( pRemoteAddress4->sin_port ));

+                }

+                else {

+                  Print ( L"Rejecting connection to remote system [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",

+                          pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],

+                          pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],

+                          pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],

+                          pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],

+                          pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],

+                          pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],

+                          pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],

+                          pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],

+                          pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],

+                          pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],

+                          pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],

+                          pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],

+                          pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],

+                          pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],

+                          pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],

+                          pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],

+                          ntohs ( pRemoteAddress6->sin6_port ));

+                }

+

+                //

+                //  No room for this connection

+                //  Close the connection

+                //

+                CloseStatus = close ( Socket );

+                if ( 0 == CloseStatus ) {

+                  bRemoveSocket = TRUE;

+                  if ( AF_INET == pRemoteAddress4->sin_family ) {

+                    DEBUG (( DEBUG_INFO,

+                              "0x%08x: Socket closed for %d.%d.%d.%d:%d\r\n",

+                              PollFd[ Index ].fd,

+                              pRemoteAddress4->sin_addr.s_addr & 0xff,

+                              ( pRemoteAddress4->sin_addr.s_addr >> 8 ) & 0xff,

+                              ( pRemoteAddress4->sin_addr.s_addr >> 16 ) & 0xff,

+                              ( pRemoteAddress4->sin_addr.s_addr >> 24 ) & 0xff,

+                              ntohs ( pRemoteAddress4->sin_port )));

+                  }

+                  else {

+                    DEBUG (( DEBUG_INFO,

+                              "0x%08x: Socket closed for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",

+                              PollFd[ Index ].fd,

+                              pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],

+                              pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],

+                              pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],

+                              pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],

+                              pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],

+                              pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],

+                              pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],

+                              pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],

+                              pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],

+                              pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],

+                              pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],

+                              pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],

+                              pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],

+                              pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],

+                              pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],

+                              pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],

+                              ntohs ( pRemoteAddress6->sin6_port )));

+                  }

+                }

+                else {

+                  DEBUG (( DEBUG_ERROR,

+                            "ERROR - Failed to close socket 0x%08x, errno: %d\r\n",

+                            PollFd[ Index ].fd,

+                            errno ));

+                }

+

+                //

+                //  Keep the application running

+                //  No issue with the listen socket

+                //

+                Status = EFI_SUCCESS;

+              }

+              else {

+                //

+                //  Display the connection

+                //

+                if ( AF_INET == pRemoteAddress4->sin_family ) {

+                  Print ( L"Connected to remote system %d.%d.%d.%d:%d\r\n",

+                          pRemoteAddress4->sin_addr.s_addr & 0xff,

+                          ( pRemoteAddress4->sin_addr.s_addr >> 8 ) & 0xff,

+                          ( pRemoteAddress4->sin_addr.s_addr >> 16 ) & 0xff,

+                          ( pRemoteAddress4->sin_addr.s_addr >> 24 ) & 0xff,

+                          ntohs ( pRemoteAddress4->sin_port ));

+                }

+                else {

+                  Print ( L"Connected to remote system [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",

+                          pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],

+                          pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],

+                          pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],

+                          pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],

+                          pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],

+                          pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],

+                          pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],

+                          pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],

+                          pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],

+                          pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],

+                          pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],

+                          pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],

+                          pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],

+                          pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],

+                          pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],

+                          pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],

+                          ntohs ( pRemoteAddress6->sin6_port ));

+                }

+

+                //

+                //  Allocate the client connection

+                //

+                Index = MaxPort++;

+                ZeroMem ( &Port[ Index ], sizeof ( Port[ Index ]));

+                CopyMem ( pPortIpAddress6, pRemoteAddress6, sizeof ( *pRemoteAddress6 ));

+                PollFd[ Index ].fd = Socket;

+                PollFd[ Index ].events = POLLRDNORM | POLLHUP;

+                PollFd[ Index ].revents = 0;

+              }

+            }

+          }

+          else {

+            //

+            //  Data received

+            //

+            BytesReceived = read ( PollFd[ Index ].fd,

+                                   &Buffer,

+                                   sizeof ( Buffer ));

+            if ( 0 < BytesReceived ) {

+              //

+              //  Display the amount of data received

+              //

+              if ( AF_INET == pPortIpAddress4->sin_family ) {

+                DEBUG (( DEBUG_INFO,

+                          "0x%08x: Socket received 0x%08x bytes from %d.%d.%d.%d:%d\r\n",

+                          PollFd[ Index ].fd,

+                          BytesReceived,

+                          pPortIpAddress4->sin_addr.s_addr & 0xff,

+                          ( pPortIpAddress4->sin_addr.s_addr >> 8 ) & 0xff,

+                          ( pPortIpAddress4->sin_addr.s_addr >> 16 ) & 0xff,

+                          ( pPortIpAddress4->sin_addr.s_addr >> 24 ) & 0xff,

+                          ntohs ( pPortIpAddress4->sin_port )));

+              }

+              else {

+                DEBUG (( DEBUG_INFO,

+                          "0x%08x: Socket received 0x%08x bytes from [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",

+                          PollFd[ Index ].fd,

+                          BytesReceived,

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],

+                          ntohs ( pPortIpAddress6->sin6_port )));

+              }

+

+              //

+              //  Synchronize with the TimerCallback routine

+              //

+              TplPrevious = gBS->RaiseTPL ( TPL_DATASINK );

+

+              //

+              //  Account for the data received

+              //

+              Port[ Index ].BytesTotal += BytesReceived;

+

+              //

+              //  Release the synchronization with the TimerCallback routine

+              //

+              gBS->RestoreTPL ( TplPrevious );

+            }

+            else if ( -1 == BytesReceived ) {

+              //

+              //  Close the socket

+              //

+              if ( AF_INET == pPortIpAddress4->sin_family ) {

+                DEBUG (( DEBUG_INFO,

+                          "ERROR - Receive failure for %d.%d.%d.%d:%d, errno: %d\r\n",

+                          pPortIpAddress4->sin_addr.s_addr & 0xff,

+                          ( pPortIpAddress4->sin_addr.s_addr >> 8 ) & 0xff,

+                          ( pPortIpAddress4->sin_addr.s_addr >> 16 ) & 0xff,

+                          ( pPortIpAddress4->sin_addr.s_addr >> 24 ) & 0xff,

+                          ntohs ( pPortIpAddress4->sin_port ),

+                          errno ));

+              }

+              else {

+                DEBUG (( DEBUG_INFO,

+                          "ERROR - Receive failure for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d, errno: %d\r\n",

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],

+                          pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],

+                          ntohs ( pPortIpAddress6->sin6_port ),

+                          errno ));

+              }

+              CloseStatus = close ( PollFd[ Index ].fd );

+              if ( 0 == CloseStatus ) {

+                bRemoveSocket = TRUE;

+                if ( AF_INET == pPortIpAddress4->sin_family ) {

+                  DEBUG (( DEBUG_INFO,

+                            "0x%08x: Socket closed for %d.%d.%d.%d:%d\r\n",

+                            PollFd[ Index ].fd,

+                            pPortIpAddress4->sin_addr.s_addr & 0xff,

+                            ( pPortIpAddress4->sin_addr.s_addr >> 8 ) & 0xff,

+                            ( pPortIpAddress4->sin_addr.s_addr >> 16 ) & 0xff,

+                            ( pPortIpAddress4->sin_addr.s_addr >> 24 ) & 0xff,

+                            ntohs ( pPortIpAddress4->sin_port )));

+                }

+                else {

+                  DEBUG (( DEBUG_INFO,

+                            "0x%08x: Socket closed for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",

+                            PollFd[ Index ].fd,

+                            pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],

+                            pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],

+                            pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],

+                            pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],

+                            pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],

+                            pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],

+                            pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],

+                            pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],

+                            pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],

+                            pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],

+                            pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],

+                            pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],

+                            pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],

+                            pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],

+                            pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],

+                            pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],

+                            ntohs ( pPortIpAddress6->sin6_port )));

+                }

+              }

+              else {

+                if ( AF_INET == pPortIpAddress4->sin_family ) {

+                  DEBUG (( DEBUG_ERROR,

+                            "ERROR - Failed to close socket 0x%08x for %d.%d.%d.%d:%d, errno: %d\r\n",

+                            PollFd[ Index ].fd,

+                            pPortIpAddress4->sin_addr.s_addr & 0xff,

+                            ( pPortIpAddress4->sin_addr.s_addr >> 8 ) & 0xff,

+                            ( pPortIpAddress4->sin_addr.s_addr >> 16 ) & 0xff,

+                            ( pPortIpAddress4->sin_addr.s_addr >> 24 ) & 0xff,

+                            ntohs ( pPortIpAddress4->sin_port ),

+                            errno ));

+                }

+                else {

+                  DEBUG (( DEBUG_ERROR,

+                            "ERROR - Failed to close socket 0x%08x for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d, errno: %d\r\n",

+                            PollFd[ Index ].fd,

+                            pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],

+                            pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],

+                            pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],

+                            pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],

+                            pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],

+                            pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],

+                            pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],

+                            pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],

+                            pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],

+                            pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],

+                            pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],

+                            pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],

+                            pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],

+                            pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],

+                            pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],

+                            pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],

+                            ntohs ( pPortIpAddress6->sin6_port ),

+                            errno ));

+                }

+              }

+            }

+

+            //

+            //  Keep the application running

+            //  No issue with the listen socket

+            //

+            Status = EFI_SUCCESS;

+          }

+        }

+

+        //

+        //  Remove the socket if necessary

+        //

+        if ( bRemoveSocket ) {

+          DEBUG (( DEBUG_INFO,

+                    "0x%08x: Socket removed from polling\r\n",

+                    PollFd[ Index ].fd ));

+          MaxPort -= 1;

+          for ( Entry = Index + 1; MaxPort >= Entry; Entry++ ) {

+            EntryPrevious = Entry;

+            CopyMem ( &Port[ EntryPrevious ],

+                      &Port[ Entry ],

+                      sizeof ( Port[ Entry ]));

+            PollFd[ EntryPrevious ].events = PollFd[ Entry ].events;

+            PollFd[ EntryPrevious ].fd = PollFd[ Entry ].fd;

+            PollFd[ EntryPrevious ].revents = PollFd[ Entry ].revents;

+          }

+          PollFd[ MaxPort ].fd = -1;

+          Index -= 1;

+        }

+

+        //

+        //  Account for this socket

+        //

+        Index += 1;

+      }

+    }

+  }

+

+  //

+  //  Return the listen failure if necessary

+  //

+  if (( !EFI_ERROR ( Status )) && bListenError ) {

+    Status = EFI_NOT_STARTED;

+  }

+

+  //

+  //  Return the poll status

+  //

+  return Status;

+}

+

+

+/**

+  Handle the timer callback

+

+  @param [in] Event     Event that caused this callback

+  @param [in] pContext  Context for this routine

+**/

+VOID

+EFIAPI

+TimerCallback (

+  IN EFI_EVENT Event,

+  IN VOID * pContext

+  )

+{

+  UINT32 Average;

+  UINT64 BitsPerSecond;

+  UINT64 BytesReceived;

+  UINT32 Count;

+  nfds_t Index;

+  UINT64 TotalBytes;

+

+  //

+  //  Notify the other code of the timer tick

+  //

+  bTick = TRUE;

+

+  //

+  //  Walk the list of ports

+  //

+  for ( Index = 0; MaxPort > Index; Index++ ) {

+    //

+    //  Determine if any data was received

+    //

+    BytesReceived = Port[ Index ].BytesTotal;

+    if (( ListenSocket != PollFd[ Index ].fd )

+      && ( 0 != BytesReceived )) {

+      //

+      //  Update the received data samples

+      //

+      Port[ Index ].BytesTotal = 0;

+      Port[ Index ].BytesReceived [ Port[ Index ].In ] = BytesReceived;

+      Port[ Index ].In += 1;

+      if ( DATA_SAMPLES <= Port[ Index ].In ) {

+        Port[ Index ].In = 0;

+      }

+      

+      //

+      //  Separate the samples

+      //

+      if ( DATA_SAMPLES == Port[ Index ].Samples ) {

+        Print ( L"---------- Stable average ----------\r\n" );

+      }

+      Port[ Index ].Samples += 1;

+

+      //

+      //  Compute the data rate

+      //

+      TotalBytes = 0;

+      for ( Count = 0; DATA_SAMPLES > Count; Count++ )

+      {

+          TotalBytes += Port[ Index ].BytesReceived[ Count ];

+      }

+      Average = (UINT32)RShiftU64 ( TotalBytes, DATA_SAMPLE_SHIFT );

+      BitsPerSecond = Average * 8;

+

+      //

+      //  Display the data rate

+      //

+      if (( RANGE_SWITCH >> 10 ) > Average ) {

+        Print ( L"Ave: %d Bytes/Sec, %Ld Bits/sec\r\n",

+                Average,

+                BitsPerSecond );

+      }

+      else {

+        BitsPerSecond /= 1000;

+        if ( RANGE_SWITCH > Average ) {

+          Print ( L"Ave: %d.%03d KiBytes/Sec, %Ld KBits/sec\r\n",

+                  Average >> 10,

+                  (( Average & 0x3ff ) * 1000 ) >> 10,

+                  BitsPerSecond );

+        }

+        else {

+          BitsPerSecond /= 1000;

+          Average >>= 10;

+          if ( RANGE_SWITCH > Average ) {

+            Print ( L"Ave: %d.%03d MiBytes/Sec, %Ld MBits/sec\r\n",

+                    Average >> 10,

+                    (( Average & 0x3ff ) * 1000 ) >> 10,

+                    BitsPerSecond );

+          }

+          else {

+            BitsPerSecond /= 1000;

+            Average >>= 10;

+            if ( RANGE_SWITCH > Average ) {

+              Print ( L"Ave: %d.%03d GiBytes/Sec, %Ld GBits/sec\r\n",

+                      Average >> 10,

+                      (( Average & 0x3ff ) * 1000 ) >> 10,

+                      BitsPerSecond );

+            }

+            else {

+              BitsPerSecond /= 1000;

+              Average >>= 10;

+              if ( RANGE_SWITCH > Average ) {

+                Print ( L"Ave: %d.%03d TiBytes/Sec, %Ld TBits/sec\r\n",

+                        Average >> 10,

+                        (( Average & 0x3ff ) * 1000 ) >> 10,

+                        BitsPerSecond );

+              }

+              else {

+                BitsPerSecond /= 1000;

+                Average >>= 10;

+                Print ( L"Ave: %d.%03d PiBytes/Sec, %Ld PBits/sec\r\n",

+                        Average >> 10,

+                        (( Average & 0x3ff ) * 1000 ) >> 10,

+                        BitsPerSecond );

+              }

+            }

+          }

+        }

+      }

+    }

+  }

+}

+

+

+/**

+  Create the timer

+

+  @retval  EFI_SUCCESS  The timer was successfully created

+  @retval  Other        Timer initialization failed

+**/

+EFI_STATUS

+TimerCreate (

+  )

+{

+  EFI_STATUS Status;

+

+  //

+  //  Create the timer

+  //

+  Status = gBS->CreateEvent ( EVT_TIMER | EVT_NOTIFY_SIGNAL,

+                              TPL_DATASINK,

+                              TimerCallback,

+                              NULL,

+                              &pTimer );

+  if ( EFI_ERROR ( Status )) {

+    DEBUG (( DEBUG_ERROR,

+              "ERROR - Failed to allocate the timer event, Status: %r\r\n",

+              Status ));

+  }

+  else {

+    DEBUG (( DEBUG_INFO,

+              "0x%08x: Timer created\r\n",

+              pTimer ));

+  }

+

+  //

+  //  Return the operation status

+  //

+  return Status;

+}

+

+

+/**

+  Stop the timer

+

+  @retval  EFI_SUCCESS  The timer was stopped successfully

+  @retval  Other        The timer failed to stop

+**/

+EFI_STATUS

+TimerStop (

+  )

+{

+  EFI_STATUS Status;

+

+  //

+  //  Assume success

+  //

+  Status = EFI_SUCCESS;

+

+  //

+  //  Determine if the timer is running

+  //

+  if ( bTimerRunning ) {

+    //

+    //  Stop the timer

+    //

+    Status = gBS->SetTimer ( pTimer,

+                             TimerCancel,

+                             0 );

+    if ( EFI_ERROR ( Status )) {

+      DEBUG (( DEBUG_ERROR,

+                "ERROR - Failed to stop the timer, Status: %r\r\n",

+                Status ));

+    }

+    else {

+      //

+      //  Timer timer is now stopped

+      //

+      bTimerRunning = FALSE;

+      DEBUG (( DEBUG_INFO,

+                "0x%08x: Timer stopped\r\n",

+                pTimer ));

+    }

+  }

+

+  //

+  //  Return the operation status

+  //

+  return Status;

+}

+

+

+/**

+  Start the timer

+

+  @param [in] Milliseconds  The number of milliseconds between timer callbacks

+

+  @retval  EFI_SUCCESS  The timer was successfully created

+  @retval  Other        Timer initialization failed

+**/

+EFI_STATUS

+TimerStart (

+  UINTN Milliseconds

+  )

+{

+  EFI_STATUS Status;

+  UINT64 TimeDelay;

+

+  //

+  //  Stop the timer if necessary

+  //

+  Status = EFI_SUCCESS;

+  if ( bTimerRunning ) {

+    Status = TimerStop ( );

+  }

+  if ( !EFI_ERROR ( Status )) {

+    //

+    //  Compute the new delay

+    //

+    TimeDelay = Milliseconds;

+    TimeDelay *= 1000 * 10;

+

+    //

+    //  Start the timer

+    //

+    Status = gBS->SetTimer ( pTimer,

+                             TimerPeriodic,

+                             TimeDelay );

+    if ( EFI_ERROR ( Status )) {

+      DEBUG (( DEBUG_ERROR,

+                "ERROR - Failed to start the timer, Status: %r\r\n",

+                Status ));

+    }

+    else {

+      //

+      //  The timer is now running

+      //

+      bTimerRunning = TRUE;

+      DEBUG (( DEBUG_INFO,

+        "0x%08x: Timer running\r\n",

+        pTimer ));

+    }

+  }

+

+  //

+  //  Return the operation status

+  //

+  return Status;

+}

+

+

+/**

+  Destroy the timer

+

+  @retval  EFI_SUCCESS  The timer was destroyed successfully

+  @retval  Other        Failed to destroy the timer

+**/

+EFI_STATUS

+TimerDestroy (

+  )

+{

+  EFI_STATUS Status;

+

+  //

+  //  Assume success

+  //

+  Status = EFI_SUCCESS;

+

+  //

+  //  Determine if the timer is running

+  //

+  if ( bTimerRunning ) {

+    //

+    //  Stop the timer

+    //

+    Status = TimerStop ( );

+  }

+  if (( !EFI_ERROR ( Status )) && ( NULL != pTimer )) {

+    //

+    //  Done with this timer

+    //

+    Status = gBS->CloseEvent ( pTimer );

+    if ( EFI_ERROR ( Status )) {

+      DEBUG (( DEBUG_ERROR,

+                "ERROR - Failed to free the timer event, Status: %r\r\n",

+                Status ));

+    }

+    else {

+      DEBUG (( DEBUG_INFO,

+                "0x%08x: Timer Destroyed\r\n",

+                pTimer ));

+      pTimer = NULL;

+    }

+  }

+

+  //

+  //  Return the operation status

+  //

+  return Status;

+}

+

+

+/**

+  Receive data from the DataSource program to test a network's bandwidth.

+

+  @param [in] Argc  The number of arguments

+  @param [in] Argv  The argument value array

+

+  @retval  0        The application exited normally.

+  @retval  Other    An error occurred.

+**/

+int

+main (

+  IN int Argc,

+  IN char **Argv

+  )

+{

+  sa_family_t Family;

+  EFI_STATUS Status;

+

+  DEBUG (( DEBUG_INFO,

+            "DataSink starting\r\n" ));

+

+  //

+  //  Determine the family to use

+  //

+  Family = ( 1 < Argc ) ? AF_INET6 : AF_INET;

+

+  //

+  //  Use for/break instead of goto

+  //

+  for ( ; ; ) {

+    //

+    //  Create the timer

+    //

+    bTick = TRUE;

+    Status = TimerCreate ( );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Start a timer to perform network polling and display updates

+    //

+    Status = TimerStart ( 1 * 1000 );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Loop forever waiting for abuse

+    //

+    do {

+      ListenSocket = -1;

+      do {

+        //

+        //  Complete any client operations

+        //

+        Status = SocketPoll ( );

+        if ( EFI_ERROR ( Status )) {

+          //

+          //  Control-C

+          //

+          break;

+        }

+      

+        //

+        //  Wait for a while

+        //

+      } while ( !bTick );

+      if ( EFI_ERROR ( Status )) {

+        //

+        //  Control-C

+        //

+        break;

+      }

+      

+      //

+      //  Wait for the network layer to initialize

+      //

+      Status = SocketNew ( Family );

+      if ( EFI_ERROR ( Status )) {

+        continue;

+      }

+

+      //

+      //  Wait for the remote network application to start

+      //

+      Status = SocketAccept ( );

+      if ( EFI_NOT_STARTED == Status ) {

+        Status = SocketClose ( );

+        continue;

+      }

+      else if ( EFI_SUCCESS != Status ) {

+        //

+        //  Control-C

+        //

+        break;

+      }

+

+      //

+      //  Receive data until the connection breaks

+      //

+      do {

+        Status = SocketPoll ( );

+      } while ( !EFI_ERROR ( Status ));

+

+      //

+      //  Done with the socket

+      //

+      Status = SocketClose ( );

+    } while ( !EFI_ERROR ( Status ));

+

+    //

+    //  Close the socket if necessary

+    //

+    SocketClose ( );

+

+    //

+    //  All done

+    //

+    break;

+  }

+

+  //

+  //  Stop the timer if necessary

+  //

+  TimerStop ( );

+  TimerDestroy ( );

+

+  //

+  //  Return the operation status

+  //

+  DEBUG (( DEBUG_INFO,

+            "DataSink exiting, Status: %r\r\n",

+            Status ));

+  return Status;

+}

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/DataSink/DataSink.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/DataSink/DataSink.inf
new file mode 100644
index 0000000..9ad6fd9
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/DataSink/DataSink.inf
@@ -0,0 +1,61 @@
+## @file

+#  DataSink Application

+#

+#  Copyright (c) 2011-2012, Intel Corporation

+#  All rights reserved. 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.php

+#

+#  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                    = 0x00010005

+  BASE_NAME                      = DataSink

+  FILE_GUID                      = A85DCA1B-198F-4e14-A673-874264687E85

+  MODULE_TYPE                    = UEFI_APPLICATION

+  VERSION_STRING                 = 1.0

+  ENTRY_POINT                    = ShellCEntryLib

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  DataSink.c

+

+

+[Pcd]

+  gAppPkgTokenSpaceGuid.DataSource_Port

+

+

+[Packages]

+  AppPkg/AppPkg.dec

+  MdePkg/MdePkg.dec

+  ShellPkg/ShellPkg.dec

+  StdLib/StdLib.dec

+

+

+[LibraryClasses]

+  BaseMemoryLib

+  BsdSocketLib

+  DebugLib

+  EfiSocketLib

+  LibC

+  LibMath

+  ShellCEntryLib

+  UefiBootServicesTableLib

+  UefiLib

+#  UseSocketDxe

+

+[BuildOptions]

+  INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186

+   MSFT:*_*_*_CC_FLAGS = /Od

+    GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable

+

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/DataSource/DataSource.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/DataSource/DataSource.c
new file mode 100644
index 0000000..0dcd882
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/DataSource/DataSource.c
@@ -0,0 +1,1755 @@
+/** @file

+  Data source for network testing.

+

+  Copyright (c) 2011-2012, Intel Corporation

+  All rights reserved. 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.php

+

+  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 <errno.h>

+#include <Uefi.h>

+

+#include <Library/BaseMemoryLib.h>

+#include <Library/DebugLib.h>

+#include <Library/PcdLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/UefiLib.h>

+

+#include <netinet/in.h>

+

+#include <Protocol/ServiceBinding.h>

+#include <Protocol/Tcp4.h>

+

+#include <sys/EfiSysCall.h>

+#include <sys/poll.h>

+#include <sys/socket.h>

+

+#include <stdio.h>

+#include <string.h>

+

+

+#define DATA_SAMPLE_SHIFT           5       ///<  Shift for number of samples

+#define RANGE_SWITCH        ( 1024 * 1024 ) ///<  Switch display ranges

+#define DATA_RATE_UPDATE_SHIFT      2       ///<  2n seconds between updates

+#define AVERAGE_SHIFT_COUNT ( 6 - DATA_RATE_UPDATE_SHIFT )  ///<  2n samples in average

+#define DATA_SAMPLES        ( 1 << DATA_SAMPLE_SHIFT )      ///<  Number of samples

+

+#define TPL_DATASOURCE      TPL_CALLBACK  ///<  Synchronization TPL

+

+#define PACKET_SIZE                 1448  ///<  Size of data packets

+#define DATA_BUFFER_SIZE    (( 65536 / PACKET_SIZE ) * PACKET_SIZE )  ///<  Buffer size in bytes

+

+

+//

+//  Socket Data

+//

+int Socket = -1;

+

+//

+//  TCP V4 Data

+//

+BOOLEAN bTcp4;                      ///<  TRUE if TCP4 is being used

+BOOLEAN bTcp4Connected;             ///<  TRUE if connected to remote system

+BOOLEAN bTcp4Connecting;            ///<  TRUE while connection in progress

+UINTN Tcp4Index;                    ///<  Index into handle array

+EFI_HANDLE Tcp4Controller;          ///<  Network controller handle

+EFI_HANDLE Tcp4Handle;              ///<  TCP4 port handle

+EFI_TCP4_PROTOCOL * pTcp4Protocol;  ///<  TCP4 protocol pointer

+EFI_SERVICE_BINDING_PROTOCOL * pTcp4Service;  ///<  TCP4 Service binding

+EFI_TCP4_CONFIG_DATA Tcp4ConfigData;///<  TCP4 configuration data

+EFI_TCP4_OPTION Tcp4Option;         ///<  TCP4 port options

+EFI_TCP4_CLOSE_TOKEN Tcp4CloseToken;///<  Close control

+EFI_TCP4_CONNECTION_TOKEN Tcp4ConnectToken; ///<  Connection control

+EFI_TCP4_LISTEN_TOKEN Tcp4ListenToken;      ///<  Listen control

+EFI_TCP4_IO_TOKEN Tcp4TxToken;      ///<  Normal data token

+

+//

+//  Timer Data

+//

+volatile BOOLEAN bTick;

+BOOLEAN bTimerRunning;

+EFI_EVENT pTimer;

+

+//

+//  Remote IP Address Data

+//

+struct sockaddr_in6 RemoteHostAddress;

+CHAR8 * pRemoteHost;

+

+//

+//  Traffic Data

+//

+UINT64 TotalBytesSent;

+UINT32 In;

+UINT32 Samples;

+UINT64 BytesSent[ DATA_SAMPLES ];

+UINT8 Buffer[ DATA_BUFFER_SIZE ];

+

+

+//

+//  Forward routine declarations

+//

+EFI_STATUS TimerStart ( UINTN Milliseconds );

+

+

+/**

+  Check for control C entered at console

+

+  @retval  EFI_SUCCESS  Control C not entered

+  @retval  EFI_ABORTED  Control C entered

+**/

+EFI_STATUS

+ControlCCheck (

+  )

+{

+  EFI_STATUS Status;

+

+  //

+  //  Assume no user intervention

+  //

+  Status = EFI_SUCCESS;

+

+  //

+  //  Display user stop request

+  //

+  if ( EFI_ERROR ( Status )) {

+    DEBUG (( DEBUG_INFO,

+              "User stop request!\r\n" ));

+  }

+

+  //

+  //  Return the check status

+  //

+  return Status;

+}

+

+

+/**

+  Get a digit

+

+  @param [in] pDigit    The address of the next digit

+  @param [out] pValue   The address to receive the value

+

+  @return   Returns the address of the separator

+

+**/

+CHAR8 *

+GetDigit (

+  CHAR8 * pDigit,

+  UINT32 * pValue

+  )

+{

+  UINT32 Value;

+

+  //

+  //  Walk the digits

+  //

+  Value = 0;

+  while (( '0' <= *pDigit ) && ( '9' >= *pDigit )) {

+    //

+    //  Make room for the new least significant digit

+    //

+    Value *= 10;

+

+    //

+    //  Convert the digit from ASCII to binary

+    //

+    Value += *pDigit - '0';

+

+    //

+    //  Set the next digit

+    //

+    pDigit += 1;

+  }

+

+  //

+  //  Return the value

+  //

+  *pValue = Value;

+

+  //

+  //  Return the next separator

+  //

+  return pDigit;

+}

+

+

+/**

+  Get the IP address

+

+  @retval  EFI_SUCCESS  The IP address is valid

+  @retval  Other        Failure to convert the IP address

+**/

+EFI_STATUS

+IpAddress (

+  )

+{

+  struct sockaddr_in * pRemoteAddress4;

+  struct sockaddr_in6 * pRemoteAddress6;

+  UINT32 RemoteAddress;

+  EFI_STATUS Status;

+  UINT32 Value1;

+  UINT32 Value2;

+  UINT32 Value3;

+  UINT32 Value4;

+  UINT32 Value5;

+  UINT32 Value6;

+  UINT32 Value7;

+  UINT32 Value8;

+

+  //

+  //  Assume failure

+  //

+  Status = EFI_INVALID_PARAMETER;

+

+  //

+  //  Get the port number

+  //

+  ZeroMem ( &RemoteHostAddress, sizeof ( RemoteHostAddress ));

+  RemoteHostAddress.sin6_port = htons ( PcdGet16 ( DataSource_Port ));

+  pRemoteAddress4 = (struct sockaddr_in *)&RemoteHostAddress;

+  pRemoteAddress6 = &RemoteHostAddress;

+  

+  //

+  //  Convert the IP address from a string to a numeric value

+  //

+  if (( 4 == sscanf ( pRemoteHost,

+                      "%d.%d.%d.%d",

+                      &Value1,

+                      &Value2,

+                      &Value3,

+                      &Value4 ))

+      && ( 255 >= Value1 )

+      && ( 255 >= Value2 )

+      && ( 255 >= Value3 )

+      && ( 255 >= Value4 )) {

+    //

+    //  Build the IPv4 address

+    //

+    pRemoteAddress4->sin_len = sizeof ( *pRemoteAddress4 );

+    pRemoteAddress4->sin_family = AF_INET;

+    RemoteAddress = Value1

+                  | ( Value2 << 8 )

+                  | ( Value3 << 16 )

+                  | ( Value4 << 24 );

+    pRemoteAddress4->sin_addr.s_addr = RemoteAddress;

+    Status = EFI_SUCCESS;

+

+    //

+    //  Display the IP address

+    //

+    DEBUG (( DEBUG_INFO,

+              "%d.%d.%d.%d: Remote host IP address\r\n",

+              Value1,

+              Value2,

+              Value3,

+              Value4 ));

+  }

+  else if (( 8 == sscanf ( pRemoteHost,

+                           "%x:%x:%x:%x:%x:%x:%x:%x",

+                           &Value1,

+                           &Value2,

+                           &Value3,

+                           &Value4,

+                           &Value5,

+                           &Value6,

+                           &Value7,

+                           &Value8 ))

+            && ( 0xffff >= Value1 )

+            && ( 0xffff >= Value2 )

+            && ( 0xffff >= Value3 )

+            && ( 0xffff >= Value4 )

+            && ( 0xffff >= Value5 )

+            && ( 0xffff >= Value6 )

+            && ( 0xffff >= Value7 )

+            && ( 0xffff >= Value8 )) {

+    //

+    //  Build the IPv6 address

+    //

+    pRemoteAddress6->sin6_len = sizeof ( *pRemoteAddress6 );

+    pRemoteAddress6->sin6_family = AF_INET6;

+    pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ] = (UINT8)( Value1 >> 8 );

+    pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ] = (UINT8)Value1;

+    pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ] = (UINT8)( Value2 >> 8 );

+    pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ] = (UINT8)Value2;

+    pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ] = (UINT8)( Value3 >> 8 );

+    pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ] = (UINT8)Value3;

+    pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ] = (UINT8)( Value4 >> 8 );

+    pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ] = (UINT8)Value4;

+    pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ] = (UINT8)( Value5 >> 8 );

+    pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ] = (UINT8)Value5;

+    pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ] = (UINT8)( Value6 >> 8 );

+    pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ] = (UINT8)Value6;

+    pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ] = (UINT8)( Value7 >> 8 );

+    pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ] = (UINT8)Value7;

+    pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ] = (UINT8)( Value8 >> 8 );

+    pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ] = (UINT8)Value8;

+    Status = EFI_SUCCESS;

+

+    //

+    //  Display the IP address

+    //

+    DEBUG (( DEBUG_INFO,

+              "[%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]: Remote host IP address\r\n",

+              Value1,

+              Value2,

+              Value3,

+              Value4,

+              Value5,

+              Value6,

+              Value7,

+              Value8 ));

+  }

+  else {

+    Print ( L"ERROR - Invalid IP address!\r\n" );

+  }

+

+  //

+  //  Return the operation status

+  //

+  return Status;

+}

+

+

+/**

+  Close the socket

+

+  @retval  EFI_SUCCESS  The application is running normally

+  @retval  Other        The user stopped the application

+**/

+EFI_STATUS

+SocketClose (

+  )

+{

+  int CloseStatus;

+  EFI_STATUS Status;

+

+  //

+  //  Determine if the socket is open

+  //

+  Status = EFI_DEVICE_ERROR;

+  if ( -1 != Socket ) {

+    //

+    //  Attempt to close the socket

+    //

+    CloseStatus = close ( Socket );

+    if ( 0 == CloseStatus ) {

+      DEBUG (( DEBUG_INFO,

+                "0x%08x: Socket closed\r\n",

+                Socket ));

+      Socket = -1;

+      Status = EFI_SUCCESS;

+    }

+    else {

+      DEBUG (( DEBUG_ERROR,

+                "ERROR: Failed to close socket, errno: %d\r\n",

+                errno ));

+    }

+  }

+

+  //

+  //  Return the operation status

+  //

+  return Status;

+}

+

+

+/**

+  Connect the socket

+

+  @retval  EFI_SUCCESS  The application is running normally

+  @retval  Other        The user stopped the application

+**/

+EFI_STATUS

+SocketConnect (

+  )

+{

+  int ConnectStatus;

+  struct sockaddr_in * pRemoteAddress4;

+  struct sockaddr_in6 * pRemoteAddress6;

+  EFI_STATUS Status;

+

+  //

+  //  Display the connecting message

+  //

+  pRemoteAddress4 = (struct sockaddr_in *)&RemoteHostAddress;

+  pRemoteAddress6 = &RemoteHostAddress;

+  if ( AF_INET == pRemoteAddress6->sin6_family ) {

+    Print ( L"Connecting to remote system %d.%d.%d.%d:%d\r\n",

+            pRemoteAddress4->sin_addr.s_addr & 0xff,

+            ( pRemoteAddress4->sin_addr.s_addr >> 8 ) & 0xff,

+            ( pRemoteAddress4->sin_addr.s_addr >> 16 ) & 0xff,

+            ( pRemoteAddress4->sin_addr.s_addr >> 24 ) & 0xff,

+            ntohs ( pRemoteAddress4->sin_port ));

+  }

+  else {

+    Print ( L"Connecting to remote system [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",

+            pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],

+            pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],

+            pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],

+            pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],

+            pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],

+            pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],

+            pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],

+            pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],

+            pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],

+            pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],

+            pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],

+            pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],

+            pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],

+            pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],

+            pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],

+            pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],

+            ntohs ( pRemoteAddress6->sin6_port ));

+  }

+

+  //

+  //  Connect to the remote system

+  //

+  Status = EFI_SUCCESS;

+  do {

+    //

+    //  Check for user stop request

+    //

+    while ( !bTick ) {

+      Status = ControlCCheck ( );

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+    }

+    bTick = FALSE;

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Connect to the remote system

+    //

+    ConnectStatus = connect ( Socket,

+                              (struct sockaddr *)pRemoteAddress6,

+                              pRemoteAddress6->sin6_len );

+    if ( -1 != ConnectStatus ) {

+      if ( AF_INET == pRemoteAddress6->sin6_family ) {

+        Print ( L"Connected to remote system %d.%d.%d.%d:%d\r\n",

+                pRemoteAddress4->sin_addr.s_addr & 0xff,

+                ( pRemoteAddress4->sin_addr.s_addr >> 8 ) & 0xff,

+                ( pRemoteAddress4->sin_addr.s_addr >> 16 ) & 0xff,

+                ( pRemoteAddress4->sin_addr.s_addr >> 24 ) & 0xff,

+                ntohs ( pRemoteAddress4->sin_port ));

+      }

+      else {

+        Print ( L"Connected to remote system [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",

+                pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],

+                pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],

+                pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],

+                pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],

+                pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],

+                pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],

+                pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],

+                pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],

+                pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],

+                pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],

+                pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],

+                pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],

+                pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],

+                pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],

+                pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],

+                pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],

+                ntohs ( pRemoteAddress6->sin6_port ));

+      }

+Print ( L"ConnectStatus: %d, Status: %r\r\n", ConnectStatus, Status );

+    }

+    else {

+      //

+      //  Close the socket and try again

+      //

+      if ( EAGAIN != errno ) {

+        Status = EFI_NOT_STARTED;

+        break;

+      }

+    }

+  } while ( -1 == ConnectStatus );

+

+  //

+  //  Return the operation status

+  //

+Print ( L"SocketConnect returning Status: %r\r\n", Status );

+  return Status;

+}

+

+

+/**

+  Create the socket

+

+  @param [in] Family    Network family, AF_INET or AF_INET6

+

+  @retval  EFI_SUCCESS  The application is running normally

+  @retval  Other        The user stopped the application

+**/

+EFI_STATUS

+SocketNew (

+  sa_family_t Family

+  )

+{

+  EFI_STATUS Status;

+

+  //

+  //  Loop creating the socket

+  //

+  DEBUG (( DEBUG_INFO,

+            "Creating the socket\r\n" ));

+  do {

+    //

+    //  Check for user stop request

+    //

+    Status = ControlCCheck ( );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Attempt to create the socket

+    //

+    Socket = socket ( Family,

+                      SOCK_STREAM,

+                      IPPROTO_TCP );

+    if ( -1 != Socket ) {

+      DEBUG (( DEBUG_INFO,

+                "0x%08x: Socket created\r\n",

+                Socket ));

+      break;

+    }

+  } while ( -1 == Socket );

+

+  //

+  //  Return the operation status

+  //

+  return Status;

+}

+

+

+/**

+  Send data over the socket

+

+  @retval  EFI_SUCCESS  The application is running normally

+  @retval  Other        The user stopped the application

+**/

+EFI_STATUS

+SocketSend (

+  )

+{

+  size_t BytesSent;

+  EFI_STATUS Status;

+  EFI_TPL TplPrevious;

+

+  //

+  //  Restart the timer

+  //

+  TimerStart ( 1 * 1000 );

+

+  //

+  //  Loop until the connection breaks or the user stops

+  //

+  do {

+    //

+    //  Check for user stop request

+    //

+    Status = ControlCCheck ( );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Send some bytes

+    //

+    BytesSent = write ( Socket, &Buffer[0], sizeof ( Buffer ));

+    if ( -1 == BytesSent ) {

+      DEBUG (( DEBUG_INFO,

+                "ERROR: send failed, errno: %d\r\n",

+                errno ));

+Print ( L"ERROR: send failed, errno: %d\r\n", errno );

+

+      //

+      //  Try again

+      //

+      Status = EFI_SUCCESS;

+

+//

+//  Exit now

+//

+Status = EFI_NOT_STARTED;

+      break;

+    }

+

+    //

+    //  Synchronize with the TimerCallback routine

+    //

+    TplPrevious = gBS->RaiseTPL ( TPL_DATASOURCE );

+

+    //

+    //  Account for the data sent

+    //

+    TotalBytesSent += BytesSent;

+

+    //

+    //  Release the TimerCallback routine synchronization

+    //

+    gBS->RestoreTPL ( TplPrevious );

+  } while ( !EFI_ERROR ( Status ));

+

+  //

+  //  Return the operation status

+  //

+  return Status;

+}

+

+

+/**

+  Open the network connection and send the data.

+

+  @retval EFI_SUCCESS   Continue looping

+  @retval other         Stopped by user's Control-C input

+

+**/

+EFI_STATUS

+SocketOpen (

+  )

+{

+  EFI_STATUS Status;

+

+  //

+  //  Use do/while and break instead of goto

+  //

+  do {

+    //

+    //  Wait for the network layer to initialize

+    //

+    Status = SocketNew ( RemoteHostAddress.sin6_family );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Wait for the remote network application to start

+    //

+    Status = SocketConnect ( );

+Print ( L"Status: %r\r\n", Status );

+    if ( EFI_NOT_STARTED == Status ) {

+      Status = SocketClose ( );

+      continue;

+    }

+    else if ( EFI_SUCCESS != Status ) {

+      //

+      //  Control-C

+      //

+      break;

+    }

+

+    //

+    //  Send data until the connection breaks

+    //

+    Status = SocketSend ( );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+  } while ( FALSE );

+

+  //

+  //  Return the operation status

+  //

+Print ( L"Returning Status: %r\r\n", Status );

+  return Status;

+}

+

+

+/**

+  Close the TCP connection

+

+  @retval  EFI_SUCCESS  The application is running normally

+  @retval  Other        The user stopped the application

+**/

+EFI_STATUS

+Tcp4Close (

+  )

+{

+  UINTN Index;

+  UINT8 * pIpAddress;

+  EFI_STATUS Status;

+

+  //

+  //  Close the port

+  //

+  if ( bTcp4Connected ) {

+    Tcp4CloseToken.AbortOnClose = TRUE;

+    Status = pTcp4Protocol->Close ( pTcp4Protocol,

+                                    &Tcp4CloseToken );

+    if ( EFI_ERROR ( Status )) {

+      DEBUG (( DEBUG_ERROR,

+                "ERROR - Failed to start the TCP port close, Status: %r\r\n",

+                Status ));

+    }

+    else {

+      Status = gBS->WaitForEvent ( 1,

+                                   &Tcp4CloseToken.CompletionToken.Event,

+                                    &Index );

+      if ( EFI_ERROR ( Status )) {

+        DEBUG (( DEBUG_ERROR,

+                  "ERROR - Failed to wait for close event, Status: %r\r\n",

+                  Status ));

+      }

+      else {

+        Status = Tcp4CloseToken.CompletionToken.Status;

+        if ( EFI_ERROR ( Status )) {

+          DEBUG (( DEBUG_ERROR,

+                    "ERROR - Failed to close the TCP port, Status: %r\r\n",

+                    Status ));

+        }

+        else {

+          DEBUG (( DEBUG_INFO,

+                    "0x%08x: TCP port closed\r\n",

+                    pTcp4Protocol ));

+          bTcp4Connected = FALSE;

+

+          //

+          //  Display the port closed message

+          //

+          pIpAddress = (UINT8 *)&((struct sockaddr_in *)&RemoteHostAddress)->sin_addr.s_addr;

+          Print ( L"Closed connection to %d.%d.%d.%d:%d\r\n",

+                  pIpAddress[0],

+                  pIpAddress[1],

+                  pIpAddress[2],

+                  pIpAddress[3],

+                  ntohs ( ((struct sockaddr_in *)&RemoteHostAddress)->sin_port ));

+        }

+      }

+    }

+  }

+

+  //

+  //  Release the events

+  //

+  if ( NULL != Tcp4TxToken.CompletionToken.Event ) {

+    Status = gBS->CloseEvent ( Tcp4TxToken.CompletionToken.Event );

+    if ( !EFI_ERROR ( Status )) {

+      DEBUG (( DEBUG_INFO,

+                "0x%08x: TX event closed\r\n",

+                Tcp4TxToken.CompletionToken.Event ));

+      Tcp4TxToken.CompletionToken.Event = NULL;

+    }

+    else {

+      DEBUG (( DEBUG_ERROR,

+                "ERROR - Failed to close the Tcp4TxToken event, Status: %r\r\n",

+                Status ));

+    }

+  }

+

+  if ( NULL != Tcp4ListenToken.CompletionToken.Event ) {

+    Status = gBS->CloseEvent ( Tcp4ListenToken.CompletionToken.Event );

+    if ( !EFI_ERROR ( Status )) {

+      DEBUG (( DEBUG_INFO,

+                "0x%08x: Listen event closed\r\n",

+                Tcp4ListenToken.CompletionToken.Event ));

+      Tcp4ListenToken.CompletionToken.Event = NULL;

+    }

+    else {

+      DEBUG (( DEBUG_ERROR,

+                "ERROR - Failed to close the Tcp4ListenToken event, Status: %r\r\n",

+                Status ));

+    }

+  }

+

+  if ( NULL != Tcp4ConnectToken.CompletionToken.Event ) {

+    Status = gBS->CloseEvent ( Tcp4ConnectToken.CompletionToken.Event );

+    if ( !EFI_ERROR ( Status )) {

+      DEBUG (( DEBUG_INFO,

+                "0x%08x: Connect event closed\r\n",

+                Tcp4ConnectToken.CompletionToken.Event ));

+      Tcp4ConnectToken.CompletionToken.Event = NULL;

+    }

+    else {

+      DEBUG (( DEBUG_ERROR,

+                "ERROR - Failed to close the Tcp4ConnectToken event, Status: %r\r\n",

+                Status ));

+    }

+  }

+

+  if ( NULL != Tcp4CloseToken.CompletionToken.Event ) {

+    Status = gBS->CloseEvent ( Tcp4CloseToken.CompletionToken.Event );

+    if ( !EFI_ERROR ( Status )) {

+      DEBUG (( DEBUG_INFO,

+                "0x%08x: Close event closed\r\n",

+                Tcp4CloseToken.CompletionToken.Event ));

+      Tcp4CloseToken.CompletionToken.Event = NULL;

+    }

+    else {

+      DEBUG (( DEBUG_ERROR,

+                "ERROR - Failed to close the Tcp4CloseToken event, Status: %r\r\n",

+                Status ));

+    }

+  }

+

+  //

+  //  Close the TCP protocol

+  //

+  if ( NULL != pTcp4Protocol ) {

+    Status = gBS->CloseProtocol ( Tcp4Handle,

+                                  &gEfiTcp4ProtocolGuid,

+                                  gImageHandle,

+                                  NULL );

+    if ( EFI_ERROR ( Status )) {

+      DEBUG (( DEBUG_ERROR,

+                "ERROR - Failed to close the TCP protocol, Status: %r\r\n",

+                Status ));

+    }

+    else {

+      DEBUG (( DEBUG_INFO,

+                "0x%08x: TCP4 protocol closed\r\n",

+                pTcp4Protocol ));

+      pTcp4Protocol = NULL;

+    }

+  }

+

+  //

+  //  Done with the TCP service

+  //

+  if ( NULL != Tcp4Handle ) {

+    Status = pTcp4Service->DestroyChild ( pTcp4Service,

+                                          Tcp4Handle );

+    if ( EFI_ERROR ( Status )) {

+      DEBUG (( DEBUG_ERROR,

+                "ERROR - Failed to release TCP service handle, Status: %r\r\n",

+                Status ));

+    }

+    else {

+      DEBUG (( DEBUG_INFO,

+                "Ox%08x: TCP service closed\r\n",

+                Tcp4Handle ));

+      Tcp4Handle = NULL;

+    }

+  }

+

+  //

+  //  Close the service protocol

+  //

+  if ( NULL != pTcp4Service ) {

+    Status = gBS->CloseProtocol ( Tcp4Controller,

+                                  &gEfiTcp4ServiceBindingProtocolGuid,

+                                  gImageHandle,

+                                  NULL );

+    if ( !EFI_ERROR ( Status )) {

+      DEBUG (( DEBUG_INFO,

+                "0x%08x: Controller closed gEfiTcp4ServiceBindingProtocolGuid protocol\r\n",

+                Tcp4Controller ));

+      pTcp4Service = NULL;

+    }

+    else {

+      DEBUG (( DEBUG_ERROR,

+                "ERROR - Failed to close the gEfiTcp4ServiceBindingProtocolGuid protocol, Status: %r\r\n",

+                Status ));

+    }

+  }

+  Tcp4Controller = NULL;

+  bTcp4Connecting = TRUE;

+

+  //

+  //  Mark the connection as closed

+  //

+  Status = EFI_SUCCESS;

+

+  //

+  //  Return the operation status

+  //

+  return Status;

+}

+

+

+/**

+  Locate TCP protocol

+

+  @retval EFI_SUCCESS   Protocol found

+  @retval other         Protocl not found

+**/

+EFI_STATUS

+Tcp4Locate (

+  )

+{

+  UINTN HandleCount;

+  EFI_HANDLE * pHandles;

+  UINT8 * pIpAddress;

+  EFI_STATUS Status;

+

+  //

+  //  Use do/while and break instead of goto

+  //

+  do {

+    //

+    //  Attempt to locate the next TCP adapter in the system

+    //

+    Status = gBS->LocateHandleBuffer ( ByProtocol,

+                                       &gEfiTcp4ServiceBindingProtocolGuid,

+                                       NULL,

+                                       &HandleCount,

+                                       &pHandles );

+    if ( EFI_ERROR ( Status )) {

+      DEBUG (( DEBUG_WARN,

+                "WARNING - No network controllers or TCP4 available, Status: %r\r\n",

+                Status ));

+      break;

+    }

+

+    //

+    //  Wrap the index if necessary

+    //

+    if ( HandleCount <= Tcp4Index ) {

+      Tcp4Index = 0;

+

+      //

+      //  Wait for the next timer tick

+      //

+      do {

+      } while ( !bTick );

+      bTick = FALSE;

+    }

+

+    //

+    //  Display the connecting message

+    //

+    if ( bTcp4Connecting ) {

+      pIpAddress = (UINT8 *)&((struct sockaddr_in *)&RemoteHostAddress)->sin_addr.s_addr;

+      Print ( L"Connecting to %d.%d.%d.%d:%d\r\n",

+              pIpAddress[0],

+              pIpAddress[1],

+              pIpAddress[2],

+              pIpAddress[3],

+              ntohs ( ((struct sockaddr_in *)&RemoteHostAddress)->sin_port ));

+      bTcp4Connecting = FALSE;

+    }

+

+    //

+    //  Open the network controller's service protocol

+    //

+    Tcp4Controller = pHandles[ Tcp4Index++ ];

+    Status = gBS->OpenProtocol (

+                    Tcp4Controller,

+                    &gEfiTcp4ServiceBindingProtocolGuid,

+                    (VOID **) &pTcp4Service,

+                    gImageHandle,

+                    NULL,

+                    EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL );

+    if ( EFI_ERROR ( Status )) {

+      DEBUG (( DEBUG_ERROR,

+                "ERROR - Failed to open gEfiTcp4ServiceBindingProtocolGuid on controller 0x%08x\r\n",

+                Tcp4Controller ));

+      Tcp4Controller = NULL;

+      break;

+    }

+    DEBUG (( DEBUG_INFO,

+              "0x%08x: Controller opened gEfiTcp4ServiceBindingProtocolGuid protocol\r\n",

+              Tcp4Controller ));

+

+    //

+    //  Connect to the TCP service

+    //

+    Status = pTcp4Service->CreateChild ( pTcp4Service,

+                                         &Tcp4Handle );

+    if ( EFI_ERROR ( Status )) {

+      DEBUG (( DEBUG_ERROR,

+                "ERROR - Failed to open TCP service, Status: %r\r\n",

+                Status ));

+      Tcp4Handle = NULL;

+      break;

+    }

+    DEBUG (( DEBUG_INFO,

+              "Ox%08x: TCP service opened\r\n",

+              Tcp4Handle ));

+

+    //

+    //  Locate the TCP protcol

+    //

+    Status = gBS->OpenProtocol ( Tcp4Handle,

+                                 &gEfiTcp4ProtocolGuid,

+                                 (VOID **)&pTcp4Protocol,

+                                 gImageHandle,

+                                 NULL,

+                                 EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL );

+    if ( EFI_ERROR ( Status )) {

+      DEBUG (( DEBUG_ERROR,

+                "ERROR - Failed to open the TCP protocol, Status: %r\r\n",

+                Status ));

+      pTcp4Protocol = NULL;

+      break;

+    }

+    DEBUG (( DEBUG_INFO,

+              "0x%08x: TCP4 protocol opened\r\n",

+              pTcp4Protocol ));

+  }while ( FALSE );

+

+  //

+  //  Release the handle buffer

+  //

+  gBS->FreePool ( pHandles );

+

+  //

+  //  Return the operation status

+  //

+  return Status;

+}

+

+

+/**

+  Send data over the TCP4 connection

+

+  @retval  EFI_SUCCESS  The application is running normally

+  @retval  Other        The user stopped the application

+**/

+EFI_STATUS

+Tcp4Send (

+  )

+{

+  UINTN Index;

+  EFI_TCP4_TRANSMIT_DATA Packet;

+  EFI_STATUS Status;

+  EFI_TPL TplPrevious;

+

+  //

+  //  Restart the timer

+  //

+  TimerStart ( 1 * 1000 );

+

+  //

+  //  Initialize the packet

+  //

+  Packet.DataLength = sizeof ( Buffer );

+  Packet.FragmentCount = 1;

+  Packet.Push = FALSE;

+  Packet.Urgent = FALSE;

+  Packet.FragmentTable[0].FragmentBuffer = &Buffer[0];

+  Packet.FragmentTable[0].FragmentLength = sizeof ( Buffer );

+  Tcp4TxToken.Packet.TxData = &Packet;

+

+  //

+  //  Loop until the connection breaks or the user stops

+  //

+  do {

+    //

+    //  Check for user stop request

+    //

+    Status = ControlCCheck ( );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Send some bytes

+    //

+    Status = pTcp4Protocol->Transmit ( pTcp4Protocol,

+                                       &Tcp4TxToken );

+    if ( EFI_ERROR ( Status )) {

+      DEBUG (( DEBUG_ERROR,

+                "ERROR - Failed to start the transmit, Status: %r\r\n",

+                Status ));

+

+      //

+      //  Try again

+      //

+      Status = EFI_SUCCESS;

+      break;

+    }

+

+    //

+    //  Wait for the transmit to complete

+    //

+    Status = gBS->WaitForEvent ( 1,

+                                 &Tcp4TxToken.CompletionToken.Event,

+                                 &Index );

+    if ( EFI_ERROR ( Status )) {

+      DEBUG (( DEBUG_ERROR,

+                "ERROR - Failed to wait for transmit completion, Status: %r\r\n",

+                Status ));

+

+      //

+      //  Try again

+      //

+      Status = EFI_SUCCESS;

+      break;

+    }

+

+    //

+    //  Get the transmit status

+    //

+    Status = Tcp4TxToken.CompletionToken.Status;

+    if ( EFI_ERROR ( Status )) {

+      DEBUG (( DEBUG_WARN,

+                "WARNING - Failed the transmission, Status: %r\r\n",

+                Status ));

+

+      //

+      //  Try again

+      //

+      Status = EFI_SUCCESS;

+

+//

+//  Exit now

+//

+Status = EFI_NOT_STARTED;

+      break;

+    }

+

+    //

+    //  Synchronize with the TimerCallback routine

+    //

+    TplPrevious = gBS->RaiseTPL ( TPL_DATASOURCE );

+

+    //

+    //  Account for the data sent

+    //

+    TotalBytesSent += Packet.DataLength;

+

+    //

+    //  Release the TimerCallback routine synchronization

+    //

+    gBS->RestoreTPL ( TplPrevious );

+  } while ( !EFI_ERROR ( Status ));

+

+  //

+  //  Return the operation status

+  //

+  return Status;

+}

+

+

+/**

+  Open the network connection and send the data.

+

+  @retval EFI_SUCCESS   Continue looping

+  @retval other         Stopped by user's Control-C input

+

+**/

+EFI_STATUS

+Tcp4Open (

+  )

+{

+  UINTN Index;

+  UINT8 * pIpAddress;

+  EFI_STATUS Status;

+

+  //

+  //  Use do/while and break instead of goto

+  //

+  do {

+    //

+    //  Locate the TCP protocol

+    //

+    Status = Tcp4Locate ( );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Create the necessary events

+    //

+    Status = gBS->CreateEvent ( 0,

+                                TPL_CALLBACK,

+                                NULL,

+                                NULL,

+                                &Tcp4CloseToken.CompletionToken.Event );

+    if ( EFI_ERROR ( Status )) {

+      DEBUG (( DEBUG_ERROR,

+                "ERROR - Failed to create the close event, Status: %r\r\n",

+                Status ));

+      Tcp4CloseToken.CompletionToken.Event = NULL;

+      break;

+    }

+    DEBUG (( DEBUG_INFO,

+              "0x%08x: Close event open\r\n",

+              Tcp4CloseToken.CompletionToken.Event ));

+

+    Status = gBS->CreateEvent ( 0,

+                                TPL_CALLBACK,

+                                NULL,

+                                NULL,

+                                &Tcp4ConnectToken.CompletionToken.Event );

+    if ( EFI_ERROR ( Status )) {

+      DEBUG (( DEBUG_ERROR,

+                "ERROR - Failed to create the connect event, Status: %r\r\n",

+                Status ));

+      Tcp4ConnectToken.CompletionToken.Event = NULL;

+      break;

+    }

+    DEBUG (( DEBUG_INFO,

+              "0x%08x: Connect event open\r\n",

+              Tcp4ConnectToken.CompletionToken.Event ));

+

+    Status = gBS->CreateEvent ( 0,

+                                TPL_CALLBACK,

+                                NULL,

+                                NULL,

+                                &Tcp4ListenToken.CompletionToken.Event );

+    if ( EFI_ERROR ( Status )) {

+      DEBUG (( DEBUG_ERROR,

+                "ERROR - Failed to create the listen event, Status: %r\r\n",

+                Status ));

+      Tcp4ListenToken.CompletionToken.Event = NULL;

+      break;

+    }

+    DEBUG (( DEBUG_INFO,

+              "0x%08x: Listen event open\r\n",

+              Tcp4ListenToken.CompletionToken.Event ));

+

+    Status = gBS->CreateEvent ( 0,

+                                TPL_CALLBACK,

+                                NULL,

+                                NULL,

+                                &Tcp4TxToken.CompletionToken.Event );

+    if ( EFI_ERROR ( Status )) {

+      DEBUG (( DEBUG_ERROR,

+                "ERROR - Failed to create the TX event, Status: %r\r\n",

+                Status ));

+      Tcp4TxToken.CompletionToken.Event = NULL;

+      break;

+    }

+    DEBUG (( DEBUG_INFO,

+              "0x%08x: TX event open\r\n",

+              Tcp4TxToken.CompletionToken.Event ));

+

+    //

+    //  Configure the local TCP port

+    //

+    Tcp4ConfigData.TimeToLive = 255;

+    Tcp4ConfigData.TypeOfService = 0;

+    Tcp4ConfigData.ControlOption = NULL;

+    Tcp4ConfigData.AccessPoint.ActiveFlag = TRUE;

+    Tcp4ConfigData.AccessPoint.StationAddress.Addr[0] = 0;

+    Tcp4ConfigData.AccessPoint.StationAddress.Addr[1] = 0;

+    Tcp4ConfigData.AccessPoint.StationAddress.Addr[2] = 0;

+    Tcp4ConfigData.AccessPoint.StationAddress.Addr[3] = 0;

+    Tcp4ConfigData.AccessPoint.StationPort = 0;

+    Tcp4ConfigData.AccessPoint.RemoteAddress.Addr[0] = (UINT8)  ((struct sockaddr_in *)&RemoteHostAddress)->sin_addr.s_addr;

+    Tcp4ConfigData.AccessPoint.RemoteAddress.Addr[1] = (UINT8)( ((struct sockaddr_in *)&RemoteHostAddress)->sin_addr.s_addr >> 8 );

+    Tcp4ConfigData.AccessPoint.RemoteAddress.Addr[2] = (UINT8)( ((struct sockaddr_in *)&RemoteHostAddress)->sin_addr.s_addr >> 16 );

+    Tcp4ConfigData.AccessPoint.RemoteAddress.Addr[3] = (UINT8)( ((struct sockaddr_in *)&RemoteHostAddress)->sin_addr.s_addr >> 24 );

+    Tcp4ConfigData.AccessPoint.RemotePort = ntohs (((struct sockaddr_in *)&RemoteHostAddress)->sin_port);

+    Tcp4ConfigData.AccessPoint.UseDefaultAddress = TRUE;

+    Tcp4ConfigData.AccessPoint.SubnetMask.Addr[0] = 0;

+    Tcp4ConfigData.AccessPoint.SubnetMask.Addr[1] = 0;

+    Tcp4ConfigData.AccessPoint.SubnetMask.Addr[2] = 0;

+    Tcp4ConfigData.AccessPoint.SubnetMask.Addr[3] = 0;

+    Status = pTcp4Protocol->Configure ( pTcp4Protocol,

+                                        &Tcp4ConfigData );

+    if ( EFI_ERROR ( Status )) {

+      DEBUG (( DEBUG_ERROR,

+                "ERROR - Failed to configure TCP port, Status: %r\r\n",

+                Status ));

+      break;

+    }

+    DEBUG (( DEBUG_INFO,

+              "0x%08x: TCP4 port configured\r\n",

+              pTcp4Protocol ));

+

+    //

+    //  Connect to the remote TCP port

+    //

+    Status = pTcp4Protocol->Connect ( pTcp4Protocol,

+                                      &Tcp4ConnectToken );

+    if ( EFI_ERROR ( Status )) {

+      DEBUG (( DEBUG_ERROR,

+                "ERROR - Failed to start the connection to the remote system, Status: %r\r\n",

+                Status ));

+      break;

+    }

+    Status = gBS->WaitForEvent ( 1,

+                                 &Tcp4ConnectToken.CompletionToken.Event,

+                                 &Index );

+    if ( EFI_ERROR ( Status )) {

+      DEBUG (( DEBUG_ERROR,

+                "ERROR - Failed to wait for the connection, Status: %r\r\n",

+                Status ));

+      break;

+    }

+    Status = Tcp4ConnectToken.CompletionToken.Status;

+    if ( EFI_ERROR ( Status )) {

+      DEBUG (( DEBUG_WARN,

+                "WARNING - Failed to connect to the remote system, Status: %r\r\n",

+                Status ));

+      break;

+    }

+    DEBUG (( DEBUG_INFO,

+              "0x%08x: TCP4 port connected\r\n",

+              pTcp4Protocol ));

+    bTcp4Connected = TRUE;

+

+    //

+    //  Display the connection

+    //

+    pIpAddress = (UINT8 *)&((struct sockaddr_in *)&RemoteHostAddress)->sin_addr.s_addr;

+    Print ( L"Connected to %d.%d.%d.%d:%d\r\n",

+            pIpAddress[0],

+            pIpAddress[1],

+            pIpAddress[2],

+            pIpAddress[3],

+            ntohs ( ((struct sockaddr_in *)&RemoteHostAddress)->sin_port ));

+  } while ( 0 );

+

+  if ( EFI_ERROR ( Status )) {

+    //

+    //  Try again

+    //

+    Status = EFI_SUCCESS;

+  }

+  else {

+    //

+    //  Semd data until the connection breaks

+    //

+    Status = Tcp4Send ( );

+  }

+

+  //

+  //  Return the operation status

+  //

+  return Status;

+}

+

+

+/**

+  Handle the timer callback

+

+  @param [in] Event     Event that caused this callback

+  @param [in] pContext  Context for this routine

+**/

+VOID

+EFIAPI

+TimerCallback (

+  IN EFI_EVENT Event,

+  IN VOID * pContext

+  )

+{

+  UINT32 Average;

+  UINT64 BitsPerSecond;

+  UINT32 Index;

+  UINT64 TotalBytes;

+

+  //

+  //  Notify the other code of the timer tick

+  //

+  bTick = TRUE;

+

+  //

+  //  Update the average bytes per second

+  //

+  if ( 0 != TotalBytesSent ) {

+    BytesSent[ In ] = TotalBytesSent;

+    TotalBytesSent = 0;

+    In += 1;

+    if ( DATA_SAMPLES <= In ) {

+      In = 0;

+    }

+

+    //

+    //  Separate the samples

+    //

+    if ( DATA_SAMPLES == Samples ) {

+      Print ( L"---------- Stable average ----------\r\n" );

+    }

+    Samples += 1;

+

+    //

+    //  Compute the data rate

+    //

+    TotalBytes = 0;

+    for ( Index = 0; DATA_SAMPLES > Index; Index++ ) {

+      TotalBytes += BytesSent[ Index ];

+    }

+    Average = (UINT32)RShiftU64 ( TotalBytes, DATA_SAMPLE_SHIFT );

+    BitsPerSecond = Average * 8;

+

+    //

+    //  Display the data rate

+    //

+    if (( RANGE_SWITCH >> 10 ) > Average ) {

+      Print ( L"Ave: %d Bytes/Sec, %Ld Bits/sec\r\n",

+              Average,

+              BitsPerSecond );

+    }

+    else {

+      BitsPerSecond /= 1000;

+      if ( RANGE_SWITCH > Average ) {

+        Print ( L"Ave: %d.%03d KiBytes/Sec, %Ld KBits/sec\r\n",

+                Average >> 10,

+                (( Average & 0x3ff ) * 1000 ) >> 10,

+                BitsPerSecond );

+      }

+      else {

+        BitsPerSecond /= 1000;

+        Average >>= 10;

+        if ( RANGE_SWITCH > Average ) {

+          Print ( L"Ave: %d.%03d MiBytes/Sec, %Ld MBits/sec\r\n",

+                  Average >> 10,

+                  (( Average & 0x3ff ) * 1000 ) >> 10,

+                  BitsPerSecond );

+        }

+        else {

+          BitsPerSecond /= 1000;

+          Average >>= 10;

+          if ( RANGE_SWITCH > Average ) {

+            Print ( L"Ave: %d.%03d GiBytes/Sec, %Ld GBits/sec\r\n",

+                    Average >> 10,

+                    (( Average & 0x3ff ) * 1000 ) >> 10,

+                    BitsPerSecond );

+          }

+          else {

+            BitsPerSecond /= 1000;

+            Average >>= 10;

+            if ( RANGE_SWITCH > Average ) {

+              Print ( L"Ave: %d.%03d TiBytes/Sec, %Ld TBits/sec\r\n",

+                      Average >> 10,

+                      (( Average & 0x3ff ) * 1000 ) >> 10,

+                      BitsPerSecond );

+            }

+            else {

+              BitsPerSecond /= 1000;

+              Average >>= 10;

+              Print ( L"Ave: %d.%03d PiBytes/Sec, %Ld PBits/sec\r\n",

+                      Average >> 10,

+                      (( Average & 0x3ff ) * 1000 ) >> 10,

+                      BitsPerSecond );

+            }

+          }

+        }

+      }

+    }

+  }

+}

+

+

+/**

+  Create the timer

+

+  @retval  EFI_SUCCESS  The timer was successfully created

+  @retval  Other        Timer initialization failed

+**/

+EFI_STATUS

+TimerCreate (

+  )

+{

+  EFI_STATUS Status;

+

+  //

+  //  Create the timer

+  //

+  Status = gBS->CreateEvent ( EVT_TIMER | EVT_NOTIFY_SIGNAL,

+                              TPL_DATASOURCE,

+                              TimerCallback,

+                              NULL,

+                              &pTimer );

+  if ( EFI_ERROR ( Status )) {

+    DEBUG (( DEBUG_ERROR,

+              "ERROR - Failed to allocate the timer event, Status: %r\r\n",

+              Status ));

+  }

+  else {

+    DEBUG (( DEBUG_INFO,

+              "0x%08x: Timer created\r\n",

+              pTimer ));

+  }

+

+  //

+  //  Return the operation status

+  //

+  return Status;

+}

+

+

+/**

+  Stop the timer

+

+  @retval  EFI_SUCCESS  The timer was stopped successfully

+  @retval  Other        The timer failed to stop

+**/

+EFI_STATUS

+TimerStop (

+  )

+{

+  EFI_STATUS Status;

+

+  //

+  //  Assume success

+  //

+  Status = EFI_SUCCESS;

+

+  //

+  //  Determine if the timer is running

+  //

+  if ( bTimerRunning ) {

+    //

+    //  Stop the timer

+    //

+    Status = gBS->SetTimer ( pTimer,

+                             TimerCancel,

+                             0 );

+    if ( EFI_ERROR ( Status )) {

+      DEBUG (( DEBUG_ERROR,

+                "ERROR - Failed to stop the timer, Status: %r\r\n",

+                Status ));

+    }

+    else {

+      //

+      //  Timer timer is now stopped

+      //

+      bTimerRunning = FALSE;

+      DEBUG (( DEBUG_INFO,

+                "0x%08x: Timer stopped\r\n",

+                pTimer ));

+    }

+  }

+

+  //

+  //  Return the operation status

+  //

+  return Status;

+}

+

+

+/**

+  Start the timer

+

+  @param [in] Milliseconds  The number of milliseconds between timer callbacks

+

+  @retval  EFI_SUCCESS  The timer was successfully created

+  @retval  Other        Timer initialization failed

+**/

+EFI_STATUS

+TimerStart (

+  UINTN Milliseconds

+  )

+{

+  EFI_STATUS Status;

+  UINT64 TimeDelay;

+

+  //

+  //  Stop the timer if necessary

+  //

+  Status = EFI_SUCCESS;

+  if ( bTimerRunning ) {

+    Status = TimerStop ( );

+  }

+  if ( !EFI_ERROR ( Status )) {

+    //

+    //  Compute the new delay

+    //

+    TimeDelay = Milliseconds;

+    TimeDelay *= 1000 * 10;

+

+    //

+    //  Start the timer

+    //

+    Status = gBS->SetTimer ( pTimer,

+                             TimerPeriodic,

+                             TimeDelay );

+    if ( EFI_ERROR ( Status )) {

+      DEBUG (( DEBUG_ERROR,

+                "ERROR - Failed to start the timer, Status: %r\r\n",

+                Status ));

+    }

+    else {

+      //

+      //  The timer is now running

+      //

+      bTimerRunning = TRUE;

+      DEBUG (( DEBUG_INFO,

+        "0x%08x: Timer running\r\n",

+        pTimer ));

+    }

+  }

+

+  //

+  //  Return the operation status

+  //

+  return Status;

+}

+

+

+/**

+  Destroy the timer

+

+  @retval  EFI_SUCCESS  The timer was destroyed successfully

+  @retval  Other        Failed to destroy the timer

+**/

+EFI_STATUS

+TimerDestroy (

+  )

+{

+  EFI_STATUS Status;

+

+  //

+  //  Assume success

+  //

+  Status = EFI_SUCCESS;

+

+  //

+  //  Determine if the timer is running

+  //

+  if ( bTimerRunning ) {

+    //

+    //  Stop the timer

+    //

+    Status = TimerStop ( );

+  }

+  if (( !EFI_ERROR ( Status )) && ( NULL != pTimer )) {

+    //

+    //  Done with this timer

+    //

+    Status = gBS->CloseEvent ( pTimer );

+    if ( EFI_ERROR ( Status )) {

+      DEBUG (( DEBUG_ERROR,

+                "ERROR - Failed to free the timer event, Status: %r\r\n",

+                Status ));

+    }

+    else {

+      DEBUG (( DEBUG_INFO,

+                "0x%08x: Timer Destroyed\r\n",

+                pTimer ));

+      pTimer = NULL;

+    }

+  }

+

+  //

+  //  Return the operation status

+  //

+  return Status;

+}

+

+

+/**

+  Send data to the DataSink program to test a network's bandwidth.

+

+  @param [in] Argc  The number of arguments

+  @param [in] Argv  The argument value array

+

+  @retval  0        The application exited normally.

+  @retval  Other    An error occurred.

+**/

+int

+main (

+  IN int Argc,

+  IN char **Argv

+  )

+{

+  EFI_STATUS (* pClose) ();

+  EFI_STATUS (* pOpen) ();

+  EFI_STATUS Status;

+

+  DEBUG (( DEBUG_INFO,

+            "DataSource starting\r\n" ));

+

+  //

+  //  Validate the command line

+  //

+  if ( 2 > Argc ) {

+    Print ( L"%s  <remote IP address> [Use TCP]\r\n", Argv[0] );

+    return -1;

+  }

+

+  //

+  //  Determine if TCP should be used

+  //

+  bTcp4 = (BOOLEAN)( 2 < Argc );

+

+  //

+  //  Determine the support routines

+  //

+  if ( bTcp4 ) {

+    pOpen = Tcp4Open;

+    pClose = Tcp4Close;

+    bTcp4Connecting = TRUE;

+  }

+  else {

+    pOpen = SocketOpen;

+    pClose = SocketClose;

+  }

+

+  //

+  //  Use for/break instead of goto

+  //

+  for ( ; ; ) {

+    //

+    //  No bytes sent so far

+    //

+    TotalBytesSent = 0;

+    Samples = 0;

+    memset ( &BytesSent, 0, sizeof ( BytesSent ));

+

+    //

+    //  Get the IP address

+    //

+    pRemoteHost = Argv[1];

+    Status = IpAddress ( );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Create the timer

+    //

+    bTick = TRUE;

+    Status = TimerCreate ( );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Loop forever abusing the specified system

+    //

+    do {

+      //

+      //  Start a timer to perform connection polling and display updates

+      //

+      Status = TimerStart ( 2 * 1000 );

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+

+      //

+      //  Open the network connection and send the data

+      //

+      Status = pOpen ( );

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+

+      //

+      //  Done with the network connection

+      //

+      Status = pClose ( );

+    } while ( !EFI_ERROR ( Status ));

+

+    //

+    //  Close the network connection if necessary

+    //

+    pClose ( );

+

+    //

+    //  All done

+    //

+    break;

+  }

+

+  //

+  //  Stop the timer if necessary

+  //

+  TimerStop ( );

+  TimerDestroy ( );

+

+  //

+  //  Return the operation status

+  //

+  DEBUG (( DEBUG_INFO,

+            "DataSource exiting, Status: %r\r\n",

+            Status ));

+  return Status;

+}

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/DataSource/DataSource.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/DataSource/DataSource.inf
new file mode 100644
index 0000000..d088177
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/DataSource/DataSource.inf
@@ -0,0 +1,64 @@
+## @file

+#  DataSource Application

+#

+#  Copyright (c) 2011-2012, Intel Corporation

+#  All rights reserved. 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.php

+#

+#  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                    = 0x00010005

+  BASE_NAME                      = DataSource

+  FILE_GUID                      = 30EB0F26-FC0A-4fd2-B9C9-751EA2BB1980

+  MODULE_TYPE                    = UEFI_APPLICATION

+  VERSION_STRING                 = 1.0

+  ENTRY_POINT                    = ShellCEntryLib

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  DataSource.c

+

+

+[Pcd]

+  gAppPkgTokenSpaceGuid.DataSource_Port

+

+

+[Packages]

+  AppPkg/AppPkg.dec

+  MdePkg/MdePkg.dec

+  ShellPkg/ShellPkg.dec

+  StdLib/StdLib.dec

+

+

+[LibraryClasses]

+  BaseMemoryLib

+  BsdSocketLib

+  EfiSocketLib

+  DebugLib

+  LibC

+  ShellCEntryLib

+  UefiBootServicesTableLib

+  UefiLib

+#  UseSocketDxe

+

+[Protocols]

+  gEfiTcp4ProtocolGuid

+  gEfiTcp4ServiceBindingProtocolGuid

+

+[BuildOptions]

+  INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186

+   MSFT:*_*_*_CC_FLAGS = /Od

+    GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable

+

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetAddrInfo/GetAddrInfo.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetAddrInfo/GetAddrInfo.c
new file mode 100644
index 0000000..27da918
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetAddrInfo/GetAddrInfo.c
@@ -0,0 +1,120 @@
+/** @file

+  Test the getaddrinfo API

+

+  Copyright (c) 2011-2012, Intel Corporation

+  All rights reserved. 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.php

+

+  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 <errno.h>

+#include <netdb.h>

+#include <string.h>

+#include <stdio.h>

+#include <Uefi.h>

+#include <unistd.h>

+

+#include <netinet/in.h>

+

+#include <sys/socket.h>

+

+char mBuffer[65536];

+

+

+/**

+  Test the getaddrinfo API

+

+  @param [in] Argc  The number of arguments

+  @param [in] Argv  The argument value array

+

+  @retval  0        The application exited normally.

+  @retval  Other    An error occurred.

+**/

+int

+main (

+  IN int Argc,

+  IN char **Argv

+  )

+{

+  int AppStatus;

+  int Index;

+  int MaxLen;

+  struct addrinfo * pAddrInfo;

+  char * pHostName;

+  struct addrinfo * pInfo;

+  char * pServerName;

+

+  //

+  //  Determine if the host name is specified

+  //

+  AppStatus = 0;

+  if ( 1 == Argc ) {

+    printf ( "%s  <host name>  <server name>\r\n", Argv[0]);

+  }

+  else {

+    //

+    //  Translate the host name

+    //

+    pHostName = Argv[1];

+    pServerName = NULL;

+    if ( 2 < Argc ) {

+      pServerName = Argv[2];

+    }

+    AppStatus = getaddrinfo ( pHostName,

+                              pServerName,

+                              NULL,

+                              &pAddrInfo );

+    if ( 0 != AppStatus ) {

+      printf ( "ERROR - address info not found, errno: %d\r\n", AppStatus );

+    }

+    if ( NULL == pAddrInfo ) {

+      printf ( "ERROR - No address info structure allocated\r\n" );

+    }

+    else {

+      //

+      //  Walk the list of addresses

+      //

+      pInfo = pAddrInfo;

+      while ( NULL != pInfo ) {

+        //

+        //  Display this entry

+        //

+        printf ( "0x%08x: ai_flags\r\n", pInfo->ai_flags );

+        printf ( "0x%08x: ai_family\r\n", pInfo->ai_family );

+        printf ( "0x%08x: ai_socktype\r\n", pInfo->ai_socktype );

+        printf ( "0x%08x: ai_protocol\r\n", pInfo->ai_protocol );

+        printf ( "0x%08x: ai_addrlen\r\n", pInfo->ai_addrlen );

+        printf ( "%s: ai_canonname\r\n", pInfo->ai_canonname );

+        printf ( "      0x%02x: ai_addr->sa_len\r\n", (UINT8)pInfo->ai_addr->sa_len );

+        printf ( "      0x%02x: ai_addr->sa_family\r\n", (UINT8)pInfo->ai_addr->sa_family );

+        MaxLen = pInfo->ai_addr->sa_len;

+        if ( sizeof ( struct sockaddr_in6 ) < MaxLen ) {

+          MaxLen = sizeof ( struct sockaddr_in6 );

+        }

+        for ( Index = 0; ( MaxLen - 2 ) > Index; Index++ ) {

+          printf ( "      0x%02x: ai_addr->sa_data[%02d]\r\n", (UINT8)pInfo->ai_addr->sa_data [ Index ], Index );

+        }

+

+        //

+        //  Set the next entry

+        //

+        pInfo = pInfo->ai_next;

+      }

+

+      //

+      //  Done with this structures

+      //

+      freeaddrinfo ( pAddrInfo );

+    }

+  }

+

+  //

+  //  All done

+  //

+  return AppStatus;

+}

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetAddrInfo/GetAddrInfo.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetAddrInfo/GetAddrInfo.inf
new file mode 100644
index 0000000..bcfb985
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetAddrInfo/GetAddrInfo.inf
@@ -0,0 +1,56 @@
+## @file

+#  GetAddrInfo Application

+#

+#  Copyright (c) 2011-2012, Intel Corporation

+#  All rights reserved. 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.php

+#

+#  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                    = 0x00010005

+  BASE_NAME                      = GetAddrInfo

+  FILE_GUID                      = 4C26DF71-EBE7-4dea-B5E2-0B5980433908

+  MODULE_TYPE                    = UEFI_APPLICATION

+  VERSION_STRING                 = 1.0

+  ENTRY_POINT                    = ShellCEntryLib

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  GetAddrInfo.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+  ShellPkg/ShellPkg.dec

+  StdLib/StdLib.dec

+

+

+[LibraryClasses]

+  BaseMemoryLib

+  BsdSocketLib

+  DevMedia

+  EfiSocketLib

+  LibC

+  LibMath

+  LibNetUtil

+  ShellCEntryLib

+  UefiBootServicesTableLib

+#  UseSocketDxe

+

+[BuildOptions]

+  INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186

+   MSFT:*_*_*_CC_FLAGS = /Od

+    GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable

+

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetHostByAddr/GetHostByAddr.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetHostByAddr/GetHostByAddr.c
new file mode 100644
index 0000000..c096f43
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetHostByAddr/GetHostByAddr.c
@@ -0,0 +1,131 @@
+/** @file

+  Translate the port number into a service name

+

+  Copyright (c) 2011 - 2012, 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.php

+

+  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 <errno.h>

+#include <netdb.h>

+#include <stdio.h>

+#include <string.h>

+#include <Uefi.h>

+#include <unistd.h>

+

+#include <arpa/nameser.h>

+#include <arpa/nameser_compat.h>

+

+#include <Library/DebugLib.h>

+#include <Library/UefiLib.h>

+

+#include <sys/socket.h>

+

+/**

+  Translate the IP address into a host name

+

+  @param[in] Argc   The number of arguments

+  @param[in] Argv   The argument value array

+

+  @retval  0        The application exited normally.

+  @retval  Other    An error occurred.

+**/

+int

+main (

+  IN int Argc,

+  IN char **Argv

+  )

+{

+  UINTN Index;

+  UINT8 IpAddress[4];

+  struct hostent * pHost;

+  UINT8 * pIpAddress;

+  char ** ppName;

+  UINT32 RemoteAddress[4];

+

+  //

+  //  Determine if the IPv4 address is specified

+  //

+  if (( 2 != Argc )

+    || ( 4 != sscanf ( Argv[1],

+                       "%d.%d.%d.%d",

+                       &RemoteAddress[0],

+                       &RemoteAddress[1],

+                       &RemoteAddress[2],

+                       &RemoteAddress[3]))

+    || ( 255 < RemoteAddress[0])

+    || ( 255 < RemoteAddress[1])

+    || ( 255 < RemoteAddress[2])

+    || ( 255 < RemoteAddress[3])) {

+    Print ( L"%a  <IPv4 Address>\r\n", Argv[0]);

+  }

+  else {

+    //

+    //  Translate the address into a host name

+    //

+    IpAddress[0] = (UINT8)RemoteAddress[0];

+    IpAddress[1] = (UINT8)RemoteAddress[1];

+    IpAddress[2] = (UINT8)RemoteAddress[2];

+    IpAddress[3] = (UINT8)RemoteAddress[3];

+    pHost = gethostbyaddr ( (const char *)&IpAddress[0], INADDRSZ, AF_INET );

+    if ( NULL == pHost ) {

+      Print ( L"ERROR - host not found, h_errno: %d\r\n", h_errno );

+    }

+    else {

+      pIpAddress = (UINT8 *)pHost->h_addr_list[ 0 ];

+      Print ( L"%d.%d.%d.%d, %a\r\n",

+              pIpAddress[0],

+              pIpAddress[1],

+              pIpAddress[2],

+              pIpAddress[3],

+              pHost->h_name );

+

+      //

+      //  Display the other addresses

+      //

+      for ( Index = 1; NULL != pHost->h_addr_list[Index]; Index++ ) {

+        pIpAddress = (UINT8 *)pHost->h_addr_list[Index];

+        Print ( L"%d.%d.%d.%d\r\n",

+                pIpAddress[0],

+                pIpAddress[1],

+                pIpAddress[2],

+                pIpAddress[3]);

+      }

+

+      //

+      //  Display the list of aliases

+      //

+      ppName = pHost->h_aliases;

+      if (( NULL == ppName ) || ( NULL == *ppName )) {

+        Print ( L"No aliases\r\n" );

+      }

+      else {

+        Print ( L"Aliases: " );

+        while ( NULL != *ppName ) {

+          //

+          //  Display the alias

+          //

+          Print ( L"%a", *ppName );

+

+          //

+          //  Set the next alias

+          //

+          ppName += 1;

+          if ( NULL != *ppName ) {

+            Print ( L", " );

+          }

+        }

+        Print ( L"\r\n" );

+      }

+    }

+  }

+

+  //

+  //  All done

+  //

+  return errno;

+}

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetHostByAddr/GetHostByAddr.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetHostByAddr/GetHostByAddr.inf
new file mode 100644
index 0000000..d164510
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetHostByAddr/GetHostByAddr.inf
@@ -0,0 +1,58 @@
+## @file

+#  GetHostByAddr Application

+#

+#  Copyright (c) 2011-2012, Intel Corporation

+#  All rights reserved. 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.php

+#

+#  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                    = 0x00010005

+  BASE_NAME                      = GetHostByAddr

+  FILE_GUID                      = C31A6189-639A-458b-B040-D7D506CA8F4F

+  MODULE_TYPE                    = UEFI_APPLICATION

+  VERSION_STRING                 = 1.0

+  ENTRY_POINT                    = ShellCEntryLib

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  GetHostByAddr.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+  ShellPkg/ShellPkg.dec

+  StdLib/StdLib.dec

+

+

+[LibraryClasses]

+  BaseMemoryLib

+  BsdSocketLib

+  DebugLib

+  DevMedia

+  EfiSocketLib

+  LibC

+  LibMath

+  LibNetUtil

+  ShellCEntryLib

+  UefiBootServicesTableLib

+  UefiLib

+#  UseSocketDxe

+

+[BuildOptions]

+  INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186

+   MSFT:*_*_*_CC_FLAGS = /Od

+    GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable

+

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetHostByDns/GetHostByDns.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetHostByDns/GetHostByDns.c
new file mode 100644
index 0000000..e87b04f
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetHostByDns/GetHostByDns.c
@@ -0,0 +1,73 @@
+/** @file

+  Translate the host name into an IP address

+

+  Copyright (c) 2011 - 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 that accompanies this distribution.

+  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php.

+

+  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 <errno.h>

+#include <netdb.h>

+#include <string.h>

+#include <Uefi.h>

+#include <unistd.h>

+

+#include <Library/DebugLib.h>

+#include <Library/UefiLib.h>

+

+#include <sys/socket.h>

+

+struct hostent * _gethostbydnsname (const char *, int);

+

+char mBuffer[65536];

+

+

+/** Translate the host name into an IP address

+

+  @param [in] Argc  The number of arguments

+  @param [in] Argv  The argument value array

+

+  @retval  0        The application exited normally.

+  @retval  Other    An error occurred.

+**/

+int

+main (

+  IN int Argc,

+  IN char **Argv

+  )

+{

+  UINT8 * pIpAddress;

+  struct hostent * pHost;

+

+  DEBUG (( DEBUG_INFO,

+            "%a starting\r\n",

+            Argv[0]));

+

+  //  Determine if the host name is specified

+  if ( 1 == Argc ) {

+    Print ( L"%a  <host name>\r\n", Argv[0]);

+  }

+  else {

+    //  Translate the host name

+    pHost = _gethostbydnsname ( Argv[1], AF_INET );

+    if ( NULL == pHost ) {

+      Print ( L"ERROR - host not found, h_errno: %d\r\n", h_errno );

+    }

+    else {

+      pIpAddress = (UINT8 *)pHost->h_addr;

+      Print ( L"%a: Type %d, %d.%d.%d.%d\r\n",

+              pHost->h_name,

+              pHost->h_addrtype,

+              pIpAddress[0],

+              pIpAddress[1],

+              pIpAddress[2],

+              pIpAddress[3]);

+    }

+  }

+  //  All done

+  return errno;

+}

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetHostByDns/GetHostByDns.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetHostByDns/GetHostByDns.inf
new file mode 100644
index 0000000..9856578
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetHostByDns/GetHostByDns.inf
@@ -0,0 +1,58 @@
+## @file

+#  GetHostByDns Application

+#

+#  Copyright (c) 2011-2012, Intel Corporation

+#  All rights reserved. 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.php

+#

+#  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                    = 0x00010005

+  BASE_NAME                      = GetHostByDns

+  FILE_GUID                      = 3698D2B0-E727-4537-A636-A8770736ABFB

+  MODULE_TYPE                    = UEFI_APPLICATION

+  VERSION_STRING                 = 1.0

+  ENTRY_POINT                    = ShellCEntryLib

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  GetHostByDns.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+  ShellPkg/ShellPkg.dec

+  StdLib/StdLib.dec

+

+

+[LibraryClasses]

+  BaseMemoryLib

+  BsdSocketLib

+  DebugLib

+  DevMedia

+  EfiSocketLib

+  LibC

+  LibMath

+  LibNetUtil

+  ShellCEntryLib

+  UefiBootServicesTableLib

+  UefiLib

+#  UseSocketDxe

+

+[BuildOptions]

+  INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186

+   MSFT:*_*_*_CC_FLAGS = /Od

+    GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable

+

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetHostByName/GetHostByName.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetHostByName/GetHostByName.c
new file mode 100644
index 0000000..4d4fe54
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetHostByName/GetHostByName.c
@@ -0,0 +1,107 @@
+/** @file

+  Translate the host name into an IP address

+

+  Copyright (c) 2011 - 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 that accompanies this distribution.

+  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php.

+

+  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 <errno.h>

+#include <netdb.h>

+#include <string.h>

+#include <Uefi.h>

+#include <unistd.h>

+

+#include <Library/DebugLib.h>

+#include <Library/UefiLib.h>

+

+#include <sys/socket.h>

+

+char mBuffer[65536];

+

+

+/** Translate the host name into an IP address

+

+  @param[in]  Argc  The number of arguments

+  @param[in]  Argv  The argument value array

+

+  @retval  0        The application exited normally.

+  @retval  Other    An error occurred.

+**/

+int

+main (

+  IN int Argc,

+  IN char **Argv

+  )

+{

+  UINTN Index;

+  struct hostent * pHost;

+  UINT8 * pIpAddress;

+  char ** ppName;

+

+  DEBUG (( DEBUG_INFO,

+            "%a starting\r\n",

+            Argv[0]));

+

+  //  Determine if the host name is specified

+  if ( 1 == Argc ) {

+    Print ( L"%a  <host name>\r\n", Argv[0]);

+  }

+  else {

+    //  Translate the host name

+    pHost = gethostbyname ( Argv[1]);

+    if ( NULL == pHost ) {

+      Print ( L"ERROR - host not found, h_errno: %d\r\n", h_errno );

+    }

+    else {

+      pIpAddress = (UINT8 *)pHost->h_addr;

+      Print ( L"%d.%d.%d.%d, Type %d, %a\r\n",

+              pIpAddress[0],

+              pIpAddress[1],

+              pIpAddress[2],

+              pIpAddress[3],

+              pHost->h_addrtype,

+              pHost->h_name );

+

+      //  Display the other addresses

+      for ( Index = 1; NULL != pHost->h_addr_list[Index]; Index++ ) {

+        pIpAddress = (UINT8 *)pHost->h_addr_list[Index];

+        Print ( L"%d.%d.%d.%d\r\n",

+                pIpAddress[0],

+                pIpAddress[1],

+                pIpAddress[2],

+                pIpAddress[3]);

+      }

+

+      //  Display the list of aliases

+      ppName = pHost->h_aliases;

+      if (( NULL == ppName ) || ( NULL == *ppName )) {

+        Print ( L"No aliases\r\n" );

+      }

+      else {

+        Print ( L"Aliases: " );

+        while ( NULL != *ppName ) {

+          //

+          //  Display the alias

+          //

+          Print ( L"%a", *ppName );

+

+          //

+          //  Set the next alias

+          //

+          ppName += 1;

+          if ( NULL != *ppName ) {

+            Print ( L", " );

+          }

+        }

+        Print ( L"\r\n" );

+      }

+    }

+  }

+  //  All done

+  return errno;

+}

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetHostByName/GetHostByName.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetHostByName/GetHostByName.inf
new file mode 100644
index 0000000..a6f001a
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetHostByName/GetHostByName.inf
@@ -0,0 +1,58 @@
+## @file

+#  GetHostByName Application

+#

+#  Copyright (c) 2011-2012, Intel Corporation

+#  All rights reserved. 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.php

+#

+#  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                    = 0x00010005

+  BASE_NAME                      = GetHostByName

+  FILE_GUID                      = 70FB9CE0-2CB1-4fd7-80EE-AB4B6CF4B43F

+  MODULE_TYPE                    = UEFI_APPLICATION

+  VERSION_STRING                 = 1.0

+  ENTRY_POINT                    = ShellCEntryLib

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  GetHostByName.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+  ShellPkg/ShellPkg.dec

+  StdLib/StdLib.dec

+

+

+[LibraryClasses]

+  BaseMemoryLib

+  BsdSocketLib

+  DebugLib

+  DevMedia

+  EfiSocketLib

+  LibC

+  LibMath

+  LibNetUtil

+  ShellCEntryLib

+  UefiBootServicesTableLib

+  UefiLib

+#  UseSocketDxe

+

+[BuildOptions]

+  INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186

+   MSFT:*_*_*_CC_FLAGS = /Od

+    GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable

+

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetNameInfo/GetNameInfo.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetNameInfo/GetNameInfo.c
new file mode 100644
index 0000000..d6fafde
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetNameInfo/GetNameInfo.c
@@ -0,0 +1,120 @@
+/** @file

+  Test the getnameinfo API

+

+  Copyright (c) 2011-2012, Intel Corporation

+  All rights reserved. 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.php

+

+  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 <errno.h>

+#include <netdb.h>

+#include <string.h>

+#include <stdio.h>

+#include <Uefi.h>

+#include <unistd.h>

+

+#include <netinet/in.h>

+

+#include <sys/socket.h>

+

+char mBuffer[65536];

+char mHostName[256];

+char mServiceName[256];

+

+/**

+  Test the getnameinfo API

+

+  @param [in] Argc  The number of arguments

+  @param [in] Argv  The argument value array

+

+  @retval  0        The application exited normally.

+  @retval  Other    An error occurred.

+**/

+int

+main (

+  IN int Argc,

+  IN char **Argv

+  )

+{

+  int AppStatus;

+  struct addrinfo * pAddrInfo;

+  char * pHostName;

+  struct addrinfo * pInfo;

+  char * pServerName;

+

+  //

+  //  Determine if the host name is specified

+  //

+  AppStatus = 0;

+  if ( 1 == Argc ) {

+    printf ( "%s  <host address>  <server name>\r\n", Argv[0]);

+  }

+  else {

+    //

+    //  Translate the host name

+    //

+    pHostName = Argv[1];

+    pServerName = NULL;

+    if ( 2 < Argc ) {

+      pServerName = Argv[2];

+    }

+    AppStatus = getaddrinfo ( pHostName,

+                              pServerName,

+                              NULL,

+                              &pAddrInfo );

+    if ( 0 != AppStatus ) {

+      printf ( "ERROR - address info not found, errno: %d\r\n", AppStatus );

+    }

+    if ( NULL == pAddrInfo ) {

+      printf ( "ERROR - No address info structure allocated\r\n" );

+    }

+    else {

+      //

+      //  Walk the list of names

+      //

+      pInfo = pAddrInfo;

+      while ( NULL != pInfo ) {

+        //

+        //  Get the name info

+        //

+        AppStatus = getnameinfo ((struct sockaddr *)pInfo->ai_addr,

+                                  pInfo->ai_addrlen,

+                                  &mHostName[0],

+                                  sizeof ( mHostName ),

+                                  &mServiceName[0],

+                                  sizeof ( mServiceName ),

+                                  0 );

+        if ( 0 != AppStatus ) {

+          break;

+        }

+

+        //

+        //  Display this entry

+        //

+        printf ( "%s: HostName\r\n", &mHostName[0]);

+        printf ( "%s: Service Name\r\n", &mServiceName[0]);

+

+        //

+        //  Set the next entry

+        //

+        pInfo = pInfo->ai_next;

+      }

+

+      //

+      //  Done with this structures

+      //

+      freeaddrinfo ( pAddrInfo );

+    }

+  }

+

+  //

+  //  All done

+  //

+  return AppStatus;

+}

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetNameInfo/GetNameInfo.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetNameInfo/GetNameInfo.inf
new file mode 100644
index 0000000..87f8910
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetNameInfo/GetNameInfo.inf
@@ -0,0 +1,56 @@
+## @file

+#  GetNameInfo Application

+#

+#  Copyright (c) 2011-2012, Intel Corporation

+#  All rights reserved. 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.php

+#

+#  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                    = 0x00010005

+  BASE_NAME                      = GetNameInfo

+  FILE_GUID                      = 553087F6-BAAC-4d7f-97B4-31D8179AAE15

+  MODULE_TYPE                    = UEFI_APPLICATION

+  VERSION_STRING                 = 1.0

+  ENTRY_POINT                    = ShellCEntryLib

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  GetNameInfo.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+  ShellPkg/ShellPkg.dec

+  StdLib/StdLib.dec

+

+

+[LibraryClasses]

+  BaseMemoryLib

+  BsdSocketLib

+  DevMedia

+  EfiSocketLib

+  LibC

+  LibMath

+  LibNetUtil

+  ShellCEntryLib

+  UefiBootServicesTableLib

+#  UseSocketDxe

+

+[BuildOptions]

+  INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186

+   MSFT:*_*_*_CC_FLAGS = /Od

+    GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable

+

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetNetByAddr/GetNetByAddr.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetNetByAddr/GetNetByAddr.c
new file mode 100644
index 0000000..156aa2b
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetNetByAddr/GetNetByAddr.c
@@ -0,0 +1,89 @@
+/** @file

+  Translate the IPv4 address into a network name

+

+  Copyright (c) 2011-2012, Intel Corporation

+  All rights reserved. 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.php

+

+  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 <errno.h>

+#include <netdb.h>

+#include <stdio.h>

+#include <string.h>

+#include <Uefi.h>

+#include <unistd.h>

+

+#include <Library/DebugLib.h>

+#include <Library/UefiLib.h>

+

+#include <sys/socket.h>

+

+/**

+  Translate the IPv4 address into a network name

+

+  @param [in] Argc  The number of arguments

+  @param [in] Argv  The argument value array

+

+  @retval  0        The application exited normally.

+  @retval  Other    An error occurred.

+**/

+int

+main (

+  IN int Argc,

+  IN char **Argv

+  )

+{

+  UINT32 RemoteAddress[4];

+  UINT8 IpAddress[4];

+  struct netent * pNetwork;

+  

+  //

+  //  Determine if the IPv4 address is specified

+  //

+  if (( 2 != Argc )

+    || ( 4 != sscanf ( Argv[1],

+                       "%d.%d.%d.%d",

+                       &RemoteAddress[0],

+                       &RemoteAddress[1],

+                       &RemoteAddress[2],

+                       &RemoteAddress[3]))

+    || ( 255 < RemoteAddress[0])

+    || ( 255 < RemoteAddress[1])

+    || ( 255 < RemoteAddress[2])

+    || ( 255 < RemoteAddress[3])) {

+    Print ( L"%a  <IPv4 Address>\r\n", Argv[0]);

+  }

+  else {

+    //

+    //  Translate the address into a network name

+    //

+    IpAddress[0] = (UINT8)RemoteAddress[0];

+    IpAddress[1] = (UINT8)RemoteAddress[1];

+    IpAddress[2] = (UINT8)RemoteAddress[2];

+    IpAddress[3] = (UINT8)RemoteAddress[3];

+    pNetwork = getnetbyaddr ( *(uint32_t *)&IpAddress[0], AF_INET );

+    if ( NULL == pNetwork ) {

+      Print ( L"ERROR - network not found, errno: %d\r\n", errno );

+    }

+    else {

+      Print ( L"%a: %d.%d.%d.%d, 0x%08x\r\n",

+              pNetwork->n_name,

+              IpAddress[0],

+              IpAddress[1],

+              IpAddress[2],

+              IpAddress[3],

+              pNetwork->n_net );

+    }

+  }

+  

+  //

+  //  All done

+  //

+  return errno;

+}

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetNetByAddr/GetNetByAddr.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetNetByAddr/GetNetByAddr.inf
new file mode 100644
index 0000000..f1b3954
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetNetByAddr/GetNetByAddr.inf
@@ -0,0 +1,58 @@
+## @file

+#  GetNetByAddr Application

+#

+#  Copyright (c) 2011-2012, Intel Corporation

+#  All rights reserved. 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.php

+#

+#  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                    = 0x00010005

+  BASE_NAME                      = GetNetByAddr

+  FILE_GUID                      = 22198FD5-4835-4842-BF31-EB957C7DD70D

+  MODULE_TYPE                    = UEFI_APPLICATION

+  VERSION_STRING                 = 1.0

+  ENTRY_POINT                    = ShellCEntryLib

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  GetNetByAddr.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+  ShellPkg/ShellPkg.dec

+  StdLib/StdLib.dec

+

+

+[LibraryClasses]

+  BaseMemoryLib

+  BsdSocketLib

+  DebugLib

+  DevMedia

+  EfiSocketLib

+  LibC

+  LibMath

+  LibNetUtil

+  ShellCEntryLib

+  UefiBootServicesTableLib

+  UefiLib

+#  UseSocketDxe

+

+[BuildOptions]

+  INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186

+   MSFT:*_*_*_CC_FLAGS = /Od

+    GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable

+

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetNetByName/GetNetByName.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetNetByName/GetNetByName.c
new file mode 100644
index 0000000..7ce741c
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetNetByName/GetNetByName.c
@@ -0,0 +1,71 @@
+/** @file

+  Translate the network name into an IP address

+

+  Copyright (c) 2011 - 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 that accompanies this distribution.

+  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php.

+

+  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 <errno.h>

+#include <netdb.h>

+#include <string.h>

+#include <Uefi.h>

+#include <unistd.h>

+

+#include <Library/DebugLib.h>

+#include <Library/UefiLib.h>

+

+#include <sys/socket.h>

+

+char mBuffer[65536];

+

+

+/** Translate the network name into an IP address

+

+  @param[in]  Argc  The number of arguments

+  @param[in]  Argv  The argument value array

+

+  @retval  0        The application exited normally.

+  @retval  Other    An error occurred.

+**/

+int

+main (

+  IN int Argc,

+  IN char **Argv

+  )

+{

+  UINT8 * pIpAddress;

+  struct netent * pNetwork;

+

+  DEBUG (( DEBUG_INFO,

+            "%a starting\r\n",

+            Argv[0]));

+

+  //  Determine if the network name is specified

+  if ( 1 == Argc ) {

+    Print ( L"%a  <network name>\r\n", Argv[0]);

+  }

+  else {

+    //  Translate the net name

+    pNetwork = getnetbyname ( Argv[1]);

+    if ( NULL == pNetwork ) {

+      Print ( L"ERROR - network not found, errno: %d\r\n", errno );

+    }

+    else {

+      pIpAddress = (UINT8 *)(UINTN)&pNetwork->n_net;

+      Print ( L"%a: Type %d, %d.%d.%d.%d\r\n",

+              pNetwork->n_name,

+              pNetwork->n_addrtype,

+              pIpAddress[0],

+              pIpAddress[1],

+              pIpAddress[2],

+              pIpAddress[3]);

+    }

+  }

+  //  All done

+  return errno;

+}

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetNetByName/GetNetByName.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetNetByName/GetNetByName.inf
new file mode 100644
index 0000000..bfb1cd6
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetNetByName/GetNetByName.inf
@@ -0,0 +1,58 @@
+## @file

+#  GetNetByName Application

+#

+#  Copyright (c) 2011-2012, Intel Corporation

+#  All rights reserved. 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.php

+#

+#  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                    = 0x00010005

+  BASE_NAME                      = GetNetByName

+  FILE_GUID                      = DAF7B0E6-32DE-4619-B63A-2B9173A75B14

+  MODULE_TYPE                    = UEFI_APPLICATION

+  VERSION_STRING                 = 1.0

+  ENTRY_POINT                    = ShellCEntryLib

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  GetNetByName.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+  ShellPkg/ShellPkg.dec

+  StdLib/StdLib.dec

+

+

+[LibraryClasses]

+  BaseMemoryLib

+  BsdSocketLib

+  DebugLib

+  DevMedia

+  EfiSocketLib

+  LibC

+  LibMath

+  LibNetUtil

+  ShellCEntryLib

+  UefiBootServicesTableLib

+  UefiLib

+#  UseSocketDxe

+

+[BuildOptions]

+  INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186

+   MSFT:*_*_*_CC_FLAGS = /Od

+    GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable

+

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetServByName/GetServByName.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetServByName/GetServByName.c
new file mode 100644
index 0000000..dede76b
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetServByName/GetServByName.c
@@ -0,0 +1,64 @@
+/** @file

+  Translate the service name into a port number

+

+  Copyright (c) 2011 - 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 that accompanies this distribution.

+  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php.

+

+  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 <errno.h>

+#include <netdb.h>

+#include <string.h>

+#include <Uefi.h>

+#include <unistd.h>

+

+#include <Library/DebugLib.h>

+#include <Library/UefiLib.h>

+

+#include <sys/socket.h>

+

+char mBuffer[65536];

+

+

+/** Translate the service name into a port number

+

+  @param[in]  Argc  The number of arguments

+  @param[in]  Argv  The argument value array

+

+  @retval  0        The application exited normally.

+  @retval  Other    An error occurred.

+**/

+int

+main (

+  IN int Argc,

+  IN char **Argv

+  )

+{

+  int PortNumber;

+  struct servent * pService;

+

+  //  Determine if the service name is specified

+  if ( 1 == Argc ) {

+    Print ( L"%a  <service name>\r\n", Argv[0]);

+  }

+  else {

+    //  Translate the service name

+    pService = getservbyname ( Argv[1], NULL );

+    if ( NULL == pService ) {

+      Print ( L"ERROR - service not found, errno: %d\r\n", errno );

+    }

+    else {

+      PortNumber = htons ( pService->s_port );

+      Print ( L"%a: %d, %a\r\n",

+              pService->s_name,

+              PortNumber,

+              pService->s_proto );

+    }

+  }

+  //  All done

+  return errno;

+}

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetServByName/GetServByName.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetServByName/GetServByName.inf
new file mode 100644
index 0000000..1b66e50
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetServByName/GetServByName.inf
@@ -0,0 +1,58 @@
+## @file

+#  GetServByName Application

+#

+#  Copyright (c) 2011-2012, Intel Corporation

+#  All rights reserved. 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.php

+#

+#  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                    = 0x00010005

+  BASE_NAME                      = GetServByName

+  FILE_GUID                      = 5D1F3F9E-8CEE-4299-93C2-4C64EBB58977

+  MODULE_TYPE                    = UEFI_APPLICATION

+  VERSION_STRING                 = 1.0

+  ENTRY_POINT                    = ShellCEntryLib

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  GetServByName.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+  ShellPkg/ShellPkg.dec

+  StdLib/StdLib.dec

+

+

+[LibraryClasses]

+  BaseMemoryLib

+  BsdSocketLib

+  DebugLib

+  DevMedia

+  EfiSocketLib

+  LibC

+  LibMath

+  LibNetUtil

+  ShellCEntryLib

+  UefiBootServicesTableLib

+  UefiLib

+#  UseSocketDxe

+

+[BuildOptions]

+  INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186

+   MSFT:*_*_*_CC_FLAGS = /Od

+    GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable

+

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetServByPort/GetServByPort.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetServByPort/GetServByPort.c
new file mode 100644
index 0000000..69441e1
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetServByPort/GetServByPort.c
@@ -0,0 +1,65 @@
+/** @file

+  Translate the port number into a service name

+

+  Copyright (c) 2011 - 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 that accompanies this distribution.

+  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php.

+

+  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 <errno.h>

+#include <netdb.h>

+#include <stdio.h>

+#include <string.h>

+#include <Uefi.h>

+#include <unistd.h>

+

+#include <Library/DebugLib.h>

+#include <Library/UefiLib.h>

+

+#include <sys/socket.h>

+

+char mBuffer[65536];

+

+

+/** Translate the port number into a service name

+

+  @param[in]  Argc  The number of arguments

+  @param[in]  Argv  The argument value array

+

+  @retval  0        The application exited normally.

+  @retval  Other    An error occurred.

+**/

+int

+main (

+  IN int Argc,

+  IN char **Argv

+  )

+{

+  int PortNumber;

+  struct servent * pService;

+

+  //  Determine if the service name is specified

+  if (( 2 != Argc )

+    || ( 1 != sscanf ( Argv[1], "%d", &PortNumber ))) {

+    Print ( L"%a  <port number>\r\n", Argv[0]);

+  }

+  else {

+    //  Translate the port number

+    pService = getservbyport ( htons ( PortNumber ), NULL );

+    if ( NULL == pService ) {

+      Print ( L"ERROR - service not found, errno: %d\r\n", errno );

+    }

+    else {

+      Print ( L"%a: %d, %a\r\n",

+              pService->s_name,

+              PortNumber,

+              pService->s_proto );

+    }

+  }

+  //  All done

+  return errno;

+}

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetServByPort/GetServByPort.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetServByPort/GetServByPort.inf
new file mode 100644
index 0000000..d2a387f
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/GetServByPort/GetServByPort.inf
@@ -0,0 +1,58 @@
+## @file

+#  GetServByPort Application

+#

+#  Copyright (c) 2011-2012, Intel Corporation

+#  All rights reserved. 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.php

+#

+#  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                    = 0x00010005

+  BASE_NAME                      = GetServByPort

+  FILE_GUID                      = 83381B06-2EEA-4cf3-9B5F-D75B9B5C93DE

+  MODULE_TYPE                    = UEFI_APPLICATION

+  VERSION_STRING                 = 1.0

+  ENTRY_POINT                    = ShellCEntryLib

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  GetServByPort.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+  ShellPkg/ShellPkg.dec

+  StdLib/StdLib.dec

+

+

+[LibraryClasses]

+  BaseMemoryLib

+  BsdSocketLib

+  DebugLib

+  DevMedia

+  EfiSocketLib

+  LibC

+  LibMath

+  LibNetUtil

+  ShellCEntryLib

+  UefiBootServicesTableLib

+  UefiLib

+#  UseSocketDxe

+

+[BuildOptions]

+  INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186

+   MSFT:*_*_*_CC_FLAGS = /Od

+    GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable

+

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/Main.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/Main.c
new file mode 100644
index 0000000..b4a37e0
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/Main.c
@@ -0,0 +1,44 @@
+/** @file

+  Out-of-band receive test application

+

+  Copyright (c) 2011-2012, Intel Corporation

+  All rights reserved. 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.php

+

+  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 <OobRx.h>

+

+

+/**

+  Receive out-of-band messages from the remote system.

+

+  @param [in] Argc  The number of arguments

+  @param [in] Argv  The argument value array

+

+  @retval  0        The application exited normally.

+  @retval  Other    An error occurred.

+**/

+int

+main (

+  IN int Argc,

+  IN char **Argv

+  )

+{

+  int RetVal;

+

+  //

+  //  Run the application

+  //

+  RetVal = OobRx ( Argc, Argv );

+

+  //

+  //  Return the operation status

+  //

+  return RetVal;

+}

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/OobRx.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/OobRx.c
new file mode 100644
index 0000000..40d056d
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/OobRx.c
@@ -0,0 +1,253 @@
+/** @file

+  Windows version of the OOB Receive application

+

+  Copyright (c) 2011-2012, Intel Corporation

+  All rights reserved. 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.php

+

+  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 <OobRx.h>

+

+UINT8 mBuffer[65536];

+

+

+/**

+  Run the OOB receive application

+

+  @param [in] ArgC      Argument count

+  @param [in] ArgV      Argument value array

+

+  @retval 0             Successfully operation

+ **/

+int

+OobRx (

+  IN int ArgC,

+  IN char **ArgV

+  )

+{

+  SOCKET a;

+  ssize_t BytesReceived;

+  struct sockaddr_in LocalPort;

+  UINT32 OobInLine;

+  UINT16 PortNumber;

+  struct timeval ReceiveTimeout;

+  struct sockaddr_in RemotePort;

+  socklen_t RemotePortLength;

+  int RetVal;

+  SOCKET s;

+  UINT32 TransmittedBefore;

+  UINT32 TransmittedDuring;

+  UINT32 TransmittedOob;

+  UINT32 TransmittedAfter;

+  UINT32 * pTransmittedBytes;

+

+  //

+  //  Create the socket

+  //

+  s = socket ( AF_INET, SOCK_STREAM, IPPROTO_TCP );

+  if ( -1 == s ) {

+    RetVal = GET_ERRNO;

+    printf ( "ERROR - socket error, errno: %d\r\n", RetVal );

+  }

+  else {

+    //

+    //  Use for/break; instead of goto

+    //

+    for ( ; ; ) {

+      //

+      //  Bind the socket to a known port

+      //

+      PortNumber = OOB_RX_PORT;

+      memset ( &LocalPort, 0, sizeof ( LocalPort ));

+      SIN_LEN ( LocalPort ) = sizeof ( LocalPort );

+      SIN_FAMILY ( LocalPort ) = AF_INET;

+      SIN_ADDR ( LocalPort ) = 0;

+      SIN_PORT ( LocalPort ) = htons ( PortNumber );

+      RetVal = bind ( s,

+                      (struct sockaddr *)&LocalPort,

+                      sizeof ( LocalPort ));

+      if ( -1 == RetVal ) {

+          RetVal = GET_ERRNO;

+          printf ( "ERROR - bind error, errno: %d\r\n", RetVal );

+          break;

+      }

+

+      //

+      //  Make the port available on the server

+      //

+      RetVal = listen ( s, 2 );

+      if ( -1 == RetVal ) {

+        RetVal = GET_ERRNO;

+        printf ( "ERROR - listen error, errno: %d\r\n", RetVal );

+        break;

+      }

+

+      //

+      //  Wait for a connection to the known port

+      //

+      RemotePortLength = sizeof ( RemotePort );

+      a = accept ( s,

+                   (struct sockaddr *)&RemotePort,

+                   &RemotePortLength );

+      if ( -1 == a ) {

+        RetVal = GET_ERRNO;

+        printf ( "ERROR - accept error, errno: %d\r\n", RetVal );

+        break;

+      }

+

+      //

+      //  Use for/break instead of goto

+      //

+      for ( ; ; ) {

+        //

+        //  Set the receive timeout

+        //

+        ReceiveTimeout.tv_sec = 0;

+        ReceiveTimeout.tv_usec = 20 * 1000;

+        RetVal = setsockopt ( a,

+                              SOL_SOCKET,

+                              SO_RCVTIMEO,

+                              (char *)&ReceiveTimeout,

+                              sizeof ( ReceiveTimeout ));

+        if ( -1 == RetVal ) {

+          RetVal = GET_ERRNO;

+          printf ( "ERROR - setsockopt RCVTIMEO error, errno: %d\r\n", RetVal );

+          break;

+        }

+

+        //

+        //  Select the OOB processing

+        //

+        OobInLine = ( 1 < ArgC );

+        RetVal = setsockopt ( s,

+                              SOL_SOCKET,

+                              SO_OOBINLINE,

+                              (char *)&OobInLine,

+                              sizeof ( OobInLine ));

+        if ( -1 == RetVal ) {

+          RetVal = GET_ERRNO;

+          printf ( "ERROR - setsockopt OOBINLINE error, errno: %d\r\n", RetVal );

+          break;

+        }

+        printf ( "%s\r\n", ( 0 != OobInLine ) ? "OOB messages are in-line"

+                                              : "OOB messages move to the head of the queue" );

+

+        //

+        //  Receive data from the remote system

+        //

+        TransmittedBefore = 0;

+        TransmittedOob = 0;

+        TransmittedDuring = 0;

+        TransmittedAfter = 0;

+        pTransmittedBytes = &TransmittedBefore;

+        do {

+          //

+          //  Attempt to receive OOB data

+          //

+          BytesReceived = recv ( a, &mBuffer[0], sizeof ( mBuffer ), MSG_OOB );

+          RetVal = (UINT32)BytesReceived;

+          if ( 0 < BytesReceived ) {

+            //

+            //  Display the received OOB data

+            //

+            printf ( "%5Ld OOB bytes received\r\n", (UINT64)BytesReceived );

+

+            //

+            //  Account for the bytes received

+            //

+            TransmittedOob += RetVal;

+            *pTransmittedBytes += TransmittedAfter;

+            TransmittedAfter = 0;

+            pTransmittedBytes = &TransmittedDuring;

+          }

+          else if ( -1 == BytesReceived ) {

+            //

+            //  Check for connection timeout

+            //

+            RetVal = GET_ERRNO;

+            if ( RX_TIMEOUT_ERROR != RetVal ) {

+              //

+              //  Receive error

+              //

+              printf ( "ERROR - recv OOB error, errno: %d\r\n", RetVal );

+              break;

+            }

+

+            //

+            //  Ignore the timeout

+            //  Try to receive normal data instead

+            //

+            BytesReceived = recv ( a, &mBuffer[0], sizeof ( mBuffer ), 0 );

+            RetVal = (UINT32)BytesReceived;

+            if ( 0 < BytesReceived ) {

+              //

+              //  Display the received data

+              //

+              printf ( "%4Ld bytes received\r\n", (UINT64)BytesReceived );

+

+              //

+              //  Account for the bytes received

+              //

+              TransmittedAfter += RetVal;

+            }

+            else if ( -1 == BytesReceived ) {

+              //

+              //  Check for a timeout

+              //

+              RetVal = GET_ERRNO;

+              if ( RX_TIMEOUT_ERROR != RetVal ) {

+                printf ( "ERROR - recv error, errno: %d\r\n", RetVal );

+                break;

+              }

+            }

+          }

+        } while ( 0 != RetVal );

+

+        //

+        //  Display the bytes received

+        //

+        if ( 0 == RetVal ) {

+          printf ( "Bytes before OOB:  %8d\r\n", TransmittedBefore );

+          if ( 0 != TransmittedDuring ) {

+            printf ( "Bytes during OOB:  %8d\r\n", TransmittedDuring );

+          }

+          printf ( "Out-of-band bytes: %8d\r\n", TransmittedOob );

+          printf ( "Bytes after OOB:   %8d\r\n", TransmittedAfter );

+          printf ( "                   --------\r\n" );

+          printf ( "Total Bytes:       %8d\r\n", TransmittedBefore

+                                                 + TransmittedDuring

+                                                 + TransmittedOob

+                                                 + TransmittedAfter );

+        }

+

+        //

+        //  Test complete

+        //

+        break;

+      }

+

+      //

+      //  Close the test socket

+      //

+      CLOSE_SOCKET ( a );

+      break;

+    }

+

+    //

+    //  Close the socket

+    //

+    CLOSE_SOCKET ( s );

+    printf ( "Socket closed\r\n" );

+  }

+

+  //

+  //  Return the operation status

+  //

+  return RetVal;

+}

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/OobRx.h b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/OobRx.h
new file mode 100644
index 0000000..0920029
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/OobRx.h
@@ -0,0 +1,97 @@
+/** @file

+  Definitions for the OOB Receive application

+

+  Copyright (c) 2011-2012, Intel Corporation

+  All rights reserved. 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.php

+

+  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 _OOB_RX_H_

+#define _OOB_RX_H_

+

+//------------------------------------------------------------------------------

+//  Include Files

+//------------------------------------------------------------------------------

+

+#ifdef  BUILD_FOR_WINDOWS

+//

+//  Build for Windows environment

+//

+

+#include <winsock2.h>

+

+#define CLOSE_SOCKET      closesocket

+#define SIN_ADDR(port)    port.sin_addr.S_un.S_addr

+#define SIN_FAMILY(port)  port.sin_family

+#define SIN_LEN(port)     port.sin_family

+#define SIN_PORT(port)    port.sin_port

+#define GET_ERRNO         WSAGetLastError ( )

+

+#define RX_TIMEOUT_ERROR  WSAETIMEDOUT

+#define ssize_t           int

+#define socklen_t         int

+

+#else   //  BUILD_FOR_WINDOWS

+//

+//  Build for EFI environment

+//

+

+#include <Uefi.h>

+#include <errno.h>

+#include <stdlib.h>

+#include <string.h>

+

+#include <netinet/in.h>

+

+#include <sys/EfiSysCall.h>

+#include <sys/endian.h>

+#include <sys/socket.h>

+#include <sys/time.h>

+

+#define CLOSE_SOCKET      close

+#define SIN_ADDR(port)    port.sin_addr.s_addr

+#define SIN_FAMILY(port)  port.sin_family

+#define SIN_LEN(port)     port.sin_len

+#define SIN_PORT(port)    port.sin_port

+#define SOCKET            int

+#define GET_ERRNO         errno

+#define RX_TIMEOUT_ERROR  ETIMEDOUT

+

+#endif  //  BUILD_FOR_WINDOWS

+

+#include <stdio.h>

+

+//------------------------------------------------------------------------------

+//  Constants

+//------------------------------------------------------------------------------

+

+#define OOB_RX_PORT       12344

+

+//------------------------------------------------------------------------------

+//  API

+//------------------------------------------------------------------------------

+

+/**

+  Run the OOB receive application

+

+  @param [in] ArgC      Argument count

+  @param [in] ArgV      Argument value array

+

+  @retval 0             Successfully operation

+ **/

+

+int

+OobRx (

+  IN int ArgC,

+  IN char **ArgV

+  );

+

+//------------------------------------------------------------------------------

+

+#endif  //  _OOB_RX_H_

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/OobRx.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/OobRx.inf
new file mode 100644
index 0000000..17a4935
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/OobRx.inf
@@ -0,0 +1,57 @@
+## @file

+#  OobRx Application

+#

+#  Copyright (c) 2011-2012, Intel Corporation

+#  All rights reserved. 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.php

+#

+#  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                    = 0x00010005

+  BASE_NAME                      = OobRx

+  FILE_GUID                      = 79DED328-7FCE-4909-9AFD-D66176AF97A6

+  MODULE_TYPE                    = UEFI_APPLICATION

+  VERSION_STRING                 = 1.0

+  ENTRY_POINT                    = ShellCEntryLib

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  Main.c

+  OobRx.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+  ShellPkg/ShellPkg.dec

+  StdLib/StdLib.dec

+

+

+[LibraryClasses]

+  BaseMemoryLib

+  BsdSocketLib

+  DebugLib

+  EfiSocketLib

+  LibC

+  LibMath

+  ShellCEntryLib

+  UefiBootServicesTableLib

+  UefiLib

+#  UseSocketDxe

+

+[BuildOptions]

+  INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186

+   MSFT:*_*_*_CC_FLAGS = /Od

+    GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable

+

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/Windows/OobRx.sln b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/Windows/OobRx.sln
new file mode 100644
index 0000000..f9c7825
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/Windows/OobRx.sln
@@ -0,0 +1,20 @@
+

+Microsoft Visual Studio Solution File, Format Version 9.00

+# Visual Studio 2005

+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OobRx", "OobRx.vcproj", "{FA34A77A-5034-4065-B4BD-B74984DEB2F7}"

+EndProject

+Global

+	GlobalSection(SolutionConfigurationPlatforms) = preSolution

+		Debug|Win32 = Debug|Win32

+		Release|Win32 = Release|Win32

+	EndGlobalSection

+	GlobalSection(ProjectConfigurationPlatforms) = postSolution

+		{FA34A77A-5034-4065-B4BD-B74984DEB2F7}.Debug|Win32.ActiveCfg = Debug|Win32

+		{FA34A77A-5034-4065-B4BD-B74984DEB2F7}.Debug|Win32.Build.0 = Debug|Win32

+		{FA34A77A-5034-4065-B4BD-B74984DEB2F7}.Release|Win32.ActiveCfg = Release|Win32

+		{FA34A77A-5034-4065-B4BD-B74984DEB2F7}.Release|Win32.Build.0 = Release|Win32

+	EndGlobalSection

+	GlobalSection(SolutionProperties) = preSolution

+		HideSolutionNode = FALSE

+	EndGlobalSection

+EndGlobal

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/Windows/OobRx.suo b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/Windows/OobRx.suo
new file mode 100644
index 0000000..025aa47
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/Windows/OobRx.suo
Binary files differ
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/Windows/OobRx.vcproj b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/Windows/OobRx.vcproj
new file mode 100644
index 0000000..e5ca534
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/Windows/OobRx.vcproj
@@ -0,0 +1,211 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="8.00"

+	Name="OobRx"

+	ProjectGUID="{FA34A77A-5034-4065-B4BD-B74984DEB2F7}"

+	RootNamespace="OobRx"

+	Keyword="Win32Proj"

+	>

+	<Platforms>

+		<Platform

+			Name="Win32"

+		/>

+	</Platforms>

+	<ToolFiles>

+	</ToolFiles>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"

+			IntermediateDirectory="$(ConfigurationName)"

+			ConfigurationType="1"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories=".."

+				PreprocessorDefinitions="BUILD_FOR_WINDOWS"

+				MinimalRebuild="true"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="3"

+				UsePrecompiledHeader="0"

+				BrowseInformation="1"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="4"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="ws2_32.lib"

+				LinkIncremental="2"

+				GenerateDebugInformation="true"

+				SubSystem="1"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"

+			IntermediateDirectory="$(ConfigurationName)"

+			ConfigurationType="1"

+			CharacterSet="1"

+			WholeProgramOptimization="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories=".."

+				PreprocessorDefinitions="BUILD_FOR_WINDOWS"

+				RuntimeLibrary="2"

+				UsePrecompiledHeader="0"

+				BrowseInformation="1"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="ws2_32.lib"

+				LinkIncremental="1"

+				GenerateDebugInformation="true"

+				SubSystem="1"

+				OptimizeReferences="2"

+				EnableCOMDATFolding="2"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+	</Configurations>

+	<References>

+	</References>

+	<Files>

+		<Filter

+			Name="Source Files"

+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"

+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"

+			>

+			<File

+				RelativePath=".\main.c"

+				>

+			</File>

+			<File

+				RelativePath="..\OobRx.c"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Header Files"

+			Filter="h;hpp;hxx;hm;inl;inc;xsd"

+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"

+			>

+			<File

+				RelativePath="..\OobRx.h"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Resource Files"

+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"

+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"

+			>

+		</Filter>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/Windows/main.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/Windows/main.c
new file mode 100644
index 0000000..afae5da
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobRx/Windows/main.c
@@ -0,0 +1,56 @@
+/** @file

+  Windows version of the OOB Receive application

+

+  Copyright (c) 2011-2012, Intel Corporation

+  All rights reserved. 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.php

+

+  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 <OobRx.h>

+

+

+/**

+  Receive out-of-band messages from the remote system.

+

+  @param [in] argc  The number of arguments

+  @param [in] argv  The argument value array

+

+  @retval  0        The application exited normally.

+  @retval  Other    An error occurred.

+**/

+int

+main(

+  int argc,

+  char ** argv

+  )

+{

+  int RetVal;

+  WSADATA WsaData;

+

+  //

+  //  Initialize the WinSock layer

+  //

+  RetVal = WSAStartup ( MAKEWORD ( 2, 2 ), &WsaData );

+  if ( 0 == RetVal ) {

+    //

+    //  Start the application

+    //

+    RetVal = OobRx ( argc, argv );

+

+    //

+    //  Done with the WinSock layer

+    //

+    WSACleanup ( );

+  }

+

+  //

+  //  Return the final result

+  //

+  return RetVal;  

+}

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/Main.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/Main.c
new file mode 100644
index 0000000..5b6ab02
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/Main.c
@@ -0,0 +1,44 @@
+/** @file

+  Out-of-band transmit test application

+

+  Copyright (c) 2011-2012, Intel Corporation

+  All rights reserved. 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.php

+

+  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 <OobTx.h>

+

+

+/**

+  Transmit out-of-band messages to the remote system.

+

+  @param [in] Argc  The number of arguments

+  @param [in] Argv  The argument value array

+

+  @retval  0        The application exited normally.

+  @retval  Other    An error occurred.

+**/

+int

+main (

+  IN int Argc,

+  IN char **Argv

+  )

+{

+  int RetVal;

+

+  //

+  //  Run the application

+  //

+  RetVal = OobTx ( Argc, Argv );

+

+  //

+  //  Return the operation status

+  //

+  return RetVal;

+}

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/OobTx.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/OobTx.c
new file mode 100644
index 0000000..545e5f4
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/OobTx.c
@@ -0,0 +1,248 @@
+/** @file

+  Windows version of the OOB Transmit application

+

+  Copyright (c) 2011-2012, Intel Corporation

+  All rights reserved. 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.php

+

+  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 <OobTx.h>

+

+UINT8 mBuffer[8192];

+UINT8 mOob[512];

+

+/**

+  Transmit out-of-band messages to the remote system.

+

+  @param [in] ArgC        Argument count

+  @param [in] ArgV        Argument value array

+

+  @retval 0               Successfully operation

+ **/

+

+int

+OobTx (

+  IN int ArgC,

+  IN char **ArgV

+  )

+{

+  UINT32 BytesSent;

+  ssize_t BytesTransmitted;

+  UINT32 Index;

+  struct sockaddr_in LocalPort;

+  UINT32 OobInLine;

+  UINT16 PortNumber;

+  UINT32 RemoteAddress[4];

+  struct sockaddr_in RemotePort;

+  int RetVal;

+  UINT32 TransmittedAfter;

+  UINT32 TransmittedBefore;

+  UINT32 TransmittedOob;

+  SOCKET s;

+

+  //

+  //  Create the socket

+  //

+  s = socket ( AF_INET, SOCK_STREAM, IPPROTO_TCP );

+  if ( -1 == s ) {

+    RetVal = GET_ERRNO;

+    printf ( "ERROR - socket error, errno: %d\r\n", RetVal );

+  }

+  else {

+    //

+    //  Use for/break; instead of goto

+    //

+    for ( ; ; ) {

+      //

+      //  Validate the arguments

+      //

+      if (( 2 > ArgC )

+        || ( 4 != sscanf ( ArgV[1],

+                           "%d.%d.%d.%d",

+                           &RemoteAddress[0],

+                           &RemoteAddress[1],

+                           &RemoteAddress[2],

+                           &RemoteAddress[3]))

+          || ( 224 < RemoteAddress[0])

+          || ( 255 < RemoteAddress[1])

+          || ( 255 < RemoteAddress[2])

+          || ( 255 < RemoteAddress[3])

+          || (( 0 == RemoteAddress[0])

+              && ( 0 == RemoteAddress[1])

+              && ( 0 == RemoteAddress[2])

+              && ( 0 == RemoteAddress[3]))) {

+        printf ( "%s  <remote IP address>  [optional: enables in-line OOB]\r\n", ArgV[0]);

+        RetVal = EINVAL;

+        break;

+      }

+

+      //

+      //  Bind the socket to a local port

+      //

+      memset ( &LocalPort, 0, sizeof ( LocalPort ));

+      SIN_LEN ( LocalPort ) = sizeof ( LocalPort );

+      SIN_FAMILY ( LocalPort ) = AF_INET;

+      SIN_ADDR ( LocalPort ) = 0;

+      SIN_PORT ( LocalPort ) = 0;

+      RetVal = bind ( s,

+                      (struct sockaddr *)&LocalPort,

+                      sizeof ( LocalPort ));

+      if ( -1 == RetVal ) {

+        RetVal = GET_ERRNO;

+        printf ( "ERROR - bind error, errno: %d\r\n", RetVal );

+        break;

+      }

+

+      //

+      //  Specify the remote port

+      //

+      PortNumber = OOB_RX_PORT;

+      memset ( &RemotePort, 0, sizeof ( RemotePort ));

+      SIN_LEN ( RemotePort ) = sizeof ( RemotePort );

+      SIN_FAMILY ( RemotePort ) = AF_INET;

+      SIN_ADDR ( RemotePort ) = ( RemoteAddress[3] << 24 )

+                              | ( RemoteAddress[2] << 16 )

+                              | ( RemoteAddress[1] << 8 )

+                              | RemoteAddress[0];

+      SIN_PORT ( RemotePort ) = htons ( PortNumber );

+

+      //

+      //  Connect to the remote server

+      //

+      RetVal = connect ( s, (struct sockaddr *)&RemotePort, sizeof ( RemotePort ));

+      if ( -1 == RetVal ) {

+        RetVal = GET_ERRNO;

+        printf ( "ERROR - connect error, errno: %d\r\n", RetVal );

+        break;

+      }

+

+      //

+      //  Select the OOB processing

+      //

+      OobInLine = ( 2 < ArgC );

+      RetVal = setsockopt ( s,

+                            SOL_SOCKET,

+                            SO_OOBINLINE,

+                            (char *)&OobInLine,

+                            sizeof ( OobInLine ));

+      if ( -1 == RetVal ) {

+        RetVal = GET_ERRNO;

+        printf ( "ERROR - setsockopt OOBINLINE error, errno: %d\r\n", RetVal );

+        break;

+      }

+      printf ( "%s\r\n", ( 0 != OobInLine ) ? "OOB messages are in-line"

+                                            : "OOB messages move to the head of the queue" );

+

+      //

+      //  Initialize the messages

+      //

+      memset ( &mBuffer[0], 0, sizeof ( mBuffer ));

+      memset ( &mOob[0], 0x11, sizeof ( mOob ));

+

+      //

+      //  Send the data before the out-of-band message

+      //

+      TransmittedBefore = 0;

+      for ( Index = 0; TX_MSGS_BEFORE > Index; Index++ ) {

+        BytesSent = 0;

+        do {

+          BytesTransmitted = send ( s,

+                                    &mBuffer[BytesSent],

+                                    sizeof ( mBuffer ) - BytesSent,

+                                    0 );

+          if ( -1 == BytesTransmitted ) {

+            RetVal = GET_ERRNO;

+            printf ( "ERROR - send before error, errno: %d\r\n", RetVal );

+            break;

+          }

+          BytesSent += (UINT32)BytesTransmitted;

+          RetVal = 0;

+        } while ( sizeof ( mBuffer ) > BytesSent );

+        if ( 0 != RetVal ) {

+          break;

+        }

+        TransmittedBefore += BytesSent;

+      }

+      if ( 0 != RetVal ) {

+        break;

+      }

+

+      //

+      //  Send the out-of-band message

+      //

+      BytesSent = 0;

+      do {

+        BytesTransmitted = send ( s,

+                                  &mOob[BytesSent],

+                                  sizeof ( mOob ) - BytesSent,

+                                  MSG_OOB );

+        if ( -1 == BytesTransmitted ) {

+          RetVal = GET_ERRNO;

+          printf ( "ERROR - send OOB error, errno: %d\r\n", RetVal );

+          break;

+        }

+        BytesSent += (UINT32)BytesTransmitted;

+        RetVal = 0;

+      } while ( sizeof ( mOob ) > BytesSent );

+      if ( 0 != RetVal ) {

+        break;

+      }

+      TransmittedOob = BytesSent;

+

+      //

+      //  Send the data after the out-of-band message

+      //

+      TransmittedAfter = 0;

+      for ( Index = 0; TX_MSGS_AFTER > Index; Index++ ) {

+        BytesSent = 0;

+        do {

+          BytesTransmitted = send ( s,

+                                    &mBuffer[BytesSent],

+                                    sizeof ( mBuffer ) - BytesSent,

+                                    0 );

+          if ( -1 == BytesTransmitted ) {

+            RetVal = GET_ERRNO;

+            printf ( "ERROR - send after error, errno: %d\r\n", RetVal );

+            break;

+          }

+          BytesSent += (UINT32)BytesTransmitted;

+          RetVal = 0;

+        } while ( sizeof ( mBuffer ) > BytesSent );

+        if ( 0 != RetVal ) {

+          break;

+        }

+        TransmittedAfter += BytesSent;

+      }

+

+      //

+      //  Test completed successfully

+      //

+      if ( 0 == RetVal ) {

+        printf ( "Bytes before OOB:  %8d\r\n", TransmittedBefore );

+        printf ( "Out-of-band bytes: %8d\r\n", TransmittedOob );

+        printf ( "Bytes after OOB:   %8d\r\n", TransmittedAfter );

+        printf ( "                   --------\r\n" );

+        printf ( "Total Bytes:       %8d\r\n", TransmittedBefore

+                                               + TransmittedOob

+                                               + TransmittedAfter );

+      }

+      break;

+    }

+

+    //

+    //  Close the socket

+    //

+    CLOSE_SOCKET ( s );

+  }

+

+  //

+  //  Return the operation status

+  //

+  return RetVal;

+}

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/OobTx.h b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/OobTx.h
new file mode 100644
index 0000000..e042a13
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/OobTx.h
@@ -0,0 +1,98 @@
+/** @file

+  Definitions for the OOB Transmit application

+

+  Copyright (c) 2011-2012, Intel Corporation

+  All rights reserved. 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.php

+

+  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 _OOB_TX_H_

+#define _OOB_TX_H_

+

+//------------------------------------------------------------------------------

+//  Include Files

+//------------------------------------------------------------------------------

+

+#ifdef  BUILD_FOR_WINDOWS

+//

+//  Build for Windows environment

+//

+

+#include <winsock2.h>

+

+#define CHAR8             char

+#define CLOSE_SOCKET      closesocket

+#define EINVAL            22    //  Invalid argument

+#define GET_ERRNO         WSAGetLastError ( )

+#define SIN_ADDR(port)    port.sin_addr.S_un.S_addr

+#define SIN_FAMILY(port)  port.sin_family

+#define SIN_LEN(port)     port.sin_family

+#define SIN_PORT(port)    port.sin_port

+#define socklen_t         int

+#define ssize_t           int

+

+#else   //  BUILD_FOR_WINDOWS

+//

+//  Build for EFI environment

+//

+

+#include <Uefi.h>

+#include <errno.h>

+#include <stdlib.h>

+#include <string.h>

+

+#include <netinet/in.h>

+

+#include <sys/EfiSysCall.h>

+#include <sys/endian.h>

+#include <sys/socket.h>

+

+#define CLOSE_SOCKET      close

+#define GET_ERRNO         errno

+#define SIN_ADDR(port)    port.sin_addr.s_addr

+#define SIN_FAMILY(port)  port.sin_family

+#define SIN_LEN(port)     port.sin_len

+#define SIN_PORT(port)    port.sin_port

+#define SOCKET            int

+

+#endif  //  BUILD_FOR_WINDOWS

+

+#include <stdio.h>

+

+//------------------------------------------------------------------------------

+//  Constants

+//------------------------------------------------------------------------------

+

+#define OOB_RX_PORT       12344

+

+#define TX_MSGS_BEFORE    32

+#define TX_MSGS_AFTER     8

+

+//------------------------------------------------------------------------------

+//  API

+//------------------------------------------------------------------------------

+

+/**

+  Transmit out-of-band messages to the remote system.

+

+  @param [in] ArgC        Argument count

+  @param [in] ArgV        Argument value array

+

+  @retval 0               Successfully operation

+ **/

+

+int

+OobTx (

+  IN int ArgC,

+  IN char **ArgV

+  );

+

+//------------------------------------------------------------------------------

+

+#endif  //  _OOB_TX_H_

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/OobTx.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/OobTx.inf
new file mode 100644
index 0000000..f12e389
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/OobTx.inf
@@ -0,0 +1,57 @@
+## @file

+#  OobTx Application

+#

+#  Copyright (c) 2011-2012, Intel Corporation

+#  All rights reserved. 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.php

+#

+#  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                    = 0x00010005

+  BASE_NAME                      = OobTx

+  FILE_GUID                      = EB740091-A494-44d7-8D96-C192F95A6394

+  MODULE_TYPE                    = UEFI_APPLICATION

+  VERSION_STRING                 = 1.0

+  ENTRY_POINT                    = ShellCEntryLib

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  Main.c

+  OobTx.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+  ShellPkg/ShellPkg.dec

+  StdLib/StdLib.dec

+

+

+[LibraryClasses]

+  BaseMemoryLib

+  BsdSocketLib

+  DebugLib

+  EfiSocketLib

+  LibC

+  LibMath

+  ShellCEntryLib

+  UefiBootServicesTableLib

+  UefiLib

+#  UseSocketDxe

+

+[BuildOptions]

+  INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186

+   MSFT:*_*_*_CC_FLAGS = /Od

+    GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable

+

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/Windows/OobTx.sln b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/Windows/OobTx.sln
new file mode 100644
index 0000000..e16b5fd
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/Windows/OobTx.sln
@@ -0,0 +1,20 @@
+

+Microsoft Visual Studio Solution File, Format Version 9.00

+# Visual Studio 2005

+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OobTx", "OobTx.vcproj", "{C5B91ED2-C2BA-4EE7-A789-F6621CE601B9}"

+EndProject

+Global

+	GlobalSection(SolutionConfigurationPlatforms) = preSolution

+		Debug|Win32 = Debug|Win32

+		Release|Win32 = Release|Win32

+	EndGlobalSection

+	GlobalSection(ProjectConfigurationPlatforms) = postSolution

+		{C5B91ED2-C2BA-4EE7-A789-F6621CE601B9}.Debug|Win32.ActiveCfg = Debug|Win32

+		{C5B91ED2-C2BA-4EE7-A789-F6621CE601B9}.Debug|Win32.Build.0 = Debug|Win32

+		{C5B91ED2-C2BA-4EE7-A789-F6621CE601B9}.Release|Win32.ActiveCfg = Release|Win32

+		{C5B91ED2-C2BA-4EE7-A789-F6621CE601B9}.Release|Win32.Build.0 = Release|Win32

+	EndGlobalSection

+	GlobalSection(SolutionProperties) = preSolution

+		HideSolutionNode = FALSE

+	EndGlobalSection

+EndGlobal

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/Windows/OobTx.suo b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/Windows/OobTx.suo
new file mode 100644
index 0000000..0ded407
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/Windows/OobTx.suo
Binary files differ
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/Windows/OobTx.vcproj b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/Windows/OobTx.vcproj
new file mode 100644
index 0000000..d53149c
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/Windows/OobTx.vcproj
@@ -0,0 +1,211 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="8.00"

+	Name="OobTx"

+	ProjectGUID="{C5B91ED2-C2BA-4EE7-A789-F6621CE601B9}"

+	RootNamespace="OobTx"

+	Keyword="Win32Proj"

+	>

+	<Platforms>

+		<Platform

+			Name="Win32"

+		/>

+	</Platforms>

+	<ToolFiles>

+	</ToolFiles>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"

+			IntermediateDirectory="$(ConfigurationName)"

+			ConfigurationType="1"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories=".."

+				PreprocessorDefinitions="BUILD_FOR_WINDOWS; _CRT_SECURE_NO_DEPRECATE"

+				MinimalRebuild="true"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="3"

+				UsePrecompiledHeader="0"

+				BrowseInformation="1"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="4"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="ws2_32.lib"

+				LinkIncremental="2"

+				GenerateDebugInformation="true"

+				SubSystem="1"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"

+			IntermediateDirectory="$(ConfigurationName)"

+			ConfigurationType="1"

+			CharacterSet="1"

+			WholeProgramOptimization="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories=".."

+				PreprocessorDefinitions="BUILD_FOR_WINDOWS; _CRT_SECURE_NO_DEPRECATE"

+				RuntimeLibrary="2"

+				UsePrecompiledHeader="0"

+				BrowseInformation="1"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="ws2_32.lib"

+				LinkIncremental="1"

+				GenerateDebugInformation="true"

+				SubSystem="1"

+				OptimizeReferences="2"

+				EnableCOMDATFolding="2"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+	</Configurations>

+	<References>

+	</References>

+	<Files>

+		<Filter

+			Name="Source Files"

+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"

+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"

+			>

+			<File

+				RelativePath=".\main.c"

+				>

+			</File>

+			<File

+				RelativePath="..\OobTx.c"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Header Files"

+			Filter="h;hpp;hxx;hm;inl;inc;xsd"

+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"

+			>

+			<File

+				RelativePath="..\OobTx.h"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Resource Files"

+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"

+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"

+			>

+		</Filter>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/Windows/main.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/Windows/main.c
new file mode 100644
index 0000000..dd0f3a2
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/OobTx/Windows/main.c
@@ -0,0 +1,56 @@
+/** @file

+  Windows version of the OOB Transmit application

+

+  Copyright (c) 2011-2012, Intel Corporation

+  All rights reserved. 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.php

+

+  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 <OobTx.h>

+

+

+/**

+  Transmit out-of-band messages to the remote system.

+

+  @param [in] Argc  The number of arguments

+  @param [in] Argv  The argument value array

+

+  @retval  0        The application exited normally.

+  @retval  Other    An error occurred.

+**/

+int

+main(

+  int argc,

+  char ** argv

+  )

+{

+  int RetVal;

+  WSADATA WsaData;

+

+  //

+  //  Initialize the WinSock layer

+  //

+  RetVal = WSAStartup ( MAKEWORD ( 2, 2 ), &WsaData );

+  if ( 0 == RetVal ) {

+    //

+    //  Start the application

+    //

+    RetVal = OobTx ( argc, argv );

+

+    //

+    //  Done with the WinSock layer

+    //

+    WSACleanup ( );

+  }

+

+  //

+  //  Return the final result

+  //

+  return RetVal;  

+}

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/Main.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/Main.c
new file mode 100644
index 0000000..0857b23
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/Main.c
@@ -0,0 +1,44 @@
+/** @file

+  Raw IP4 receive test application

+

+  Copyright (c) 2011-2012, Intel Corporation

+  All rights reserved. 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.php

+

+  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 "RawIp4Rx.h"

+

+

+/**

+  Receive raw datagrams from a remote system.

+

+  @param [in] Argc  The number of arguments

+  @param [in] Argv  The argument value array

+

+  @retval  0        The application exited normally.

+  @retval  Other    An error occurred.

+**/

+int

+main (

+  IN int Argc,

+  IN char **Argv

+  )

+{

+  int RetVal;

+

+  //

+  //  Run the application

+  //

+  RetVal = RawIp4Rx ( Argc, Argv );

+

+  //

+  //  Return the operation status

+  //

+  return RetVal;

+}

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/RawIp4Rx.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/RawIp4Rx.c
new file mode 100644
index 0000000..bce4578
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/RawIp4Rx.c
@@ -0,0 +1,188 @@
+/** @file

+  Raw IP4 receive application

+

+  Copyright (c) 2011-2012, Intel Corporation

+  All rights reserved. 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.php

+

+  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 "RawIp4Rx.h"

+

+UINT8 mBuffer[65536];

+

+

+/**

+  Run the raw IP4 receive application

+

+  @param [in] ArgC      Argument count

+  @param [in] ArgV      Argument value array

+

+  @retval 0             Successfully operation

+ **/

+int

+RawIp4Rx (

+  IN int ArgC,

+  IN char **ArgV

+  )

+{

+  ssize_t BytesReceived;

+  struct sockaddr_in LocalPort;

+  socklen_t LocalPortLength;

+  struct sockaddr_in RemotePort;

+  socklen_t RemotePortLength;

+  int RetVal;

+  SOCKET s;

+  UINT64 TotalBytesReceived;

+

+  //

+  //  Create the socket

+  //

+  s = socket ( AF_INET, SOCK_RAW, RAW_PROTOCOL );

+  if ( -1 == s ) {

+    RetVal = GET_ERRNO;

+    printf ( "ERROR - socket error, errno: %d\r\n", RetVal );

+  }

+  else {

+    //

+    //  Use for/break; instead of goto

+    //

+    for ( ; ; ) {

+      //

+      //  Bind the socket to a known port

+      //

+      memset ( &LocalPort, 0, sizeof ( LocalPort ));

+      SIN_LEN ( LocalPort ) = sizeof ( LocalPort );

+      SIN_FAMILY ( LocalPort ) = AF_INET;

+      SIN_ADDR ( LocalPort ) = 0;

+      SIN_PORT ( LocalPort ) = 0;

+      RetVal = bind ( s,

+                      (struct sockaddr *)&LocalPort,

+                      sizeof ( LocalPort ));

+      if ( -1 == RetVal ) {

+          RetVal = GET_ERRNO;

+          printf ( "ERROR - bind error, errno: %d\r\n", RetVal );

+          break;

+      }

+

+      //

+      //  Display the local address and protocol

+      //

+      LocalPortLength = sizeof ( LocalPort );

+      RetVal = getsockname ( s, (struct sockaddr *)&LocalPort, &LocalPortLength );

+      if ( 0 != RetVal ) {

+          RetVal = GET_ERRNO;

+          printf ( "ERROR - getsockname error, errno: %d\r\n", RetVal );

+          break;

+      }

+      printf ( "Local Address: %d.%d.%d.%d, Protocol: %d\r\n",

+               (UINT8)SIN_ADDR ( LocalPort ),

+               (UINT8)( SIN_ADDR ( LocalPort ) >> 8 ),

+               (UINT8)( SIN_ADDR ( LocalPort ) >> 16 ),

+               (UINT8)( SIN_ADDR ( LocalPort ) >> 24 ),

+               RAW_PROTOCOL );

+

+      //

+      //  Use for/break instead of goto

+      //

+      TotalBytesReceived = 0;

+      for ( ; ; ) {

+        //

+        //  Receive data from the remote system

+        //

+        do {

+          //

+          //  Attempt to receive a packet

+          //

+          RemotePortLength = sizeof ( RemotePort );

+          BytesReceived = recvfrom ( s,

+                                     &mBuffer[0],

+                                     sizeof ( mBuffer ),

+                                     0,

+                                     (struct sockaddr *)&RemotePort,

+                                     &RemotePortLength );

+          RetVal = (UINT32)BytesReceived;

+          if ( 0 < BytesReceived ) {

+            //

+            //  Display the received data

+            //

+            printf ( "%4d bytes received from %d.%d.%d.%d:%d\r\n"

+                     "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\r\n"

+                     "%02x %02x %02x %02x\r\n",

+                     (UINT32)BytesReceived,

+                     (UINT8)SIN_ADDR ( RemotePort ),

+                     (UINT8)( SIN_ADDR ( RemotePort ) >> 8 ),

+                     (UINT8)( SIN_ADDR ( RemotePort ) >> 16 ),

+                     (UINT8)( SIN_ADDR ( RemotePort ) >> 24 ),

+                     SIN_PORT ( RemotePort ),

+                     mBuffer[0],

+                     mBuffer[1],

+                     mBuffer[2],

+                     mBuffer[3],

+                     mBuffer[4],

+                     mBuffer[5],

+                     mBuffer[6],

+                     mBuffer[7],

+                     mBuffer[8],

+                     mBuffer[9],

+                     mBuffer[10],

+                     mBuffer[11],

+                     mBuffer[12],

+                     mBuffer[13],

+                     mBuffer[14],

+                     mBuffer[15],

+                     mBuffer[16],

+                     mBuffer[17],

+                     mBuffer[18],

+                     mBuffer[19]);

+            TotalBytesReceived += BytesReceived;

+

+            //

+            //  All done when the correct packet is received

+            //

+            if ( mBuffer[9] == RAW_PROTOCOL ) {

+              break;

+            }

+          }

+          else if ( -1 == BytesReceived ) {

+            //

+            //  Check for a timeout

+            //

+            RetVal = GET_ERRNO;

+            printf ( "ERROR - recv error, errno: %d\r\n", RetVal );

+            break;

+          }

+        } while ( 0 != RetVal );

+

+        //

+        //  Display the bytes received

+        //

+        if ( 0 == RetVal ) {

+          printf ( "Total Bytes Received:  %Ld\r\n", TotalBytesReceived );

+        }

+

+        //

+        //  Test complete

+        //

+        break;

+      }

+      break;

+    }

+

+    //

+    //  Close the socket

+    //

+    CLOSE_SOCKET ( s );

+    printf ( "Socket closed\r\n" );

+  }

+

+  //

+  //  Return the operation status

+  //

+  return RetVal;

+}

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/RawIp4Rx.h b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/RawIp4Rx.h
new file mode 100644
index 0000000..ae8daac
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/RawIp4Rx.h
@@ -0,0 +1,99 @@
+/** @file

+  Definitions for the raw IP4 receive application

+

+  Copyright (c) 2011-2012, Intel Corporation

+  All rights reserved. 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.php

+

+  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 _RAW_IP4_RX_H_

+#define _RAW_IP4_RX_H_

+

+//------------------------------------------------------------------------------

+//  Include Files

+//------------------------------------------------------------------------------

+

+#ifdef  BUILD_FOR_WINDOWS

+//

+//  Build for Windows environment

+//

+

+#include <winsock2.h>

+

+#define CLOSE_SOCKET      closesocket

+#define SIN_ADDR(port)    port.sin_addr.S_un.S_addr

+#define SIN_FAMILY(port)  port.sin_family

+#define SIN_LEN(port)     port.sin_family

+#define SIN_PORT(port)    port.sin_port

+#define GET_ERRNO         WSAGetLastError ( )

+

+#define ssize_t           int

+#define socklen_t         int

+

+#else   //  BUILD_FOR_WINDOWS

+//

+//  Build for EFI environment

+//

+

+#include <Uefi.h>

+#include <errno.h>

+#include <stdlib.h>

+#include <string.h>

+

+#include <netinet/in.h>

+

+#include <sys/EfiSysCall.h>

+#include <sys/endian.h>

+#include <sys/socket.h>

+#include <sys/time.h>

+

+#define CLOSE_SOCKET      close

+#define SIN_ADDR(port)    port.sin_addr.s_addr

+#define SIN_FAMILY(port)  port.sin_family

+#define SIN_LEN(port)     port.sin_len

+#define SIN_PORT(port)    port.sin_port

+#define SOCKET            int

+#define GET_ERRNO         errno

+

+#endif  //  BUILD_FOR_WINDOWS

+

+#include <stdio.h>

+

+//------------------------------------------------------------------------------

+//  Constants

+//------------------------------------------------------------------------------

+

+//

+//  See http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xml

+//  and http://tools.ietf.org/html/rfc3692

+//

+#define RAW_PROTOCOL      253

+

+//------------------------------------------------------------------------------

+//  API

+//------------------------------------------------------------------------------

+

+/**

+  Run the raw IP4 receive application

+

+  @param [in] ArgC      Argument count

+  @param [in] ArgV      Argument value array

+

+  @retval 0             Successfully operation

+ **/

+

+int

+RawIp4Rx (

+  IN int ArgC,

+  IN char **ArgV

+  );

+

+//------------------------------------------------------------------------------

+

+#endif  //  _RAW_IP4_RX_H_

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/RawIp4Rx.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/RawIp4Rx.inf
new file mode 100644
index 0000000..232f050
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/RawIp4Rx.inf
@@ -0,0 +1,57 @@
+## @file

+#  RawIp4 Application

+#

+#  Copyright (c) 2011-2012, Intel Corporation

+#  All rights reserved. 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.php

+#

+#  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                    = 0x00010005

+  BASE_NAME                      = RawIp4Rx

+  FILE_GUID                      = 8D7AE6A9-B490-45e1-8795-C2BEAADC3814

+  MODULE_TYPE                    = UEFI_APPLICATION

+  VERSION_STRING                 = 1.0

+  ENTRY_POINT                    = ShellCEntryLib

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  Main.c

+  RawIp4Rx.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+  ShellPkg/ShellPkg.dec

+  StdLib/StdLib.dec

+

+

+[LibraryClasses]

+  BaseMemoryLib

+  BsdSocketLib

+  DebugLib

+  EfiSocketLib

+  LibC

+  LibMath

+  ShellCEntryLib

+  UefiBootServicesTableLib

+  UefiLib

+#  UseSocketDxe

+

+[BuildOptions]

+  INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186

+   MSFT:*_*_*_CC_FLAGS = /Od

+    GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable

+

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/Windows/RawIp4Rx.sln b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/Windows/RawIp4Rx.sln
new file mode 100644
index 0000000..5c2b797
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/Windows/RawIp4Rx.sln
@@ -0,0 +1,20 @@
+

+Microsoft Visual Studio Solution File, Format Version 9.00

+# Visual Studio 2005

+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RawIp4Rx", "RawIp4Rx.vcproj", "{FAD3909F-E05E-4A2A-9681-7C474EAC5025}"

+EndProject

+Global

+	GlobalSection(SolutionConfigurationPlatforms) = preSolution

+		Debug|Win32 = Debug|Win32

+		Release|Win32 = Release|Win32

+	EndGlobalSection

+	GlobalSection(ProjectConfigurationPlatforms) = postSolution

+		{FAD3909F-E05E-4A2A-9681-7C474EAC5025}.Debug|Win32.ActiveCfg = Debug|Win32

+		{FAD3909F-E05E-4A2A-9681-7C474EAC5025}.Debug|Win32.Build.0 = Debug|Win32

+		{FAD3909F-E05E-4A2A-9681-7C474EAC5025}.Release|Win32.ActiveCfg = Release|Win32

+		{FAD3909F-E05E-4A2A-9681-7C474EAC5025}.Release|Win32.Build.0 = Release|Win32

+	EndGlobalSection

+	GlobalSection(SolutionProperties) = preSolution

+		HideSolutionNode = FALSE

+	EndGlobalSection

+EndGlobal

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/Windows/RawIp4Rx.vcproj b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/Windows/RawIp4Rx.vcproj
new file mode 100644
index 0000000..f0f61c4
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/Windows/RawIp4Rx.vcproj
@@ -0,0 +1,211 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="8.00"

+	Name="RawIp4Rx"

+	ProjectGUID="{FAD3909F-E05E-4A2A-9681-7C474EAC5025}"

+	RootNamespace="RawIp4Rx"

+	Keyword="Win32Proj"

+	>

+	<Platforms>

+		<Platform

+			Name="Win32"

+		/>

+	</Platforms>

+	<ToolFiles>

+	</ToolFiles>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"

+			IntermediateDirectory="$(ConfigurationName)"

+			ConfigurationType="1"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories=".."

+				PreprocessorDefinitions="BUILD_FOR_WINDOWS"

+				MinimalRebuild="true"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="3"

+				UsePrecompiledHeader="0"

+				BrowseInformation="1"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="4"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="ws2_32.lib"

+				LinkIncremental="2"

+				GenerateDebugInformation="true"

+				SubSystem="1"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"

+			IntermediateDirectory="$(ConfigurationName)"

+			ConfigurationType="1"

+			CharacterSet="1"

+			WholeProgramOptimization="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories=".."

+				PreprocessorDefinitions="BUILD_FOR_WINDOWS"

+				RuntimeLibrary="2"

+				UsePrecompiledHeader="0"

+				BrowseInformation="1"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="ws2_32.lib"

+				LinkIncremental="1"

+				GenerateDebugInformation="true"

+				SubSystem="1"

+				OptimizeReferences="2"

+				EnableCOMDATFolding="2"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+	</Configurations>

+	<References>

+	</References>

+	<Files>

+		<Filter

+			Name="Source Files"

+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"

+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"

+			>

+			<File

+				RelativePath=".\main.c"

+				>

+			</File>

+			<File

+				RelativePath="..\RawIp4Rx.c"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Header Files"

+			Filter="h;hpp;hxx;hm;inl;inc;xsd"

+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"

+			>

+			<File

+				RelativePath="..\RawIp4Rx.h"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Resource Files"

+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"

+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"

+			>

+		</Filter>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/Windows/main.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/Windows/main.c
new file mode 100644
index 0000000..530c2d6
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Rx/Windows/main.c
@@ -0,0 +1,61 @@
+/** @file

+  Windows version of the raw IP4 receive application

+

+  Copyright (c) 2011-2012, Intel Corporation

+  All rights reserved. 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.php

+

+  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 <RawIp4Rx.h>

+

+

+/**

+  Receive raw IP4 packets from a remote system.

+

+  Please note that this program must be run with administrator privileges!

+

+  @param [in] argc  The number of arguments

+  @param [in] argv  The argument value array

+

+  @retval  0        The application exited normally.

+  @retval  Other    An error occurred.

+**/

+int

+main(

+  int argc,

+  char ** argv

+  )

+{

+  int RetVal;

+  WSADATA WsaData;

+

+  //

+  //  Initialize the WinSock layer

+  //

+  RetVal = WSAStartup ( MAKEWORD ( 2, 2 ), &WsaData );

+  if ( 0 == RetVal ) {

+    //

+    //  Start the application

+    //

+    RetVal = RawIp4Rx ( argc, argv );

+    if ( WSAEACCES == RetVal ) {

+      printf ( "Requires administrator privileges to run!\r\n" );

+    }

+

+    //

+    //  Done with the WinSock layer

+    //

+    WSACleanup ( );

+  }

+

+  //

+  //  Return the final result

+  //

+  return RetVal;  

+}

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/Main.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/Main.c
new file mode 100644
index 0000000..451193a
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/Main.c
@@ -0,0 +1,44 @@
+/** @file

+  Raw IP4 transmit test application

+

+  Copyright (c) 2011-2012, Intel Corporation

+  All rights reserved. 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.php

+

+  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 "RawIp4Tx.h"

+

+

+/**

+  Transmit raw IP4 packets to the remote system.

+

+  @param [in] Argc  The number of arguments

+  @param [in] Argv  The argument value array

+

+  @retval  0        The application exited normally.

+  @retval  Other    An error occurred.

+**/

+int

+main (

+  IN int Argc,

+  IN char **Argv

+  )

+{

+  int RetVal;

+

+  //

+  //  Run the application

+  //

+  RetVal = RawIp4Tx ( Argc, Argv );

+

+  //

+  //  Return the operation status

+  //

+  return RetVal;

+}

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/RawIp4Tx.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/RawIp4Tx.c
new file mode 100644
index 0000000..f6efbe1
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/RawIp4Tx.c
@@ -0,0 +1,157 @@
+/** @file

+  Raw IP4 transmit application

+

+  Copyright (c) 2011-2012, Intel Corporation

+  All rights reserved. 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.php

+

+  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 "RawIp4Tx.h"

+

+UINT8 mBuffer[1024];

+

+/**

+  Transmit raw IP4 packets to the remote system.

+

+  @param [in] ArgC        Argument count

+  @param [in] ArgV        Argument value array

+

+  @retval 0               Successfully operation

+ **/

+

+int

+RawIp4Tx (

+  IN int ArgC,

+  IN char **ArgV

+  )

+{

+  UINT32 BytesSent;

+  ssize_t BytesTransmitted;

+  struct sockaddr_in LocalPort;

+  UINT32 RemoteAddress[4];

+  struct sockaddr_in RemotePort;

+  int RetVal;

+  UINT32 TotalSent;

+  SOCKET s;

+

+  //

+  //  Create the socket

+  //

+  s = socket ( AF_INET, SOCK_RAW, RAW_PROTOCOL );

+  if ( -1 == s ) {

+    RetVal = GET_ERRNO;

+    printf ( "ERROR - socket error, errno: %d\r\n", RetVal );

+  }

+  else {

+    //

+    //  Use for/break; instead of goto

+    //

+    for ( ; ; ) {

+      //

+      //  Validate the arguments

+      //

+      if (( 2 > ArgC )

+        || ( 4 != sscanf ( ArgV[1],

+                           "%d.%d.%d.%d",

+                           &RemoteAddress[0],

+                           &RemoteAddress[1],

+                           &RemoteAddress[2],

+                           &RemoteAddress[3]))

+          || ( 224 < RemoteAddress[0])

+          || ( 255 < RemoteAddress[1])

+          || ( 255 < RemoteAddress[2])

+          || ( 255 < RemoteAddress[3])

+          || (( 0 == RemoteAddress[0])

+              && ( 0 == RemoteAddress[1])

+              && ( 0 == RemoteAddress[2])

+              && ( 0 == RemoteAddress[3]))) {

+        printf ( "%s  <remote IP address>\r\n", ArgV[0]);

+        RetVal = EINVAL;

+        break;

+      }

+

+      //

+      //  Bind the socket to a local port

+      //

+      memset ( &LocalPort, 0, sizeof ( LocalPort ));

+      SIN_LEN ( LocalPort ) = sizeof ( LocalPort );

+      SIN_FAMILY ( LocalPort ) = AF_INET;

+      SIN_ADDR ( LocalPort ) = 0;

+      SIN_PORT ( LocalPort ) = 0;

+      RetVal = bind ( s,

+                      (struct sockaddr *)&LocalPort,

+                      sizeof ( LocalPort ));

+      if ( -1 == RetVal ) {

+        RetVal = GET_ERRNO;

+        printf ( "ERROR - bind error, errno: %d\r\n", RetVal );

+        break;

+      }

+

+      //

+      //  Specify the remote port

+      //

+      memset ( &RemotePort, 0, sizeof ( RemotePort ));

+      SIN_LEN ( RemotePort ) = sizeof ( RemotePort );

+      SIN_FAMILY ( RemotePort ) = AF_INET;

+      SIN_ADDR ( RemotePort ) = ( RemoteAddress[3] << 24 )

+                              | ( RemoteAddress[2] << 16 )

+                              | ( RemoteAddress[1] << 8 )

+                              | RemoteAddress[0];

+      SIN_PORT ( RemotePort ) = 0;

+

+      //

+      //  Initialize the messages

+      //

+      memset ( &mBuffer[0], 0, sizeof ( mBuffer ));

+

+      //

+      //  Send the data before the out-of-band message

+      //

+      TotalSent = 0;

+      BytesSent = 0;

+      do {

+        BytesTransmitted = sendto ( s,

+                                    &mBuffer[BytesSent],

+                                    sizeof ( mBuffer ) - BytesSent,

+                                    0,

+                                    (struct sockaddr *)&RemotePort,

+                                    sizeof ( RemotePort ));

+        if ( -1 == BytesTransmitted ) {

+          RetVal = GET_ERRNO;

+          printf ( "ERROR - send before error, errno: %d\r\n", RetVal );

+          break;

+        }

+        BytesSent += (UINT32)BytesTransmitted;

+        RetVal = 0;

+      } while ( sizeof ( mBuffer ) > BytesSent );

+      if ( 0 != RetVal ) {

+        break;

+      }

+      TotalSent += BytesSent;

+

+      //

+      //  Test completed successfully

+      //

+      if ( 0 == RetVal ) {

+        printf ( "Bytes sent:  %8d\r\n", TotalSent );

+      }

+      break;

+    }

+

+    //

+    //  Close the socket

+    //

+    CLOSE_SOCKET ( s );

+  }

+

+  //

+  //  Return the operation status

+  //

+  return RetVal;

+}

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/RawIp4Tx.h b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/RawIp4Tx.h
new file mode 100644
index 0000000..2fe2839
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/RawIp4Tx.h
@@ -0,0 +1,99 @@
+/** @file

+  Definitions for the raw IP4 transmit application

+

+  Copyright (c) 2011-2012, Intel Corporation

+  All rights reserved. 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.php

+

+  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 _RAW_IP4_TX_H_

+#define _RAW_IP4_TX_H_

+

+//------------------------------------------------------------------------------

+//  Include Files

+//------------------------------------------------------------------------------

+

+#ifdef  BUILD_FOR_WINDOWS

+//

+//  Build for Windows environment

+//

+

+#include <winsock2.h>

+

+#define CHAR8             char

+#define CLOSE_SOCKET      closesocket

+#define EINVAL            22    //  Invalid argument

+#define GET_ERRNO         WSAGetLastError ( )

+#define SIN_ADDR(port)    port.sin_addr.S_un.S_addr

+#define SIN_FAMILY(port)  port.sin_family

+#define SIN_LEN(port)     port.sin_family

+#define SIN_PORT(port)    port.sin_port

+#define socklen_t         int

+#define ssize_t           int

+

+#else   //  BUILD_FOR_WINDOWS

+//

+//  Build for EFI environment

+//

+

+#include <Uefi.h>

+#include <errno.h>

+#include <stdlib.h>

+#include <string.h>

+

+#include <netinet/in.h>

+

+#include <sys/EfiSysCall.h>

+#include <sys/endian.h>

+#include <sys/socket.h>

+

+#define CLOSE_SOCKET      close

+#define GET_ERRNO         errno

+#define SIN_ADDR(port)    port.sin_addr.s_addr

+#define SIN_FAMILY(port)  port.sin_family

+#define SIN_LEN(port)     port.sin_len

+#define SIN_PORT(port)    port.sin_port

+#define SOCKET            int

+

+#endif  //  BUILD_FOR_WINDOWS

+

+#include <stdio.h>

+

+//------------------------------------------------------------------------------

+//  Constants

+//------------------------------------------------------------------------------

+

+//

+//  See http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xml

+//  and http://tools.ietf.org/html/rfc3692

+//

+#define RAW_PROTOCOL      253

+

+//------------------------------------------------------------------------------

+//  API

+//------------------------------------------------------------------------------

+

+/**

+  Transmit raw IP4 packets to the remote system.

+

+  @param [in] ArgC        Argument count

+  @param [in] ArgV        Argument value array

+

+  @retval 0               Successfully operation

+ **/

+

+int

+RawIp4Tx (

+  IN int ArgC,

+  IN char **ArgV

+  );

+

+//------------------------------------------------------------------------------

+

+#endif  //  _RAW_IP4_TX_H_
\ No newline at end of file
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/RawIp4Tx.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/RawIp4Tx.inf
new file mode 100644
index 0000000..32d5182
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/RawIp4Tx.inf
@@ -0,0 +1,57 @@
+## @file

+#  RawIp4Tx Application

+#

+#  Copyright (c) 2011-2012, Intel Corporation

+#  All rights reserved. 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.php

+#

+#  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                    = 0x00010005

+  BASE_NAME                      = RawIp4Tx

+  FILE_GUID                      = 3DFE0FAB-70C7-4b53-9855-985F14DB2DDA

+  MODULE_TYPE                    = UEFI_APPLICATION

+  VERSION_STRING                 = 1.0

+  ENTRY_POINT                    = ShellCEntryLib

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  Main.c

+  RawIp4Tx.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+  ShellPkg/ShellPkg.dec

+  StdLib/StdLib.dec

+

+

+[LibraryClasses]

+  BaseMemoryLib

+  BsdSocketLib

+  DebugLib

+  EfiSocketLib

+  LibC

+  LibMath

+  ShellCEntryLib

+  UefiBootServicesTableLib

+  UefiLib

+#  UseSocketDxe

+

+[BuildOptions]

+  INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186

+   MSFT:*_*_*_CC_FLAGS = /Od

+    GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable

+

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/Windows/RawIp4Tx.sln b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/Windows/RawIp4Tx.sln
new file mode 100644
index 0000000..d5a5d37
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/Windows/RawIp4Tx.sln
@@ -0,0 +1,20 @@
+

+Microsoft Visual Studio Solution File, Format Version 9.00

+# Visual Studio 2005

+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RawIp4Tx", "RawIp4Tx.vcproj", "{11018D35-F3E3-40F4-9213-7D277AF01A17}"

+EndProject

+Global

+	GlobalSection(SolutionConfigurationPlatforms) = preSolution

+		Debug|Win32 = Debug|Win32

+		Release|Win32 = Release|Win32

+	EndGlobalSection

+	GlobalSection(ProjectConfigurationPlatforms) = postSolution

+		{11018D35-F3E3-40F4-9213-7D277AF01A17}.Debug|Win32.ActiveCfg = Debug|Win32

+		{11018D35-F3E3-40F4-9213-7D277AF01A17}.Debug|Win32.Build.0 = Debug|Win32

+		{11018D35-F3E3-40F4-9213-7D277AF01A17}.Release|Win32.ActiveCfg = Release|Win32

+		{11018D35-F3E3-40F4-9213-7D277AF01A17}.Release|Win32.Build.0 = Release|Win32

+	EndGlobalSection

+	GlobalSection(SolutionProperties) = preSolution

+		HideSolutionNode = FALSE

+	EndGlobalSection

+EndGlobal

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/Windows/RawIp4Tx.vcproj b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/Windows/RawIp4Tx.vcproj
new file mode 100644
index 0000000..87d3d5d
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/Windows/RawIp4Tx.vcproj
@@ -0,0 +1,211 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="8.00"

+	Name="RawIp4Tx"

+	ProjectGUID="{11018D35-F3E3-40F4-9213-7D277AF01A17}"

+	RootNamespace="RawIp4Tx"

+	Keyword="Win32Proj"

+	>

+	<Platforms>

+		<Platform

+			Name="Win32"

+		/>

+	</Platforms>

+	<ToolFiles>

+	</ToolFiles>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"

+			IntermediateDirectory="$(ConfigurationName)"

+			ConfigurationType="1"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories=".."

+				PreprocessorDefinitions="BUILD_FOR_WINDOWS; _CRT_SECURE_NO_DEPRECATE"

+				MinimalRebuild="true"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="3"

+				UsePrecompiledHeader="0"

+				BrowseInformation="1"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="4"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="WS2_32.lib"

+				LinkIncremental="2"

+				GenerateDebugInformation="true"

+				SubSystem="1"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"

+			IntermediateDirectory="$(ConfigurationName)"

+			ConfigurationType="1"

+			CharacterSet="1"

+			WholeProgramOptimization="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories=".."

+				PreprocessorDefinitions="BUILD_FOR_WINDOWS; _CRT_SECURE_NO_DEPRECATE"

+				RuntimeLibrary="2"

+				UsePrecompiledHeader="0"

+				BrowseInformation="1"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="WS2_32.lib"

+				LinkIncremental="1"

+				GenerateDebugInformation="true"

+				SubSystem="1"

+				OptimizeReferences="2"

+				EnableCOMDATFolding="2"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+	</Configurations>

+	<References>

+	</References>

+	<Files>

+		<Filter

+			Name="Source Files"

+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"

+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"

+			>

+			<File

+				RelativePath=".\main.c"

+				>

+			</File>

+			<File

+				RelativePath="..\RawIp4Tx.c"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Header Files"

+			Filter="h;hpp;hxx;hm;inl;inc;xsd"

+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"

+			>

+			<File

+				RelativePath="..\RawIp4Tx.h"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Resource Files"

+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"

+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"

+			>

+		</Filter>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/Windows/main.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/Windows/main.c
new file mode 100644
index 0000000..441a951
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RawIp4Tx/Windows/main.c
@@ -0,0 +1,62 @@
+/** @file

+  Windows version of the raw IP4 transmit application

+

+  Copyright (c) 2011-2012, Intel Corporation

+  All rights reserved. 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.php

+

+  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 <RawIp4Tx.h>

+

+

+/**

+  Transmit raw IP4 packets to the remote system.

+

+  Please note that this program must be run with administrator privileges!

+

+  @param [in] argc  The number of arguments

+  @param [in] argv  The argument value array

+

+  @retval  0        The application exited normally.

+  @retval  Other    An error occurred.

+**/

+int

+main(

+  int argc,

+  char ** argv

+  )

+{

+  int RetVal;

+  WSADATA WsaData;

+

+  //

+  //  Initialize the WinSock layer

+  //

+  RetVal = WSAStartup ( MAKEWORD ( 2, 2 ), &WsaData );

+  if ( 0 == RetVal ) {

+    //

+    //  Start the application

+    //  See http://msdn.microsoft.com/en-us/library/ms740548(v=vs.85).aspx

+    //

+    RetVal = RawIp4Tx ( argc, argv );

+    if ( WSAEACCES == RetVal ) {

+      printf ( "Requires administrator privileges to run!\r\n" );

+    }

+

+    //

+    //  Done with the WinSock layer

+    //

+    WSACleanup ( );

+  }

+

+  //

+  //  Return the final result

+  //

+  return RetVal;  

+}

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/ReadMe.txt b/uefi/linaro-edk2/AppPkg/Applications/Sockets/ReadMe.txt
new file mode 100644
index 0000000..6cfa615
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/ReadMe.txt
@@ -0,0 +1,11 @@
+Users of the socket library need to do the following:

+

+•	Use the development branch: https://edk2.svn.sourceforge.net/svnroot/edk2/branches/EADK/

+•	Create an Efi\StdLib\etc directory on their system or USB flash device

+•	Copy the files from StdLib\Efi\StdLib\etc into that directory

+•	Edit the files appropriately

+	o	Set the correct DNS servers in resolv.conf

+	o	Set the search order in host.conf

+•	At the EFI shell

+	o	Set the device containing the \Efi directory as the default device

+	o	Run the socket application

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/RecvDgram/RecvDgram.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RecvDgram/RecvDgram.c
new file mode 100644
index 0000000..8467005
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RecvDgram/RecvDgram.c
@@ -0,0 +1,116 @@
+/** @file

+  Receive a datagram

+

+  Copyright (c) 2011-2012, Intel Corporation

+  All rights reserved. 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.php

+

+  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 <errno.h>

+#include <string.h>

+#include <Uefi.h>

+#include <unistd.h>

+

+#include <Library/DebugLib.h>

+#include <Library/UefiLib.h>

+

+#include <netinet/in.h>

+

+#include <sys/socket.h>

+#include <sys/time.h>

+

+UINT8 mBuffer[ 65536 ];

+

+/**

+  Receive a datagram

+

+  @param [in] Argc  The number of arguments

+  @param [in] Argv  The argument value array

+

+  @retval  0        The application exited normally.

+  @retval  Other    An error occurred.

+**/

+int

+main (

+  IN int Argc,

+  IN char **Argv

+  )

+{

+  struct sockaddr_in Address;

+  socklen_t AddressLength;

+  ssize_t LengthInBytes;

+  int s;

+  int Status;

+  struct timeval Timeout;

+  

+

+  DEBUG (( DEBUG_INFO,

+            "%a starting\r\n",

+            Argv[0]));

+

+  //

+  //  Get the socket

+  //

+  s = socket ( AF_INET, SOCK_DGRAM, 0 );

+  if ( -1 == s ) {

+    Print ( L"ERROR - Unable to open the socket, errno: %d\r\n", errno );

+  }

+  else {

+    Timeout.tv_sec = 5;

+    Timeout.tv_usec = 0;

+    Status = setsockopt ( s,

+                          SOL_SOCKET,

+                          SO_RCVTIMEO,

+                          &Timeout,

+                          sizeof ( Timeout ));

+    if ( -1 == Status ) {

+      Print ( L"ERROR - Unable to set the receive timeout, errno: %d\r\n", errno );

+    }

+    else {

+      AddressLength = sizeof ( Address );

+      LengthInBytes = recvfrom ( s,

+                                 &mBuffer[0],

+                                 sizeof ( mBuffer[0]),

+                                 0,

+                                 (struct sockaddr *)&Address,

+                                 &AddressLength );

+      if ( -1 == LengthInBytes ) {

+        if ( ETIMEDOUT == errno ) {

+          Print ( L"No datagram received\r\n" );

+        }

+        else {

+          Print ( L"ERROR - No datagram received, errno: %d\r\n", errno );

+        }

+      }

+      else {

+        Print ( L"Received %d bytes from %d.%d.%d.%d:%d\r\n",

+                LengthInBytes,

+                (UINT8)Address.sin_addr.s_addr,

+                (UINT8)( Address.sin_addr.s_addr >> 8 ),

+                (UINT8)( Address.sin_addr.s_addr >> 16 ),

+                (UINT8)( Address.sin_addr.s_addr >> 24 ),

+                htons ( Address.sin_port ));

+      }

+    }

+

+    //

+    //  Done with the socket

+    //

+    close ( s );

+  }

+

+  //

+  //  All done

+  //

+  DEBUG (( DEBUG_INFO,

+            "%a exiting, errno: %d\r\n",

+            Argv[0],

+            errno ));

+  return errno;

+}

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/RecvDgram/RecvDgram.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RecvDgram/RecvDgram.inf
new file mode 100644
index 0000000..9a9ca71
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/RecvDgram/RecvDgram.inf
@@ -0,0 +1,57 @@
+## @file

+#  Receive Datagram Application

+#

+#  Copyright (c) 2011-2012, Intel Corporation

+#  All rights reserved. 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.php

+#

+#  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                    = 0x00010005

+  BASE_NAME                      = RecvDgram

+  FILE_GUID                      = 929189C9-0670-4c0b-AF7D-135D1550C8C0

+  MODULE_TYPE                    = UEFI_APPLICATION

+  VERSION_STRING                 = 1.0

+  ENTRY_POINT                    = ShellCEntryLib

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  RecvDgram.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+  ShellPkg/ShellPkg.dec

+  StdLib/StdLib.dec

+

+

+[LibraryClasses]

+  BaseMemoryLib

+  BsdSocketLib

+  DebugLib

+  DevMedia

+  EfiSocketLib

+  LibC

+  LibMath

+  ShellCEntryLib

+  UefiBootServicesTableLib

+  UefiLib

+#  UseSocketDxe

+

+[BuildOptions]

+  INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186

+   MSFT:*_*_*_CC_FLAGS = /Od

+    GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable

+

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/SetHostName/SetHostName.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/SetHostName/SetHostName.c
new file mode 100644
index 0000000..2c8001e
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/SetHostName/SetHostName.c
@@ -0,0 +1,100 @@
+/** @file

+  Set the host name

+

+  Copyright (c) 2011-2012, Intel Corporation

+  All rights reserved. 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.php

+

+  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 <errno.h>

+#include <string.h>

+#include <Uefi.h>

+#include <unistd.h>

+

+#include <Library/DebugLib.h>

+#include <Library/UefiLib.h>

+

+#include <sys/socket.h>

+

+char mBuffer[65536];

+

+

+/**

+  Set the host name

+

+  @param [in] Argc  The number of arguments

+  @param [in] Argv  The argument value array

+

+  @retval  0        The application exited normally.

+  @retval  Other    An error occurred.

+**/

+int

+main (

+  IN int Argc,

+  IN char **Argv

+  )

+{

+  int AppStatus;

+

+  DEBUG (( DEBUG_INFO,

+            "%a starting\r\n",

+            Argv[0]));

+

+  //

+  //  Determine if the host name is specified

+  //

+  AppStatus = 0;

+  if ( 1 < Argc ) {

+    //

+    //  Set the host name

+    //

+    AppStatus = sethostname ( Argv[1], strlen ( Argv[1]));

+    if ( -1 == AppStatus ) {

+      switch ( errno ) {

+      default:

+        Print ( L"ERROR - errno: %d\r\n", errno );

+        break;

+

+      case ENODEV:

+        Print ( L"WARNING - Plarform does not support permanent storage!\r\n" );

+        break;

+

+      case ENOMEM:

+        Print ( L"ERROR - Insufficient storage to save host name!\r\n" );

+        break;

+

+      case ENOTSUP:

+        Print ( L"ERROR - Platform does not support environment variable storage!\r\n" );

+        break;

+      }

+    }

+  }

+  else {

+    //

+    //  Display the current host name

+    //

+    AppStatus = gethostname ( &mBuffer[0], sizeof ( mBuffer ));

+    if ( -1 == AppStatus ) {

+      Print ( L"ERROR - Unable to get host name, errno: %d\r\n", errno );

+    }

+    else {

+      if ( 0 == mBuffer[0]) {

+        Print ( L"Host name is not set!\r\n" );

+      }

+      else {

+        Print ( L"Host name: %a", &mBuffer[0]);

+      }

+    }

+  }

+

+  //

+  //  All done

+  //

+  return errno;

+}

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/SetHostName/SetHostName.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/SetHostName/SetHostName.inf
new file mode 100644
index 0000000..ed1b495
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/SetHostName/SetHostName.inf
@@ -0,0 +1,57 @@
+## @file

+#  SetHostName Application

+#

+#  Copyright (c) 2011-2012, Intel Corporation

+#  All rights reserved. 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.php

+#

+#  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                    = 0x00010005

+  BASE_NAME                      = SetHostName

+  FILE_GUID                      = 4BC80B15-255D-4858-8072-51D6D98CF90E

+  MODULE_TYPE                    = UEFI_APPLICATION

+  VERSION_STRING                 = 1.0

+  ENTRY_POINT                    = ShellCEntryLib

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  SetHostName.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+  ShellPkg/ShellPkg.dec

+  StdLib/StdLib.dec

+

+

+[LibraryClasses]

+  BaseMemoryLib

+  BsdSocketLib

+  DebugLib

+  DevMedia

+  EfiSocketLib

+  LibC

+  LibMath

+  ShellCEntryLib

+  UefiBootServicesTableLib

+  UefiLib

+#  UseSocketDxe

+

+[BuildOptions]

+  INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186

+   MSFT:*_*_*_CC_FLAGS = /Od

+    GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable

+

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/SetSockOpt/SetSockOpt.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/SetSockOpt/SetSockOpt.c
new file mode 100644
index 0000000..bba8f4b
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/SetSockOpt/SetSockOpt.c
@@ -0,0 +1,381 @@
+/** @file

+  Set the socket options

+

+  Copyright (c) 2011-2012, Intel Corporation

+  All rights reserved. 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.php

+

+  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 <errno.h>

+#include <stdio.h>

+#include <string.h>

+#include <Uefi.h>

+#include <unistd.h>

+

+#include <Library/DebugLib.h>

+#include <Library/UefiLib.h>

+

+#include <sys/socket.h>

+#include <sys/time.h>

+

+typedef enum _DATA_TYPE {

+  DATA_TYPE_UNKNOWN = 0,

+  DATA_TYPE_INT32_DECIMAL,

+  DATA_TYPE_SOCKET_TYPE,

+  DATA_TYPE_TIMEVAL

+} DATA_TYPE;

+

+typedef struct {

+  char * pOptionName;

+  int OptionValue;

+  int OptionLevel;

+  BOOLEAN bSetAllowed;

+  DATA_TYPE DataType;

+} OPTIONS;

+

+CONST OPTIONS mOptions[] = {

+  { "SO_ACCEPTCONN", SO_ACCEPTCONN, SOL_SOCKET, FALSE, DATA_TYPE_UNKNOWN },

+  { "SO_BROADCAST", SO_BROADCAST, SOL_SOCKET, TRUE, DATA_TYPE_UNKNOWN },

+  { "SO_DEBUG", SO_DEBUG, SOL_SOCKET, TRUE, DATA_TYPE_UNKNOWN },

+  { "SO_DONTROUTE", SO_DONTROUTE, SOL_SOCKET, TRUE, DATA_TYPE_UNKNOWN },

+  { "SO_ERROR", SO_ERROR, SOL_SOCKET, FALSE, DATA_TYPE_UNKNOWN },

+  { "SO_KEEPALIVE", SO_KEEPALIVE, SOL_SOCKET, TRUE, DATA_TYPE_UNKNOWN },

+  { "SO_OOBINLINE", SO_OOBINLINE, SOL_SOCKET, TRUE, DATA_TYPE_UNKNOWN },

+  { "SO_OVERFLOWED", SO_OVERFLOWED, SOL_SOCKET, TRUE, DATA_TYPE_UNKNOWN },

+  { "SO_RCVBUF", SO_RCVBUF, SOL_SOCKET, TRUE, DATA_TYPE_INT32_DECIMAL },

+  { "SO_RCVLOWAT", SO_RCVLOWAT, SOL_SOCKET, TRUE, DATA_TYPE_UNKNOWN },

+  { "SO_RCVTIMEO", SO_RCVTIMEO, SOL_SOCKET, TRUE, DATA_TYPE_TIMEVAL },

+  { "SO_REUSEADDR", SO_REUSEADDR, SOL_SOCKET, TRUE, DATA_TYPE_UNKNOWN },

+  { "SO_REUSEPORT", SO_REUSEPORT, SOL_SOCKET, TRUE, DATA_TYPE_UNKNOWN },

+  { "SO_SNDBUF", SO_SNDBUF, SOL_SOCKET, TRUE, DATA_TYPE_INT32_DECIMAL },

+  { "SO_SNDLOWAT", SO_SNDLOWAT, SOL_SOCKET, TRUE, DATA_TYPE_UNKNOWN },

+  { "SO_SNDTIMEO", SO_SNDTIMEO, SOL_SOCKET, TRUE, DATA_TYPE_UNKNOWN },

+  { "SO_TIMESTAMP", SO_TIMESTAMP, SOL_SOCKET, TRUE, DATA_TYPE_UNKNOWN },

+  { "SO_TYPE", SO_TYPE, SOL_SOCKET, FALSE, DATA_TYPE_SOCKET_TYPE },

+  { "SO_USELOOPBACK", SO_USELOOPBACK, SOL_SOCKET, TRUE, DATA_TYPE_UNKNOWN }

+};

+

+

+UINT8 mBuffer[ 65536 ];

+UINT8 mValue[ 65536 ];

+char * mSocketType[] = {

+  "SOCK_STREAM",

+  "SOCK_DGRAM",

+  "SOCK_RAW",

+  "SOCK_RDM",

+  "SOCK_SEQPACKET"

+};

+

+void

+DisplayOption (

+  CONST OPTIONS * pOption,

+  socklen_t LengthInBytes,

+  BOOLEAN bDisplayUpdate,

+  BOOLEAN bDisplayCrLf

+  )

+{

+  UINT8 * pEnd;

+  char * pString;

+  union {

+    UINT8 * u8;

+    INT32 * i32;

+    struct timeval * TimeVal;

+  } Value;

+

+  //

+  //  Display the value length

+  //

+  if ( !bDisplayUpdate ) {

+    Print ( L"LengthInBytes: %d\r\n", LengthInBytes );

+    Print ( L"%a: ", pOption->pOptionName );

+  }

+  else {

+    Print ( L" --> " );

+  }

+

+  //

+  //  Display the value

+  //

+  Value.u8 = &mBuffer[0];

+  switch ( pOption->DataType ) {

+  case DATA_TYPE_UNKNOWN:

+    Print ( L"%a:", pOption->pOptionName );

+    pEnd = &Value.u8[ LengthInBytes ];

+    while ( pEnd > Value.u8 ) {

+      Print ( L" %02x", *Value.u8 );

+      Value.u8 += 1;

+    }

+    break;

+    

+  case DATA_TYPE_INT32_DECIMAL:

+    if ( 4 == LengthInBytes ) {

+      Print ( L"%d", *Value.i32 );

+    }

+    else {

+      errno = ( 4 > LengthInBytes ) ? EBUFSIZE : ERANGE;

+      Print ( L"\r\nERROR - Invalid length, errno: %d\r\n", errno );

+    }

+    break;

+

+  case DATA_TYPE_SOCKET_TYPE:

+    if ( 4 == LengthInBytes ) {

+      if (( SOCK_STREAM <= *Value.i32 ) && ( SOCK_SEQPACKET >= *Value.i32 )) {

+        pString = mSocketType[ *Value.i32 - SOCK_STREAM ];

+        Print ( L"%a", pString );

+      }

+      else {

+        Print ( L"%08x (unknown type)", *Value.i32 );

+      }

+    }

+    else {

+      errno = ( 4 > LengthInBytes ) ? EBUFSIZE : ERANGE;

+      Print ( L"\r\nERROR - Invalid length, errno: %d\r\n", errno );

+    }

+    break;

+

+  case DATA_TYPE_TIMEVAL:

+    if ( sizeof ( *Value.TimeVal ) == LengthInBytes ) {

+      if (( 0 == Value.TimeVal->tv_sec )

+        && ( 0 == Value.TimeVal->tv_usec )) {

+        Print ( L"Infinite" );

+      }

+      else {

+        Print ( L"%d.%06d sec",

+                Value.TimeVal->tv_sec,

+                Value.TimeVal->tv_usec );

+      }

+    }

+    else {

+      errno = ( 4 > LengthInBytes ) ? EBUFSIZE : ERANGE;

+      Print ( L"\r\nERROR - Invalid length, errno: %d\r\n", errno );

+    }

+    break;

+  }

+

+  //

+  //  Terminate the line

+  //

+  if ( bDisplayCrLf ) {

+    Print ( L"\r\n" );

+  }

+}

+

+socklen_t

+GetOptionValue (

+  CONST OPTIONS * pOption,

+  char * pValue

+  )

+{

+  socklen_t BytesToWrite;

+  union {

+    UINT8 * u8;

+    INT32 * i32;

+    struct timeval * TimeVal;

+  } Value;

+  int Values;

+

+  //

+  //  Assume failure

+  //

+  errno = EINVAL;

+  BytesToWrite = 0;

+

+  //

+  //  Determine the type of parameter

+  //

+  if ( pOption->bSetAllowed ) {

+    Value.u8 = &mValue[0];

+    switch ( pOption->DataType ) {

+    default:

+      break;

+

+    case DATA_TYPE_INT32_DECIMAL:

+      Values = sscanf ( pValue, "%d", Value.i32 );

+      if ( 1 == Values ) {

+        BytesToWrite = sizeof ( *Value.i32);

+        errno = 0;

+      }

+      break;

+

+    case DATA_TYPE_TIMEVAL:

+      Values = sscanf ( pValue, "%d.%d",

+                        &Value.TimeVal->tv_sec,

+                        &Value.TimeVal->tv_usec );

+      if (( 2 == Values )

+        && ( 0 <= Value.TimeVal->tv_sec )

+        && ( 0 <= Value.TimeVal->tv_usec )

+        && ( 1000000 > Value.TimeVal->tv_usec )){

+        BytesToWrite = sizeof ( *Value.TimeVal );

+        errno = 0;

+      }

+    }

+  }

+

+  //

+  //  Display the error

+  //

+  if ( 0 == BytesToWrite ) {

+    Print ( L"ERROR - Invalid value!\r\n" );

+  }

+

+  //

+  //  Return the number of bytes to be written

+  //

+  return BytesToWrite;

+}

+

+

+/**

+  Set the socket options

+

+  @param [in] Argc  The number of arguments

+  @param [in] Argv  The argument value array

+

+  @retval  0        The application exited normally.

+  @retval  Other    An error occurred.

+**/

+int

+main (

+  IN int Argc,

+  IN char **Argv

+  )

+{

+  socklen_t BytesToWrite;

+  socklen_t LengthInBytes;

+  CONST OPTIONS * pEnd;

+  CONST OPTIONS * pOption;

+  int s;

+  int Status;

+

+  DEBUG (( DEBUG_INFO,

+            "%a starting\r\n",

+            Argv[0]));

+

+  //

+  //  Parse the socket option

+  //

+  pOption = &mOptions[0];

+  pEnd = &pOption[sizeof ( mOptions ) / sizeof ( mOptions[0])];

+  if ( 2 <= Argc ) {

+    while ( pEnd > pOption ) {

+      if ( 0 == strcmp ( Argv[1], pOption->pOptionName )) {

+        break;

+      }

+      pOption += 1;

+    }

+    if ( pEnd <= pOption ) {

+      Print ( L"ERROR: Invalid option: %a\r\n", Argv[1]);

+      Argc = 1;

+    }

+  }

+

+  //

+  //  Display the help if necessary

+  //

+  if (( 2 > Argc ) || ( 3 < Argc )) {

+    Print ( L"%a <option>\r\n", Argv[0]);

+    Print ( L"\r\n" );

+    Print ( L"Option one of:\r\n" );

+    pOption = &mOptions[0];

+    while ( pEnd > pOption ) {

+      Print ( L"   %a: %a\r\n",

+              pOption->pOptionName,

+              pOption->bSetAllowed ? "get/set" : "get" );

+      pOption += 1;

+    }

+    errno = EINVAL;

+  }

+  else {

+    //

+    //  Determine if the value is to be set

+    //

+    BytesToWrite = 0;

+    if (( 3 > Argc )

+      || ( 0 < ( BytesToWrite = GetOptionValue ( pOption, Argv[2])))) {

+      //

+      //  Get the socket

+      //

+      s = socket ( AF_INET, 0, 0 );

+      if ( -1 == s ) {

+        Print ( L"ERROR - Unable to open the socket, errno: %d\r\n", errno );

+      }

+      else {

+        //

+        //  Display the option value

+        //

+        LengthInBytes = sizeof ( mBuffer );

+        Status = getsockopt ( s,

+                              pOption->OptionLevel,

+                              pOption->OptionValue,

+                              &mBuffer,

+                              &LengthInBytes );

+        if ( -1 == Status ) {

+          Print ( L"ERROR - getsockopt failed, errno: %d\r\n", errno );

+        }

+        else {

+          DisplayOption ( pOption,

+                          LengthInBytes,

+                          FALSE,

+                          (BOOLEAN)( 0 == BytesToWrite ));

+

+          //

+          //  Determine if the value is to be set

+          //

+          if (( 0 < BytesToWrite )

+              && ( BytesToWrite == LengthInBytes )) {

+            //

+            //  Set the option value

+            //

+            Status = setsockopt ( s,

+                                  pOption->OptionLevel,

+                                  pOption->OptionValue,

+                                  &mValue,

+                                  BytesToWrite );

+            if ( -1 == Status ) {

+              Print ( L"ERROR - setsockopt failed, errno: %d\r\n", errno );

+            }

+            else {

+              //

+              //  Display the updated option value

+              //

+              Status = getsockopt ( s,

+                                    pOption->OptionLevel,

+                                    pOption->OptionValue,

+                                    &mBuffer,

+                                    &LengthInBytes );

+              if ( -1 == Status ) {

+                Print ( L"ERROR - getsockopt failed, errno: %d\r\n", errno );

+              }

+              else {

+                DisplayOption ( pOption,

+                                LengthInBytes,

+                                TRUE,

+                                TRUE );

+              }

+            }

+          }

+        }

+

+        //

+        //  Done with the socket

+        //

+        close ( s );

+      }

+    }

+  }

+

+  //

+  //  All done

+  //

+  DEBUG (( DEBUG_INFO,

+            "%a exiting, errno: %d\r\n",

+            Argv[0],

+            errno ));

+  return errno;

+}

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/SetSockOpt/SetSockOpt.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/SetSockOpt/SetSockOpt.inf
new file mode 100644
index 0000000..e088be7
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/SetSockOpt/SetSockOpt.inf
@@ -0,0 +1,57 @@
+## @file

+#  SetHostName Application

+#

+#  Copyright (c) 2011-2012, Intel Corporation

+#  All rights reserved. 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.php

+#

+#  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                    = 0x00010005

+  BASE_NAME                      = SetSockOpt

+  FILE_GUID                      = 6E851687-A7A9-4aa2-8DD0-673E03E51433

+  MODULE_TYPE                    = UEFI_APPLICATION

+  VERSION_STRING                 = 1.0

+  ENTRY_POINT                    = ShellCEntryLib

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  SetSockOpt.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+  ShellPkg/ShellPkg.dec

+  StdLib/StdLib.dec

+

+

+[LibraryClasses]

+  BaseMemoryLib

+  BsdSocketLib

+  DebugLib

+  DevMedia

+  EfiSocketLib

+  LibC

+  LibMath

+  ShellCEntryLib

+  UefiBootServicesTableLib

+  UefiLib

+#  UseSocketDxe

+

+[BuildOptions]

+  INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186

+   MSFT:*_*_*_CC_FLAGS = /Od

+    GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable

+

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/Sockets.inc b/uefi/linaro-edk2/AppPkg/Applications/Sockets/Sockets.inc
new file mode 100644
index 0000000..4ad109f
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/Sockets.inc
@@ -0,0 +1,42 @@
+

+################################################################################

+#  Socket Applications

+################################################################################

+

+[Components]

+  AppPkg/Applications/Sockets/DataSink/DataSink.inf

+  AppPkg/Applications/Sockets/DataSource/DataSource.inf

+  AppPkg/Applications/Sockets/GetAddrInfo/GetAddrInfo.inf

+  AppPkg/Applications/Sockets/GetHostByAddr/GetHostByAddr.inf

+  AppPkg/Applications/Sockets/GetHostByDns/GetHostByDns.inf

+  AppPkg/Applications/Sockets/GetHostByName/GetHostByName.inf

+  AppPkg/Applications/Sockets/GetNameInfo/GetNameInfo.inf

+  AppPkg/Applications/Sockets/GetNetByAddr/GetNetByAddr.inf

+  AppPkg/Applications/Sockets/GetNetByName/GetNetByName.inf

+  AppPkg/Applications/Sockets/GetServByName/GetServByName.inf

+  AppPkg/Applications/Sockets/GetServByPort/GetServByPort.inf

+  AppPkg/Applications/Sockets/OobRx/OobRx.inf

+  AppPkg/Applications/Sockets/OobTx/OobTx.inf

+  AppPkg/Applications/Sockets/RawIp4Rx/RawIp4Rx.inf

+  AppPkg/Applications/Sockets/RawIp4Tx/RawIp4Tx.inf

+  AppPkg/Applications/Sockets/RecvDgram/RecvDgram.inf

+  AppPkg/Applications/Sockets/SetHostName/SetHostName.inf

+  AppPkg/Applications/Sockets/SetSockOpt/SetSockOpt.inf

+  AppPkg/Applications/Sockets/WebServer/WebServer.inf {

+    <LibraryClasses>

+      CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf

+      DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf

+      MtrrLib|UefiCpuPkg/Library/MtrrLib/MtrrLib.inf

+

+    <PcdsFixedAtBuild>

+      gAppPkgTokenSpaceGuid.WebServer_HttpPort|80

+  }

+

+################################################################################

+#  The following application requires TimerLib (platform specific library)

+################################################################################

+

+[Components]

+#  AppPkg/Applications/Sockets/TftpServer/TftpServer.inf

+

+

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/TftpServer/TftpServer.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/TftpServer/TftpServer.c
new file mode 100644
index 0000000..30d9dae
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/TftpServer/TftpServer.c
@@ -0,0 +1,2367 @@
+/** @file

+  This is a simple TFTP server application

+

+  Copyright (c) 2011, 2012, Intel Corporation

+  All rights reserved. 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.php

+

+  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 <TftpServer.h>

+

+TSDT_TFTP_SERVER mTftpServer;       ///<  TFTP server's control structure

+volatile BOOLEAN mbTftpServerExit;  ///<  Set TRUE to cause TFTP server to exit

+

+

+/**

+  Read file data into a buffer

+

+  @param [in] pContext    Connection context structure address

+

+  @retval TRUE if a read error occurred

+

+**/

+BOOLEAN

+BufferFill (

+  IN TSDT_CONNECTION_CONTEXT * pContext

+  )

+{

+  BOOLEAN bReadError;

+  size_t BytesRead;

+  UINT64 LengthInBytes;

+

+  DBG_ENTER ( );

+

+  //

+  //  Use break instead of goto

+  //

+  bReadError = FALSE;

+  for ( ; ; ) {

+    //

+    //  Determine if there is any work to do

+    //

+    LengthInBytes = DIM ( pContext->FileData ) >> 1;

+    if (( pContext->ValidBytes > LengthInBytes )

+      || ( 0 == pContext->BytesRemaining )) {

+      break;

+    }

+

+    //

+    //  Determine the number of bytes to read

+    //

+    if ( LengthInBytes > pContext->BytesRemaining ) {

+      LengthInBytes = pContext->BytesRemaining;

+    }

+

+    //

+    //  Read in the next portion of the file

+    //

+    BytesRead = fread ( pContext->pFill,

+                        1,

+                        (size_t)LengthInBytes,

+                        pContext->File );

+    if ( -1 == BytesRead ) {

+      bReadError = TRUE;

+      break;

+    }

+

+    //

+    //  Account for the file data read

+    //

+    pContext->BytesRemaining -= BytesRead;

+    pContext->ValidBytes += BytesRead;

+    DEBUG (( DEBUG_FILE_BUFFER,

+              "0x%08x: Buffer filled with %Ld bytes, %Ld bytes ramaining\r\n",

+              pContext->pFill,

+              BytesRead,

+              pContext->BytesRemaining ));

+

+    //

+    //  Set the next buffer location

+    //

+    pContext->pFill += BytesRead;

+    if ( pContext->pEnd <= pContext->pFill ) {

+      pContext->pFill = &pContext->FileData[ 0 ];

+    }

+

+    //

+    //  Verify that the end of the buffer is reached

+    //

+    ASSERT ( 0 == ( DIM ( pContext->FileData ) & 1 ));

+    break;

+  }

+

+  //

+  //  Return the read status

+  //

+  DBG_EXIT ( );

+  return bReadError;

+}

+

+

+/**

+  Add a connection context to the list of connection contexts.

+

+  @param [in] pTftpServer   Address of the ::TSDT_TFTP_SERVER structure

+  @param [in] SocketFd      Socket file descriptor

+

+  @retval Context structure address, NULL if allocation fails

+

+**/

+TSDT_CONNECTION_CONTEXT *

+ContextAdd (

+  IN TSDT_TFTP_SERVER * pTftpServer,

+  IN int SocketFd

+  )

+{

+  TSDT_CONNECTION_CONTEXT * pContext;

+  TFTP_PACKET * pEnd;

+  TFTP_PACKET * pPacket;

+

+  DBG_ENTER ( );

+

+  //

+  //  Allocate a new context

+  //

+  pContext = (TSDT_CONNECTION_CONTEXT *)AllocateZeroPool ( sizeof ( *pContext ));

+  if ( NULL != pContext ) {

+    //

+    //  Initialize the context

+    //

+    pContext->SocketFd = SocketFd;

+    CopyMem ( &pContext->RemoteAddress,

+              &pTftpServer->RemoteAddress,

+              sizeof ( pContext->RemoteAddress ));

+    pContext->BlockSize = 512;

+

+    //

+    //  Buffer management

+    //

+    pContext->pFill = &pContext->FileData[ 0 ];

+    pContext->pEnd = &pContext->FileData[ sizeof ( pContext->FileData )];

+    pContext->pBuffer = pContext->pFill;

+

+    //

+    //  Window management

+    //

+    pContext->MaxTimeout = MultU64x32 ( PcdGet32 ( Tftp_MaxTimeoutInSec ),

+                                        2 * 1000 * 1000 * 1000 );

+    pContext->Rtt2x = pContext->MaxTimeout;

+    pContext->WindowSize = MAX_PACKETS;

+    WindowTimeout ( pContext );

+

+    //

+    //  Place the packets on the free list

+    //

+    pPacket = &pContext->Tx[ 0 ];

+    pEnd = &pPacket[ DIM ( pContext->Tx )];

+    while ( pEnd > pPacket ) {

+      PacketFree ( pContext, pPacket );

+      pPacket += 1;

+    }

+

+    //

+    //  Display the new context

+    //

+    if ( AF_INET == pTftpServer->RemoteAddress.v4.sin_family ) {

+      DEBUG (( DEBUG_PORT_WORK,

+                "0x%08x: Context for %d.%d.%d.%d:%d\r\n",

+                pContext,

+                (UINT8)pTftpServer->RemoteAddress.v4.sin_addr.s_addr,

+                (UINT8)( pTftpServer->RemoteAddress.v4.sin_addr.s_addr >> 8 ),

+                (UINT8)( pTftpServer->RemoteAddress.v4.sin_addr.s_addr >> 16 ),

+                (UINT8)( pTftpServer->RemoteAddress.v4.sin_addr.s_addr >> 24 ),

+                htons ( pTftpServer->RemoteAddress.v4.sin_port )));

+    }

+    else {

+      DEBUG (( DEBUG_PORT_WORK,

+                "0x%08x: Context for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",

+                pContext,

+                pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 0 ],

+                pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 1 ],

+                pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 2 ],

+                pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 3 ],

+                pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 4 ],

+                pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 5 ],

+                pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 6 ],

+                pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 7 ],

+                pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 8 ],

+                pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 9 ],

+                pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 10 ],

+                pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 11 ],

+                pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 12 ],

+                pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 13 ],

+                pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 14 ],

+                pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 15 ],

+                htons ( pTftpServer->RemoteAddress.v6.sin6_port )));

+    }

+

+    //

+    //  Add the context to the context list

+    //

+    pContext->pNext = pTftpServer->pContextList;

+    pTftpServer->pContextList = pContext;

+  }

+

+  //

+  //  Return the connection context

+  //

+  DBG_EXIT_STATUS ( pContext );

+  return pContext;

+}

+

+

+/**

+  Locate a remote connection context.

+

+  @param [in] pTftpServer   Address of the ::TSDT_TFTP_SERVER structure

+  @param [in] pIpAddress    The start of the remote IP address in network order

+  @param [in] Port          The remote port number

+

+  @retval Context structure address, NULL if not found

+

+**/

+TSDT_CONNECTION_CONTEXT *

+ContextFind (

+  IN TSDT_TFTP_SERVER * pTftpServer

+  )

+{

+  TSDT_CONNECTION_CONTEXT * pContext;

+

+  DBG_ENTER ( );

+

+  //

+  //  Walk the list of connection contexts

+  //

+  pContext = pTftpServer->pContextList;

+  while ( NULL != pContext ) {

+    //

+    //  Attempt to locate the remote network connection

+    //

+    if ( 0 == memcmp ( &pTftpServer->RemoteAddress,

+                       &pContext->RemoteAddress,

+                       pTftpServer->RemoteAddress.v6.sin6_len )) {

+      //

+      //  The connection was found

+      //

+      DEBUG (( DEBUG_TFTP_REQUEST,

+                "0x%08x: pContext found\r\n",

+                pContext ));

+      break;

+    }

+

+    //

+    //  Set the next context

+    //

+    pContext = pContext->pNext;

+  }

+

+  //

+  //  Return the connection context structure address

+  //

+  DBG_EXIT_HEX ( pContext );

+  return pContext;

+}

+

+

+/**

+  Remove a context from the list.

+

+  @param [in] pTftpServer   Address of the ::TSDT_TFTP_SERVER structure

+  @param [in] pContext      Address of a ::TSDT_CONNECTION_CONTEXT structure

+

+**/

+VOID

+ContextRemove (

+  IN TSDT_TFTP_SERVER * pTftpServer,

+  IN TSDT_CONNECTION_CONTEXT * pContext

+  )

+{

+  TSDT_CONNECTION_CONTEXT * pNextContext;

+  TSDT_CONNECTION_CONTEXT * pPreviousContext;

+

+  DBG_ENTER ( );

+

+  //

+  //  Attempt to locate the context in the list

+  //

+  pPreviousContext = NULL;

+  pNextContext = pTftpServer->pContextList;

+  while ( NULL != pNextContext ) {

+    //

+    //  Determine if the context was found

+    //

+    if ( pNextContext == pContext ) {

+      //

+      //  Remove the context from the list

+      //

+      if ( NULL == pPreviousContext ) {

+        pTftpServer->pContextList = pContext->pNext;

+      }

+      else {

+        pPreviousContext->pNext = pContext->pNext;

+      }

+      break;

+    }

+

+    //

+    //  Set the next context

+    //

+    pPreviousContext = pNextContext;

+    pNextContext = pNextContext->pNext;

+  }

+

+  //

+  //  Determine if the context was found

+  //

+  if ( NULL != pContext ) {

+    //

+    //  Return the resources

+    //

+    gBS->FreePool ( pContext );

+  }

+

+  DBG_EXIT ( );

+}

+

+

+/**

+  Queue data packets for transmission

+

+  @param [in] pContext    Connection context structure address

+

+  @retval TRUE if a read error occurred

+

+**/

+BOOLEAN

+PacketFill (

+  IN TSDT_CONNECTION_CONTEXT * pContext

+  )

+{

+  BOOLEAN bReadError;

+  UINT64 LengthInBytes;

+  UINT8 * pBuffer;

+  TFTP_PACKET * pPacket;

+

+  DBG_ENTER ( );

+

+  //

+  //  Use break instead of goto

+  //

+  bReadError = FALSE;

+  for ( ; ; ) {

+    //

+    //  Fill the buffer if necessary

+    //

+    bReadError = BufferFill ( pContext );

+    if ( bReadError ) {

+      //

+      //  File access mode not supported

+      //

+      DEBUG (( DEBUG_ERROR | DEBUG_TFTP_REQUEST,

+                "ERROR - File read failure!\r\n" ));

+

+      //

+      //  Tell the client of the error

+      //

+      SendError ( pContext,

+                  TFTP_ERROR_SEE_MSG,

+                  (UINT8 *)"Read failure" );

+      break;

+    }

+

+    //

+    //  Determine if any packets can be filled

+    //

+    if ( pContext->bEofSent

+      || ( NULL == pContext->pFreeList )) {

+      //

+      //  All of the packets are filled

+      //

+      break;

+    }

+

+    //

+    //  Set the TFTP opcode and block number

+    //

+    pPacket = PacketGet ( pContext );

+    pBuffer = &pPacket->TxBuffer[ 0 ];

+    *pBuffer++ = 0;

+    *pBuffer++ = TFTP_OP_DATA;

+    *pBuffer++ = (UINT8)( pContext->BlockNumber >> 8 );

+    *pBuffer++ = (UINT8)pContext->BlockNumber;

+

+    //

+    //  Determine how much data needs to be sent

+    //

+    LengthInBytes = pContext->BlockSize;

+    if (( pContext->BytesToSend < TFTP_MAX_BLOCK_SIZE )

+      && ( LengthInBytes > pContext->BytesToSend )) {

+      LengthInBytes = pContext->BytesToSend;

+      pContext->bEofSent = TRUE;

+    }

+    DEBUG (( DEBUG_TX_PACKET,

+              "0x%08x: Packet, Block %d filled with %d bytes\r\n",

+              pPacket,

+              pContext->BlockNumber,

+              (UINT32)LengthInBytes ));

+    

+    //

+    //  Copy the file data into the packet

+    //

+    pPacket->TxBytes = (ssize_t)( 2 + 2 + LengthInBytes );

+    if ( 0 < LengthInBytes ) {

+      CopyMem ( pBuffer,

+                pContext->pBuffer,

+                (UINTN)LengthInBytes );

+      DEBUG (( DEBUG_FILE_BUFFER,

+                "0x%08x: Buffer consumed %d bytes of file data\r\n",

+                pContext->pBuffer,

+                LengthInBytes ));

+

+      //

+      //  Account for the file data consumed

+      //

+      pContext->ValidBytes -= LengthInBytes;

+      pContext->BytesToSend -= LengthInBytes;

+      pContext->pBuffer += LengthInBytes;

+      if ( pContext->pEnd <= pContext->pBuffer ) {

+        pContext->pBuffer = &pContext->FileData[ 0 ];

+      }

+    }

+    

+    //

+    //  Queue the packet for transmission

+    //

+    PacketQueue ( pContext, pPacket );

+  }

+

+  //

+  //  Return the read status

+  //

+  DBG_EXIT ( );

+  return bReadError;

+}

+

+

+/**

+  Free the packet

+

+  @param [in] pContext    Address of a ::TSDT_CONNECTION_CONTEXT structure

+  @param [in] pPacket     Address of a ::TFTP_PACKET structure

+

+**/

+VOID

+PacketFree(

+  IN TSDT_CONNECTION_CONTEXT * pContext,

+  IN TFTP_PACKET * pPacket

+  )

+{

+  DBG_ENTER ( );

+

+  //

+  //  Don't free the error packet

+  //

+  if ( pPacket != &pContext->ErrorPacket ) {

+    //

+    //  Place the packet on the free list

+    //

+    pPacket->pNext = pContext->pFreeList;

+    pContext->pFreeList = pPacket;

+    DEBUG (( DEBUG_TX_PACKET,

+              "0x%08x: Packet queued to free list\r\n",

+              pPacket ));

+  }

+

+  DBG_EXIT ( );

+}

+

+

+/**

+  Get a packet from the free list for transmission

+

+  @param [in] pContext    Address of a ::TSDT_CONNECTION_CONTEXT structure

+

+  @retval Address of a ::TFTP_PACKET structure

+

+**/

+TFTP_PACKET *

+PacketGet (

+  IN TSDT_CONNECTION_CONTEXT * pContext

+  )

+{

+  TFTP_PACKET * pPacket;

+

+  DBG_ENTER ( );

+

+  //

+  //  Get the next packet from the free list

+  //

+  pPacket = pContext->pFreeList;

+  if ( NULL != pPacket ) {

+    pContext->pFreeList = pPacket->pNext;

+    pPacket->RetryCount = 0;

+    DEBUG (( DEBUG_TX_PACKET,

+              "0x%08x: Packet removed from free list\r\n",

+              pPacket ));

+  }

+

+  //

+  //  Return the packet

+  //

+  DBG_EXIT_HEX ( pPacket );

+  return pPacket;

+}

+

+

+/**

+  Queue the packet for transmission

+

+  @param [in] pContext    Address of a ::TSDT_CONNECTION_CONTEXT structure

+  @param [in] pPacket     Address of a ::TFTP_PACKET structure

+

+  @retval TRUE if a transmission error has occurred

+

+**/

+BOOLEAN

+PacketQueue (

+  IN TSDT_CONNECTION_CONTEXT * pContext,

+  IN TFTP_PACKET * pPacket

+  )

+{

+  BOOLEAN bTransmitError;

+  TFTP_PACKET * pTail;

+  EFI_STATUS Status;

+

+  DBG_ENTER ( );

+

+  //

+  //  Account for this data block

+  //

+  pPacket->BlockNumber = pContext->BlockNumber;

+  pContext->BlockNumber += 1;

+

+  //

+  //  Queue the packet for transmission

+  //

+  pTail = pContext->pTxTail;

+  if ( NULL == pTail ) {

+    pContext->pTxHead = pPacket;

+  }

+  else {

+    pTail->pNext = pPacket;

+  }

+  pContext->pTxTail = pPacket;

+  pPacket->pNext = NULL;

+  DEBUG (( DEBUG_TX_PACKET,

+            "0x%08x: Packet queued to TX list\r\n",

+            pPacket ));

+

+  //

+  //  Start the transmission if necessary

+  //

+  bTransmitError = FALSE;

+  if ( pContext->PacketsInWindow < pContext->WindowSize ) {

+    Status = PacketTx ( pContext, pPacket );

+    bTransmitError = (BOOLEAN)( EFI_ERROR ( Status ));

+  }

+

+  //

+  //  Return the transmit status

+  //

+  DBG_EXIT_TF ( bTransmitError );

+  return bTransmitError;

+}

+

+

+/**

+  Remove a packet from the transmit queue

+

+  @param [in] pContext    Address of a ::TSDT_CONNECTION_CONTEXT structure

+

+**/

+TFTP_PACKET *

+PacketRemove(

+  IN TSDT_CONNECTION_CONTEXT * pContext

+  )

+{

+  TFTP_PACKET * pNext;

+  TFTP_PACKET * pPacket;

+

+  DBG_ENTER ( );

+

+  //

+  //  Remove a packet from the transmit queue

+  //

+  //

+  pPacket = pContext->pTxHead;

+  if ( NULL != pPacket ) {

+    pNext = pPacket->pNext;

+    pContext->pTxHead = pNext;

+    if ( NULL == pNext ) {

+      pContext->pTxTail = NULL;

+    }

+    DEBUG (( DEBUG_TX_PACKET,

+              "0x%08x: Packet removed from TX list\r\n",

+              pPacket ));

+

+    //

+    //  Remove this packet from the window

+    //

+    pContext->PacketsInWindow -= 1;

+  }

+

+  //

+  //  Return the packet

+  //

+  DBG_EXIT_HEX ( pPacket );

+  return pPacket;

+}

+

+

+/**

+  Transmit the packet

+

+  @param [in] pContext    Address of a ::TSDT_CONNECTION_CONTEXT structure

+  @param [in] pPacket     Address of a ::TFTP_PACKET structure

+

+  @retval EFI_SUCCESS   Message processed successfully

+

+**/

+EFI_STATUS

+PacketTx (

+  IN TSDT_CONNECTION_CONTEXT * pContext,

+  IN TFTP_PACKET * pPacket

+  )

+{

+  ssize_t LengthInBytes;

+  EFI_STATUS Status;

+

+  DBG_ENTER ( );

+

+  //

+  //  Assume success

+  //

+  Status = EFI_SUCCESS;

+

+  //

+  //  Determine if this packet should be transmitted

+  //

+  if ( PcdGet32 ( Tftp_MaxRetry ) >= pPacket->RetryCount ) {

+    pPacket->RetryCount += 1;

+

+    //

+    //  Display the operation

+    //

+    DEBUG (( DEBUG_TX_PACKET,

+              "0x%08x: Packet transmiting\r\n",

+              pPacket ));

+    DEBUG (( DEBUG_TX,

+              "0x%08x: pContext sending 0x%08x bytes\r\n",

+              pContext,

+              pPacket->TxBytes ));

+

+    //

+    //  Keep track of when the packet was transmitted

+    //

+    if ( PcdGetBool ( Tftp_HighSpeed )) {

+      pPacket->TxTime = GetPerformanceCounter ( );

+    }

+

+    //

+    //  Send the TFTP packet

+    //

+    pContext->PacketsInWindow += 1;

+    LengthInBytes = sendto ( pContext->SocketFd,

+                             &pPacket->TxBuffer[ 0 ],

+                             pPacket->TxBytes,

+                             0,

+                             (struct sockaddr *)&pContext->RemoteAddress,

+                             pContext->RemoteAddress.sin6_len );

+    if ( -1 == LengthInBytes ) {

+      DEBUG (( DEBUG_ERROR | DEBUG_TX,

+                "ERROR - Transmit failure, errno: 0x%08x\r\n",

+                errno ));

+      pContext->PacketsInWindow -= 1;

+      Status = EFI_DEVICE_ERROR;

+    }

+  }

+  else {

+    //

+    //  Too many retries

+    //

+    Status = EFI_NO_RESPONSE;

+    DEBUG (( DEBUG_WARN | DEBUG_WINDOW,

+              "WARNING - No response from TFTP client\r\n" ));

+  }

+

+  //

+  //  Return the operation status

+  //

+  DBG_EXIT_STATUS ( Status );

+  return Status;

+}

+

+

+/**

+  Process the work for the sockets.

+

+  @param [in] pTftpServer   Address of the ::TSDT_TFTP_SERVER structure

+  @param [in] pIndex        Address of an index into the pollfd array

+

+**/

+VOID

+PortWork (

+  IN TSDT_TFTP_SERVER * pTftpServer,

+  IN int * pIndex

+  )

+{

+  int Index;

+  TSDT_CONNECTION_CONTEXT * pContext;

+  struct pollfd * pTftpPort;

+  socklen_t RemoteAddressLength;

+  int revents;

+

+  DBG_ENTER ( );

+

+  //

+  //  Locate the port

+  //

+  Index = *pIndex;

+  if ( -1 != Index ) {

+    pTftpPort = &pTftpServer->TftpPort[ *pIndex ];

+

+    //

+    //  Handle input events

+    //

+    revents = pTftpPort->revents;

+    pTftpPort->revents = 0;

+    if ( 0 != ( revents & POLLRDNORM )) {

+      //

+      //  Receive the message from the remote system

+      //

+      RemoteAddressLength = sizeof ( pTftpServer->RemoteAddress );

+      pTftpServer->RxBytes = recvfrom ( pTftpPort->fd,

+                                        &pTftpServer->RxBuffer[ 0 ],

+                                        sizeof ( pTftpServer->RxBuffer ),

+                                        0,

+                                        (struct sockaddr *) &pTftpServer->RemoteAddress,

+                                        &RemoteAddressLength );

+      if ( -1 != pTftpServer->RxBytes ) {

+        if ( PcdGetBool ( Tftp_HighSpeed )) {

+          pTftpServer->RxTime = GetPerformanceCounter ( );

+        }

+        if ( AF_INET == pTftpServer->RemoteAddress.v4.sin_family ) {

+          DEBUG (( DEBUG_TFTP_PORT,

+                   "Received %d bytes from %d.%d.%d.%d:%d\r\n",

+                   pTftpServer->RxBytes,

+                   pTftpServer->RemoteAddress.v4.sin_addr.s_addr & 0xff,

+                   ( pTftpServer->RemoteAddress.v4.sin_addr.s_addr >> 8 ) & 0xff,

+                   ( pTftpServer->RemoteAddress.v4.sin_addr.s_addr >> 16 ) & 0xff,

+                   ( pTftpServer->RemoteAddress.v4.sin_addr.s_addr >> 24 ) & 0xff,

+                   htons ( pTftpServer->RemoteAddress.v4.sin_port )));

+        }

+        else {

+          DEBUG (( DEBUG_TFTP_PORT,

+                   "Received %d bytes from [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",

+                   pTftpServer->RxBytes,

+                   pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 0 ],

+                   pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 1 ],

+                   pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 2 ],

+                   pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 3 ],

+                   pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 4 ],

+                   pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 5 ],

+                   pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 6 ],

+                   pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 7 ],

+                   pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 8 ],

+                   pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 9 ],

+                   pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 10 ],

+                   pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 11 ],

+                   pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 12 ],

+                   pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 13 ],

+                   pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 14 ],

+                   pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 15 ],

+                   htons ( pTftpServer->RemoteAddress.v6.sin6_port )));

+        }

+

+        //

+        //  Lookup connection context using the remote system address and port

+        //  to determine if an existing connection to this remote

+        //  system exists

+        //

+        pContext = ContextFind ( pTftpServer );

+

+        //

+        //  Process the received message

+        //

+        TftpProcessRequest ( pTftpServer, pContext, pTftpPort->fd );

+      }

+      else {

+        //

+        //  Receive error on the TFTP server port

+        //  Close the server socket

+        //

+        DEBUG (( DEBUG_ERROR,

+                  "ERROR - Failed receive on TFTP server port, errno: 0x%08x\r\n",

+                  errno ));

+        revents |= POLLHUP;

+      }

+    }

+

+    //

+    //  Handle the close event

+    //

+    if ( 0 != ( revents & POLLHUP )) {

+      //

+      //  Close the port

+      //

+      close ( pTftpPort->fd );

+      pTftpPort->fd = -1;

+      *pIndex = -1;

+      pTftpServer->Entries -= 1;

+      ASSERT ( 0 <= pTftpServer->Entries );

+    }

+  }

+

+  DBG_EXIT ( );

+}

+

+

+/**

+  Build and send an error packet

+

+  @param [in] pContext    Address of a ::TSDT_CONNECTION_CONTEXT structure

+  @param [in] Error       Error number for the packet

+  @param [in] pError      Zero terminated error string address

+

+  @retval EFI_SUCCESS     Message processed successfully

+

+**/

+EFI_STATUS

+SendError (

+  IN TSDT_CONNECTION_CONTEXT * pContext,

+  IN UINT16 Error,

+  IN UINT8 * pError

+  )

+{

+  UINT8 Character;

+  UINT8 * pBuffer;

+  TFTP_PACKET * pPacket;

+  EFI_STATUS Status;

+

+  DBG_ENTER ( );

+

+  //

+  //  Build the error packet

+  //

+  pPacket = &pContext->ErrorPacket;

+  pBuffer = &pPacket->TxBuffer[ 0 ];

+  pBuffer[ 0 ] = 0;

+  pBuffer[ 1 ] = TFTP_OP_ERROR;

+  pBuffer[ 2 ] = (UINT8)( Error >> 8 );

+  pBuffer[ 3 ] = (UINT8)Error;

+

+  //

+  //  Copy the zero terminated string into the buffer

+  //

+  pBuffer += 4;

+  do {

+    Character = *pError++;

+    *pBuffer++ = Character;

+  } while ( 0 != Character );

+

+  //

+  //  Send the error message

+  //

+  pPacket->TxBytes = pBuffer - &pPacket->TxBuffer[ 0 ];

+  Status = PacketTx ( pContext, pPacket );

+

+  //

+  //  Return the operation status

+  //

+  DBG_EXIT_STATUS ( Status );

+  return Status;

+}

+

+

+/**

+  Scan the list of sockets and process any pending work

+

+  @param [in] pTftpServer   Address of the ::TSDT_TFTP_SERVER structure

+

+**/

+VOID

+SocketPoll (

+  IN TSDT_TFTP_SERVER * pTftpServer

+  )

+{

+  int FDCount;

+

+  DEBUG (( DEBUG_SOCKET_POLL, "Entering SocketPoll\r\n" ));

+

+  //

+  //  Determine if any ports are active

+  //

+  if ( 0 != pTftpServer->Entries ) {

+    FDCount = poll ( &pTftpServer->TftpPort[ 0 ],

+                     pTftpServer->Entries,

+                     CLIENT_POLL_DELAY );

+    if ( 0 < FDCount ) {

+      //

+      //  Process this port

+      //

+      PortWork ( pTftpServer, &pTftpServer->Udpv4Index );

+      PortWork ( pTftpServer, &pTftpServer->Udpv6Index );

+    }

+  }

+

+  DEBUG (( DEBUG_SOCKET_POLL, "Exiting SocketPoll\r\n" ));

+}

+

+

+/**

+  Process the ACK

+

+  @param [in] pTftpServer   Address of the ::TSDT_TFTP_SERVER structure

+  @param [in] pContext    Connection context structure address

+

+  @retval TRUE if the context should be closed

+

+**/

+BOOLEAN

+TftpAck (

+  IN TSDT_TFTP_SERVER * pTftpServer,

+  IN TSDT_CONNECTION_CONTEXT * pContext

+  )

+{

+  INTN AckNumber;

+  BOOLEAN bCloseContext;

+  UINT16 BlockNumber;

+  UINT8 * pBuffer;

+  TFTP_PACKET * pPacket;

+  EFI_STATUS Status;

+

+  DBG_ENTER ( );

+

+  //

+  //  Use break instead of goto

+  //

+  bCloseContext = FALSE;

+  for ( ; ; ) {

+    //

+    //  Validate the parameters

+    //

+    if ( NULL == pContext ) {

+      if ( AF_INET == pTftpServer->RemoteAddress.v4.sin_family ) {

+        DEBUG (( DEBUG_ERROR,

+                  "ERROR - File not open for %d.%d.%d.%d:%d\r\n",

+                  (UINT8)pTftpServer->RemoteAddress.v4.sin_addr.s_addr,

+                  (UINT8)( pTftpServer->RemoteAddress.v4.sin_addr.s_addr >> 8 ),

+                  (UINT8)( pTftpServer->RemoteAddress.v4.sin_addr.s_addr >> 16 ),

+                  (UINT8)( pTftpServer->RemoteAddress.v4.sin_addr.s_addr >> 24 ),

+                  htons ( pTftpServer->RemoteAddress.v4.sin_port )));

+      }

+      else {

+        DEBUG (( DEBUG_ERROR,

+                  "ERROR - File not open for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 0 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 1 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 2 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 3 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 4 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 5 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 6 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 7 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 8 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 9 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 10 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 11 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 12 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 13 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 14 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 15 ],

+                  htons ( pTftpServer->RemoteAddress.v6.sin6_port )));

+      }

+      break;

+    }

+

+    //

+    //  Verify that the ACK was expected

+    //

+    pPacket = pContext->pTxHead;

+    if ( NULL == pPacket ) {

+      //

+      //  ACK not expected!

+      //

+      DEBUG (( DEBUG_ERROR,

+                "ERROR - Expecting data not ACKs for pContext 0x%08x\r\n",

+                pContext ));

+      break;

+    }

+

+    //

+    //  Get the ACKed block number

+    //

+    pBuffer = &pTftpServer->RxBuffer[ 0 ];

+    BlockNumber = HTONS ( *(UINT16 *)&pBuffer[ 2 ]);

+

+    //

+    //  Determine if this is the correct ACK

+    //

+    DEBUG (( DEBUG_TFTP_ACK,

+              "ACK for block 0x%04x received\r\n",

+              BlockNumber ));

+    AckNumber = BlockNumber - pPacket->BlockNumber;

+    if (( 0 > AckNumber ) || ( AckNumber >= (INTN)pContext->PacketsInWindow )){

+      DEBUG (( DEBUG_WARN | DEBUG_TFTP_ACK,

+                "WARNING - Expecting ACK 0x%0x4 not received ACK 0x%08x\r\n",

+                pPacket->BlockNumber,

+                BlockNumber ));

+      break;

+    }

+

+    //

+    //  Release the ACKed packets

+    //

+    do {

+      //

+      //  Remove the packet from the transmit list and window

+      //

+      pPacket = PacketRemove ( pContext );

+

+      //

+      //  Get the block number of this packet

+      //

+      AckNumber = pPacket->BlockNumber;

+

+      //

+      //  Increase the size of the transmit window

+      //

+      if ( PcdGetBool ( Tftp_HighSpeed )

+        && ( AckNumber == BlockNumber )) {

+        WindowAck ( pTftpServer, pContext, pPacket );

+      }

+

+      //

+      //  Free this packet

+      //

+      PacketFree ( pContext, pPacket );

+    } while (( NULL != pContext->pTxHead ) && ( AckNumber != BlockNumber ));

+

+    //

+    //  Fill the window with packets

+    //

+    pPacket = pContext->pTxHead;

+    while (( NULL != pPacket )

+      && ( pContext->PacketsInWindow < pContext->WindowSize )

+      && ( !bCloseContext )) {

+      Status = PacketTx ( pContext, pPacket );

+      bCloseContext = (BOOLEAN)( EFI_ERROR ( Status ));

+      pPacket = pPacket->pNext;

+    }

+    

+    //

+    //  Get more packets ready for transmission

+    //

+    PacketFill ( pContext );

+

+    //

+    //  Close the context when the last packet is ACKed

+    //

+    if ( 0 == pContext->PacketsInWindow ) {

+      bCloseContext = TRUE;

+

+      //

+      //  Display the bandwidth

+      //

+      if ( PcdGetBool ( Tftp_Bandwidth )) {

+        UINT64 Bandwidth;

+        UINT64 DeltaTime;

+        UINT64 NanoSeconds;

+        UINT32 Value;

+

+        //

+        //  Compute the download time

+        //

+        DeltaTime = GetPerformanceCounter ( );

+        if ( pTftpServer->Time2 > pTftpServer->Time1 ) {

+          DeltaTime = DeltaTime - pContext->TimeStart;

+        }

+        else {

+          DeltaTime = pContext->TimeStart - DeltaTime;

+        }

+        NanoSeconds = GetTimeInNanoSecond ( DeltaTime );

+        Bandwidth = pContext->LengthInBytes;

+        DEBUG (( DEBUG_WINDOW,

+                  "File Length %Ld, Transfer Time: %d.%03d Sec\r\n",

+                  Bandwidth,

+                  DivU64x32 ( NanoSeconds, 1000 * 1000 * 1000 ),

+                  ((UINT32)DivU64x32 ( NanoSeconds, 1000 * 1000 )) % 1000 ));

+

+        //

+        //  Display the round trip time

+        //

+        Bandwidth = MultU64x32 ( Bandwidth, 8 * 1000 * 1000 );

+        Bandwidth /= NanoSeconds;

+        if ( 1000 > Bandwidth ) {

+          Value = (UINT32)Bandwidth;

+          Print ( L"Bandwidth: %d Kbits/Sec\r\n",

+                  Value );

+        }

+        else if (( 1000 * 1000 ) > Bandwidth ) {

+          Value = (UINT32)Bandwidth;

+          Print ( L"Bandwidth: %d.%03d Mbits/Sec\r\n",

+                  Value / 1000,

+                  Value % 1000 );

+        }

+        else {

+          Value = (UINT32)DivU64x32 ( Bandwidth, 1000 );

+          Print ( L"Bandwidth: %d.%03d Gbits/Sec\r\n",

+                  Value / 1000,

+                  Value % 1000 );

+        }

+      }

+    }

+    break;

+  }

+

+  //

+  //  Return the operation status

+  //

+  DBG_EXIT ( );

+  return bCloseContext;

+}

+

+

+/**

+  Get the next TFTP option

+

+  @param [in] pOption       Address of a zero terminated option string

+  @param [in] pEnd          End of buffer address

+  @param [in] ppNextOption  Address to receive the address of the next

+                            zero terminated option string

+

+  @retval EFI_SUCCESS   Message processed successfully

+

+**/

+EFI_STATUS

+TftpOptionGet (

+  IN UINT8 * pOption,

+  IN UINT8 * pEnd,

+  IN UINT8 ** ppNextOption

+  )

+{

+  UINT8 * pNextOption;

+  EFI_STATUS Status;

+

+  //

+  //  Locate the end of the option

+  //

+  pNextOption = pOption;

+  while (( pEnd > pNextOption ) && ( 0 != *pNextOption )) {

+    pNextOption += 1;

+  }

+  if ( pEnd <= pNextOption ) {

+    //

+    //  Error - end of buffer reached

+    //

+    DEBUG (( DEBUG_ERROR | DEBUG_TFTP_REQUEST,

+              "ERROR - Option without zero termination received!\r\n" ));

+    Status = EFI_INVALID_PARAMETER;

+  }

+  else {

+    //

+    //  Zero terminated option found

+    //

+    pNextOption += 1;

+

+    //

+    //  Display the zero terminated ASCII option string

+    //

+    DEBUG (( DEBUG_TFTP_REQUEST,

+              "Option: %a\r\n",

+              pOption ));

+    Status = EFI_SUCCESS;

+  }

+

+  //

+  //  Return the next option address

+  //

+  *ppNextOption = pNextOption;

+

+  //

+  //  Return the operation status

+  //

+  return Status;

+}

+

+

+/**

+  Place an option value into the option acknowledgement

+

+  @param [in] pOack     Option acknowledgement address

+  @param [in] Value     Value to translate into ASCII decimal

+

+  @return               Option acknowledgement address

+

+**/

+UINT8 *

+TftpOptionSet (

+  IN UINT8 * pOack,

+  IN UINT64 Value

+  )

+{

+  UINT64 NextValue;

+

+  //

+  //  Determine the next value

+  //

+  NextValue = Value / 10;

+

+  //

+  //  Supress leading zeros

+  //

+  if ( 0 != NextValue ) {

+    pOack = TftpOptionSet ( pOack, NextValue );

+  }

+

+  //

+  //  Output this digit

+  //

+  *pOack++ = (UINT8)( Value - ( NextValue * 10 ) + '0' );

+

+  //

+  //  Return the next option acknowledgement location

+  //

+  return pOack;

+}

+

+

+/**

+  Process the TFTP request

+

+  @param [in] pContext  Address of a ::TSDT_CONNECTION_CONTEXT structure

+  @param [in] pOption   Address of the first zero terminated option string

+  @param [in] pEnd      End of buffer address

+

+**/

+VOID

+TftpOptions (

+  IN TSDT_CONNECTION_CONTEXT * pContext,

+  IN UINT8 * pOption,

+  IN UINT8 * pEnd

+  )

+{

+  UINT8 * pNextOption;

+  UINT8 * pOack;

+  TFTP_PACKET * pPacket;

+  UINT8 * pTemp;

+  UINT8 * pValue;

+  EFI_STATUS Status;

+  INT32 Value;

+

+  //

+  //  Get a packet

+  //

+  pPacket = PacketGet ( pContext );

+

+  //

+  //  Start the OACK packet

+  //  Let the OACK handle the parsing errors

+  //  See http://tools.ietf.org/html/rfc2347

+  //

+  pOack = &pPacket->TxBuffer[ 0 ];

+  *pOack++ = 0;

+  *pOack++ = TFTP_OP_OACK;

+  pPacket->TxBytes = 2;

+  pPacket->BlockNumber = 0;

+

+  //

+  //  Walk the list of options

+  //

+  do {

+    //

+    //  Get the next option, skip junk at end of message

+    //

+    Status = TftpOptionGet ( pOption, pEnd, &pNextOption );

+    if ( !EFI_ERROR ( Status )) {

+      //

+      //  Process the option

+      //

+

+      //

+      //  blksize - See http://tools.ietf.org/html/rfc2348

+      //

+      pValue = pNextOption;

+      if ( 0 == strcasecmp ((char *)pOption, "blksize" )) {

+        //

+        //  Get the value

+        //

+        Status = TftpOptionGet ( pValue, pEnd, &pNextOption );

+        if ( !EFI_ERROR ( Status )) {

+          //

+          //  Validate the block size, skip non-numeric block sizes

+          //

+          Status = TftpOptionValue ( pValue, &Value );

+          if ( !EFI_ERROR ( Status )) {

+            //

+            //  Propose a smaller block size if necessary

+            //

+            if ( Value > TFTP_MAX_BLOCK_SIZE ) {

+              Value = TFTP_MAX_BLOCK_SIZE;

+            }

+

+            //

+            //  Set the new block size

+            //

+            pContext->BlockSize = Value;

+            DEBUG (( DEBUG_TFTP_REQUEST,

+                      "Using block size of %d bytes\r\n",

+                      pContext->BlockSize ));

+

+            //

+            //  Update the OACK

+            //

+            pTemp = pOack;

+            *pOack++ = 'b';

+            *pOack++ = 'l';

+            *pOack++ = 'k';

+            *pOack++ = 's';

+            *pOack++ = 'i';

+            *pOack++ = 'z';

+            *pOack++ = 'e';

+            *pOack++ = 0;

+            pOack = TftpOptionSet ( pOack, pContext->BlockSize );

+            *pOack++ = 0;

+            pPacket->TxBytes += pOack - pTemp;

+          }

+        }

+      }

+

+      //

+      //  timeout - See http://tools.ietf.org/html/rfc2349

+      //

+      else if ( 0 == strcasecmp ((char *)pOption, "timeout" )) {

+        //

+        //  Get the value

+        //

+        Status = TftpOptionGet ( pValue, pEnd, &pNextOption );

+        if ( !EFI_ERROR ( Status )) {

+          Status = TftpOptionValue ( pValue, &Value );

+          if ( !EFI_ERROR ( Status )) {

+            //

+            //  Set the timeout value

+            //

+            pContext->MaxTimeout = Value;

+            DEBUG (( DEBUG_TFTP_REQUEST,

+                      "Using timeout of %d seconds\r\n",

+                      pContext->MaxTimeout ));

+

+            //

+            //  Update the OACK

+            //

+            pTemp = pOack;

+            *pOack++ = 't';

+            *pOack++ = 'i';

+            *pOack++ = 'm';

+            *pOack++ = 'e';

+            *pOack++ = 'o';

+            *pOack++ = 'u';

+            *pOack++ = 't';

+            *pOack++ = 0;

+            pOack = TftpOptionSet ( pOack, pContext->MaxTimeout );

+            *pOack++ = 0;

+            pPacket->TxBytes += pOack - pTemp;

+          }

+        }

+      }

+

+      //

+      //  tsize - See http://tools.ietf.org/html/rfc2349

+      //

+      else if ( 0 == strcasecmp ((char *)pOption, "tsize" )) {

+        //

+        //  Get the value

+        //

+        Status = TftpOptionGet ( pValue, pEnd, &pNextOption );

+        if ( !EFI_ERROR ( Status )) {

+          Status = TftpOptionValue ( pValue, &Value );

+          if ( !EFI_ERROR ( Status )) {

+            //

+            //  Return the file size

+            //

+            DEBUG (( DEBUG_TFTP_REQUEST,

+                      "Returning file size of %Ld bytes\r\n",

+                      pContext->LengthInBytes ));

+

+            //

+            //  Update the OACK

+            //

+            pTemp = pOack;

+            *pOack++ = 't';

+            *pOack++ = 's';

+            *pOack++ = 'i';

+            *pOack++ = 'z';

+            *pOack++ = 'e';

+            *pOack++ = 0;

+            pOack = TftpOptionSet ( pOack, pContext->LengthInBytes );

+            *pOack++ = 0;

+            pPacket->TxBytes += pOack - pTemp;

+          }

+        }

+      }

+      else {

+        //

+        //  Unknown option - Ignore it

+        //

+        DEBUG (( DEBUG_WARN | DEBUG_TFTP_REQUEST,

+                  "WARNING - Skipping unknown option: %a\r\n",

+                  pOption ));

+      }

+    }

+

+    //

+    //  Set the next option

+    //

+    pOption = pNextOption;

+  } while ( pEnd > pOption );

+

+  //

+  //  Transmit the OACK if necessary

+  //

+  if ( 2 < pPacket->TxBytes ) {

+    PacketQueue ( pContext, pPacket );

+  }

+  else {

+    PacketFree ( pContext, pPacket );

+  }

+}

+

+

+/**

+  Process the TFTP request

+

+  @param [in] pOption   Address of the first zero terminated option string

+  @param [in] pValue    Address to receive the value

+

+  @retval EFI_SUCCESS   Option translated into a value

+

+**/

+EFI_STATUS

+TftpOptionValue (

+  IN UINT8 * pOption,

+  IN INT32 * pValue

+  )

+{

+  UINT8 Digit;

+  EFI_STATUS Status;

+  INT32 Value;

+

+  //

+  //  Assume success

+  //

+  Status = EFI_SUCCESS;

+

+  //

+  //  Walk the characters in the option

+  //

+  Value = 0;

+  while ( 0 != *pOption ) {

+    //

+    //  Convert the next digit to binary

+    //

+    Digit = *pOption++;

+    if (( '0' <= Digit ) && ( '9' >= Digit )) {

+      Value *= 10;

+      Value += Digit - '0';

+    }

+    else {

+      DEBUG (( DEBUG_ERROR | DEBUG_TFTP_REQUEST,

+                "ERROR - Invalid character '0x%02x' in the value\r\n",

+                Digit ));

+      Status = EFI_INVALID_PARAMETER;

+      break;

+    }

+  }

+

+  //

+  //  Return the value

+  //

+  *pValue = Value;

+

+  //

+  //  Return the conversion status

+  //

+  return Status;

+}

+

+

+/**

+  Process the TFTP request

+

+  @param [in] pTftpServer Address of the ::TSDT_TFTP_SERVER structure

+  @param [in] pContext    Address of a ::TSDT_CONNECTION_CONTEXT structure

+  @param [in] SocketFd    Socket file descriptor

+

+**/

+VOID

+TftpProcessRequest (

+  IN TSDT_TFTP_SERVER * pTftpServer,

+  IN TSDT_CONNECTION_CONTEXT * pContext,

+  IN int SocketFd

+  )

+{

+  BOOLEAN bCloseContext;

+  UINT16 Opcode;

+

+  DBG_ENTER ( );

+

+  //

+  //  Get the opcode

+  //

+  Opcode = HTONS ( *(UINT16 *)&pTftpServer->RxBuffer[ 0 ]);

+  DEBUG (( DEBUG_TFTP_REQUEST,

+            "TFTP Opcode: 0x%08x\r\n",

+            Opcode ));

+

+  //

+  //  Validate the parameters

+  //

+  bCloseContext = FALSE;

+  switch ( Opcode ) {

+  default:

+    DEBUG (( DEBUG_TFTP_REQUEST,

+              "ERROR - Unknown TFTP opcode: %d\r\n",

+              Opcode ));

+    break;

+

+  case TFTP_OP_ACK:

+    bCloseContext = TftpAck ( pTftpServer, pContext );

+    break;

+

+  case TFTP_OP_READ_REQUEST:

+    bCloseContext = TftpRead ( pTftpServer, pContext, SocketFd );

+    break;

+

+

+

+  

+  case TFTP_OP_DATA:

+    if ( NULL == pContext ) {

+      if ( AF_INET == pTftpServer->RemoteAddress.v4.sin_family ) {

+        DEBUG (( DEBUG_ERROR,

+                  "ERROR - File not open for %d.%d.%d.%d:%d\r\n",

+                  (UINT8)pTftpServer->RemoteAddress.v4.sin_addr.s_addr,

+                  (UINT8)( pTftpServer->RemoteAddress.v4.sin_addr.s_addr >> 8 ),

+                  (UINT8)( pTftpServer->RemoteAddress.v4.sin_addr.s_addr >> 16 ),

+                  (UINT8)( pTftpServer->RemoteAddress.v4.sin_addr.s_addr >> 24 ),

+                  htons ( pTftpServer->RemoteAddress.v4.sin_port )));

+      }

+      else {

+        DEBUG (( DEBUG_ERROR,

+                  "ERROR - File not open for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 0 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 1 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 2 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 3 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 4 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 5 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 6 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 7 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 8 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 9 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 10 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 11 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 12 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 13 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 14 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 15 ],

+                  htons ( pTftpServer->RemoteAddress.v6.sin6_port )));

+      }

+      break;

+    }

+    if ( 0 != pContext->PacketsInWindow ) {

+      DEBUG (( DEBUG_ERROR,

+                "ERROR - Expecting ACKs not data for pContext 0x%08x\r\n",

+                pContext ));

+      break;

+    }

+    if ( pTftpServer->RxBytes > (ssize_t)( pContext->BlockSize + 2 + 2 )) {

+      DEBUG (( DEBUG_ERROR,

+                "ERROR - Receive data length of %d > %d bytes (maximum block size) for pContext 0x%08x\r\n",

+                pTftpServer->RxBytes - 2 - 2,

+                pContext->BlockSize,

+                pContext ));

+      break;

+    }

+    break;

+

+  case TFTP_OP_ERROR:

+    if ( NULL == pContext ) {

+      if ( AF_INET == pTftpServer->RemoteAddress.v4.sin_family ) {

+        DEBUG (( DEBUG_ERROR,

+                  "ERROR - File not open for %d.%d.%d.%d:%d\r\n",

+                  (UINT8)pTftpServer->RemoteAddress.v4.sin_addr.s_addr,

+                  (UINT8)( pTftpServer->RemoteAddress.v4.sin_addr.s_addr >> 8 ),

+                  (UINT8)( pTftpServer->RemoteAddress.v4.sin_addr.s_addr >> 16 ),

+                  (UINT8)( pTftpServer->RemoteAddress.v4.sin_addr.s_addr >> 24 ),

+                  htons ( pTftpServer->RemoteAddress.v4.sin_port )));

+      }

+      else {

+        DEBUG (( DEBUG_ERROR,

+                  "ERROR - File not open for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 0 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 1 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 2 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 3 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 4 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 5 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 6 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 7 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 8 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 9 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 10 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 11 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 12 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 13 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 14 ],

+                  pTftpServer->RemoteAddress.v6.sin6_addr.__u6_addr.__u6_addr8[ 15 ],

+                  htons ( pTftpServer->RemoteAddress.v6.sin6_port )));

+      }

+    }

+    break;

+  }

+

+  //

+  //  Determine if the context should be closed

+  //

+  if ( bCloseContext ) {

+    ContextRemove ( pTftpServer, pContext );

+  }

+

+  DBG_EXIT ( );

+}

+

+

+/**

+  Process the read request

+

+  @param [in] pTftpServer Address of the ::TSDT_TFTP_SERVER structure

+  @param [in] pContext    Address of a ::TSDT_CONNECTION_CONTEXT structure

+  @param [in] SocketFd    Socket file descriptor

+

+  @retval TRUE if the context should be closed

+

+**/

+BOOLEAN

+TftpRead (

+  IN TSDT_TFTP_SERVER * pTftpServer,

+  IN TSDT_CONNECTION_CONTEXT * pContext,

+  IN int SocketFd

+  )

+{

+  BOOLEAN bCloseContext;

+  struct stat FileStatus;

+  UINT8 * pBuffer;

+  UINT8 * pEnd;

+  UINT8 * pFileName;

+  UINT8 * pMode;

+  UINT8 * pOption;

+  CHAR8 * pReadMode;

+  UINT64 TimeStart;

+

+  DBG_ENTER ( );

+

+  //

+  //  Log the receive time

+  //

+  TimeStart = 0;

+  if ( PcdGetBool ( Tftp_Bandwidth )) {

+    TimeStart = GetPerformanceCounter ( );

+  }

+

+  //

+  //  Close the context if necessary

+  //

+  bCloseContext = FALSE;

+  if ( NULL != pContext ) {

+    ContextRemove ( pTftpServer, pContext );

+  }

+

+  //

+  //  Use break instead of goto

+  //

+  for ( ; ; ) {

+    //

+    //  Create the connection context

+    //

+    pContext = ContextAdd ( pTftpServer, SocketFd );

+    if ( NULL == pContext ) {

+      break;

+    }

+

+    //

+    //  Set the start time

+    //

+    if ( PcdGetBool ( Tftp_Bandwidth )) {

+      pContext->TimeStart = TimeStart;

+    }

+

+    //

+    //  Locate the mode

+    //

+    pBuffer = &pTftpServer->RxBuffer[ 0 ];

+    pEnd = &pBuffer[ pTftpServer->RxBytes ];

+    pFileName = &pBuffer[ 2 ];

+    pMode = pFileName;

+    while (( pEnd > pMode ) && ( 0 != *pMode )) {

+      pMode += 1;

+    }

+    if ( pEnd <= pMode ) {

+      //

+      //  Mode not found

+      //

+      DEBUG (( DEBUG_ERROR | DEBUG_RX,

+                "ERROR - File mode not found\r\n" ));

+      //

+      //  Tell the client of the error

+      //

+      SendError ( pContext,

+                  TFTP_ERROR_SEE_MSG,

+                  (UINT8 *)"File open mode not found" );

+      break;

+    }

+    pMode += 1;

+    DEBUG (( DEBUG_TFTP_REQUEST,

+              "TFTP - FileName: %a\r\n",

+              pFileName ));

+

+    //

+    //  Locate the options

+    //

+    pOption = pMode;

+    while (( pEnd > pOption ) && ( 0 != *pOption )) {

+      pOption += 1;

+    }

+    if ( pEnd <= pOption ) {

+      //

+      //  End of mode not found

+      //

+      DEBUG (( DEBUG_ERROR | DEBUG_RX,

+                "ERROR - File mode not valid\r\n" ));

+      //

+      //  Tell the client of the error

+      //

+      SendError ( pContext,

+                  TFTP_ERROR_SEE_MSG,

+                  (UINT8 *)"File open mode not valid" );

+      break;

+    }

+    pOption += 1;

+    DEBUG (( DEBUG_TFTP_REQUEST,

+              "TFTP - Mode: %a\r\n",

+              pMode ));

+

+    //

+    //  Verify the mode is supported

+    //

+    pReadMode = "r";

+    if ( 0 == strcasecmp ((char *)pMode, "octet" )) {

+      //

+      //  Read the file as binary input

+      //

+      pReadMode = "rb";

+    }

+

+    //

+    //  Determine the file length

+    //

+    pContext->File = fopen ((const char *)pFileName, pReadMode );

+    if (( NULL == pContext->File )

+        || ( -1 == stat ((const char *)pFileName, &FileStatus ))) {

+      //

+      //  File not found

+      //

+      DEBUG (( DEBUG_ERROR | DEBUG_TFTP_REQUEST,

+                ( NULL == pContext->File )

+                ? "ERROR - File not found!\r\n"

+                : "ERROR - Unable to determine file %a size!\r\n",

+                pFileName ));

+

+      //

+      //  Tell the client of the error

+      //

+      SendError ( pContext,

+                  TFTP_ERROR_NOT_FOUND,

+                  (UINT8 *)"File not found" );

+      break;

+    }

+    pContext->LengthInBytes = FileStatus.st_size;

+    pContext->BytesRemaining = pContext->LengthInBytes;

+    pContext->BytesToSend = pContext->LengthInBytes;

+

+    //

+    //  Display the file size

+    //

+    DEBUG_CODE_BEGIN ( );

+    UINT32 Value;

+

+    if ( 1024 > pContext->LengthInBytes ) {

+      Value = (UINT32)pContext->LengthInBytes;

+      DEBUG (( DEBUG_FILE_BUFFER,

+                "%a size: %d Bytes\r\n",

+                pFileName,

+                Value ));

+    }

+    else if (( 1024 * 1024 ) > pContext->LengthInBytes ) {

+      Value = (UINT32)pContext->LengthInBytes;

+      DEBUG (( DEBUG_FILE_BUFFER,

+                "%a size: %d.%03d KiBytes (%Ld Bytes)\r\n",

+                pFileName,

+                Value / 1024,

+                (( Value % 1024 ) * 1000 ) / 1024,

+                pContext->LengthInBytes ));

+    }

+    else if (( 1024 * 1024 * 1024 ) > pContext->LengthInBytes ) {

+      Value = (UINT32)DivU64x32 ( pContext->LengthInBytes, 1024 );

+      DEBUG (( DEBUG_FILE_BUFFER,

+                "%a size: %d.%03d MiBytes (%Ld Bytes)\r\n",

+                pFileName,

+                Value / 1024,

+                (( Value % 1024 ) * 1000 ) / 1024,

+                pContext->LengthInBytes ));

+    }

+    else {

+      Value = (UINT32)DivU64x32 ( pContext->LengthInBytes, 1024 * 1024 );

+      DEBUG (( DEBUG_FILE_BUFFER,

+                "%a size: %d.%03d GiBytes (%Ld Bytes)\r\n",

+                pFileName,

+                Value / 1024,

+                (( Value % 1024 ) * 1000 ) / 1024,

+                pContext->LengthInBytes ));

+    }

+    DEBUG_CODE_END ( );

+

+    //

+    //  Process the options

+    //

+    if ( pEnd > pOption ) {

+      TftpOptions ( pContext, pOption, pEnd );

+    }

+    else {

+      //

+      //  Skip the open ACK

+      //

+      pContext->BlockNumber = 1;

+    }

+

+    //

+    //  Send the first packet (OACK or data block)

+    //

+    bCloseContext = PacketFill ( pContext );

+    break;

+  }

+

+  //

+  //  Return the close status

+  //

+  DBG_EXIT ( );

+  return bCloseContext;

+}

+

+

+/**

+  Create the port for the TFTP server

+

+  This routine polls the network layer to create the TFTP port for the

+  TFTP server.  More than one attempt may be necessary since it may take

+  some time to get the IP address and initialize the upper layers of

+  the network stack.

+

+  @param [in] pTftpServer   Address of the ::TSDT_TFTP_SERVER structure

+  @param [in] AddressFamily The address family to use for the conection.

+  @param [in] pIndex        Address of the index into the port array

+

+**/

+VOID

+TftpServerSocket (

+  IN TSDT_TFTP_SERVER * pTftpServer,

+  IN sa_family_t AddressFamily,

+  IN int * pIndex

+  )

+{

+  int SocketStatus;

+  struct pollfd * pTftpPort;

+  UINT16 TftpPort;

+  union {

+    struct sockaddr_in v4;

+    struct sockaddr_in6 v6;

+  } TftpServerAddress;

+

+  DEBUG (( DEBUG_SERVER_TIMER, "Entering TftpServerListen\r\n" ));

+

+  //

+  //  Determine if the socket is already initialized

+  //

+  if ( -1 == *pIndex ) {

+    //

+    //  Attempt to create the socket for the TFTP server

+    //

+    pTftpPort = &pTftpServer->TftpPort[ pTftpServer->Entries ];

+    pTftpPort->fd = socket ( AddressFamily,

+                             SOCK_DGRAM,

+                             IPPROTO_UDP );

+    if ( -1 != pTftpPort->fd ) {

+      //

+      //  Initialize the poll structure

+      //

+      pTftpPort->events = POLLRDNORM | POLLHUP;

+      pTftpPort->revents = 0;

+

+      //

+      //  Set the socket address

+      //

+      TftpPort = 69;

+      ZeroMem ( &TftpServerAddress, sizeof ( TftpServerAddress ));

+      TftpServerAddress.v4.sin_port = htons ( TftpPort );

+      if ( AF_INET == AddressFamily ) {

+        TftpServerAddress.v4.sin_len = sizeof ( TftpServerAddress.v4 );

+        TftpServerAddress.v4.sin_family = AF_INET;

+      }

+      else {

+        TftpServerAddress.v6.sin6_len = sizeof ( TftpServerAddress.v6 );

+        TftpServerAddress.v6.sin6_family = AF_INET6;

+      }

+

+      //

+      //  Bind the socket to the TFTP port

+      //

+      SocketStatus = bind ( pTftpPort->fd,

+                            (struct sockaddr *) &TftpServerAddress,

+                            TftpServerAddress.v6.sin6_len );

+      if ( -1 != SocketStatus ) {

+        DEBUG (( DEBUG_TFTP_PORT,

+                  "0x%08x: Socket bound to port %d\r\n",

+                  pTftpPort->fd,

+                  TftpPort ));

+

+        //

+        //  Account for this connection

+        //

+        *pIndex = pTftpServer->Entries;

+        pTftpServer->Entries += 1;

+        ASSERT ( DIM ( pTftpServer->TftpPort ) >= pTftpServer->Entries );

+      }

+

+      //

+      //  Release the socket if necessary

+      //

+      if ( -1 == SocketStatus ) {

+        close ( pTftpPort->fd );

+        pTftpPort->fd = -1;

+      }

+    }

+  }

+

+  DEBUG (( DEBUG_SERVER_TIMER, "Exiting TftpServerListen\r\n" ));

+}

+

+

+/**

+  Update the window due to the ACK

+

+  @param [in] pTftpServer Address of the ::TSDT_TFTP_SERVER structure

+  @param [in] pContext    Address of a ::TSDT_CONNECTION_CONTEXT structure

+  @param [in] pPacket     Address of a ::TFTP_PACKET structure

+

+**/

+VOID

+WindowAck (

+  IN TSDT_TFTP_SERVER * pTftpServer,

+  IN TSDT_CONNECTION_CONTEXT * pContext,

+  IN TFTP_PACKET * pPacket

+  )

+{

+  if ( PcdGetBool ( Tftp_HighSpeed )) {

+    UINT64 DeltaTime;

+    UINT64 NanoSeconds;

+

+    DBG_ENTER ( );

+

+    //

+    //  Compute the round trip time

+    //

+    if ( pTftpServer->Time2 > pTftpServer->Time1 ) {

+      DeltaTime = pTftpServer->RxTime - pPacket->TxTime;

+    }

+    else {

+      DeltaTime = pPacket->TxTime - pTftpServer->RxTime;

+    }

+

+    //

+    //  Adjust the round trip time

+    //

+    NanoSeconds = GetTimeInNanoSecond ( DeltaTime );

+    DeltaTime = RShiftU64 ( pContext->Rtt2x, ACK_SHIFT );

+    pContext->Rtt2x += NanoSeconds + NanoSeconds - DeltaTime;

+    if ( pContext->Rtt2x > pContext->MaxTimeout ) {

+      pContext->Rtt2x = pContext->MaxTimeout;

+    }

+

+    //

+    //  Account for the ACK

+    //

+    if ( pContext->WindowSize < MAX_PACKETS ) {

+      pContext->AckCount -= 1;

+      if ( 0 == pContext->AckCount ) {

+        //

+        //  Increase the window

+        //

+        pContext->WindowSize += 1;

+

+        //

+        //  Set the ACK count

+        //

+        if ( pContext->WindowSize < pContext->Threshold ) {

+          pContext->AckCount = pContext->WindowSize * PcdGet32 ( Tftp_AckMultiplier );

+        }

+        else {

+          pContext->AckCount = PcdGet32 ( Tftp_AckLogBase ) << pContext->WindowSize;

+        }

+

+        //

+        //  Display the round trip time

+        //

+        DEBUG_CODE_BEGIN ( );

+        UINT32 Value;

+        

+        DeltaTime = RShiftU64 ( pContext->Rtt2x, 1 );

+        if ( 1000 > DeltaTime ) {

+          DEBUG (( DEBUG_WINDOW,

+                    "WindowSize: %d, Threshold: %d, AckCount: %4d, RTT: %Ld nSec\r\n",

+                    pContext->WindowSize,

+                    pContext->Threshold,

+                    pContext->AckCount,

+                    DeltaTime ));

+        }

+        else if (( 1000 * 1000 ) > DeltaTime ) {

+          Value = (UINT32)DeltaTime;

+          DEBUG (( DEBUG_WINDOW,

+                    "WindowSize: %d, Threshold: %d, AckCount: %4d, RTT: %d.%03d uSec\r\n",

+                    pContext->WindowSize,

+                    pContext->Threshold,

+                    pContext->AckCount,

+                    Value / 1000,

+                    Value % 1000 ));

+        }

+        else if (( 1000 * 1000 * 1000 ) > DeltaTime ) {

+          Value = (UINT32)DivU64x32 ( DeltaTime, 1000 );

+          DEBUG (( DEBUG_WINDOW,

+                    "WindowSize: %d, Threshold: %d, AckCount: %4d, RTT: %d.%03d mSec\r\n",

+                    pContext->WindowSize,

+                    pContext->Threshold,

+                    pContext->AckCount,

+                    Value / 1000,

+                    Value % 1000 ));

+        }

+        else {

+          Value = (UINT32)DivU64x32 ( DeltaTime, 1000 * 1000 );

+          DEBUG (( DEBUG_WINDOW,

+                    "WindowSize: %d, Threshold: %d, AckCount: %4d, RTT: %d.%03d Sec\r\n",

+                    pContext->WindowSize,

+                    pContext->Threshold,

+                    pContext->AckCount,

+                    Value / 1000,

+                    Value % 1000 ));

+        }

+        DEBUG_CODE_END ( );

+      }

+    }

+

+    DBG_EXIT ( );

+  }

+}

+

+

+/**

+  A timeout has occurred, close the window

+

+  @param [in] pContext    Address of a ::TSDT_CONNECTION_CONTEXT structure

+

+**/

+VOID

+WindowTimeout (

+  IN TSDT_CONNECTION_CONTEXT * pContext

+  )

+{

+  if ( PcdGetBool ( Tftp_HighSpeed )) {

+    TFTP_PACKET * pPacket;

+

+    DBG_ENTER ( );

+

+    //

+    //  Set the threshold at half the previous window size

+    //

+    pContext->Threshold = ( pContext->WindowSize + 1 ) >> 1;

+

+    //

+    //  Close the transmit window

+    //

+    pContext->WindowSize = 1;

+    pContext->PacketsInWindow = 0;

+

+    //

+    //  Double the round trip time

+    //

+    pContext->Rtt2x = LShiftU64 ( pContext->Rtt2x, 1 );

+    if ( pContext->Rtt2x > pContext->MaxTimeout ) {

+      pContext->Rtt2x = pContext->MaxTimeout;

+    }

+

+    //

+    //  Set the ACK count

+    //

+    if ( pContext->WindowSize < pContext->Threshold ) {

+      pContext->AckCount = pContext->WindowSize * PcdGet32 ( Tftp_AckMultiplier );

+    }

+    else {

+      pContext->AckCount = PcdGet32 ( Tftp_AckLogBase ) << pContext->WindowSize;

+    }

+

+    //

+    //  Display the round trip time

+    //

+    DEBUG_CODE_BEGIN ( );

+    UINT64 DeltaTime;

+    UINT32 Value;

+    

+    DeltaTime = RShiftU64 ( pContext->Rtt2x, 1 );

+    if ( 1000 > DeltaTime ) {

+      DEBUG (( DEBUG_WINDOW,

+                "WindowSize: %d, Threshold: %d, AckCount: %4d, RTT: %Ld nSec\r\n",

+                pContext->WindowSize,

+                pContext->Threshold,

+                pContext->AckCount,

+                DeltaTime ));

+    }

+    else if (( 1000 * 1000 ) > DeltaTime ) {

+      Value = (UINT32)DeltaTime;

+      DEBUG (( DEBUG_WINDOW,

+                "WindowSize: %d, Threshold: %d, AckCount: %4d, RTT: %d.%03d uSec\r\n",

+                pContext->WindowSize,

+                pContext->Threshold,

+                pContext->AckCount,

+                Value / 1000,

+                Value % 1000 ));

+    }

+    else if (( 1000 * 1000 * 1000 ) > DeltaTime ) {

+      Value = (UINT32)DivU64x32 ( DeltaTime, 1000 );

+      DEBUG (( DEBUG_WINDOW,

+                "WindowSize: %d, Threshold: %d, AckCount: %4d, RTT: %d.%03d mSec\r\n",

+                pContext->WindowSize,

+                pContext->Threshold,

+                pContext->AckCount,

+                Value / 1000,

+                Value % 1000 ));

+    }

+    else {

+      Value = (UINT32)DivU64x32 ( DeltaTime, 1000 * 1000 );

+      DEBUG (( DEBUG_WINDOW,

+                "WindowSize: %d, Threshold: %d, AckCount: %4d, RTT: %d.%03d Sec\r\n",

+                pContext->WindowSize,

+                pContext->Threshold,

+                pContext->AckCount,

+                Value / 1000,

+                Value % 1000 ));

+    }

+    DEBUG_CODE_END ( );

+

+    //

+    //  Retransmit the first packet in the window

+    //

+    pPacket = pContext->pTxHead;

+    if ( NULL != pPacket ) {

+      PacketTx ( pContext, pPacket );

+    }

+    

+    DBG_EXIT ( );

+  }

+}

+

+

+/**

+  Entry point for the TFTP server application.

+

+  @param [in] Argc  The number of arguments

+  @param [in] Argv  The argument value array

+

+  @retval  0        The application exited normally.

+  @retval  Other    An error occurred.

+**/

+int

+main (

+  IN int Argc,

+  IN char **Argv

+  )

+{

+  UINTN Index;

+  TSDT_TFTP_SERVER * pTftpServer;

+  EFI_STATUS Status;

+  UINT64 TriggerTime;

+

+  //

+  //  Get the performance counter characteristics

+  //

+  pTftpServer = &mTftpServer;

+  if ( PcdGetBool ( Tftp_HighSpeed )

+    || PcdGetBool ( Tftp_Bandwidth )) {

+    pTftpServer->ClockFrequency = GetPerformanceCounterProperties ( &pTftpServer->Time1,

+                                                                  &pTftpServer->Time2 );

+  }

+

+  //

+  //  Create a timer event to start TFTP port

+  //

+  Status = gBS->CreateEvent ( EVT_TIMER,

+                              TPL_TFTP_SERVER,

+                              NULL,

+                              NULL,

+                              &pTftpServer->TimerEvent );

+  if ( !EFI_ERROR ( Status )) {

+    //

+    //  Compute the poll interval

+    //

+    TriggerTime = TFTP_PORT_POLL_DELAY * ( 1000 * 10 );

+    Status = gBS->SetTimer ( pTftpServer->TimerEvent,

+                             TimerPeriodic,

+                             TriggerTime );

+    if ( !EFI_ERROR ( Status )) {

+      DEBUG (( DEBUG_TFTP_PORT, "TFTP port timer started\r\n" ));

+

+      //

+      //  Run the TFTP server forever

+      //

+      pTftpServer->Udpv4Index = -1;

+      pTftpServer->Udpv6Index = -1;

+      do {

+        //

+        //  Poll the network layer to create the TFTP port

+        //  for the tftp server.  More than one attempt may

+        //  be necessary since it may take some time to get

+        //  the IP address and initialize the upper layers

+        //  of the network stack.

+        //

+        if ( DIM ( pTftpServer->TftpPort ) != pTftpServer->Entries ) {

+          do {

+            //

+            //  Wait a while before polling for a connection

+            //

+            if ( EFI_SUCCESS != gBS->CheckEvent ( pTftpServer->TimerEvent )) {

+              if ( 0 == pTftpServer->Entries ) {

+                break;

+              }

+              gBS->WaitForEvent ( 1, &pTftpServer->TimerEvent, &Index );

+            }

+

+            //

+            //  Poll for a network connection

+            //

+            TftpServerSocket ( pTftpServer,

+                               AF_INET,

+                               &pTftpServer->Udpv4Index );

+            TftpServerSocket ( pTftpServer,

+                               AF_INET6,

+                               &pTftpServer->Udpv6Index );

+          } while ( 0 == pTftpServer->Entries );

+        }

+

+        //

+        //  Poll the socket for activity

+        //

+        do {

+          SocketPoll ( pTftpServer );

+

+          //

+          //  Normal TFTP lets the client request the retransmit by

+          //  sending another ACK for the previous packet

+          //

+          if ( PcdGetBool ( Tftp_HighSpeed )) {

+            UINT64 CurrentTime;

+            UINT64 ElapsedTime;

+            TSDT_CONNECTION_CONTEXT * pContext;

+            TFTP_PACKET * pPacket;

+

+            //

+            //  High speed TFTP uses an agressive retransmit to

+            //  get the TFTP client moving again when the ACK or

+            //  previous data packet was lost.

+            //

+            //  Get the current time

+            //

+            CurrentTime = GetPerformanceCounter ( );

+

+            //

+            //  Walk the list of contexts

+            //

+            pContext = pTftpServer->pContextList;

+            while ( NULL != pContext )

+            {

+              //

+              //  Check for a transmit timeout

+              //

+              pPacket = pContext->pTxHead;

+              if ( NULL != pPacket ) {

+                //

+                //  Compute the elapsed time

+                //

+                if ( pTftpServer->Time2 > pTftpServer->Time1 ) {

+                  ElapsedTime = CurrentTime - pPacket->TxTime;

+                }

+                else {

+                  ElapsedTime = pPacket->TxTime - CurrentTime;

+                }

+                ElapsedTime = GetTimeInNanoSecond ( ElapsedTime );

+

+                //

+                //  Determine if a retransmission is necessary

+                //

+                if ( ElapsedTime >= pContext->Rtt2x ) {

+                  DEBUG (( DEBUG_WINDOW,

+                            "0x%08x: Context TX timeout for packet 0x%08x, Window: %d\r\n",

+                            pContext,

+                            pPacket,

+                            pContext->WindowSize ));

+                  WindowTimeout ( pContext );

+                }

+              }

+

+              //

+              //  Set the next context

+              //

+              pContext = pContext->pNext;

+            }

+          }

+        } while ( DIM ( pTftpServer->TftpPort ) == pTftpServer->Entries );

+      } while ( !mbTftpServerExit );

+

+      //

+      //  Done with the timer event

+      //

+      gBS->SetTimer ( pTftpServer->TimerEvent,

+                      TimerCancel,

+                      0 );

+    }

+    gBS->CloseEvent ( pTftpServer->TimerEvent );

+  }

+

+  //

+  //  Return the final status

+  //

+  DBG_EXIT_STATUS ( Status );

+  return Status;

+}

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/TftpServer/TftpServer.h b/uefi/linaro-edk2/AppPkg/Applications/Sockets/TftpServer/TftpServer.h
new file mode 100644
index 0000000..2166893
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/TftpServer/TftpServer.h
@@ -0,0 +1,431 @@
+/** @file

+  Definitions for the TFTP server.

+

+  Copyright (c) 2011, 2012, Intel Corporation

+  All rights reserved. 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.php

+

+  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 _TFTP_SERVER_H_

+#define _TFTP_SERVER_H_

+

+#include <errno.h>

+#include <stdio.h>

+#include <stdlib.h>

+#include <string.h>

+#include <Uefi.h>

+

+#include <Guid/EventGroup.h>

+

+#include <Library/BaseMemoryLib.h>

+#include <Library/DebugLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/PcdLib.h>

+#include <Library/TimerLib.h>

+#include <Library/UefiApplicationEntryPoint.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/UefiLib.h>

+#include <Protocol/BlockIo.h>

+

+#include <netinet/in.h>

+#include <netinet6/in6.h>

+

+#include <sys/EfiSysCall.h>

+#include <sys/poll.h>

+#include <sys/socket.h>

+#include <sys/stat.h>

+

+//------------------------------------------------------------------------------

+//  Macros

+//------------------------------------------------------------------------------

+

+#if defined(_MSC_VER)           /* Handle Microsoft VC++ compiler specifics. */

+#define DBG_ENTER()             DEBUG (( DEBUG_ENTER_EXIT, "Entering " __FUNCTION__ "\n" )) ///<  Display routine entry

+#define DBG_EXIT()              DEBUG (( DEBUG_ENTER_EXIT, "Exiting " __FUNCTION__ "\n" ))  ///<  Display routine exit

+#define DBG_EXIT_DEC(Status)    DEBUG (( DEBUG_ENTER_EXIT, "Exiting " __FUNCTION__ ", Status: %d\n", Status ))      ///<  Display routine exit with decimal value

+#define DBG_EXIT_HEX(Status)    DEBUG (( DEBUG_ENTER_EXIT, "Exiting " __FUNCTION__ ", Status: 0x%08x\n", Status ))  ///<  Display routine exit with hex value

+#define DBG_EXIT_STATUS(Status) DEBUG (( DEBUG_ENTER_EXIT, "Exiting " __FUNCTION__ ", Status: %r\n", Status ))      ///<  Display routine exit with status value

+#define DBG_EXIT_TF(Status)     DEBUG (( DEBUG_ENTER_EXIT, "Exiting " __FUNCTION__ ", returning %s\n", (FALSE == Status) ? L"FALSE" : L"TRUE" ))  ///<  Display routine with TRUE/FALSE value

+#else   //  _MSC_VER

+#define DBG_ENTER()

+#define DBG_EXIT()

+#define DBG_EXIT_DEC(Status)

+#define DBG_EXIT_HEX(Status)

+#define DBG_EXIT_STATUS(Status)

+#define DBG_EXIT_TF(Status)

+#endif  //  _MSC_VER

+

+#define DIM(x)    ( sizeof ( x ) / sizeof ( x[0] ))   ///<  Compute the number of entries in an array

+

+//------------------------------------------------------------------------------

+//  Constants

+//------------------------------------------------------------------------------

+

+#define ACK_SHIFT               4           ///<  Number of samples in ACK average

+

+#define DEBUG_WINDOW            0x00000001  ///<  Display the window messages

+#define DEBUG_TX_PACKET         0x00000002  ///<  Display the transmit packet messages

+#define DEBUG_FILE_BUFFER       0x00000004  ///<  Display the file buffer messages

+#define DEBUG_SERVER_TIMER      0x00000008  ///<  Display the socket poll messages

+#define DEBUG_TFTP_REQUEST      0x00000010  ///<  Display the TFTP request messages

+#define DEBUG_PORT_WORK         0x00000020  ///<  Display the port work messages

+#define DEBUG_SOCKET_POLL       0x00000040  ///<  Display the socket poll messages

+#define DEBUG_TFTP_PORT         0x00000080  ///<  Display the TFTP port messages

+#define DEBUG_TX                0x00000100  ///<  Display transmit messages

+#define DEBUG_RX                0x00000200  ///<  Display receive messages

+#define DEBUG_TFTP_ACK          0x00000400  ///<  Display the TFTP ACK messages

+#define DEBUG_ENTER_EXIT        0x00000800  ///<  Display entry and exit messages

+

+#define MAX_PACKETS             8           ///<  Maximum number of packets in the window

+

+#define TFTP_PORT_POLL_DELAY  ( 2 * 1000 )  ///<  Delay in milliseconds for attempts to open the TFTP port

+#define CLIENT_POLL_DELAY     50            ///<  Delay in milliseconds between client polls

+

+#define TPL_TFTP_SERVER        TPL_CALLBACK ///<  TPL for routine synchronization

+

+/**

+  Verify new TPL value

+

+  This macro which is enabled when debug is enabled verifies that

+  the new TPL value is >= the current TPL value.

+**/

+#ifdef VERIFY_TPL

+#undef VERIFY_TPL

+#endif  //  VERIFY_TPL

+

+#if !defined(MDEPKG_NDEBUG)

+

+#define VERIFY_TPL(tpl)                           \

+{                                                 \

+  EFI_TPL PreviousTpl;                            \

+                                                  \

+  PreviousTpl = gBS->RaiseTPL ( TPL_HIGH_LEVEL ); \

+  gBS->RestoreTPL ( PreviousTpl );                \

+  if ( PreviousTpl > tpl ) {                      \

+    DEBUG (( DEBUG_ERROR, "Current TPL: %d, New TPL: %d\r\n", PreviousTpl, tpl ));  \

+    ASSERT ( PreviousTpl <= tpl );                \

+  }                                               \

+}

+

+#else   //  MDEPKG_NDEBUG

+

+#define VERIFY_TPL(tpl)

+

+#endif  //  MDEPKG_NDEBUG

+

+#define TFTP_SERVER_SIGNATURE       SIGNATURE_32('T','F','T','P') ///<  TSDT_TFTP_SERVER memory signature

+

+//

+//  See: http://www.rfc-editor.org/rfc/pdfrfc/rfc1350.txt.pdf

+//

+//  TFTP Operations

+//

+

+#define TFTP_OP_READ_REQUEST      1     ///<  Read request, zero terminated file name, zero terminated mode

+#define TFTP_OP_WRITE_REQUEST     2     ///<  Write request, zero terminated file name, zero terminated mode

+#define TFTP_OP_DATA              3     ///<  Data block, end-of-file indicated by short block

+#define TFTP_OP_ACK               4     ///<  ACK block number

+#define TFTP_OP_ERROR             5     ///<  Error number and explaination

+#define TFTP_OP_OACK              6     ///<  ACK the options

+

+#define TFTP_MAX_BLOCK_SIZE       4096  ///<  Maximum block size

+

+#define TFTP_ERROR_SEE_MSG          0   ///<  See the error message

+#define TFTP_ERROR_NOT_FOUND        1   ///<  File not found

+#define TFTP_ERROR_ACCESS_VIOLATION 2   ///<  Access violation

+#define TFTP_ERROR_DISK_FULL        3   ///<  Disk full

+#define TFTP_ERROR_ILLEGAL_OP       4   ///<  Illegal operation

+#define TFTP_ERROR_UNKNOWN_XFER_ID  5   ///<  Unknown transfer ID

+#define TFTP_ERROR_FILE_EXISTS      6   ///<  File already exists

+#define TFTP_ERROR_NO_SUCH_USER     7   ///<  No such user

+

+//------------------------------------------------------------------------------

+//  Data Types

+//------------------------------------------------------------------------------

+

+/**

+  Packet structure

+**/

+typedef struct _TFTP_PACKET TFTP_PACKET;

+typedef struct _TFTP_PACKET {

+  TFTP_PACKET * pNext;          ///<  Next packet in list

+  UINT64    TxTime;             ///<  Time the transmit was performed

+  ssize_t   TxBytes;            ///<  Bytes in the TX buffer

+  UINT32    RetryCount;         ///<  Number of transmissions

+  UINT16    BlockNumber;        ///<  Block number of this packet

+  UINT8     TxBuffer[ 2 + 2 + TFTP_MAX_BLOCK_SIZE ];  ///<  Transmit buffer

+} GCC_TFTP_PACKET;

+

+/**

+  Port control structure

+**/

+typedef struct _TSDT_CONNECTION_CONTEXT TSDT_CONNECTION_CONTEXT;

+typedef struct _TSDT_CONNECTION_CONTEXT {

+  //

+  //  Remote connection management

+  //

+  TSDT_CONNECTION_CONTEXT * pNext;    ///<  Next context in the connection list

+  struct sockaddr_in6 RemoteAddress;  ///<  Remote address

+  int SocketFd;                       ///<  Socket file descriptor

+

+  //

+  //  File management parameters

+  //

+  FILE * File;                  ///<  NULL while file is closed

+  UINT64 LengthInBytes;         ///<  Size of the file

+  UINT64 BytesRemaining;        ///<  Number of bytes remaining to be sent

+  UINT64 BytesToSend;           ///<  Number of bytes to send

+  UINT64 ValidBytes;            ///<  Number of valid bytes in the buffer

+  BOOLEAN bEofSent;             ///<  End of file sent

+  UINT8 * pFill;                ///<  Next portion of the buffer to fill

+  UINT8 * pBuffer;              ///<  Pointer into the file data

+  UINT8 * pEnd;                 ///<  End of the file data

+  UINT8 FileData[ 2 * MAX_PACKETS * TFTP_MAX_BLOCK_SIZE ];  ///<  File data to send

+  UINT64 TimeStart;             ///<  Start of file transfer

+

+  //

+  //  TFTP management parameters

+  //

+  UINT16 BlockNumber;           ///<  Next block to be transmitted

+  UINT32 BlockSize;             ///<  Negotiated block size

+

+  //

+  //  Window management

+  //

+  UINT32 AckCount;              ///<  Number of ACKs to receive before increasing the window

+  UINT32 PacketsInWindow;       ///<  Number of packets in the window

+  UINT32 Threshold;             ///<  Size of window when ACK count becomes logrithmic

+  UINT32 WindowSize;            ///<  Size of the transmit window

+  UINT64 MaxTimeout;            ///<  Maximum number of seconds to wait before retransmission

+  UINT64 Rtt2x;                 ///<  Twice the average round trip time in nanoseconds

+

+  //

+  //  Buffer management

+  //

+  TFTP_PACKET * pFreeList;      ///<  List of free packets

+  TFTP_PACKET * pTxHead;        ///<  First packet in the list of packets for transmission

+  TFTP_PACKET * pTxTail;        ///<  Last packet in the list of packets for transmission

+  TFTP_PACKET ErrorPacket;      ///<  Error packet

+  TFTP_PACKET Tx[ MAX_PACKETS ];///<  Transmit packets

+}GCC_TSDT_CONNECTION_CONTEXT;

+

+/**

+  TFTP server control structure

+**/

+typedef struct {

+  UINTN Signature;              ///<  Structure identification

+

+  //

+  //  Image attributes

+  //

+  EFI_HANDLE ImageHandle;       ///<  Image handle

+

+  //

+  //  Performance management

+  //

+  UINT64 ClockFrequency;        ///<  Frequency of the clock

+  UINT64 Time1;                 ///<  Clock value after rollover

+  UINT64 Time2;                 ///<  Clock value before rollover

+  UINT64 RxTime;                ///<  Time when the packet was recevied

+

+  //

+  //  TFTP port management

+  //

+  EFI_EVENT TimerEvent;         ///<  Timer to open TFTP port

+  int Udpv4Index;               ///<  Entry for UDPv4

+  int Udpv6Index;               ///<  Entry for UDPv6

+  int Entries;                  ///<  Number of TFTP ports

+  struct pollfd TftpPort [ 2 ]; ///<  Poll descriptor for the TFTP ports (UDP4, UDP6)

+

+  //

+  //  Request management

+  //

+  union {

+    struct sockaddr_in v4;      ///<  UDP4 address

+    struct sockaddr_in6 v6;     ///<  UDP6 address

+  } RemoteAddress;              ///<  Remote address

+  ssize_t RxBytes;              ///<  Receive data length in bytes

+  UINT8 RxBuffer[ 2 + 2 + TFTP_MAX_BLOCK_SIZE ];  ///<  Receive buffer

+

+  //

+  //  Client port management

+  //

+  TSDT_CONNECTION_CONTEXT * pContextList; ///<  List of connection context structures

+} TSDT_TFTP_SERVER;

+

+//#define SERVER_FROM_SERVICE(a) CR(a, TSDT_TFTP_SERVER, ServiceBinding, TFTP_SERVER_SIGNATURE) ///< Locate DT_LAYER from service binding

+

+extern TSDT_TFTP_SERVER mTftpServer;

+

+//------------------------------------------------------------------------------

+// Support routines

+//------------------------------------------------------------------------------

+

+/**

+  Queue data packets for transmission

+

+  @param [in] pContext    Connection context structure address

+

+  @retval TRUE if a read error occurred

+

+**/

+BOOLEAN

+PacketFill (

+  IN TSDT_CONNECTION_CONTEXT * pContext

+  );

+

+/**

+  Free the packet

+

+  @param [in] pContext    Address of a ::TSDT_CONNECTION_CONTEXT structure

+  @param [in] pPacket     Address of a ::TFTP_PACKET structure

+

+**/

+VOID

+PacketFree(

+  IN TSDT_CONNECTION_CONTEXT * pContext,

+  IN TFTP_PACKET * pPacket

+  );

+

+/**

+  Get a packet for transmission

+

+  @param [in] pContext    Address of a ::TSDT_CONNECTION_CONTEXT structure

+

+  @retval Address of a ::TFTP_PACKET structure

+

+**/

+TFTP_PACKET *

+PacketGet (

+  IN TSDT_CONNECTION_CONTEXT * pContext

+  );

+

+/**

+  Queue the packet for transmission

+

+  @param [in] pContext    Address of a ::TSDT_CONNECTION_CONTEXT structure

+  @param [in] pPacket     Address of a ::TFTP_PACKET structure

+

+  @retval TRUE if a transmission error has occurred

+

+**/

+BOOLEAN

+PacketQueue (

+  IN TSDT_CONNECTION_CONTEXT * pContext,

+  IN TFTP_PACKET * pPacket

+  );

+

+/**

+  Transmit the packet

+

+  @param [in] pContext    Address of a ::TSDT_CONNECTION_CONTEXT structure

+  @param [in] pPacket     Address of a ::TFTP_PACKET structure

+

+  @retval EFI_SUCCESS   Message processed successfully

+

+**/

+EFI_STATUS

+PacketTx (

+  IN TSDT_CONNECTION_CONTEXT * pContext,

+  IN TFTP_PACKET * pPacket

+  );

+

+/**

+  Build and send an error packet

+

+  @param [in] pContext    The context structure address.

+  @param [in] Error       Error number for the packet

+  @param [in] pError      Zero terminated error string address

+

+  @retval EFI_SUCCESS     Message processed successfully

+

+**/

+EFI_STATUS

+SendError (

+  IN TSDT_CONNECTION_CONTEXT * pContext,

+  IN UINT16 Error,

+  IN UINT8 * pError

+  );

+

+/**

+  Process the TFTP request

+

+  @param [in] pOption   Address of the first zero terminated option string

+  @param [in] pValue    Address to receive the value

+

+  @retval EFI_SUCCESS   Option translated into a value

+

+**/

+EFI_STATUS

+TftpOptionValue (

+  IN UINT8 * pOption,

+  IN INT32 * pValue

+  );

+

+/**

+  Process the TFTP request

+

+  @param [in] pTftpServer The TFTP server control structure address.

+  @param [in] pContext    Connection context structure address

+  @param [in] SocketFd    Socket file descriptor

+

+**/

+VOID

+TftpProcessRequest (

+  IN TSDT_TFTP_SERVER * pTftpServer,

+  IN TSDT_CONNECTION_CONTEXT * pContext,

+  IN int SocketFd

+  );

+

+/**

+  Process the read request

+

+  @param [in] pTftpServer Address of the ::TSDT_TFTP_SERVER structure

+  @param [in] pContext    Connection context structure address

+  @param [in] SocketFd    Socket file descriptor

+

+  @retval TRUE if the context should be closed

+

+**/

+BOOLEAN

+TftpRead (

+  IN TSDT_TFTP_SERVER * pTftpServer,

+  IN TSDT_CONNECTION_CONTEXT * pContext,

+  IN int SocketFd

+  );

+

+/**

+  Update the window due to the ACK

+

+  @param [in] pTftpServer Address of the ::TSDT_TFTP_SERVER structure

+  @param [in] pContext    Address of a ::TSDT_CONNECTION_CONTEXT structure

+  @param [in] pPacket     Address of a ::TFTP_PACKET structure

+

+**/

+VOID

+WindowAck (

+  IN TSDT_TFTP_SERVER * pTftpServer,

+  IN TSDT_CONNECTION_CONTEXT * pContext,

+  IN TFTP_PACKET * pPacket

+  );

+

+/**

+  A timeout has occurred, close the window

+

+  @param [in] pContext    Address of a ::TSDT_CONNECTION_CONTEXT structure

+

+**/

+VOID

+WindowTimeout (

+  IN TSDT_CONNECTION_CONTEXT * pContext

+  );

+

+//------------------------------------------------------------------------------

+

+#endif  //  _TFTP_SERVER_H_

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/TftpServer/TftpServer.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/TftpServer/TftpServer.inf
new file mode 100644
index 0000000..79513c2
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/TftpServer/TftpServer.inf
@@ -0,0 +1,70 @@
+## @file

+#  TFTP Server Application

+#

+#  Copyright (c) 2011-2012, Intel Corporation

+#  All rights reserved. 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.php

+#

+#  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                    = 0x00010005

+  BASE_NAME                      = TftpServer

+  FILE_GUID                      = 94621F9E-B5CA-4cfd-82BE-0C542EB0D9BE

+  MODULE_TYPE                    = UEFI_APPLICATION

+  VERSION_STRING                 = 1.0

+  ENTRY_POINT                    = ShellCEntryLib

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  TftpServer.h

+  TftpServer.c

+

+

+[Pcd]

+  gAppPkgTokenSpaceGuid.Tftp_AckLogBase

+  gAppPkgTokenSpaceGuid.Tftp_AckMultiplier

+  gAppPkgTokenSpaceGuid.Tftp_Bandwidth

+  gAppPkgTokenSpaceGuid.Tftp_HighSpeed

+  gAppPkgTokenSpaceGuid.Tftp_MaxRetry

+  gAppPkgTokenSpaceGuid.Tftp_MaxTimeoutInSec

+

+

+[Packages]

+  AppPkg/AppPkg.dec

+  MdePkg/MdePkg.dec

+  ShellPkg/ShellPkg.dec

+  StdLib/StdLib.dec

+

+

+[LibraryClasses]

+  BaseMemoryLib

+  BsdSocketLib

+  DebugLib

+  DevMedia

+  EfiSocketLib

+  LibC

+  ShellLib

+  ShellCEntryLib

+  TimerLib

+  UefiBootServicesTableLib

+  UefiLib

+  UefiRuntimeServicesTableLib

+#  UseSocketDxe

+

+[BuildOptions]

+  INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186

+   MSFT:*_*_*_CC_FLAGS = /Od

+    GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable

+

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/ACPI.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/ACPI.c
new file mode 100644
index 0000000..e086a2d
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/ACPI.c
@@ -0,0 +1,2557 @@
+/**

+  @file

+  Display the ACPI tables

+

+  Copyright (c) 2011-2012, Intel Corporation

+  All rights reserved. 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.php

+

+  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 <WebServer.h>

+#include <Guid/Acpi.h>

+#include <IndustryStandard/Acpi10.h>

+#include <IndustryStandard/Acpi30.h>

+

+#if defined(_MSC_VER)   //  Handle Microsoft VC++ compiler specifics.

+#pragma warning ( disable : 4305 )

+#endif  //  defined(_MSC_VER)

+

+//

+// Ensure proper structure formats

+//

+#pragma pack(1)

+

+typedef struct {

+  UINT8 AddressSpaceId;

+  UINT8 RegisterBitWidth;

+  UINT8 RegisterBitOffset;

+  UINT8 AccessSize;

+  UINT64 Address;

+} GENERIC_ADDRESS;

+

+

+typedef struct {

+  UINT32 Signature;           //    0

+  UINT32 Length;              //    4

+  UINT8 Revision;             //    8

+  UINT8 Checksum;             //    9

+  UINT8 OemId[6];             //   10

+  UINT8 OemTableId[8];        //   16

+  UINT32 OemRevision;         //   24

+  UINT32 CreatorId;           //   28

+  UINT32 CreatorRevision;     //   32

+  UINT8 DefinitionBlock[1];   //   36

+} ACPI_DSDT;

+

+

+typedef struct {

+  UINT32 Signature;           //    0

+  UINT32 Length;              //    4

+  UINT8 Revision;             //    8

+  UINT8 Checksum;             //    9

+  UINT8 OemId[6];             //   10

+  UINT8 OemTableId[8];        //   16

+  UINT32 OemRevision;         //   24

+  UINT32 CreatorId;           //   28

+  UINT32 CreatorRevision;     //   32

+  UINT32 FirmwareCtrl;        //   36

+  UINT32 DSDT;                //   40

+  UINT8 Reserved;             //   44

+  UINT8 PreferredPmProfile;   //   45

+  UINT16 SciInt;              //   46

+  UINT32 SmiCmd;              //   48

+  UINT8 AcpiEnable;           //   52

+  UINT8 AcpiDisable;          //   53

+  UINT8 S4BiosReq;            //   54

+  UINT8 PStateCnt;            //   55

+  UINT32 Pm1aEvtBlk;          //   56

+  UINT32 Pm1bEvtBlk;          //   60

+  UINT32 Pm1aCntBlk;          //   64

+  UINT32 Pm1bCntBlk;          //   68

+  UINT32 Pm2CntBlk;           //   72

+  UINT32 PmTmrBlk;            //   76

+  UINT32 Gpe0Blk;             //   80

+  UINT32 Gpe1Blk;             //   84

+  UINT8 Pm1EvtLen;            //   88

+  UINT8 Pm1CntLen;            //   89

+  UINT8 PM2CntLen;            //   90

+  UINT8 PmTmrLen;             //   91

+  UINT8 Gpe0BlkLen;           //   92

+  UINT8 Gpe1BlkLen;           //   93

+  UINT8 Gpe1Base;             //   94

+  UINT8 CstCnt;               //   95

+  UINT16 PLvl2Lat;            //   96

+  UINT16 PLvl3Lat;            //   98

+  UINT16 FlushSize;           //  100

+  UINT16 FlushStride;         //  102

+  UINT8 DutyOffset;           //  104

+  UINT8 DutyWidth;            //  105

+  UINT8 DayAlrm;              //  106

+  UINT8 MonAlrm;              //  107

+  UINT8 Century;              //  108

+  UINT16 IapcBootArch;        //  109

+  UINT8 Reserved2;            //  111

+  UINT32 Flags;               //  112

+  UINT32 ResetReg[3];         //  116

+  UINT8 ResetValue;           //  128

+  UINT8 Reserved3[3];         //  129

+  UINT64 XFirmwareCtrl;       //  132

+  UINT64 XDsdt;               //  140

+  UINT32 XPm1aEvtBlk[3];      //  148

+  UINT32 XPm1bEvtBlk[3];      //  160

+  UINT32 XPm1aCntBlk[3];      //  172

+  UINT32 XPm1bCntBlk[3];      //  184

+  UINT32 XPm2CntBlk[3];       //  196

+  UINT32 XPmTmrBlk[3];        //  208

+  UINT32 XGpe0Blk[3];         //  220

+  UINT32 XGpe1Blk[3];         //  232

+} ACPI_FADT;

+

+

+typedef struct {

+  UINT32 Signature;

+  UINT32 Length;

+  UINT8 Revision;

+  UINT8 Checksum;

+  UINT8 OemId[6];

+  UINT8 OemTableId[8];

+  UINT32 OemRevision;

+  UINT32 CreatorId;

+  UINT32 CreatorRevision;

+  UINT32 Entry[1];

+} ACPI_RSDT;

+

+

+typedef struct {

+  UINT32 Signature;           //    0

+  UINT32 Length;              //    4

+} ACPI_UNKNOWN;

+

+#pragma pack()

+

+

+typedef struct {

+  UINT32 Signature;

+  CONST CHAR8 * pTableName;

+  CONST CHAR16 * pWebPage;

+} TABLE_SIGNATURE;

+

+

+CONST TABLE_SIGNATURE mTableId[] = {

+  { APIC_SIGNATURE, "APIC", PAGE_ACPI_APIC },

+  { BGRT_SIGNATURE, "BGRT", PAGE_ACPI_BGRT },

+  { DSDT_SIGNATURE, "DSDT", PAGE_ACPI_DSDT },

+  { FADT_SIGNATURE, "FADT", PAGE_ACPI_FADT },

+  { HPET_SIGNATURE, "HPET", PAGE_ACPI_HPET },

+  { MCFG_SIGNATURE, "MCFG", PAGE_ACPI_MCFG },

+  { SSDT_SIGNATURE, "SSDT", PAGE_ACPI_SSDT },

+  { TCPA_SIGNATURE, "TCPA", PAGE_ACPI_TCPA },

+  { UEFI_SIGNATURE, "UEFI", PAGE_ACPI_UEFI }

+};

+

+

+/**

+  Locate the RSDT table

+

+  @return  Table address or NULL if not found

+

+**/

+CONST ACPI_RSDT *

+LocateRsdt (

+  VOID

+  )

+{

+  CONST EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER * pRsdp10b;

+  CONST EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER * pRsdp30;

+  CONST ACPI_RSDT * pRsdt;

+  EFI_STATUS Status;

+

+  //

+  //  Use for/break instead of goto

+  //

+  pRsdt = NULL;

+  for ( ; ; ) {

+    //

+    //  Locate the RSDT

+    //

+    Status = EfiGetSystemConfigurationTable ( &gEfiAcpiTableGuid, (VOID **)&pRsdp30 );

+    if ( !EFI_ERROR ( Status )) {

+      pRsdt = (ACPI_RSDT *)(UINTN)pRsdp30->RsdtAddress;

+    }

+    else {

+      Status = EfiGetSystemConfigurationTable (&gEfiAcpi10TableGuid, (VOID **)&pRsdp10b );

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+      pRsdt = (ACPI_RSDT *)(UINTN)pRsdp10b->RsdtAddress;

+    }

+    break;

+  }

+

+  //

+  //  The entry was not found

+  //

+  return pRsdt;

+}

+

+

+/**

+  Locate the specified table

+

+  @param [in] Signature     Table signature

+

+  @return  Table address or NULL if not found

+

+**/

+CONST VOID *

+LocateTable (

+  IN UINT32 Signature

+  )

+{

+  CONST UINT32 * pEnd;

+  CONST UINT32 * pEntry;

+  CONST EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER * pRsdp10b;

+  CONST EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER * pRsdp30;

+  CONST ACPI_RSDT * pRsdt;

+  CONST UINT32 * pSignature;

+  EFI_STATUS Status;

+

+  //

+  //  Use for/break instead of goto

+  //

+  for ( ; ; ) {

+    //

+    //  Locate the RSDT

+    //

+    Status = EfiGetSystemConfigurationTable ( &gEfiAcpiTableGuid, (VOID **)&pRsdp30 );

+    if ( !EFI_ERROR ( Status )) {

+      pRsdt = (ACPI_RSDT *)(UINTN)pRsdp30->RsdtAddress;

+    }

+    else {

+      Status = EfiGetSystemConfigurationTable (&gEfiAcpi10TableGuid, (VOID **)&pRsdp10b );

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+      pRsdt = (ACPI_RSDT *)(UINTN)pRsdp10b->RsdtAddress;

+    }

+

+    //

+    //  Walk the list of entries

+    //

+    pEntry = &pRsdt->Entry[ 0 ];

+    pEnd = &pEntry[(( pRsdt->Length - sizeof ( *pRsdt )) >> 2 ) + 1 ];

+    while ( pEnd > pEntry ) {

+      //

+      //  The entry is actually a 32-bit physical table address

+      //  The first entry in the table is the 32-bit table signature

+      //

+      pSignature = (UINT32 *)(UINTN)*pEntry;

+      if ( *pSignature == Signature ) {

+        return (CONST VOID *)(UINTN)*pEntry;

+      }

+

+      //

+      //  Set the next entry

+      //

+      pEntry++;

+    }

+    break;

+  }

+

+  //

+  //  The entry was not found

+  //

+  return NULL;

+}

+

+

+/**

+  Display a row containing a hex value

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [in] pName         Address of a zero terminated name string

+  @param [in] Length        Length in bytes

+  @param [in] pChar         Address of the first character

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+RowAnsiArray (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN CONST CHAR8 * pName,

+  IN UINTN Length,

+  IN CONST CHAR8 * pChar

+  )

+{

+  CONST CHAR8 * pData;

+  CONST CHAR8 * pEnd;

+  EFI_STATUS Status;

+

+  DBG_ENTER ( );

+

+  //

+  //  Use for/break instead of goto

+  //

+  for ( ; ; ) {

+    //

+    //  Start the row

+    //

+    Status = HttpSendAnsiString ( SocketFD,

+                                  pPort,

+                                  "<tr><td>" );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = HttpSendAnsiString ( SocketFD,

+                                  pPort,

+                                  pName );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = HttpSendAnsiString ( SocketFD,

+                                  pPort,

+                                  "</td><td><code>" );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Display the characters

+    //

+    pData = pChar;

+    pEnd = &pChar[ Length ];

+    while ( pEnd > pData ) {

+      Status = HttpSendCharacter ( SocketFD,

+                                   pPort,

+                                   *pData++,

+                                   " " );

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+    }

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Display the byte values

+    //

+    Status = HttpSendAnsiString ( SocketFD,

+                                  pPort,

+                                  "<br/>0x" );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    pData = pChar;

+    while ( pEnd > pData ) {

+      Status = HttpSendHexBits ( SocketFD,

+                                 pPort,

+                                 8,

+                                 *pData++ );

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+      if ( pEnd > pData ) {

+        Status = HttpSendAnsiString ( SocketFD,

+                                      pPort,

+                                      " 0x" );

+        if ( EFI_ERROR ( Status )) {

+          break;

+        }

+      }

+    }

+

+    //

+    //  Terminate the row

+    //

+    Status = HttpSendAnsiString ( SocketFD,

+                                  pPort,

+                                  "</code></td></tr>\r\n" );

+    break;

+  }

+

+  //

+  //  Return the operation status

+  //

+  DBG_EXIT_STATUS ( Status );

+  return Status;

+}

+

+

+/**

+  Format a row with a list of bytes

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [in] pName         Zero terminated name string

+  @param [in] ByteCount     The number of bytes to display

+  @param [in] pData         Address of the byte array

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+RowBytes (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN CHAR8 * pName,

+  IN UINTN ByteCount,

+  IN CONST UINT8 * pData

+  )

+{

+  CONST UINT8 * pEnd;

+  EFI_STATUS Status;

+

+  //

+  //  Use for/break instead of goto

+  //

+  for ( ; ; ) {

+    //

+    //  Start the row

+    //

+    Status = HttpSendAnsiString ( SocketFD,

+                                  pPort,

+                                  "<tr><td>" );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Display the field name

+    //

+    Status = HttpSendAnsiString ( SocketFD,

+                                  pPort,

+                                  pName );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Display the field value

+    //

+    Status = HttpSendAnsiString ( SocketFD,

+                                  pPort,

+                                  "</td><td><code>0x" );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    pEnd = &pData[ ByteCount ];

+    while ( pEnd > pData ) {

+      Status = HttpSendHexBits ( SocketFD,

+                                 pPort,

+                                 8,

+                                 *pData++ );

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+      if ( pEnd > pData ) {

+        Status = HttpSendAnsiString ( SocketFD,

+                                      pPort,

+                                      " 0x" );

+        if ( EFI_ERROR ( Status )) {

+          break;

+        }

+      }

+    }

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Terminate the row

+    //

+    Status = HttpSendAnsiString ( SocketFD,

+                                  pPort,

+                                  "</code></td></tr>\r\n" );

+    break;

+  }

+

+  //

+  //  Return the operation status

+  //

+  return Status;

+}

+

+

+/**

+  Format a row with a list of bytes

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [in] pName         Zero terminated name string

+  @param [in] ByteCount     The number of bytes to display

+  @param [in] pData         Address of the byte array

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+RowDump (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN CHAR8 * pName,

+  IN UINTN ByteCount,

+  IN CONST UINT8 * pData

+  )

+{

+  EFI_STATUS Status;

+

+  //

+  //  Use for/break instead of goto

+  //

+  for ( ; ; ) {

+    //

+    //  Start the row

+    //

+    Status = HttpSendAnsiString ( SocketFD,

+                                  pPort,

+                                  "<tr><td>" );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Display the field name

+    //

+    Status = HttpSendAnsiString ( SocketFD,

+                                  pPort,

+                                  pName );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Start the field value

+    //

+    Status = HttpSendAnsiString ( SocketFD,

+                                  pPort,

+                                  "</td><td>" );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Dump the buffer

+    //

+    Status = HttpSendDump ( SocketFD,

+                            pPort,

+                            ByteCount,

+                            pData );

+

+    //

+    //  Terminate the field value and row

+    //

+    Status = HttpSendAnsiString ( SocketFD,

+                                  pPort,

+                                  "</td></tr>\r\n" );

+    break;

+  }

+

+  //

+  //  Return the operation status

+  //

+  return Status;

+}

+

+

+/**

+  Format a row with a general address

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [in] pName         Zero terminated name string

+  @param [in] pAddr         Address of the general address buffer

+  @param [in] pWebPage      Zero terminated web page address

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+RowGenericAddress (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN CHAR8 * pName,

+  IN CONST UINT32 * pAddr,

+  IN CONST CHAR16 * pWebPage

+  )

+{

+  CONST GENERIC_ADDRESS * pGenericAddress;

+  EFI_STATUS Status;

+

+  //

+  //  Use for/break instead of goto

+  //

+  for ( ; ; ) {

+    //

+    //  Start the row

+    //

+    Status = HttpSendAnsiString ( SocketFD,

+                                  pPort,

+                                  "<tr><td>" );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Display the field name

+    //

+    Status = HttpSendAnsiString ( SocketFD,

+                                  pPort,

+                                  pName );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Display the field value

+    //

+    Status = HttpSendAnsiString ( SocketFD,

+                                  pPort,

+                                  "</td><td><code>" );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Determine the type of address

+    //

+    pGenericAddress = (CONST GENERIC_ADDRESS *)pAddr;

+    if ( 0 == pGenericAddress->AddressSpaceId ) {

+      Status = HttpSendAnsiString ( SocketFD, pPort, "System Memory" );

+    }

+    else if ( 1 == pGenericAddress->AddressSpaceId ) {

+      Status = HttpSendAnsiString ( SocketFD, pPort, "I/O Space" );

+    }

+    else if ( 2 == pGenericAddress->AddressSpaceId ) {

+      Status = HttpSendAnsiString ( SocketFD, pPort, "PCI Configuration Space" );

+    }

+    else if ( 3 == pGenericAddress->AddressSpaceId ) {

+      Status = HttpSendAnsiString ( SocketFD, pPort, "Embedded Controller" );

+    }

+    else if ( 4 == pGenericAddress->AddressSpaceId ) {

+      Status = HttpSendAnsiString ( SocketFD, pPort, "SMBus" );

+    }

+    else if ( 0x7f == pGenericAddress->AddressSpaceId ) {

+      Status = HttpSendAnsiString ( SocketFD, pPort, "Functional Fixed Hardware" );

+    }

+    else if (( 0xc0 <= pGenericAddress->AddressSpaceId )

+      && ( 0xff >= pGenericAddress->AddressSpaceId )) {

+      Status = HttpSendAnsiString ( SocketFD, pPort, "OEM Defined" );

+    }

+    else {

+      Status = HttpSendAnsiString ( SocketFD, pPort, "Reserved" );

+    }

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = HttpSendAnsiString ( SocketFD,

+                                  pPort,

+                                  "<br/>Register Bit Width: " );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = HttpSendValue ( SocketFD,

+                             pPort,

+                             pGenericAddress->RegisterBitWidth );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = HttpSendAnsiString ( SocketFD,

+                                  pPort,

+                                  "<br/>Register Bit Offset: " );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = HttpSendHexValue ( SocketFD,

+                                pPort,

+                                pGenericAddress->RegisterBitOffset );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = HttpSendAnsiString ( SocketFD,

+                                  pPort,

+                                  "<br/>Access Size: " );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = HttpSendValue ( SocketFD,

+                             pPort,

+                             pGenericAddress->AccessSize );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = HttpSendAnsiString ( SocketFD,

+                                  pPort,

+                                  "<br/>Address: " );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Add the web-page link if necessary

+    //

+    if ( NULL != pWebPage ) {

+      Status = HttpSendAnsiString ( SocketFD,

+                                    pPort,

+                                    "<a target=\"_blank\" href=\"" );

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+      Status = HttpSendUnicodeString ( SocketFD,

+                                       pPort,

+                                       pWebPage );

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+      Status = HttpSendAnsiString ( SocketFD,

+                                    pPort,

+                                    "\">" );

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+    }

+

+    //

+    //  Display the address

+    //

+    Status = HttpSendAnsiString ( SocketFD,

+                                  pPort,

+                                  "0x" );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = HttpSendHexBits ( SocketFD,

+                               pPort,

+                               64,

+                               pGenericAddress->Address );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Finish the web-page link if necessary

+    //

+    if ( NULL != pWebPage ) {

+      Status = HttpSendAnsiString ( SocketFD,

+                                    pPort,

+                                    "</a>" );

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+    }

+

+    //

+    //  Terminate the row

+    //

+    Status = HttpSendAnsiString ( SocketFD,

+                                  pPort,

+                                  "</code></td></tr>\r\n" );

+    break;

+  }

+

+  //

+  //  Return the operation status

+  //

+  return Status;

+}

+

+

+/**

+  Translate a table address into a web page

+

+  @param [in] pSignature      Address of the table signature

+  @param [out] ppTableName    Address to receive the table name address

+

+  @return  Zero terminated web page address or NULL if not found

+

+**/

+CONST CHAR16 *

+SignatureLookup (

+  IN UINT32 * pSignature,

+  OUT CONST CHAR8 ** ppTableName

+  )

+{

+  CONST TABLE_SIGNATURE * pTableId;

+  CONST TABLE_SIGNATURE * pEnd;

+  UINT32 Signature;

+

+  //

+  //  Walk the list of tables

+  //

+  Signature = *pSignature;

+  pTableId = &mTableId[ 0 ];

+  pEnd = &pTableId[ sizeof ( mTableId ) / sizeof ( mTableId[ 0 ])];

+  while ( pEnd > pTableId ) {

+    //

+    //  Attempt to locate the table signature

+    //

+    if ( pTableId->Signature == Signature ) {

+      //

+      //  The signature was found

+      //  Return the web page

+      //

+      *ppTableName = pTableId->pTableName;

+      return pTableId->pWebPage;

+    }

+

+    //

+    //  Set the next table

+    //

+    pTableId += 1;

+  }

+

+  //

+  //  The table was not found

+  //

+  *ppTableName = (CONST CHAR8 *)pSignature;

+  return NULL;

+}

+

+

+/**

+  Respond with the APIC table

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+AcpiApicPage (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  )

+{

+  CONST ACPI_UNKNOWN * pApic;

+  EFI_STATUS Status;

+

+  DBG_ENTER ( );

+

+  //

+  //  Send the APIC page

+  //

+  for ( ; ; ) {

+    //

+    //  Locate the APIC

+    //

+    pApic = (ACPI_UNKNOWN *)LocateTable ( APIC_SIGNATURE );

+    if ( NULL == pApic ) {

+      Status = EFI_NOT_FOUND;

+      break;

+    }

+

+    //

+    //  Send the page and table header

+    //

+    Status = TableHeader ( SocketFD, pPort, L"APIC Table", pApic );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Display the header

+    //

+    Status = RowAnsiArray ( SocketFD,

+                            pPort,

+                            "Signature",

+                            sizeof ( pApic->Signature ),

+                            (CHAR8 *)&pApic->Signature );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowDecimalValue ( SocketFD,

+                               pPort,

+                               "Length",

+                               pApic->Length );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Display the data from the table

+    //

+    Status = RowDump ( SocketFD,

+                       pPort,

+                       "Data",

+                       pApic->Length - sizeof ( *pApic ) + 1,

+                       (UINT8 *)( pApic + 1 ));

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Build the table trailer

+    //

+    Status = TableTrailer ( SocketFD,

+                            pPort,

+                            pbDone );

+    break;

+  }

+

+  //

+  //  Return the operation status

+  //

+  DBG_EXIT_STATUS ( Status );

+  return Status;

+}

+

+

+/**

+  Respond with the BGRT table

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+AcpiBgrtPage (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  )

+{

+  CONST ACPI_UNKNOWN * pBgrt;

+  EFI_STATUS Status;

+

+  DBG_ENTER ( );

+

+  //

+  //  Send the BGRT page

+  //

+  for ( ; ; ) {

+    //

+    //  Locate the BGRT

+    //

+    pBgrt = (ACPI_UNKNOWN *)LocateTable ( BGRT_SIGNATURE );

+    if ( NULL == pBgrt ) {

+      Status = EFI_NOT_FOUND;

+      break;

+    }

+

+    //

+    //  Send the page and table header

+    //

+    Status = TableHeader ( SocketFD, pPort, L"BGRT Table", pBgrt );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Display the header

+    //

+    Status = RowAnsiArray ( SocketFD,

+                            pPort,

+                            "Signature",

+                            sizeof ( pBgrt->Signature ),

+                            (CHAR8 *)&pBgrt->Signature );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowDecimalValue ( SocketFD,

+                               pPort,

+                               "Length",

+                               pBgrt->Length );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Display the data from the table

+    //

+    Status = RowDump ( SocketFD,

+                       pPort,

+                       "Data",

+                       pBgrt->Length - sizeof ( *pBgrt ) + 1,

+                       (UINT8 *)( pBgrt + 1 ));

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Build the table trailer

+    //

+    Status = TableTrailer ( SocketFD,

+                            pPort,

+                            pbDone );

+    break;

+  }

+

+  //

+  //  Return the operation status

+  //

+  DBG_EXIT_STATUS ( Status );

+  return Status;

+}

+

+

+/**

+  Respond with the ACPI DSDT table

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+AcpiDsdtPage (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  )

+{

+  CONST ACPI_DSDT * pDsdt;

+  CONST ACPI_FADT * pFadt;

+  EFI_STATUS Status;

+

+  DBG_ENTER ( );

+

+  //

+  //  Send the DADT page

+  //

+  for ( ; ; ) {

+    //

+    //  Locate the DADT

+    //

+    pFadt = (ACPI_FADT *)LocateTable ( FADT_SIGNATURE );

+    if ( NULL == pFadt ) {

+      Status = EFI_NOT_FOUND;

+      break;

+    }

+    pDsdt = (VOID *)(UINTN)pFadt->XDsdt;

+

+    //

+    //  Send the page and table header

+    //

+    Status = TableHeader ( SocketFD, pPort, L"DSDT - Differentiated System Description Table", pDsdt );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Display the DSDT header

+    //

+    Status = RowAnsiArray ( SocketFD,

+                            pPort,

+                            "Signature",

+                            sizeof ( pDsdt->Signature ),

+                            (CHAR8 *)&pDsdt->Signature );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowDecimalValue ( SocketFD,

+                               pPort,

+                               "Length",

+                               pDsdt->Length );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowDecimalValue ( SocketFD,

+                               pPort,

+                               "Revision",

+                               pDsdt->Revision );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "Checksum",

+                           pDsdt->Checksum,

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowAnsiArray ( SocketFD,

+                            pPort,

+                            "OEMID",

+                            sizeof ( pDsdt->OemId ),

+                            (CONST CHAR8 *)&pDsdt->OemId[ 0 ]);

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowAnsiArray ( SocketFD,

+                            pPort,

+                            "OEM Table ID",

+                            sizeof ( pDsdt->OemTableId ),

+                            (CONST CHAR8 *)&pDsdt->OemTableId[ 0 ]);

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowRevision ( SocketFD,

+                           pPort,

+                           "OEM Revision",

+                           pDsdt->OemRevision );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowAnsiArray ( SocketFD,

+                            pPort,

+                            "Creator ID",

+                            sizeof ( pDsdt->CreatorId ),

+                            (CHAR8 *)&pDsdt->CreatorId );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowRevision ( SocketFD,

+                           pPort,

+                           "Creator Revision",

+                           pDsdt->CreatorRevision );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Display the data from the DSDT

+    //

+    Status = RowDump ( SocketFD,

+                       pPort,

+                       "Definition Block",

+                       pDsdt->Length - sizeof ( *pDsdt ) + 1,

+                       &pDsdt->DefinitionBlock[0]);

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Build the table trailer

+    //

+    Status = TableTrailer ( SocketFD,

+                            pPort,

+                            pbDone );

+    break;

+  }

+

+  //

+  //  Return the operation status

+  //

+  DBG_EXIT_STATUS ( Status );

+  return Status;

+}

+

+

+/**

+  Respond with the ACPI FADT table

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+AcpiFadtPage (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  )

+{

+  CONST ACPI_FADT * pFadt;

+  EFI_STATUS Status;

+

+  DBG_ENTER ( );

+

+  //

+  //  Send the FADT page

+  //

+  for ( ; ; ) {

+    //

+    //  Locate the FADT

+    //

+    pFadt = (ACPI_FADT *)LocateTable ( FADT_SIGNATURE );

+    if ( NULL == pFadt ) {

+      Status = EFI_NOT_FOUND;

+      break;

+    }

+

+    //

+    //  Send the page and table header

+    //

+    Status = TableHeader ( SocketFD, pPort, L"FADT - Fixed ACPI Description Table", pFadt );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Display the FSDT header

+    //

+    Status = RowAnsiArray ( SocketFD,

+                            pPort,

+                            "Signature",

+                            sizeof ( pFadt->Signature ),

+                            (CHAR8 *)&pFadt->Signature );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowDecimalValue ( SocketFD,

+                               pPort,

+                               "Length",

+                               pFadt->Length );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowDecimalValue ( SocketFD,

+                               pPort,

+                               "Revision",

+                               pFadt->Revision );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "Checksum",

+                           pFadt->Checksum,

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowAnsiArray ( SocketFD,

+                            pPort,

+                            "OEMID",

+                            sizeof ( pFadt->OemId ),

+                            (CONST CHAR8 *)&pFadt->OemId[ 0 ]);

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowAnsiArray ( SocketFD,

+                            pPort,

+                            "OEM Table ID",

+                            sizeof ( pFadt->OemTableId ),

+                            (CONST CHAR8 *)&pFadt->OemTableId[ 0 ]);

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowRevision ( SocketFD,

+                           pPort,

+                           "OEM Revision",

+                           pFadt->OemRevision );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowAnsiArray ( SocketFD,

+                            pPort,

+                            "Creator ID",

+                            sizeof ( pFadt->CreatorId ),

+                            (CHAR8 *)&pFadt->CreatorId );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowRevision ( SocketFD,

+                           pPort,

+                           "Creator Revision",

+                           pFadt->CreatorRevision );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Display the data from the FADT

+    //

+    Status = RowPointer ( SocketFD,

+                          pPort,

+                          "FIRMWARE_CTRL",

+                          (CONST VOID *)(UINTN)pFadt->FirmwareCtrl,

+                          NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowPointer ( SocketFD,

+                          pPort,

+                          "DSDT",

+                          (CONST VOID *)(UINTN)pFadt->DSDT,

+                          ( pFadt->DSDT == pFadt->XDsdt ) ? PAGE_ACPI_DSDT : NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "Reserved",

+                           pFadt->Reserved,

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "Preferred_PM_Profile",

+                           pFadt->PreferredPmProfile,

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "SCI_INT",

+                           pFadt->SciInt,

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "SMI_CMD",

+                           pFadt->SmiCmd,

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "ACPI_ENABLE",

+                           pFadt->AcpiEnable,

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "ACPI_DISABLE",

+                           pFadt->AcpiDisable,

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "S4BIOS_REQ",

+                           pFadt->S4BiosReq,

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "PSTATE_CNT",

+                           pFadt->PStateCnt,

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "PM1a_EVT_BLK",

+                           pFadt->Pm1aEvtBlk,

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "PM1b_EVT_BLK",

+                           pFadt->Pm1bEvtBlk,

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "PM1a_CNT_BLK",

+                           pFadt->Pm1aCntBlk,

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "PM1b_CNT_BLK",

+                           pFadt->Pm1bCntBlk,

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "PM2_CNT_BLK",

+                           pFadt->Pm2CntBlk,

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "PM_TMR_BLK",

+                           pFadt->PmTmrBlk,

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "GPE0_BLK",

+                           pFadt->Gpe0Blk,

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "GPE1_BLK",

+                           pFadt->Gpe1Blk,

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowDecimalValue ( SocketFD,

+                               pPort,

+                               "PM1_EVT_LEN",

+                               pFadt->Pm1EvtLen );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowDecimalValue ( SocketFD,

+                               pPort,

+                               "PM1_CNT_LEN",

+                               pFadt->Pm1CntLen );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowDecimalValue ( SocketFD,

+                               pPort,

+                               "PM2_CNT_LEN",

+                               pFadt->PM2CntLen );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowDecimalValue ( SocketFD,

+                               pPort,

+                               "PM_TMR_LEN",

+                               pFadt->PmTmrLen );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowDecimalValue ( SocketFD,

+                               pPort,

+                               "GPE0_BLK_LEN",

+                               pFadt->Gpe0BlkLen );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowDecimalValue ( SocketFD,

+                               pPort,

+                               "GPE1_BLK_LEN",

+                               pFadt->Gpe1BlkLen );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "GPE1_BASE",

+                           pFadt->Gpe1Base,

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowDecimalValue ( SocketFD,

+                               pPort,

+                               "CST_CNT",

+                               pFadt->CstCnt );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "P_LVL2_LAT",

+                           pFadt->PLvl2Lat,

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "P_LVL3_LAT",

+                           pFadt->PLvl3Lat,

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowDecimalValue ( SocketFD,

+                               pPort,

+                               "FLUSH_SIZE",

+                               pFadt->FlushSize );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowDecimalValue ( SocketFD,

+                               pPort,

+                               "FLUSH_Stride",

+                               pFadt->FlushStride );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "DUTY_OFFSET",

+                           pFadt->DutyOffset,

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "DUTY_WIDTH",

+                           pFadt->DutyWidth,

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "DAY_ALRM",

+                           pFadt->DayAlrm,

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "MON_ALRM",

+                           pFadt->MonAlrm,

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "CENTURY",

+                           pFadt->Century,

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "IAPC_BOOT_ARCH",

+                           pFadt->IapcBootArch,

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "Reserved",

+                           pFadt->Reserved2,

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "Flags",

+                           pFadt->Flags,

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowGenericAddress ( SocketFD,

+                                 pPort,

+                                 "RESET_REG",

+                                 &pFadt->ResetReg[0],

+                                 NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "RESET_VALUE",

+                           pFadt->ResetValue,

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "Reserved",

+                           pFadt->Reserved3[0],

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "Reserved",

+                           pFadt->Reserved3[1],

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "Reserved",

+                           pFadt->Reserved3[2],

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "X_FIRMWARE_CTRL",

+                           pFadt->XFirmwareCtrl,

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "X_DSDT",

+                           pFadt->XDsdt,

+                           PAGE_ACPI_DSDT );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowGenericAddress ( SocketFD,

+                                 pPort,

+                                 "X_PM1a_EVT_BLK",

+                                 &pFadt->XPm1aEvtBlk[0],

+                                 NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowGenericAddress ( SocketFD,

+                                 pPort,

+                                 "X_PM1b_EVT_BLK",

+                                 &pFadt->XPm1bEvtBlk[0],

+                                 NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowGenericAddress ( SocketFD,

+                                 pPort,

+                                 "X_PM1a_CNT_BLK",

+                                 &pFadt->XPm1aCntBlk[0],

+                                 NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowGenericAddress ( SocketFD,

+                                 pPort,

+                                 "X_PM1b_CNT_BLK",

+                                 &pFadt->XPm1bCntBlk[0],

+                                 NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowGenericAddress ( SocketFD,

+                                 pPort,

+                                 "X_PM2_CNT_BLK",

+                                 &pFadt->XPm2CntBlk[0],

+                                 NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowGenericAddress ( SocketFD,

+                                 pPort,

+                                 "X_PM_TMR_BLK",

+                                 &pFadt->XPmTmrBlk[0],

+                                 NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowGenericAddress ( SocketFD,

+                                 pPort,

+                                 "X_GPE0_BLK",

+                                 &pFadt->XGpe0Blk[0],

+                                 NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowGenericAddress ( SocketFD,

+                                 pPort,

+                                 "X_GPE1_BLK",

+                                 &pFadt->XGpe1Blk[0],

+                                 NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Build the table trailer

+    //

+    Status = TableTrailer ( SocketFD,

+                            pPort,

+                            pbDone );

+    break;

+  }

+

+  //

+  //  Return the operation status

+  //

+  DBG_EXIT_STATUS ( Status );

+  return Status;

+}

+

+

+/**

+  Respond with the HPET table

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+AcpiHpetPage (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  )

+{

+  CONST ACPI_UNKNOWN * pHpet;

+  EFI_STATUS Status;

+

+  DBG_ENTER ( );

+

+  //

+  //  Send the HPET page

+  //

+  for ( ; ; ) {

+    //

+    //  Locate the HPET

+    //

+    pHpet = (ACPI_UNKNOWN *)LocateTable ( HPET_SIGNATURE );

+    if ( NULL == pHpet ) {

+      Status = EFI_NOT_FOUND;

+      break;

+    }

+

+    //

+    //  Send the page and table header

+    //

+    Status = TableHeader ( SocketFD, pPort, L"HPET Table", pHpet );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Display the header

+    //

+    Status = RowAnsiArray ( SocketFD,

+                            pPort,

+                            "Signature",

+                            sizeof ( pHpet->Signature ),

+                            (CHAR8 *)&pHpet->Signature );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowDecimalValue ( SocketFD,

+                               pPort,

+                               "Length",

+                               pHpet->Length );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Display the data from the table

+    //

+    Status = RowDump ( SocketFD,

+                       pPort,

+                       "Data",

+                       pHpet->Length - sizeof ( *pHpet ) + 1,

+                       (UINT8 *)( pHpet + 1 ));

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Build the table trailer

+    //

+    Status = TableTrailer ( SocketFD,

+                            pPort,

+                            pbDone );

+    break;

+  }

+

+  //

+  //  Return the operation status

+  //

+  DBG_EXIT_STATUS ( Status );

+  return Status;

+}

+

+

+/**

+  Respond with the MCFG table

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+AcpiMcfgPage (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  )

+{

+  CONST ACPI_UNKNOWN * pMcfg;

+  EFI_STATUS Status;

+

+  DBG_ENTER ( );

+

+  //

+  //  Send the MCFG page

+  //

+  for ( ; ; ) {

+    //

+    //  Locate the MCFG

+    //

+    pMcfg = (ACPI_UNKNOWN *)LocateTable ( MCFG_SIGNATURE );

+    if ( NULL == pMcfg ) {

+      Status = EFI_NOT_FOUND;

+      break;

+    }

+

+    //

+    //  Send the page and table header

+    //

+    Status = TableHeader ( SocketFD, pPort, L"MCFG Table", pMcfg );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Display the header

+    //

+    Status = RowAnsiArray ( SocketFD,

+                            pPort,

+                            "Signature",

+                            sizeof ( pMcfg->Signature ),

+                            (CHAR8 *)&pMcfg->Signature );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowDecimalValue ( SocketFD,

+                               pPort,

+                               "Length",

+                               pMcfg->Length );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Display the data from the table

+    //

+    Status = RowDump ( SocketFD,

+                       pPort,

+                       "Data",

+                       pMcfg->Length - sizeof ( *pMcfg ) + 1,

+                       (UINT8 *)( pMcfg + 1 ));

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Build the table trailer

+    //

+    Status = TableTrailer ( SocketFD,

+                            pPort,

+                            pbDone );

+    break;

+  }

+

+  //

+  //  Return the operation status

+  //

+  DBG_EXIT_STATUS ( Status );

+  return Status;

+}

+

+

+/**

+  Respond with the ACPI RSDP 1.0b table

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+AcpiRsdp10Page (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  )

+{

+  CONST EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER * pRsdp10b;

+  EFI_STATUS Status;

+

+  DBG_ENTER ( );

+

+  //

+  //  Send the RSDP page

+  //

+  for ( ; ; ) {

+    //

+    //  Locate the RSDP

+    //

+    Status = EfiGetSystemConfigurationTable ( &gEfiAcpi10TableGuid, (VOID **) &pRsdp10b );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Send the page and table header

+    //

+    Status = TableHeader ( SocketFD, pPort, L"RSDP - ACPI 1.0b Root System Description Pointer", pRsdp10b );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Display the RSDP

+    //

+    Status = RowAnsiArray ( SocketFD,

+                            pPort,

+                            "Signature",

+                            sizeof ( pRsdp10b->Signature ),

+                            (CHAR8 *)&pRsdp10b->Signature );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "Checksum",

+                           pRsdp10b->Checksum,

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowAnsiArray ( SocketFD,

+                            pPort,

+                            "OemId",

+                            sizeof ( pRsdp10b->OemId ),

+                            (CONST CHAR8 *)&pRsdp10b->OemId[ 0 ]);

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "Reserved",

+                           pRsdp10b->Reserved,

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowPointer ( SocketFD,

+                          pPort,

+                          "RsdtAddress",

+                          (VOID *)(UINTN)pRsdp10b->RsdtAddress,

+                          PAGE_ACPI_RSDT );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Build the table trailer

+    //

+    Status = TableTrailer ( SocketFD,

+                            pPort,

+                            pbDone );

+    break;

+  }

+

+  //

+  //  Return the operation status

+  //

+  DBG_EXIT_STATUS ( Status );

+  return Status;

+}

+

+

+/**

+  Respond with the ACPI RSDP 3.0 table

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+AcpiRsdp30Page (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  )

+{

+  CONST EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER * pRsdp30;

+  EFI_STATUS Status;

+

+  DBG_ENTER ( );

+

+  //

+  //  Send the RSDP page

+  //

+  for ( ; ; ) {

+    //

+    //  Locate the RSDP

+    //

+    Status = EfiGetSystemConfigurationTable ( &gEfiAcpiTableGuid, (VOID **) &pRsdp30 );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Send the page and table header

+    //

+    Status = TableHeader ( SocketFD, pPort, L"RSDP - ACPI 3.0 Root System Description Pointer", pRsdp30 );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Display the RSDP

+    //

+    Status = RowAnsiArray ( SocketFD,

+                            pPort,

+                            "Signature",

+                            sizeof ( pRsdp30->Signature ),

+                            (CHAR8 *)&pRsdp30->Signature );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "Checksum",

+                           pRsdp30->Checksum,

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowAnsiArray ( SocketFD,

+                            pPort,

+                            "OemId",

+                            sizeof ( pRsdp30->OemId ),

+                            (CONST CHAR8 *)&pRsdp30->OemId[ 0 ]);

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "Revision",

+                           pRsdp30->Revision,

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowPointer ( SocketFD,

+                          pPort,

+                          "RsdtAddress",

+                          (VOID *)(UINTN)pRsdp30->RsdtAddress,

+                          PAGE_ACPI_RSDT );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowDecimalValue ( SocketFD,

+                               pPort,

+                               "Length",

+                               pRsdp30->Length );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowPointer ( SocketFD,

+                          pPort,

+                          "XsdtAddress",

+                          (VOID *)(UINTN)pRsdp30->XsdtAddress,

+                          NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "ExtendedChecksum",

+                           pRsdp30->ExtendedChecksum,

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowBytes ( SocketFD,

+                        pPort,

+                        "Reserved",

+                        sizeof ( pRsdp30->Reserved ),

+                        &pRsdp30->Reserved[ 0 ]);

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Build the table trailer

+    //

+    Status = TableTrailer ( SocketFD,

+                            pPort,

+                            pbDone );

+    break;

+  }

+

+  //

+  //  Return the operation status

+  //

+  DBG_EXIT_STATUS ( Status );

+  return Status;

+}

+

+

+/**

+  Respond with the ACPI RSDT table

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+AcpiRsdtPage (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  )

+{

+  CONST UINT32 * pEnd;

+  CONST UINT32 * pEntry;

+  CONST ACPI_RSDT * pRsdt;

+  CONST CHAR8 * pTableName;

+  CONST CHAR16 * pWebPage;

+  EFI_STATUS Status;

+  UINT32 TableName[ 2 ];

+

+  DBG_ENTER ( );

+

+  //

+  //  Send the RSDT page

+  //

+  for ( ; ; ) {

+    //

+    //  Locate the RSDT

+    //

+    pRsdt = LocateRsdt ( );

+    if ( NULL == pRsdt ) {

+      Status = EFI_NOT_FOUND;

+      break;

+    }

+

+    //

+    //  Send the page and table header

+    //

+    Status = TableHeader ( SocketFD, pPort, L"RSDT - ACPI Root System Description Table", pRsdt );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Display the RSDT

+    //

+    Status = RowAnsiArray ( SocketFD,

+                            pPort,

+                            "Signature",

+                            sizeof ( pRsdt->Signature ),

+                            (CHAR8 *)&pRsdt->Signature );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowDecimalValue ( SocketFD,

+                               pPort,

+                               "Length",

+                               pRsdt->Length );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowDecimalValue ( SocketFD,

+                               pPort,

+                               "Revision",

+                               pRsdt->Revision );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowHexValue ( SocketFD,

+                           pPort,

+                           "Checksum",

+                           pRsdt->Checksum,

+                           NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowAnsiArray ( SocketFD,

+                            pPort,

+                            "OEMID",

+                            sizeof ( pRsdt->OemId ),

+                            (CONST CHAR8 *)&pRsdt->OemId[ 0 ]);

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowAnsiArray ( SocketFD,

+                            pPort,

+                            "OEM Table ID",

+                            sizeof ( pRsdt->OemTableId ),

+                            (CONST CHAR8 *)&pRsdt->OemTableId[ 0 ]);

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowRevision ( SocketFD,

+                           pPort,

+                           "OEM Revision",

+                           pRsdt->OemRevision );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowAnsiArray ( SocketFD,

+                            pPort,

+                            "Creator ID",

+                            sizeof ( pRsdt->CreatorId ),

+                            (CHAR8 *)&pRsdt->CreatorId );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowRevision ( SocketFD,

+                           pPort,

+                           "Creator Revision",

+                           pRsdt->CreatorRevision );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Walk the list of entries

+    //

+    pEntry = &pRsdt->Entry[ 0 ];

+    pEnd = &pEntry[(( pRsdt->Length - sizeof ( *pRsdt )) >> 2 ) + 1 ];

+    TableName[ 1 ] = 0;

+    while ( pEnd > pEntry ) {

+      //

+      //  The entry is actually a 32-bit physical table address

+      //  The first entry in the table is the 32-bit table signature

+      //

+      TableName[ 0 ] = *(UINT32 *)(UINTN)*pEntry;

+      pWebPage = SignatureLookup ( &TableName[ 0 ], &pTableName );

+

+      //

+      //  Display the table address

+      //

+      Status = RowPointer ( SocketFD,

+                            pPort,

+                            pTableName,

+                            (VOID *)(UINTN)*pEntry,

+                            pWebPage );

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+      pEntry++;

+    }

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Build the table trailer

+    //

+    Status = TableTrailer ( SocketFD,

+                            pPort,

+                            pbDone );

+    break;

+  }

+

+  //

+  //  Return the operation status

+  //

+  DBG_EXIT_STATUS ( Status );

+  return Status;

+}

+

+

+/**

+  Respond with the SSDT table

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+AcpiSsdtPage (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  )

+{

+  CONST ACPI_UNKNOWN * pSsdt;

+  EFI_STATUS Status;

+

+  DBG_ENTER ( );

+

+  //

+  //  Send the SSDT page

+  //

+  for ( ; ; ) {

+    //

+    //  Locate the SSDT

+    //

+    pSsdt = (ACPI_UNKNOWN *)LocateTable ( SSDT_SIGNATURE );

+    if ( NULL == pSsdt ) {

+      Status = EFI_NOT_FOUND;

+      break;

+    }

+

+    //

+    //  Send the page and table header

+    //

+    Status = TableHeader ( SocketFD, pPort, L"SSDT Table", pSsdt );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Display the header

+    //

+    Status = RowAnsiArray ( SocketFD,

+                            pPort,

+                            "Signature",

+                            sizeof ( pSsdt->Signature ),

+                            (CHAR8 *)&pSsdt->Signature );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowDecimalValue ( SocketFD,

+                               pPort,

+                               "Length",

+                               pSsdt->Length );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Display the data from the table

+    //

+    Status = RowDump ( SocketFD,

+                       pPort,

+                       "Data",

+                       pSsdt->Length - sizeof ( *pSsdt ) + 1,

+                       (UINT8 *)( pSsdt + 1 ));

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Build the table trailer

+    //

+    Status = TableTrailer ( SocketFD,

+                            pPort,

+                            pbDone );

+    break;

+  }

+

+  //

+  //  Return the operation status

+  //

+  DBG_EXIT_STATUS ( Status );

+  return Status;

+}

+

+

+/**

+  Respond with the TCPA table

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+AcpiTcpaPage (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  )

+{

+  CONST ACPI_UNKNOWN * pTcpa;

+  EFI_STATUS Status;

+

+  DBG_ENTER ( );

+

+  //

+  //  Send the TCPA page

+  //

+  for ( ; ; ) {

+    //

+    //  Locate the TCPA

+    //

+    pTcpa = (ACPI_UNKNOWN *)LocateTable ( TCPA_SIGNATURE );

+    if ( NULL == pTcpa ) {

+      Status = EFI_NOT_FOUND;

+      break;

+    }

+

+    //

+    //  Send the page and table header

+    //

+    Status = TableHeader ( SocketFD, pPort, L"TCPA Table", pTcpa );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Display the header

+    //

+    Status = RowAnsiArray ( SocketFD,

+                            pPort,

+                            "Signature",

+                            sizeof ( pTcpa->Signature ),

+                            (CHAR8 *)&pTcpa->Signature );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowDecimalValue ( SocketFD,

+                               pPort,

+                               "Length",

+                               pTcpa->Length );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Display the data from the table

+    //

+    Status = RowDump ( SocketFD,

+                       pPort,

+                       "Data",

+                       pTcpa->Length - sizeof ( *pTcpa ) + 1,

+                       (UINT8 *)( pTcpa + 1 ));

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Build the table trailer

+    //

+    Status = TableTrailer ( SocketFD,

+                            pPort,

+                            pbDone );

+    break;

+  }

+

+  //

+  //  Return the operation status

+  //

+  DBG_EXIT_STATUS ( Status );

+  return Status;

+}

+

+

+/**

+  Respond with the UEFI table

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+AcpiUefiPage (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  )

+{

+  CONST ACPI_UNKNOWN * pUefi;

+  EFI_STATUS Status;

+

+  DBG_ENTER ( );

+

+  //

+  //  Send the UEFI page

+  //

+  for ( ; ; ) {

+    //

+    //  Locate the UEFI

+    //

+    pUefi = (ACPI_UNKNOWN *)LocateTable ( UEFI_SIGNATURE );

+    if ( NULL == pUefi ) {

+      Status = EFI_NOT_FOUND;

+      break;

+    }

+

+    //

+    //  Send the page and table header

+    //

+    Status = TableHeader ( SocketFD, pPort, L"UEFI Table", pUefi );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Display the header

+    //

+    Status = RowAnsiArray ( SocketFD,

+                            pPort,

+                            "Signature",

+                            sizeof ( pUefi->Signature ),

+                            (CHAR8 *)&pUefi->Signature );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowDecimalValue ( SocketFD,

+                               pPort,

+                               "Length",

+                               pUefi->Length );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Display the data from the table

+    //

+    Status = RowDump ( SocketFD,

+                       pPort,

+                       "Data",

+                       pUefi->Length - sizeof ( *pUefi ) + 1,

+                       (UINT8 *)( pUefi + 1 ));

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Build the table trailer

+    //

+    Status = TableTrailer ( SocketFD,

+                            pPort,

+                            pbDone );

+    break;

+  }

+

+  //

+  //  Return the operation status

+  //

+  DBG_EXIT_STATUS ( Status );

+  return Status;

+}

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/BootServicesTable.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/BootServicesTable.c
new file mode 100644
index 0000000..4fc1324
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/BootServicesTable.c
@@ -0,0 +1,471 @@
+/**
+  @file
+  Display the boot services table
+
+  Copyright (c) 2011-2012, Intel Corporation
+  All rights reserved. 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.php
+
+  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 <WebServer.h>
+
+/**
+  Respond with the boot services table
+
+  @param [in] SocketFD      The socket's file descriptor to add to the list.
+  @param [in] pPort         The WSDT_PORT structure address
+  @param [out] pbDone       Address to receive the request completion status
+
+  @retval EFI_SUCCESS       The request was successfully processed
+
+**/
+EFI_STATUS
+BootServicesTablePage (
+  IN int SocketFD,
+  IN WSDT_PORT * pPort,
+  OUT BOOLEAN * pbDone
+  )
+{
+  EFI_STATUS Status;
+
+  DBG_ENTER ( );
+  
+  //
+  //  Send the boot services page
+  //
+  for ( ; ; ) {
+    //
+    //  Send the page and table header
+    //
+    Status = TableHeader ( SocketFD, pPort, L"Boot Services Table", gBS );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    ///
+    /// The table header for the EFI Boot Services Table.
+    ///
+    Status = EfiTableHeader ( SocketFD,
+                              pPort,
+                              &gBS->Hdr );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+  
+    //
+    // Task Priority Services
+    //
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "RaiseTPL",
+                          (CONST VOID *)gBS->RaiseTPL,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "RestoreTPL",
+                          (CONST VOID *)gBS->RestoreTPL,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+  
+    //
+    // Memory Services
+    //
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "AllocatePages",
+                          (CONST VOID *)gBS->AllocatePages,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "FreePages",
+                          (CONST VOID *)gBS->FreePages,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "GetMemoryMap",
+                          (CONST VOID *)gBS->GetMemoryMap,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "AllocatePool",
+                          (CONST VOID *)gBS->AllocatePool,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "FreePool",
+                          (CONST VOID *)gBS->FreePool,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+  
+    //
+    // Event & Timer Services
+    //
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "CreateEvent",
+                          (CONST VOID *)gBS->CreateEvent,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "SetTimer",
+                          (CONST VOID *)gBS->SetTimer,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "WaitForEvent",
+                          (CONST VOID *)gBS->WaitForEvent,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "SignalEvent",
+                          (CONST VOID *)gBS->SignalEvent,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "CloseEvent",
+                          (CONST VOID *)gBS->CloseEvent,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "CheckEvent",
+                          (CONST VOID *)gBS->CheckEvent,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+  
+    //
+    // Protocol Handler Services
+    //
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "InstallProtocolInterface",
+                          (CONST VOID *)gBS->InstallProtocolInterface,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "ReinstallProtocolInterface",
+                          (CONST VOID *)gBS->ReinstallProtocolInterface,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "UninstallProtocolInterface",
+                          (CONST VOID *)gBS->UninstallProtocolInterface,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "HandleProtocol",
+                          (CONST VOID *)gBS->HandleProtocol,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "Reserved",
+                          (CONST VOID *)gBS->Reserved,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "RegisterProtocolNotify",
+                          (CONST VOID *)gBS->RegisterProtocolNotify,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "LocateHandle",
+                          (CONST VOID *)gBS->LocateHandle,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "LocateDevicePath",
+                          (CONST VOID *)gBS->LocateDevicePath,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "InstallConfigurationTable",
+                          (CONST VOID *)gBS->InstallConfigurationTable,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+  
+    //
+    // Image Services
+    //
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "LoadImage",
+                          (CONST VOID *)gBS->LoadImage,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "StartImage",
+                          (CONST VOID *)gBS->StartImage,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "Exit",
+                          (CONST VOID *)gBS->Exit,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "UnloadImage",
+                          (CONST VOID *)gBS->UnloadImage,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "ExitBootServices",
+                          (CONST VOID *)gBS->ExitBootServices,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+  
+    //
+    // Miscellaneous Services
+    //
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "GetNextMonotonicCount",
+                          (CONST VOID *)gBS->GetNextMonotonicCount,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "Stall",
+                          (CONST VOID *)gBS->Stall,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "SetWatchdogTimer",
+                          (CONST VOID *)gBS->SetWatchdogTimer,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+  
+    //
+    // DriverSupport Services
+    //
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "ConnectController",
+                          (CONST VOID *)gBS->ConnectController,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "DisconnectController",
+                          (CONST VOID *)gBS->DisconnectController,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+  
+    //
+    // Open and Close Protocol Services
+    //
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "OpenProtocol",
+                          (CONST VOID *)gBS->OpenProtocol,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "CloseProtocol",
+                          (CONST VOID *)gBS->CloseProtocol,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "OpenProtocolInformation",
+                          (CONST VOID *)gBS->OpenProtocolInformation,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+  
+    //
+    // Library Services
+    //
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "ProtocolsPerHandle",
+                          (CONST VOID *)gBS->ProtocolsPerHandle,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "LocateHandleBuffer",
+                          (CONST VOID *)gBS->LocateHandleBuffer,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "LocateProtocol",
+                          (CONST VOID *)gBS->LocateProtocol,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "InstallMultipleProtocolInterfaces",
+                          (CONST VOID *)gBS->InstallMultipleProtocolInterfaces,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "UninstallMultipleProtocolInterfaces",
+                          (CONST VOID *)gBS->UninstallMultipleProtocolInterfaces,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+  
+    //
+    // 32-bit CRC Services
+    //
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "CalculateCrc32",
+                          (CONST VOID *)gBS->CalculateCrc32,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+  
+    //
+    // Miscellaneous Services
+    //
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "CopyMem",
+                          (CONST VOID *)gBS->CopyMem,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "SetMem",
+                          (CONST VOID *)gBS->SetMem,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "CreateEventEx",
+                          (CONST VOID *)gBS->CreateEventEx,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Build the table trailer
+    //
+    Status = TableTrailer ( SocketFD,
+                            pPort,
+                            pbDone );
+    break;
+  }
+    
+  //
+  //  Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/ConfigurationTable.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/ConfigurationTable.c
new file mode 100644
index 0000000..f6303df
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/ConfigurationTable.c
@@ -0,0 +1,370 @@
+/**
+  @file
+  Display the configuration table
+
+  Copyright (c) 2011-2012, Intel Corporation
+  All rights reserved. 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.php
+
+  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 <WebServer.h>
+#include <Guid/Acpi.h>
+#include <Guid/DebugImageInfoTable.h>
+#include <Guid/DxeServices.h>
+#include <Guid/HobList.h>
+#include <Guid/MemoryTypeInformation.h>
+#include <Guid/LoadModuleAtFixedAddress.h>
+
+
+typedef struct {
+  CHAR16 * GuidName;
+  EFI_GUID * pGuid;
+  CHAR16 * pWebPage;
+} GUID_NAME;
+
+CONST GUID_NAME mGuidName[] = {
+  { L"gEfiAcpi10TableGuid", &gEfiAcpi10TableGuid, PAGE_ACPI_RSDP_10B },
+  { L"gEfiAcpiTableGuid", &gEfiAcpiTableGuid, PAGE_ACPI_RSDP_30 },
+  { L"gEfiDebugImageInfoTableGuid", &gEfiDebugImageInfoTableGuid, NULL },
+  { L"gEfiDxeServicesTableGuid", &gEfiDxeServicesTableGuid, PAGE_DXE_SERVICES_TABLE },
+  { L"gEfiHobListGuid", &gEfiHobListGuid, NULL },
+  { L"gEfiMemoryTypeInformationGuid", &gEfiMemoryTypeInformationGuid, NULL },
+  { L"gLoadFixedAddressConfigurationTableGuid", &gLoadFixedAddressConfigurationTableGuid, NULL }
+};
+
+/**
+  Display a row containing a GUID value
+
+  @param [in] SocketFD      The socket's file descriptor to add to the list.
+  @param [in] pPort         The WSDT_PORT structure address
+  @param [in] pName         Address of a zero terminated name string
+  @param [in] pGuid         Address of the GUID to display
+
+  @retval EFI_SUCCESS       The request was successfully processed
+
+**/
+EFI_STATUS
+RowGuid (
+  IN int SocketFD,
+  IN WSDT_PORT * pPort,
+  IN CONST CHAR8 * pName,
+  IN CONST EFI_GUID * pGuid
+  )
+{
+  CONST GUID_NAME * pGuidName;
+  CONST GUID_NAME * pGuidNameEnd;
+  EFI_STATUS Status;
+  UINTN Value;
+
+  DBG_ENTER ( );
+  
+  //
+  //  Use for/break instead of goto
+  //
+  for ( ; ; ) {
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "<tr><td>" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  pName );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "</td><td><code>" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Determine if this is a known GUID
+    //
+    pGuidName = &mGuidName[0];
+    pGuidNameEnd = &pGuidName[ sizeof ( mGuidName ) / sizeof ( mGuidName[0])];
+    while ( pGuidNameEnd > pGuidName ) {
+      if ( CompareGuid ( pGuidName->pGuid, pGuid )) {
+        //
+        //  Display the web link if available
+        //
+        if ( NULL != pGuidName->pWebPage ) {
+          Status = HttpSendAnsiString ( SocketFD,
+                                        pPort,
+                                        "<a target=\"_blank\" href=\"" );
+          if ( EFI_ERROR ( Status )) {
+            break;
+          }
+          Status = HttpSendUnicodeString ( SocketFD,
+                                           pPort,
+                                           pGuidName->pWebPage );
+          if ( EFI_ERROR ( Status )) {
+            break;
+          }
+          Status = HttpSendAnsiString ( SocketFD,
+                                        pPort,
+                                        "\">" );
+          if ( EFI_ERROR ( Status )) {
+            break;
+          }
+        }
+
+        //
+        //  Display the GUID name
+        //
+        Status = HttpSendUnicodeString ( SocketFD,
+                                         pPort,
+                                         pGuidName->GuidName );
+
+        //
+        //  Complete the web link if available
+        //
+        if ( NULL != pGuidName->pWebPage ) {
+          if ( EFI_ERROR ( Status )) {
+            break;
+          }
+          Status = HttpSendAnsiString ( SocketFD,
+                                        pPort,
+                                        "</a>" );
+        }
+        break;
+      }
+    
+      //
+      //  Set the next GUID name
+      //
+      pGuidName += 1;
+    }
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Only if the entry is not known, display the GUID and type
+    //
+    if ( pGuidNameEnd <= pGuidName ) {
+      //
+      //  Display the GUID
+      //
+      Status = HttpSendGuid ( SocketFD,
+                              pPort,
+                              pGuid );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+
+      //
+      //  Display the GUID type
+      //
+      Status = HttpSendAnsiString ( SocketFD,
+                                    pPort,
+                                    "<br/><a target=\"_blank\" href=\"http://www.ietf.org/rfc/rfc4122.txt\">Guid Type</a>: " );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+      Value = pGuid->Data4[1];
+      Value >>= 5;
+      if ( 3 >= Value ) {
+        //
+        //  Network type
+        //
+        Status = HttpSendAnsiString ( SocketFD,
+                                      pPort,
+                                      "Network " );
+      }
+      else if ( 5 >= Value ) {
+        //
+        //  Standard type
+        //
+        Status = HttpSendAnsiString ( SocketFD,
+                                      pPort,
+                                      "Standard " );
+        if ( EFI_ERROR ( Status )) {
+          break;
+        }
+
+        //
+        //  Decode the standard type using RFC 4122
+        //
+        Value = pGuid->Data3;
+        Value >>= 12;
+        switch ( Value ) {
+        default:
+          //
+          //  Display the MAC address
+          //
+          Status = HttpSendAnsiString ( SocketFD,
+                                        pPort,
+                                        "Version " );
+          if ( EFI_ERROR ( Status )) {
+            break;
+          }
+          Status = HttpSendValue ( SocketFD,
+                                   pPort,
+                                   pGuid->Data3 >> 12 );
+          break;
+
+        case 1:
+          Status = HttpSendAnsiString ( SocketFD,
+                                        pPort,
+                                        "MAC address" );
+          break;
+
+        case 2:
+          Status = HttpSendAnsiString ( SocketFD,
+                                        pPort,
+                                        "DCE Security" );
+          break;
+
+        case 3:
+          Status = HttpSendAnsiString ( SocketFD,
+                                        pPort,
+                                        "MD5 hash" );
+          break;
+
+        case 4:
+          Status = HttpSendAnsiString ( SocketFD,
+                                        pPort,
+                                        "Random" );
+          break;
+
+        case 5:
+          Status = HttpSendAnsiString ( SocketFD,
+                                        pPort,
+                                        "SHA-1 hash" );
+          break;
+        }
+      }
+      else if ( 6 == Value ) {
+        //
+        //  Microsoft's Component Object Model (COM) type
+        //
+        Status = HttpSendAnsiString ( SocketFD,
+                                      pPort,
+                                      "Microsoft COM" );
+      }
+      else {
+        //
+        //  Reserved type
+        //
+        Status = HttpSendAnsiString ( SocketFD,
+                                      pPort,
+                                      "Reserved" );
+      }
+    }
+
+    //
+    //  Done with this entry
+    //
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "</code></td></tr>\r\n" );
+    break;
+  }
+  
+  //
+  //  Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  Respond with the configuration tables
+
+  @param [in] SocketFD      The socket's file descriptor to add to the list.
+  @param [in] pPort         The WSDT_PORT structure address
+  @param [out] pbDone       Address to receive the request completion status
+
+  @retval EFI_SUCCESS       The request was successfully processed
+
+**/
+EFI_STATUS
+ConfigurationTablePage (
+  IN int SocketFD,
+  IN WSDT_PORT * pPort,
+  OUT BOOLEAN * pbDone
+  )
+{
+  EFI_CONFIGURATION_TABLE * pEnd;
+  EFI_CONFIGURATION_TABLE * pTable;
+  EFI_STATUS Status;
+
+  DBG_ENTER ( );
+  
+  //
+  //  Send the system table page
+  //
+  for ( ; ; ) {
+    //
+    //  Send the page and table header
+    //
+    Status = TableHeader ( SocketFD, pPort, L"Configuration Tables", gST );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Display the table size
+    //
+    Status = RowDecimalValue ( SocketFD,
+                               pPort,
+                               "Entries",
+                               gST->NumberOfTableEntries );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Determine the location of the configuration tables
+    //
+    pTable = gST->ConfigurationTable;
+    pEnd = &pTable[ gST->NumberOfTableEntries ];
+    while ( pEnd > pTable ) {
+      Status = RowGuid ( SocketFD,
+                         pPort,
+                         "VendorGuid",
+                         &pTable->VendorGuid );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+      Status = RowPointer ( SocketFD,
+                            pPort,
+                            "VendorTable",
+                            (VOID *)pTable->VendorTable,
+                            NULL );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+
+      //
+      //  Set the next row
+      //
+      pTable += 1;
+    }
+
+    //
+    //  Build the table trailer
+    //
+    Status = TableTrailer ( SocketFD,
+                            pPort,
+                            pbDone );
+    break;
+  }
+    
+  //
+  //  Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/DhcpOptions.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/DhcpOptions.c
new file mode 100644
index 0000000..8eeff45
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/DhcpOptions.c
@@ -0,0 +1,222 @@
+/** @file
+    Display the DHCP options
+
+    Copyright (c) 2011 - 2012, 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 <WebServer.h>

+#include <Guid/DxeServices.h>

+#include <Pi/PiDxeCis.h>

+

+#include <Protocol/Dhcp4.h>

+#include <Protocol/ServiceBinding.h>

+

+/**

+  Respond with the DHCP options

+

+  @param[in]  SocketFD      The socket's file descriptor to add to the list.

+  @param[in]  pPort         The WSDT_PORT structure address

+  @param[out] pbDone        Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+DhcpOptionsPage (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  )

+{

+//  EFI_HANDLE Dhcp4Handle;

+  EFI_DHCP4_MODE_DATA Dhcp4Mode;

+  UINTN HandleCount;

+  EFI_DHCP4_PROTOCOL * pDhcp4;

+  EFI_DHCP4_PACKET * pDhcp4Packet;

+  EFI_HANDLE * pEnd;

+  EFI_HANDLE * pHandle;

+//  EFI_SERVICE_BINDING_PROTOCOL * pService;

+  EFI_STATUS Status;

+

+  DBG_ENTER ( );

+

+  //

+  //  Send the DHCP options

+  //

+  for ( ; ; ) {

+    //

+    //  Send the page header

+    //

+    Status = HttpPageHeader ( SocketFD, pPort, L"DHCP Options" );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Build the header

+    //

+    Status = HttpSendAnsiString ( SocketFD,

+                                  pPort,

+                                  "<h1>" );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = HttpSendUnicodeString ( SocketFD,

+                                     pPort,

+                                     L"DHCP Options" );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = HttpSendAnsiString ( SocketFD,

+                                  pPort,

+                                  "</h1>\r\n" );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Attempt to locate DHCP clients

+    //

+    Status = gBS->LocateHandleBuffer ( ByProtocol,

+//                                       &gEfiDhcp4ServiceBindingProtocolGuid,

+                                       &gEfiDhcp4ProtocolGuid,

+                                       NULL,

+                                       &HandleCount,

+                                       &pHandle );

+    if ( EFI_ERROR ( Status )) {

+      Status = HttpSendAnsiString ( SocketFD,

+                                    pPort,

+                                    "DHCP not in use" );

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+    }

+    else {

+      //

+      //  Walk the list of handles

+      //

+      pEnd = &pHandle [ HandleCount ];

+      while ( pEnd > pHandle ) {

+/*

+        //

+        //  Get the DHCP service binding

+        //

+        Status = gBS->OpenProtocol ( *pHandle,

+                                      &gEfiDhcp4ServiceBindingProtocolGuid,

+                                      &pService,

+                                      NULL,

+                                      gImageHandle,

+                                      EFI_OPEN_PROTOCOL_GET_PROTOCOL );

+        if ( EFI_ERROR ( Status )) {

+          Status = HttpSendAnsiString ( SocketFD,

+                                        pPort,

+                                        "Failed to open gEfiDhcp4ServiceBindingProtocolGuid" );

+          break;

+        }

+

+        //

+        //  Get the DHCP handle

+        //

+        Status = pService->CreateChild ( pService,

+                                         &Dhcp4Handle );

+        if ( EFI_ERROR ( Status )) {

+          Status = HttpSendAnsiString ( SocketFD,

+                                        pPort,

+                                        "Failed to create DHCP4 child" );

+        }

+        else {

+*/

+          //

+          //  Get the DHCP protocol

+          //

+          Status = gBS->OpenProtocol ( *pHandle,

+//                                       Dhcp4Handle,

+                                       &gEfiDhcp4ProtocolGuid,

+                                       (VOID **)&pDhcp4,

+                                       NULL,

+                                       gImageHandle,

+                                       EFI_OPEN_PROTOCOL_GET_PROTOCOL );

+          if ( EFI_ERROR ( Status )) {

+            Status = HttpSendAnsiString ( SocketFD,

+                                          pPort,

+                                          "Failed to open gEfiDhcp4ProtocolGuid" );

+          }

+          else {

+            //

+            //  Get the DHCP packet

+            //

+            Status = pDhcp4->GetModeData ( pDhcp4,

+                                           &Dhcp4Mode );

+            if ( EFI_ERROR ( Status )) {

+              Status = HttpSendAnsiString ( SocketFD,

+                                            pPort,

+                                            "Failed to get DHCP4 mode" );

+            }

+            else {

+              //

+              //  Get the last packet

+              //

+              pDhcp4Packet = Dhcp4Mode.ReplyPacket;

+              if ( NULL == pDhcp4Packet ) {

+                Status = HttpSendAnsiString ( SocketFD,

+                                              pPort,

+                                              "No DHCP reply received!<br/>DHCP Mode:<br/>" );

+                if ( EFI_ERROR ( Status )) {

+                  break;

+                }

+

+                //

+                //  Display the DHCP mode data

+                //

+                Status = HttpSendDump ( SocketFD,

+                                        pPort,

+                                        sizeof ( Dhcp4Mode ),

+                                        (UINT8 *)&Dhcp4Mode );

+              }

+              else {

+                //

+                //  Display the DHCP packet

+                //

+                Status = HttpSendDump ( SocketFD,

+                                        pPort,

+                                        pDhcp4Packet->Length,

+                                        (UINT8 *)&pDhcp4Packet->Dhcp4 );

+              }

+            }

+/*

+          }

+

+          //

+          //  Done with the DHCP protocol

+          //

+          pService->DestroyChild ( pService,

+                                   Dhcp4Handle );

+*/

+        }

+

+        //

+        //  Set the next service binding

+        //

+        pHandle += 1;

+      }

+    }

+

+    //

+    //  Send the page trailer

+    //

+    Status = HttpPageTrailer ( SocketFD, pPort, pbDone );

+    break;

+  }

+

+  //

+  //  Return the operation status

+  //

+  DBG_EXIT_STATUS ( Status );

+  return Status;

+}

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/DxeServicesTable.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/DxeServicesTable.c
new file mode 100644
index 0000000..fe0f597
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/DxeServicesTable.c
@@ -0,0 +1,232 @@
+/** @file
+    Display the DXE services table
+
+    Copyright (c)  2011 - 2012 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 <WebServer.h>

+#include <Guid/DxeServices.h>

+#include <Pi/PiDxeCis.h>

+

+/**

+  Respond with the DXE services table

+

+  @param[in]  SocketFD      The socket's file descriptor to add to the list.

+  @param[in]  pPort         The WSDT_PORT structure address

+  @param[out] pbDone        Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+DxeServicesTablePage (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  )

+{

+  EFI_DXE_SERVICES * pDS;

+  EFI_STATUS Status;

+

+  DBG_ENTER ( );

+

+  //

+  //  Send the DXE services page

+  //

+  for ( ; ; ) {

+    //

+    //  Get the DXE services table

+    //

+    Status = EfiGetSystemConfigurationTable (&gEfiDxeServicesTableGuid, (VOID **) &pDS);

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Send the page and table header

+    //

+    Status = TableHeader ( SocketFD, pPort, L"DXE Services Table", pDS );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    ///

+    /// The table header for the DXE Services Table.

+    /// This header contains the DXE_SERVICES_SIGNATURE and DXE_SERVICES_REVISION values.

+    ///

+    Status = EfiTableHeader ( SocketFD,

+                              pPort,

+                              &pDS->Hdr );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    // Global Coherency Domain Services

+    //

+    Status = RowPointer ( SocketFD,

+                          pPort,

+                          "AddMemorySpace",

+                          (VOID *)pDS->AddMemorySpace,

+                          NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowPointer ( SocketFD,

+                          pPort,

+                          "AllocateMemorySpace",

+                          (VOID *)pDS->AllocateMemorySpace,

+                          NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowPointer ( SocketFD,

+                          pPort,

+                          "FreeMemorySpace",

+                          (VOID *)pDS->FreeMemorySpace,

+                          NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowPointer ( SocketFD,

+                          pPort,

+                          "RemoveMemorySpace",

+                          (VOID *)pDS->RemoveMemorySpace,

+                          NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowPointer ( SocketFD,

+                          pPort,

+                          "GetMemorySpaceDescriptor",

+                          (VOID *)pDS->GetMemorySpaceDescriptor,

+                          NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowPointer ( SocketFD,

+                          pPort,

+                          "SetMemorySpaceAttributes",

+                          (VOID *)pDS->SetMemorySpaceAttributes,

+                          NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowPointer ( SocketFD,

+                          pPort,

+                          "GetMemorySpaceMap",

+                          (VOID *)pDS->GetMemorySpaceMap,

+                          NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowPointer ( SocketFD,

+                          pPort,

+                          "AddIoSpace",

+                          (VOID *)pDS->AddIoSpace,

+                          NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowPointer ( SocketFD,

+                          pPort,

+                          "AllocateIoSpace",

+                          (VOID *)pDS->AllocateIoSpace,

+                          NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowPointer ( SocketFD,

+                          pPort,

+                          "FreeIoSpace",

+                          (VOID *)pDS->FreeIoSpace,

+                          NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowPointer ( SocketFD,

+                          pPort,

+                          "RemoveIoSpace",

+                          (VOID *)pDS->RemoveIoSpace,

+                          NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowPointer ( SocketFD,

+                          pPort,

+                          "GetIoSpaceDescriptor",

+                          (VOID *)pDS->GetIoSpaceDescriptor,

+                          NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowPointer ( SocketFD,

+                          pPort,

+                          "GetIoSpaceMap",

+                          (VOID *)pDS->GetIoSpaceMap,

+                          NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    // Dispatcher Services

+    //

+    Status = RowPointer ( SocketFD,

+                          pPort,

+                          "Dispatch",

+                          (VOID *)pDS->Dispatch,

+                          NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowPointer ( SocketFD,

+                          pPort,

+                          "Schedule",

+                          (VOID *)pDS->Schedule,

+                          NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = RowPointer ( SocketFD,

+                          pPort,

+                          "Trust",

+                          (VOID *)pDS->Trust,

+                          NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    // Service to process a single firmware volume found in a capsule

+    //

+    Status = RowPointer ( SocketFD,

+                          pPort,

+                          "ProcessFirmwareVolume",

+                          (VOID *)pDS->ProcessFirmwareVolume,

+                          NULL );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Build the table trailer

+    //

+    Status = TableTrailer ( SocketFD,

+                            pPort,

+                            pbDone );

+    break;

+  }

+

+  //

+  //  Return the operation status

+  //

+  DBG_EXIT_STATUS ( Status );

+  return Status;

+}

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Exit.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Exit.c
new file mode 100644
index 0000000..5ff09d3
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Exit.c
@@ -0,0 +1,82 @@
+/**
+  @file
+  Exit response page
+
+  Copyright (c) 2011-2012, Intel Corporation
+  All rights reserved. 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.php
+
+  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 <WebServer.h>
+
+
+/**
+  Respond with the Exit page
+
+  @param [in] SocketFD      The socket's file descriptor to add to the list.
+  @param [in] pPort         The WSDT_PORT structure address
+  @param [out] pbDone       Address to receive the request completion status
+
+  @retval EFI_SUCCESS       The request was successfully processed
+
+**/
+EFI_STATUS
+ExitPage (
+  IN int SocketFD,
+  IN WSDT_PORT * pPort,
+  OUT BOOLEAN * pbDone
+  )
+{
+  EFI_STATUS Status;
+  
+  DBG_ENTER ( );
+  
+  //
+  //  Send the Hello World page
+  //
+  for ( ; ; ) {
+    //
+    //  Tell the web-server to exit
+    //
+    mWebServer.bRunning = FALSE;
+
+    //
+    //  Send the page header
+    //
+    Status = HttpPageHeader ( SocketFD, pPort, L"Exit" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+  
+    //
+    //  Send the page body
+    //
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "<h1>Exit</h1>\r\n"
+                                  "<p>\r\n"
+                                  "  Exiting the web-server application.\r\n"
+                                  "</p>\r\n" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+  
+    //
+    //  Send the page trailer
+    //
+    Status = HttpPageTrailer ( SocketFD, pPort, pbDone );
+    break;
+  }
+    
+  //
+  //  Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Firmware.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Firmware.c
new file mode 100644
index 0000000..a29da5e
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Firmware.c
@@ -0,0 +1,96 @@
+/**
+  @file
+  Display the firmware
+
+  Copyright (c) 2011-2012, Intel Corporation
+  All rights reserved. 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.php
+
+  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 <WebServer.h>
+
+
+/**
+  Respond with the firmware status
+
+  @param [in] SocketFD      The socket's file descriptor to add to the list.
+  @param [in] pPort         The WSDT_PORT structure address
+  @param [out] pbDone       Address to receive the request completion status
+
+  @retval EFI_SUCCESS       The request was successfully processed
+
+**/
+EFI_STATUS
+FirmwarePage (
+  IN int SocketFD,
+  IN WSDT_PORT * pPort,
+  OUT BOOLEAN * pbDone
+  )
+{
+  EFI_STATUS Status;
+
+  DBG_ENTER ( );
+  
+  //
+  //  Send the system table page
+  //
+  for ( ; ; ) {
+    //
+    //  Send the page and table header
+    //
+    Status = TableHeader ( SocketFD, pPort, L"Firmware", NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Display the firmware vendor and revision
+    //
+    Status = RowUnicodeString ( SocketFD,
+                                pPort,
+                                "Vendor",
+                                gST->FirmwareVendor );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    
+    Status = RowRevision ( SocketFD,
+                           pPort,
+                           "Revision",
+                           gST->FirmwareRevision );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Display the UEFI version
+    //
+    Status = RowRevision ( SocketFD,
+                           pPort,
+                           "UEFI",
+                           gST->Hdr.Revision );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Build the table trailer
+    //
+    Status = TableTrailer ( SocketFD,
+                            pPort,
+                            pbDone );
+    break;
+  }
+    
+  //
+  //  Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/HTTP.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/HTTP.c
new file mode 100644
index 0000000..fae1dd9
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/HTTP.c
@@ -0,0 +1,1735 @@
+/**

+  @file

+  HTTP processing for the web server.

+

+  Copyright (c) 2011-2012, Intel Corporation

+  All rights reserved. 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.php

+

+  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 <WebServer.h>

+

+

+/**

+  Get a UTF-8 character from the buffer

+

+  @param [in] pData     The address of the buffer containing the character

+  @param [out] ppData   The address to receive the next character address

+

+  @return     The character value

+

+**/

+INTN

+HttpCharGet (

+  IN UINT8 * pData,

+  IN UINT8 ** ppData

+  )

+{

+  INTN Data;

+  INTN Character;

+  INTN Control;

+  INTN Mask;

+

+  //

+  //  Verify that there is some data left

+  //

+  if ( NULL == pData ) {

+    //

+    //  No data to return

+    //

+    pData = NULL;

+    Character = 0;

+  }

+  else {

+    //

+    //  Get the first portion of the character

+    //

+    Character = *pData++;

+    Control = Character;

+    Mask = 0xc0;

+

+    //

+    //  Append the rest of the character

+    //

+    if ( 0 != ( Control & 0x80 )) {

+      while ( 0 != ( Control & 0x40 )) {

+        Character &= Mask;

+        Mask <<= 5;

+        Control <<= 1;

+        Character <<= 6;

+        Data = *pData++ & 0x3f;

+        if ( 0x80 != ( Data & 0xc0 )) {

+          //

+          //  Invalid character

+          //

+          pData = NULL;

+          Character = 0;

+          break;

+        }

+        Character |= Data & 0x3f;

+      }

+    }

+  }

+

+  //

+  //  Return the next character location and the character

+  //

+  *ppData = pData;

+  return Character;

+}

+

+

+/**

+  Transmit a portion of the HTTP response

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+HttpFlush (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort

+  )

+{

+  INTN LengthInBytes;

+  UINT8 * pBuffer;

+  EFI_STATUS Status;

+

+  DBG_ENTER ( );

+

+  //

+  //  Assume success

+  //

+  Status = EFI_SUCCESS;

+  pBuffer = &pPort->TxBuffer[0];

+  do {

+    //

+    //  Attempt to send the data

+    //

+    LengthInBytes = send ( SocketFD,

+                           pBuffer,

+                           pPort->TxBytes,

+                           0 );

+    if ( -1 != LengthInBytes ) {

+      //

+      //  Account for the data sent

+      //

+      pBuffer += LengthInBytes;

+      pPort->TxBytes -= LengthInBytes;

+    }

+    else {

+      //

+      //  Transmit error

+      //

+      Status = EFI_DEVICE_ERROR;

+      break;

+    }

+  } while ( 0 < pPort->TxBytes );

+

+  //

+  //  Return the operation status

+  //

+  DBG_EXIT_STATUS ( Status );

+  return Status;

+}

+

+

+/**

+  Convert the ANSI character to lower case

+

+  @param [in] Character The character to convert to lower case.

+

+  @return   The lower case character

+

+**/

+INTN

+HttpLowerCase (

+  IN INTN Character

+  )

+{

+  //

+  //  Determine if the character is upper case

+  //

+  if (( 'A' <= Character ) && ( 'Z' >= Character )) {

+    Character += 'a' - 'A';

+  }

+

+  //

+  //  Return the lower case value of the character

+  //

+  return Character;

+}

+

+

+/**

+  Match a Unicode string against a UTF-8 string

+

+  @param [in] pString     A zero terminated Unicode string

+  @param [in] pData       A zero terminated UTF-8 string

+  @param [in] bIgnoreCase TRUE if case is to be ignored

+

+  @return     The difference between the last two characters tested.

+              Returns -1 for error.

+

+**/

+INTN

+HttpMatch (

+  IN UINT16 * pString,

+  IN UINT8 * pData,

+  IN BOOLEAN bIgnoreCase

+  )

+{

+  INTN Character1;

+  INTN Character2;

+  INTN Difference;

+

+  do {

+    //

+    //  Get the character from the comparison string

+    //

+    Character1 = *pString++;

+

+    //

+    //  Convert the character to lower case

+    //

+    if ( bIgnoreCase ) {

+      Character1 = HttpLowerCase ( Character1 );

+    }

+

+    //

+    //  Get the character from the request

+    //

+    Character2 = HttpCharGet ( pData, &pData );

+    if ( NULL == pData ) {

+       //

+       // Error getting character

+       //

+       Difference = -1;

+       break;

+    }

+

+    //

+    //  Convert the character to lower case

+    //

+    if ( bIgnoreCase ) {

+      Character2 = HttpLowerCase ( Character2 );

+    }

+

+    //

+    //  Compare the characters

+    //

+    Difference = Character1 - Character2;

+    if ( 0 != Difference ) {

+      return Difference;

+    }

+  } while ( 0 != Character1 );

+

+  //

+  //  Return the difference

+  //

+  return Difference;

+}

+

+

+/**

+  Buffer the HTTP page header

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [in] pTitle        A zero terminated Unicode title string

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+HttpPageHeader (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN CONST CHAR16 * pTitle

+  )

+{

+  EFI_STATUS Status;

+

+  DBG_ENTER ( );

+

+  //

+  //  Build the page header

+  //

+  for ( ; ; ) {

+    Status = HttpSendAnsiString ( SocketFD,

+                                  pPort,

+                                  "<!DOCTYPE "

+                                  "HTML "

+                                  "PUBLIC "

+                                  "\"-//W3C//DTD HTML 4.01 Transitional//EN\" "

+                                  "\"http://www.w3.org/TR/html4/loose.dtd\">\r\n" );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = HttpSendAnsiString ( SocketFD, pPort, "<html lang=\"en-US\">\r\n" );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    if ( NULL != pTitle ) {

+      Status = HttpSendAnsiString ( SocketFD, pPort, "  <head>\r\n" );

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+      Status = HttpSendAnsiString ( SocketFD, pPort, "    <title>" );

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+      Status = HttpSendUnicodeString ( SocketFD, pPort, pTitle );

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+      Status = HttpSendAnsiString ( SocketFD, pPort, "</title>\r\n" );

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+      Status = HttpSendAnsiString ( SocketFD, pPort, "  </head>\r\n" );

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+    }

+    Status = HttpSendAnsiString ( SocketFD, pPort, "  <body>\r\n" );

+    break;

+  }

+

+  //

+  //  Return the operation status

+  //

+  DBG_EXIT_STATUS ( Status );

+  return Status;

+}

+

+

+/**

+  Respond with an error indicating that the page was not found

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+HttpPageNotFound (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN BOOLEAN * pbDone

+  )

+{

+  EFI_STATUS Status;

+

+  DBG_ENTER ( );

+

+  //

+  //  Send the page not found

+  //

+  for ( ; ; ) {

+    //

+    //  Send the page header

+    //

+    Status = HttpPageHeader ( SocketFD, pPort, L"404 Not found" );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Send the page body

+    //

+    Status = HttpSendAnsiString ( SocketFD,

+                                  pPort,

+                                  "ERROR <b>404</b><br />"

+                                  "Requested page is not available\r\n" );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Send the page trailer

+    //

+    Status = HttpPageTrailer ( SocketFD, pPort, pbDone );

+    break;

+  }

+

+  //

+  //  Return the operation status

+  //

+  DBG_EXIT_STATUS ( Status );

+  return Status;

+}

+

+

+/**

+  Buffer and send the HTTP page trailer

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+HttpPageTrailer (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN BOOLEAN * pbDone

+  )

+{

+  int RetVal;

+  EFI_STATUS Status;

+  socklen_t LengthInBytes;

+  struct sockaddr_in6 LocalAddress;

+  struct sockaddr_in6 RemoteAddress;

+

+  DBG_ENTER ( );

+

+  //

+  //  Build the page header

+  //

+  for ( ; ; ) {

+    LengthInBytes = sizeof ( LocalAddress );

+    RetVal = getsockname ( SocketFD, (struct sockaddr *)&LocalAddress, &LengthInBytes );

+    if ( 0 == RetVal ) {

+      LengthInBytes = sizeof ( LocalAddress );

+      RetVal = getpeername ( SocketFD, (struct sockaddr *)&RemoteAddress, &LengthInBytes );

+      if ( 0 == RetVal ) {

+        //

+        //  Seperate the body from the trailer

+        //

+        Status = HttpSendAnsiString ( SocketFD, pPort, "  <hr>\r\n<code>" );

+        if ( EFI_ERROR ( Status )) {

+          break;

+        }

+

+        //

+        //  Display the system addresses and the page transfer direction

+        //

+        Status = HttpSendIpAddress ( SocketFD, pPort, &LocalAddress );

+        if ( EFI_ERROR ( Status )) {

+          break;

+        }

+        Status = HttpSendAnsiString ( SocketFD, pPort, "  -->  " );

+        if ( EFI_ERROR ( Status )) {

+          break;

+        }

+        Status = HttpSendIpAddress ( SocketFD, pPort, &RemoteAddress );

+        if ( EFI_ERROR ( Status )) {

+          break;

+        }

+        Status = HttpSendAnsiString ( SocketFD, pPort, "</code>\r\n" );

+        if ( EFI_ERROR ( Status )) {

+          break;

+        }

+      }

+    }

+

+    //

+    //  Terminate the page

+    //

+    Status = HttpSendAnsiString ( SocketFD, pPort, "  </body>\r\n" );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = HttpSendAnsiString ( SocketFD, pPort, "  </html>\r\n" );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Send the page trailer

+    //

+    Status = HttpFlush ( SocketFD, pPort );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Mark the page as complete

+    //

+    *pbDone = TRUE;

+    break;

+  }

+

+  //

+  //  Return the operation status

+  //

+  DBG_EXIT_STATUS ( Status );

+  return Status;

+}

+

+

+/**

+  Replace a space with a zero

+

+  @param [in] pData     The request buffer address

+  @param [in] pEnd      End of buffer address

+

+  @return     The next character location

+

+**/

+UINT8 *

+HttpReplaceSpace (

+  IN UINT8 * pData,

+  IN UINT8 * pEnd

+  )

+{

+  INTN Character;

+  UINT8 * pSpace;

+

+  pSpace = pData;

+  while ( pEnd > pData ) {

+    //

+    //  Get the character from the request

+    //

+    Character = HttpCharGet ( pData, &pData );

+    if ( ' ' == Character ) {

+      break;

+    }

+    pSpace = pData;

+  }

+

+  //

+  //  Replace the space character with zero

+  //

+  ZeroMem ( pSpace, pData - pSpace );

+

+  //

+  //  Return the next character location

+  //

+  return pData;

+}

+

+

+/**

+  Process an HTTP request

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+HttpRequest (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  )

+{

+  UINT8 * pData;

+  UINT8 * pEnd;

+  CONST DT_PAGE * pPage;

+  CONST DT_PAGE * pPageEnd;

+  UINT8 * pVerb;

+  UINT8 * pVersion;

+  UINT8 * pWebPage;

+  EFI_STATUS Status;

+

+  DBG_ENTER ( );

+

+  //

+  //  Assume the request is not finished

+  //

+  *pbDone = FALSE;

+  Status = EFI_SUCCESS;

+  for ( ; ; ) {

+

+    //

+    //  Attempt to parse the command

+    //

+    pData = &pPort->Request[0];

+    pEnd = &pData[ pPort->RequestLength ];

+    pVerb = pData;

+    pWebPage = HttpReplaceSpace ( pVerb, pEnd );

+    if ( pEnd <= pWebPage ) {

+      break;

+    }

+    pVersion = HttpReplaceSpace ( pWebPage, pEnd );

+    if ( pEnd <= pVersion ) {

+      break;

+    }

+

+    //

+    //  Validate the request

+    //

+    if ( 0 != HttpMatch ( L"GET", pVerb, TRUE )) {

+      //

+      //  Invalid request type

+      //

+      DEBUG (( DEBUG_REQUEST,

+                "HTTP: Invalid verb\r\n" ));

+      Status = EFI_NOT_FOUND;

+      break;

+    }

+

+    //

+    //  Walk the page table

+    //

+    pPage = &mPageList[0];

+    pPageEnd = &pPage[ mPageCount ];

+    while ( pPageEnd > pPage ) {

+      //

+      //  Determine if the page was located

+      //

+      if ( 0 == HttpMatch ( pPage->pPageName, pWebPage, FALSE )) {

+        break;

+      }

+

+      //

+      //  Set the next page

+      //

+      pPage += 1;

+    }

+    if ( pPageEnd <= pPage ) {

+      //

+      //  The page was not found

+      //

+      DEBUG (( DEBUG_REQUEST,

+                "HTTP: Page not found in page table\r\n" ));

+      Status = EFI_NOT_FOUND;

+      break;

+    }

+

+    //

+    //  Respond with the page contents

+    //

+    Status = pPage->pfnResponse ( SocketFD, pPort, pbDone );

+    break;

+  }

+

+  //

+  //  Return page not found if necessary

+  //

+  if ( EFI_NOT_FOUND == Status ) {

+    Status = HttpPageNotFound ( SocketFD, pPort, pbDone );

+  }

+

+  //

+  //  Return the operation status

+  //

+  DBG_EXIT_STATUS ( Status );

+  return Status;

+}

+

+

+/**

+  Buffer data for sending

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [in] LengthInBytes Length of valid data in the buffer

+  @param [in] pBuffer       Buffer of data to send

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+HttpSend (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN size_t LengthInBytes,

+  IN CONST UINT8 * pBuffer

+  )

+{

+  size_t DataBytes;

+  size_t MaxBytes;

+  EFI_STATUS Status;

+

+  //

+  //  Assume success

+  //

+  Status = EFI_SUCCESS;

+  do {

+    //

+    //  Determine how much data fits into the buffer

+    //

+    MaxBytes = sizeof ( pPort->TxBuffer );

+    DataBytes = MaxBytes - pPort->TxBytes;

+    if ( DataBytes > LengthInBytes ) {

+      DataBytes = LengthInBytes;

+    }

+

+    //

+    //  Copy the data into the buffer

+    //

+    CopyMem ( &pPort->TxBuffer[ pPort->TxBytes ],

+              pBuffer,

+              DataBytes );

+

+    //

+    //  Account for the data copied

+    //

+    pPort->TxBytes += DataBytes;

+    LengthInBytes -= DataBytes;

+

+    //

+    //  Transmit the buffer if it is full

+    //

+    if ( MaxBytes <= pPort->TxBytes ) {

+      Status = HttpFlush ( SocketFD, pPort );

+    }

+  } while (( EFI_SUCCESS == Status ) && ( 0 < LengthInBytes ));

+

+  //

+  //  Return the operation status

+  //

+  return Status;

+}

+

+

+/**

+  Send an ANSI string

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [in] pString       A zero terminated Unicode string

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+HttpSendAnsiString (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN CONST char * pString

+  )

+{

+  CONST char * pData;

+  EFI_STATUS Status;

+

+  //

+  //  Assume success

+  //

+  Status = EFI_SUCCESS;

+

+  //

+  //  Walk the characters in he string

+  //

+  pData = pString;

+  while ( 0 != *pData ) {

+    pData += 1;

+  }

+

+  //

+  //  Send the string

+  //

+  Status = HttpSend ( SocketFD,

+                      pPort,

+                      pData - pString,

+                      (CONST UINT8 *)pString );

+

+  //

+  //  Return the operation status

+  //

+  return Status;

+}

+

+

+/**

+  Buffer a single byte

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [in] Data          The data byte to send

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+HttpSendByte (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN UINT8 Data

+  )

+{

+  EFI_STATUS Status;

+

+  //

+  //  Send the data byte

+  //

+  Status = HttpSend ( SocketFD,

+                      pPort,

+                      1,

+                      &Data );

+

+  //

+  //  Return the operation status

+  //

+  return Status;

+}

+

+

+/**

+  Display a character

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [in] Character     Character to display

+  @param [in] pReplacement  Replacement character string

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+HttpSendCharacter (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN CHAR8 Character,

+  IN CHAR8 * pReplacement

+  )

+{

+  EFI_STATUS Status;

+

+  //

+  //  Determine if this is a printable character

+  //

+  if (( 0x20 <= Character ) && ( 0x7f > Character )) {

+    if ( '<' == Character ) {

+      //

+      //  Replace with HTML equivalent

+      //

+      Status = HttpSendAnsiString ( SocketFD,

+                                    pPort,

+                                    "&lt;" );

+    }

+    else if ( '>' == Character ) {

+      //

+      //  Replace with HTML equivalent

+      //

+      Status = HttpSendAnsiString ( SocketFD,

+                                    pPort,

+                                    "&gt;" );

+    }

+    else if ( '&' == Character ) {

+      //

+      //  Replace with HTML equivalent

+      //

+      Status = HttpSendAnsiString ( SocketFD,

+                                    pPort,

+                                    "&amp;" );

+    }

+    else if ( '\"' == Character ) {

+      //

+      //  Replace with HTML equivalent

+      //

+      Status = HttpSendAnsiString ( SocketFD,

+                                    pPort,

+                                    "&quot;" );

+    }

+    else {

+      //

+      //  Display the character

+      //

+      Status = HttpSendByte ( SocketFD,

+                              pPort,

+                              Character );

+    }

+  }

+  else {

+    //

+    //  Not a displayable character

+    //

+    Status = HttpSendAnsiString ( SocketFD,

+                                  pPort,

+                                  pReplacement );

+  }

+

+  //

+  //  Return the operation status

+  //

+  return Status;

+}

+

+

+/**

+  Send a buffer dump

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [in] ByteCount     The number of bytes to display

+  @param [in] pData         Address of the byte array

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+HttpSendDump (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN UINTN ByteCount,

+  IN CONST UINT8 * pData

+  )

+{

+  INTN BytesToDisplay;

+  UINT8 Character;

+  INTN Index;

+  INTN InitialSpaces;

+  CONST UINT8 * pDataEnd;

+  CONST UINT8 * pEnd;

+  CONST UINT8 * pTemp;

+  EFI_STATUS Status;

+

+  //

+  //  Use for/break instead of goto

+  //

+  for ( ; ; ) {

+    //

+    //  Start the field value

+    //

+    Status = HttpSendAnsiString ( SocketFD,

+                                  pPort,

+                                  "<code>" );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Walk the bytes to be displayed

+    //

+    pEnd = &pData[ ByteCount ];

+    while ( pEnd > pData ) {

+      //

+      //  Display the address

+      //

+      Status = HttpSendHexBits ( SocketFD,

+                                 pPort,

+                                 sizeof ( pData ) * 8,

+                                 (UINT64)(UINTN)pData );

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+

+      //

+      //  Separate the address and data

+      //

+      Status = HttpSendByte ( SocketFD, pPort, ':' );

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+

+      //

+      //  Position the starting data correctly

+      //

+      InitialSpaces = (UINTN)pData;

+      InitialSpaces &= BYTES_ON_A_LINE - 1;

+      for ( Index = SPACES_ADDRESS_TO_DATA

+                  + (( 2 + SPACES_BETWEEN_BYTES )

+                        * InitialSpaces );

+            0 < Index; Index-- ) {

+        Status = HttpSendAnsiString ( SocketFD,

+                                      pPort,

+                                      "&nbsp;" );

+        if ( EFI_ERROR ( Status )) {

+          break;

+        }

+      }

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+

+      //

+      //  Display the data

+      //

+      BytesToDisplay = pEnd - pData;

+      if (( BYTES_ON_A_LINE - InitialSpaces ) < BytesToDisplay ) {

+        BytesToDisplay = BYTES_ON_A_LINE - InitialSpaces;

+      }

+      pDataEnd = &pData[ BytesToDisplay ];

+      pTemp = pData;

+      while ( pDataEnd > pTemp ) {

+        Status = HttpSendHexBits ( SocketFD,

+                                   pPort,

+                                   8,

+                                   *pTemp++ );

+        if ( EFI_ERROR ( Status )) {

+          break;

+        }

+

+        //

+        //  Separate the data bytes

+        //

+        for ( Index = SPACES_BETWEEN_BYTES; 0 < Index; Index-- ) {

+          Status = HttpSendAnsiString ( SocketFD,

+                                        pPort,

+                                        "&nbsp;" );

+          if ( EFI_ERROR ( Status )) {

+            break;

+          }

+        }

+        if ( EFI_ERROR ( Status )) {

+          break;

+        }

+      }

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+

+      //

+      //  Separate the data from the ASCII display

+      //

+      for ( Index = (( 2 + SPACES_BETWEEN_BYTES )

+                       * ( BYTES_ON_A_LINE - BytesToDisplay - InitialSpaces ))

+                  - SPACES_BETWEEN_BYTES

+                  + SPACES_DATA_TO_ASCII

+                  + InitialSpaces;

+            0 < Index; Index-- ) {

+        Status = HttpSendAnsiString ( SocketFD,

+                                      pPort,

+                                      "&nbsp;" );

+        if ( EFI_ERROR ( Status )) {

+          break;

+        }

+      }

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+

+      //

+      //  Display the ASCII data

+      //

+      while ( pDataEnd > pData ) {

+        Character = *pData++;

+        Status = HttpSendCharacter ( SocketFD,

+                                     pPort,

+                                     Character,

+                                     "." );

+        if ( EFI_ERROR ( Status )) {

+          break;

+        }

+      }

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+

+      //

+      //  Terminate the line

+      //

+      Status = HttpSendAnsiString ( SocketFD,

+                                    pPort,

+                                    "<br/>\r\n" );

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+    }

+

+    //

+    //  Terminate the field value and row

+    //

+    Status = HttpSendAnsiString ( SocketFD,

+                                  pPort,

+                                  "</code>\r\n" );

+    break;

+  }

+

+  //

+  //  Return the operation status

+  //

+  return Status;

+}

+

+

+/**

+  Display a row containing a GUID value

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [in] pGuid         Address of the GUID to display

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+HttpSendGuid (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN CONST EFI_GUID * pGuid

+  )

+{

+  UINT32 Index;

+  EFI_STATUS Status;

+

+  DBG_ENTER ( );

+

+  //

+  //  Use for/break instead of goto

+  //

+  for ( ; ; ) {

+    //

+    //  Display the GUID in a form found in the code

+    //

+    //  E.g. 0xca16005f, 0x11ec, 0x4bdc, { 0x99, 0x97, 0x27, 0x2c, 0xa9, 0xba, 0x15, 0xe5 }

+    //

+

+    //

+    //  Display the first 32 bits

+    //

+    Status = HttpSendAnsiString ( SocketFD,

+                                  pPort,

+                                  "0x" );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = HttpSendHexBits ( SocketFD,

+                               pPort,

+                               32,

+                               pGuid->Data1 );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Display the second 16 bits

+    //

+    Status = HttpSendAnsiString ( SocketFD,

+                                  pPort,

+                                  ", 0x" );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = HttpSendHexBits ( SocketFD,

+                               pPort,

+                               16,

+                               pGuid->Data2 );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Display the thrid 16 bits

+    //

+    Status = HttpSendAnsiString ( SocketFD,

+                                  pPort,

+                                  ", 0x" );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = HttpSendHexBits ( SocketFD,

+                               pPort,

+                               16,

+                               pGuid->Data3 );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Place the last 64 bits in braces

+    //

+    Status = HttpSendAnsiString ( SocketFD,

+                                  pPort,

+                                  ", { 0x" );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    for ( Index = 0; 7 >= Index; Index++ ) {

+      //

+      //  Display the next 8 bits

+      //

+      Status = HttpSendHexBits ( SocketFD,

+                                 pPort,

+                                 8,

+                                 pGuid->Data4[ Index ]);

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+

+      //

+      //  Separate the bytes

+      //

+      Status = HttpSendAnsiString ( SocketFD,

+                                    pPort,

+                                    ( 7 != Index ) ? ", 0x" : " }" );

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+    }

+    break;

+  }

+

+  //

+  //  Return the operation status

+  //

+  DBG_EXIT_STATUS ( Status );

+  return Status;

+}

+

+

+/**

+  Output a hex value to the HTML page

+

+  @param [in] SocketFD    Socket file descriptor

+  @param [in] pPort       The WSDT_PORT structure address

+  @param [in] Bits        Number of bits to display

+  @param [in] Value       Value to display

+

+  @retval EFI_SUCCESS Successfully displayed the address

+**/

+EFI_STATUS

+HttpSendHexBits (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN INT32 Bits,

+  IN UINT64 Value

+  )

+{

+  UINT32 Digit;

+  INT32 Shift;

+  EFI_STATUS Status;

+

+  //

+  //  Assume success

+  //

+  Status = EFI_SUCCESS;

+

+  //

+  //  Walk the list of divisors

+  //

+  Shift = (( Bits + 3 ) & ( ~3 )) - 4;

+  while ( 0 <= Shift ) {

+    //

+    //  Determine the next digit

+    //

+    Digit = (UINT32)(( Value >> Shift ) & 0xf );

+    if ( 10 <= Digit ) {

+      Digit += 'a' - '0' - 10;

+    }

+

+    //

+    //  Display the digit

+    //

+    Status = HttpSendByte ( SocketFD, pPort, (UINT8)( '0' + Digit ));

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Set the next shift

+    //

+    Shift -= 4;

+  }

+

+  //

+  //  Return the operation status

+  //

+  return Status;

+}

+

+

+/**

+  Output a hex value to the HTML page

+

+  @param [in] SocketFD    Socket file descriptor

+  @param [in] pPort       The WSDT_PORT structure address

+  @param [in] Value       Value to display

+

+  @retval EFI_SUCCESS Successfully displayed the address

+**/

+EFI_STATUS

+HttpSendHexValue (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN UINT64 Value

+  )

+{

+  BOOLEAN bDisplayZeros;

+  UINT32 Digit;

+  INT32 Shift;

+  EFI_STATUS Status;

+

+  //

+  //  Assume success

+  //

+  Status = EFI_SUCCESS;

+

+  //

+  //  Walk the list of divisors

+  //

+  bDisplayZeros = FALSE;

+  Shift = 60;

+  do {

+    //

+    //  Determine the next digit

+    //

+    Digit = (UINT32)(( Value >> Shift ) & 0xf );

+    if ( 10 <= Digit ) {

+      Digit += 'a' - '0' - 10;

+    }

+

+    //

+    //  Suppress leading zeros

+    //

+    if (( 0 != Digit ) || bDisplayZeros || ( 0 == Shift )) {

+      bDisplayZeros = TRUE;

+

+      //

+      //  Display the digit

+      //

+      Status = HttpSendByte ( SocketFD, pPort, (UINT8)( '0' + Digit ));

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+    }

+

+    //

+    //  Set the next shift

+    //

+    Shift -= 4;

+  } while ( 0 <= Shift );

+

+  //

+  //  Return the operation status

+  //

+  return Status;

+}

+

+

+/**

+  Output an IP6 address value to the HTML page

+

+  @param [in] SocketFD          Socket file descriptor

+  @param [in] pPort             The WSDT_PORT structure address

+  @param [in] Value             Value to display

+  @param [in] bFirstValue       TRUE if first value

+  @param [in] bLastValue        TRUE if last value

+  @param [in] bZeroSuppression  TRUE while zeros are being suppressed

+  @param [in] pbZeroSuppression Address to receive TRUE when zero suppression

+                                has started, use NULL if next colon value not

+                                needed.

+

+  @retval EFI_SUCCESS Successfully displayed the address

+**/

+EFI_STATUS

+HttpSendIp6Value (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN UINT16 Value,

+  IN BOOLEAN bFirstValue,

+  IN BOOLEAN bLastValue,

+  IN BOOLEAN bZeroSuppression,

+  IN BOOLEAN * pbZeroSuppression

+  )

+{

+  BOOLEAN bZeroSuppressionStarting;

+  UINT32 Digit;

+  EFI_STATUS Status;

+

+  //

+  //  Use break instead of goto

+  //

+  bZeroSuppressionStarting = FALSE;

+  Status = EFI_SUCCESS;

+  for ( ; ; ) {

+    //

+    //  Display the leading colon if necessary

+    //

+    if ( bZeroSuppression && ( bLastValue || ( 0 != Value ))) {

+      Status = HttpSendByte ( SocketFD, pPort, ':' );

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+    }

+

+    //

+    //  Skip over a series of zero values

+    //

+    bZeroSuppressionStarting = (BOOLEAN)( 0 == Value );

+    if ( !bZeroSuppressionStarting ) {

+      //

+      //  Display the value

+      //

+      Digit = ( Value >> 4 ) & 0xf;

+      Status = HttpSendHexValue ( SocketFD,

+                                  pPort,

+                                  Digit );

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+      Digit = Value & 0xf;

+      Status = HttpSendHexValue ( SocketFD,

+                                  pPort,

+                                  Digit );

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+      Digit = ( Value >> 12 ) & 0xf;

+      Status = HttpSendHexValue ( SocketFD,

+                                  pPort,

+                                  Digit );

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+      Digit = ( Value >> 8 ) & 0xf;

+      Status = HttpSendHexValue ( SocketFD,

+                                  pPort,

+                                  Digit );

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+    }

+

+    //

+    //  Display the trailing colon if necessary

+    //

+    if (( !bLastValue ) && ( bFirstValue || ( 0 != Value ))) {

+      Status = HttpSendByte ( SocketFD, pPort, ':' );

+    }

+    break;

+  }

+

+  //

+  //  Return the next colon display

+  if ( NULL != pbZeroSuppression ) {

+    *pbZeroSuppression = bZeroSuppressionStarting;

+  }

+

+  //

+  //  Return the operation status

+  //

+  return Status;

+}

+

+

+/**

+  Output an IP address to the HTML page

+

+  @param [in] SocketFD    Socket file descriptor

+  @param [in] pPort       The WSDT_PORT structure address

+  @param [in] pAddress    Address of the socket address

+

+  @retval EFI_SUCCESS Successfully displayed the address

+**/

+EFI_STATUS

+HttpSendIpAddress (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN struct sockaddr_in6 * pAddress

+  )

+{

+  BOOLEAN bZeroSuppression;

+  UINT32 Index;

+  struct sockaddr_in * pIpv4;

+  struct sockaddr_in6 * pIpv6;

+  UINT16 PortNumber;

+  EFI_STATUS Status;

+

+  //

+  //  Use break instead of goto

+  //

+  for ( ; ; ) {

+    //

+    //  Determine the type of address

+    //

+    if ( AF_INET6 == pAddress->sin6_family ) {

+      pIpv6 = pAddress;

+

+      //

+      //  Display the address in RFC2732 format

+      //

+      bZeroSuppression = FALSE;

+      Status = HttpSendByte ( SocketFD, pPort, '[' );

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+      for ( Index = 0; 8 > Index; Index++ ) {

+        Status = HttpSendIp6Value ( SocketFD,

+                                    pPort,

+                                    pIpv6->sin6_addr.__u6_addr.__u6_addr16[ Index ],

+                                    (BOOLEAN)( 0 == Index ),

+                                    (BOOLEAN)( 7 == Index ),

+                                    bZeroSuppression,

+                                    &bZeroSuppression );

+        if ( EFI_ERROR ( Status )) {

+          break;

+        }

+      }

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+

+      //

+      //  Separate the port number

+      //

+      Status = HttpSendByte ( SocketFD, pPort, ']' );

+

+      //

+      //  Get the port number

+      //

+      PortNumber = pIpv6->sin6_port;

+    }

+    else {

+      //

+      //  Output the IPv4 address

+      //

+      pIpv4 = (struct sockaddr_in *)pAddress;

+      Status = HttpSendValue ( SocketFD, pPort, (UINT8)pIpv4->sin_addr.s_addr );

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+      Status = HttpSendByte ( SocketFD, pPort, '.' );

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+      Status = HttpSendValue ( SocketFD, pPort, (UINT8)( pIpv4->sin_addr.s_addr >> 8 ));

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+      Status = HttpSendByte ( SocketFD, pPort, '.' );

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+      Status = HttpSendValue ( SocketFD, pPort, (UINT8)( pIpv4->sin_addr.s_addr >> 16 ));

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+      Status = HttpSendByte ( SocketFD, pPort, '.' );

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+      Status = HttpSendValue ( SocketFD, pPort, (UINT8)( pIpv4->sin_addr.s_addr >> 24 ));

+

+      //

+      //  Get the port number

+      //

+      PortNumber = pIpv4->sin_port;

+    }

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+

+    //

+    //  Display the port number

+    //

+    Status = HttpSendByte ( SocketFD, pPort, ':' );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+    Status = HttpSendValue ( SocketFD, pPort, htons ( PortNumber ));

+    break;

+  }

+

+  //

+  //  Return the operation status

+  //

+  return Status;

+}

+

+

+/**

+  Send a Unicode string

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [in] pString       A zero terminated Unicode string

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+HttpSendUnicodeString (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN CONST UINT16 * pString

+  )

+{

+  UINT8 Data;

+  UINT16 Character;

+  EFI_STATUS Status;

+

+  //

+  //  Assume success

+  //

+  Status = EFI_SUCCESS;

+

+  //

+  //  Walk the characters in he string

+  //

+  while ( 0 != ( Character = *pString++ )) {

+    //

+    //  Convert the character to UTF-8

+    //

+    if ( 0 != ( Character & 0xf800 )) {

+      //

+      //  Send the upper 4 bits

+      //

+      Data = (UINT8)(( Character >> 12 ) & 0xf );

+      Data |= 0xe0;

+      Status = HttpSendByte ( SocketFD,

+                              pPort,

+                              Data );

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+

+      //

+      //  Send the next 6 bits

+      //

+      Data = (UINT8)(( Character >> 6 ) & 0x3f );

+      Data |= 0x80;

+      Status = HttpSendByte ( SocketFD,

+                              pPort,

+                              Data );

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+

+      //

+      //  Send the last 6 bits

+      //

+      Data = (UINT8)( Character & 0x3f );

+      Data |= 0x80;

+    }

+    else if ( 0 != ( Character & 0x0780 )) {

+      //

+      //  Send the upper 5 bits

+      //

+      Data = (UINT8)(( Character >> 6 ) & 0x1f );

+      Data |= 0xc0;

+      Status = HttpSendByte ( SocketFD,

+                              pPort,

+                              Data );

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+

+      //

+      //  Send the last 6 bits

+      //

+      Data = (UINT8)( Character & 0x3f );

+      Data |= 0x80;

+    }

+    else {

+      Data = (UINT8)( Character & 0x7f );

+    }

+

+    //

+    //  Send the last data byte

+    //

+    Status = HttpSendByte ( SocketFD,

+                            pPort,

+                            Data );

+    if ( EFI_ERROR ( Status )) {

+      break;

+    }

+  }

+

+  //

+  //  Return the operation status

+  //

+  return Status;

+}

+

+

+/**

+  Output a value to the HTML page

+

+  @param [in] SocketFD    Socket file descriptor

+  @param [in] pPort       The WSDT_PORT structure address

+  @param [in] Value       Value to display

+

+  @retval EFI_SUCCESS Successfully displayed the address

+**/

+EFI_STATUS

+HttpSendValue (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN UINT64 Value

+  )

+{

+  BOOLEAN bDisplayZeros;

+  UINT64 Digit;

+  CONST UINT64 * pEnd;

+  CONST UINT64 * pDivisor;

+  CONST UINT64 pDivisors[ ] = {

+     10000000000000000000ULL,

+      1000000000000000000ULL,

+       100000000000000000ULL,

+        10000000000000000ULL,

+         1000000000000000ULL,

+          100000000000000ULL,

+           10000000000000ULL,

+            1000000000000ULL,

+             100000000000ULL,

+              10000000000ULL,

+               1000000000ULL,

+                100000000ULL,

+                 10000000ULL,

+                  1000000ULL,

+                   100000ULL,

+                    10000ULL,

+                     1000ULL,

+                      100ULL,

+                       10ULL

+  };

+  EFI_STATUS Status;

+  UINT64 Temp;

+

+  //

+  //  Assume success

+  //

+  Status = EFI_SUCCESS;

+

+  //

+  //  Walk the list of divisors

+  //

+  bDisplayZeros = FALSE;

+  pDivisor = &pDivisors[0];

+  pEnd = &pDivisor[ sizeof ( pDivisors ) / sizeof ( pDivisors[0])];

+  while ( pEnd > pDivisor ) {

+    //

+    //  Determine the next digit

+    //

+    Digit = Value / *pDivisor;

+

+    //

+    //  Suppress leading zeros

+    //

+    if (( 0 != Digit ) || bDisplayZeros ) {

+      bDisplayZeros = TRUE;

+

+      //

+      //  Display the digit

+      //

+      Status = HttpSendByte ( SocketFD, pPort, (UINT8)( '0' + Digit ));

+      if ( EFI_ERROR ( Status )) {

+        break;

+      }

+

+      //

+      //  Determine the remainder

+      //

+      Temp = *pDivisor * Digit;

+      Value -= Temp;

+    }

+

+    //

+    //  Set the next divisor

+    //

+    pDivisor += 1;

+  }

+

+  //

+  //  Display the final digit

+  //

+  if ( !EFI_ERROR ( Status )) {

+    Status = HttpSendByte ( SocketFD, pPort, (UINT8)( '0' + Value ));

+  }

+

+  //

+  //  Return the operation status

+  //

+  return Status;

+}

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Handles.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Handles.c
new file mode 100644
index 0000000..19a55dd
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Handles.c
@@ -0,0 +1,284 @@
+/**
+  @file
+  Display the handles in the system
+
+  Copyright (c) 2011-2012, Intel Corporation
+  All rights reserved. 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.php
+
+  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 <WebServer.h>
+
+
+/**
+  Respond with the handles in the system
+
+  @param [in] SocketFD      The socket's file descriptor to add to the list.
+  @param [in] pPort         The WSDT_PORT structure address
+  @param [out] pbDone       Address to receive the request completion status
+
+  @retval EFI_SUCCESS       The request was successfully processed
+
+**/
+EFI_STATUS
+HandlePage (
+  IN int SocketFD,
+  IN WSDT_PORT * pPort,
+  OUT BOOLEAN * pbDone
+  )
+{
+  INTN Digit;
+  INTN Entries;
+  INTN Index;
+  UINTN GuidCount;
+  UINTN LengthInBytes;
+  UINT8 * pDigit;
+  EFI_HANDLE * pHandleArray;
+  EFI_HANDLE * pHandle;
+  EFI_HANDLE * pHandleEnd;
+  EFI_GUID ** ppGuidArray;
+  EFI_GUID ** ppGuid;
+  EFI_GUID ** ppGuidEnd;
+  INTN Shift;
+  EFI_STATUS Status;
+  UINTN Value;
+  CONST UINTN cDigit [] = {
+    3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11, 12, 13, 14, 15 };
+  
+  DBG_ENTER ( );
+  
+  //
+  //  Send the handles page
+  //
+  for ( ; ; ) {
+    //
+    //  Send the page header
+    //
+    Status = HttpPageHeader ( SocketFD, pPort, L"Handle Database" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Build the table header
+    //
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "<h1>Handle Database</h1>\r\n"
+                                  "<table border=\"1\">\r\n"
+                                  "  <tr bgcolor=\"c0c0ff\"><th>Handle</th><th>Protocol Guids</th></tr>\r\n" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Determine the number of handles in the database
+    //
+    LengthInBytes = 0;
+    Status = gBS->LocateHandle ( AllHandles,
+                                 NULL,
+                                 NULL,
+                                 &LengthInBytes,
+                                 NULL );
+    if ( EFI_BUFFER_TOO_SMALL == Status ) {
+      //
+      //  Allocate space for the handles
+      //
+      Status = gBS->AllocatePool ( EfiRuntimeServicesData,
+                                   LengthInBytes,
+                                   (VOID **) &pHandleArray );
+      if ( !EFI_ERROR ( Status )) {
+        //
+        //  Get the list of handles
+        //
+        Status = gBS->LocateHandle ( AllHandles,
+                                     NULL,
+                                     NULL,
+                                     &LengthInBytes,
+                                     pHandleArray );
+        if ( !EFI_ERROR ( Status )) {
+          Entries = LengthInBytes / sizeof ( *pHandleArray );
+          pHandle = pHandleArray;
+          pHandleEnd = &pHandle [ Entries ];
+          while ( pHandleEnd > pHandle ) {
+            //
+            //  Build the table entry for this page
+            //
+            Status = HttpSendAnsiString ( SocketFD,
+                                          pPort,
+                                          "<tr><td><code>0x" );
+            if ( EFI_ERROR ( Status )) {
+              break;
+            }
+            Value = (UINTN) *pHandle;
+            for ( Shift = ( sizeof ( Shift ) << 3 ) - 4; 0 <= Shift; Shift -= 4 ) {
+              //
+              //  Convert the next address nibble to ANSI hex
+              //
+              Digit = (( Value >> Shift ) & 0xf ) | '0';
+              if ( '9' < Digit ) {
+                Digit += 'a' - '0' - 10;
+              }
+
+              //
+              //  Display the address digit
+              //
+              Status = HttpSendByte ( SocketFD,
+                                      pPort,
+                                      (UINT8) Digit );
+              if ( EFI_ERROR ( Status )) {
+                break;
+              }
+            }
+            if ( EFI_ERROR ( Status )) {
+              break;
+            }
+
+            //
+            //  Start the second column
+            //
+            Status = HttpSendAnsiString ( SocketFD,
+                                          pPort,
+                                          "</code></td><td><code>\r\n" );
+            if ( EFI_ERROR ( Status )) {
+              break;
+            }
+
+            //
+            //  Determine the number of protocols connected to this handle
+            //
+            Status = gBS->ProtocolsPerHandle ( *pHandle,
+                                               &ppGuidArray,
+                                               &GuidCount );
+            if ( EFI_ERROR ( Status )) {
+              break;
+            }
+            ppGuid = ppGuidArray;
+            ppGuidEnd = &ppGuid [ GuidCount ];
+            while ( ppGuidEnd > ppGuid ) {
+              //
+              //  Display the guid
+              //
+              pDigit = (UINT8 *) *ppGuid;
+              for ( Index = 0; 16 > Index; Index++ ) {
+                //
+                //  Separate the portions of the GUID
+                //  99E87DCF-6162-40c5-9FA1-32111F5197F7
+                //
+                if (( 4 == Index )
+                  || ( 6 == Index )
+                  || ( 8 == Index )
+                  || ( 10 == Index )) {
+                  Status = HttpSendByte ( SocketFD,
+                                          pPort,
+                                          '-' );
+                  if ( EFI_ERROR ( Status )) {
+                    break;
+                  }
+                }
+
+                //
+                //  Display the GUID digits
+                //
+                Value = pDigit [ cDigit [ Index ]];
+                for ( Shift = 4; 0 <= Shift; Shift -= 4 ) {
+                  //
+                  //  Convert the next address nibble to ANSI hex
+                  //
+                  Digit = (( Value >> Shift ) & 0xf ) | '0';
+                  if ( '9' < Digit ) {
+                    Digit += 'a' - '0' - 10;
+                  }
+                
+                  //
+                  //  Display the address digit
+                  //
+                  Status = HttpSendByte ( SocketFD,
+                                          pPort,
+                                          (UINT8) Digit );
+                  if ( EFI_ERROR ( Status )) {
+                    break;
+                  }
+                }
+                if ( EFI_ERROR ( Status )) {
+                  break;
+                }
+              }
+
+              //
+              //  Separate each GUID
+              //
+              Status = HttpSendAnsiString ( SocketFD,
+                                            pPort,
+                                            "<br/>\r\n" );
+              if ( EFI_ERROR ( Status )) {
+                break;
+              }
+
+              //
+              //  Set the next protocol
+              //
+              ppGuid+= 1;
+            }
+
+            //
+            //  Free the GUID array
+            //
+            gBS->FreePool ( ppGuidArray );
+            if ( EFI_ERROR ( Status )) {
+              break;
+            }
+
+            //
+            //  End the row
+            //
+            Status = HttpSendAnsiString ( SocketFD,
+                                          pPort,
+                                          "</code></td></tr>\r\n" );
+            if ( EFI_ERROR ( Status )) {
+              break;
+            }
+
+            //
+            //  Set the next handle
+            //
+            pHandle += 1;
+          }
+        }
+
+        //
+        //  Done with the handle array
+        //
+        gBS->FreePool ( pHandleArray );
+      }
+    }
+    
+    //
+    //  Build the table trailer
+    //
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "</table>\r\n" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Send the page trailer
+    //
+    Status = HttpPageTrailer ( SocketFD, pPort, pbDone );
+    break;
+  }
+    
+  //
+  //  Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Hello.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Hello.c
new file mode 100644
index 0000000..3d1f979
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Hello.c
@@ -0,0 +1,77 @@
+/**
+  @file
+  Hello World response page
+
+  Copyright (c) 2011-2012, Intel Corporation
+  All rights reserved. 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.php
+
+  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 <WebServer.h>
+
+
+/**
+  Respond with the Hello World page
+
+  @param [in] SocketFD      The socket's file descriptor to add to the list.
+  @param [in] pPort         The WSDT_PORT structure address
+  @param [out] pbDone       Address to receive the request completion status
+
+  @retval EFI_SUCCESS       The request was successfully processed
+
+**/
+EFI_STATUS
+HelloPage (
+  IN int SocketFD,
+  IN WSDT_PORT * pPort,
+  OUT BOOLEAN * pbDone
+  )
+{
+  EFI_STATUS Status;
+  
+  DBG_ENTER ( );
+  
+  //
+  //  Send the Hello World page
+  //
+  for ( ; ; ) {
+    //
+    //  Send the page header
+    //
+    Status = HttpPageHeader ( SocketFD, pPort, L"Hello World" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+  
+    //
+    //  Send the page body
+    //
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "<h1>Hello World</h1>\r\n"
+                                  "<p>\r\n"
+                                  "  This response was generated by the UEFI web server application.\r\n"
+                                  "</p>\r\n" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+  
+    //
+    //  Send the page trailer
+    //
+    Status = HttpPageTrailer ( SocketFD, pPort, pbDone );
+    break;
+  }
+    
+  //
+  //  Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Index.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Index.c
new file mode 100644
index 0000000..64c1ffc
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Index.c
@@ -0,0 +1,151 @@
+/**
+  @file
+  Generate the list of known pages.
+
+  Copyright (c) 2011-2012, Intel Corporation
+  All rights reserved. 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.php
+
+  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 <WebServer.h>
+
+
+/**
+  Respond with the list of known pages
+
+  @param [in] SocketFD      The socket's file descriptor to add to the list.
+  @param [in] pPort         The WSDT_PORT structure address
+  @param [out] pbDone       Address to receive the request completion status
+
+  @retval EFI_SUCCESS       The request was successfully processed
+
+**/
+EFI_STATUS
+IndexPage (
+  IN int SocketFD,
+  IN WSDT_PORT * pPort,
+  OUT BOOLEAN * pbDone
+  )
+{
+  CONST DT_PAGE * pPage;
+  CONST DT_PAGE * pPageEnd;
+  EFI_STATUS Status;
+  
+  DBG_ENTER ( );
+  
+  //
+  //  Send the index page
+  //
+  for ( ; ; ) {
+    //
+    //  Send the page header
+    //
+    Status = HttpPageHeader ( SocketFD, pPort, L"Index" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Build the table header
+    //
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "<h1>UEFI Web Server</h1>\r\n"
+                                  "<table border=\"1\">\r\n"
+                                  "  <tr bgcolor=\"c0c0ff\"><th>Page</th><th>Description</th></tr>\r\n" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Walk the list of pages
+    //  Skip the first page
+    //
+    pPage = &mPageList[0];
+    pPageEnd = &pPage[mPageCount];
+    pPage += 1;
+    while ( pPageEnd > pPage ) {
+      //
+      //  Build the table entry for this page
+      //
+      Status = HttpSendAnsiString ( SocketFD,
+                                    pPort,
+                                    "<tr><td><a target=\"_blank\" href=\"" );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+      Status = HttpSendUnicodeString ( SocketFD,
+                                       pPort,
+                                       &pPage->pPageName[1]);
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+      Status = HttpSendAnsiString ( SocketFD,
+                                    pPort,
+                                    "\">" );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+      Status = HttpSendUnicodeString ( SocketFD,
+                                       pPort,
+                                       &pPage->pPageName[1]);
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+      Status = HttpSendAnsiString ( SocketFD,
+                                    pPort,
+                                    "</a></td><td>" );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+      Status = HttpSendUnicodeString ( SocketFD,
+                                       pPort,
+                                       pPage->pDescription );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+      Status = HttpSendAnsiString ( SocketFD,
+                                    pPort,
+                                    "</td></tr>\r\n" );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+
+      //
+      //  Set the next page
+      //
+      pPage += 1;
+    }
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+  
+    //
+    //  Build the table trailer
+    //
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "</table>\r\n" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Send the page trailer
+    //
+    Status = HttpPageTrailer ( SocketFD, pPort, pbDone );
+    break;
+  }
+    
+  //
+  //  Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/MemoryMap.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/MemoryMap.c
new file mode 100644
index 0000000..71a5b1d
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/MemoryMap.c
@@ -0,0 +1,364 @@
+/**
+  @file
+  Display the memory map
+
+  Copyright (c) 2012, Intel Corporation
+  All rights reserved. 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.php
+
+  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 <WebServer.h>
+#include <PiDxe.h>
+#include <Library/DxeServicesTableLib.h>
+
+
+CONST char * mpMemoryType[ ] = {
+  "Non-existent",
+  "Reserved",
+  "System Memory",
+  "Memory Mapped I/O"
+};
+
+
+/**
+  Page to display the memory map
+
+  @param [in] SocketFD      The socket's file descriptor to add to the list.
+  @param [in] pPort         The WSDT_PORT structure address
+  @param [out] pbDone       Address to receive the request completion status
+
+  @retval EFI_SUCCESS       The request was successfully processed
+
+**/
+EFI_STATUS
+MemoryMapPage (
+  IN int SocketFD,
+  IN WSDT_PORT * pPort,
+  OUT BOOLEAN * pbDone
+  )
+{
+  UINT64 Attributes;
+  BOOLEAN bSomethingDisplayed;
+  UINTN Count;
+  EFI_GCD_MEMORY_SPACE_DESCRIPTOR * pMemoryEnd;
+  EFI_GCD_MEMORY_SPACE_DESCRIPTOR * pMemoryDescriptor;
+  EFI_GCD_MEMORY_SPACE_DESCRIPTOR * pMemoryDescriptorStart;
+  EFI_STATUS Status;
+  
+  DBG_ENTER ( );
+  
+  //
+  //  Send the memory map page
+  //
+  pMemoryDescriptorStart = NULL;
+  for ( ; ; ) {
+    //
+    //  Send the page header
+    //
+    Status = HttpPageHeader ( SocketFD, pPort, L"Memory Map" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+  
+    //
+    //  Start the table
+    //
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "<h1>Memory Map</h1>\r\n"
+                                  "<table>\r\n"
+                                  "  <tr><th align=\"right\">Type</th><th align=\"right\">Start</th><th align=\"right\">End</th><th align=\"right\">Attributes</th></tr>\r\n" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Get the memory map
+    //
+    Status = gDS->GetMemorySpaceMap ( &Count,
+                                      &pMemoryDescriptor );
+    if ( !EFI_ERROR ( Status )) {
+      pMemoryDescriptorStart = pMemoryDescriptor;
+      pMemoryEnd = &pMemoryDescriptor[ Count ];
+      while ( pMemoryEnd > pMemoryDescriptor ) {
+        //
+        //  Display the type
+        //
+        Status = HttpSendAnsiString ( SocketFD, pPort, "<tr><td align=\"right\"><code>" );
+        if ( EFI_ERROR ( Status )) {
+          break;
+        }
+        if ( DIM ( mpMemoryType ) > pMemoryDescriptor->GcdMemoryType ) {
+          Status = HttpSendAnsiString ( SocketFD,
+                                        pPort,
+                                        mpMemoryType[ pMemoryDescriptor->GcdMemoryType ]);
+        }
+        else {
+          Status = HttpSendValue ( SocketFD,
+                                   pPort,
+                                   pMemoryDescriptor->GcdMemoryType );
+        }
+        if ( EFI_ERROR ( Status )) {
+          break;
+        }
+
+        //
+        //  Display the start address
+        //
+        Status = HttpSendAnsiString ( SocketFD, pPort, "</code></td><td align=\"right\"><code>0x" );
+        if ( EFI_ERROR ( Status )) {
+          break;
+        }
+        Status = HttpSendHexValue ( SocketFD,
+                                    pPort,
+                                    pMemoryDescriptor->BaseAddress );
+        if ( EFI_ERROR ( Status )) {
+          break;
+        }
+
+        //
+        //  Display the end address
+        //
+        Status = HttpSendAnsiString ( SocketFD, pPort, "</code></td><td align=\"right\"><code>0x" );
+        if ( EFI_ERROR ( Status )) {
+          break;
+        }
+        Status = HttpSendHexValue ( SocketFD,
+                                    pPort,
+                                    pMemoryDescriptor->BaseAddress
+                                    + pMemoryDescriptor->Length
+                                    - 1 );
+        if ( EFI_ERROR ( Status )) {
+          break;
+        }
+
+        //
+        //  Display the attributes
+        //
+        Status = HttpSendAnsiString ( SocketFD, pPort, "</code></td><td align=\"right\"><code>0x" );
+        if ( EFI_ERROR ( Status )) {
+          break;
+        }
+        Status = HttpSendHexValue ( SocketFD,
+                                    pPort,
+                                    pMemoryDescriptor->Attributes );
+        if ( EFI_ERROR ( Status )) {
+          break;
+        }
+
+        //
+        //  Decode the attributes
+        //
+        Status = HttpSendAnsiString ( SocketFD, pPort, "</code></td><td>" );
+        if ( EFI_ERROR ( Status )) {
+          break;
+        }
+        bSomethingDisplayed = FALSE;
+        Attributes = pMemoryDescriptor->Attributes;
+
+        if ( 0 != ( Attributes & EFI_MEMORY_RUNTIME )) {
+          bSomethingDisplayed = TRUE;
+          Status = HttpSendAnsiString ( SocketFD,
+                                        pPort,
+                                        "Runtime" );
+          if ( EFI_ERROR ( Status )) {
+            break;
+          }
+        }
+
+        if ( 0 != ( Attributes & EFI_MEMORY_XP )) {
+          if ( bSomethingDisplayed ) {
+            Status = HttpSendAnsiString ( SocketFD,
+                                          pPort,
+                                          ", " );
+            if ( EFI_ERROR ( Status )) {
+              break;
+            }
+          }
+          bSomethingDisplayed = TRUE;
+          Status = HttpSendAnsiString ( SocketFD,
+                                        pPort,
+                                        "No Execute" );
+          if ( EFI_ERROR ( Status )) {
+            break;
+          }
+        }
+
+        if ( 0 != ( Attributes & EFI_MEMORY_RP )) {
+          if ( bSomethingDisplayed ) {
+            Status = HttpSendAnsiString ( SocketFD,
+                                          pPort,
+                                          ", " );
+            if ( EFI_ERROR ( Status )) {
+              break;
+            }
+          }
+          bSomethingDisplayed = TRUE;
+          Status = HttpSendAnsiString ( SocketFD,
+                                        pPort,
+                                        "No Read" );
+          if ( EFI_ERROR ( Status )) {
+            break;
+          }
+        }
+
+        if ( 0 != ( Attributes & EFI_MEMORY_WP )) {
+          if ( bSomethingDisplayed ) {
+            Status = HttpSendAnsiString ( SocketFD,
+                                          pPort,
+                                          ", " );
+            if ( EFI_ERROR ( Status )) {
+              break;
+            }
+          }
+          bSomethingDisplayed = TRUE;
+          Status = HttpSendAnsiString ( SocketFD,
+                                        pPort,
+                                        "No Write" );
+          if ( EFI_ERROR ( Status )) {
+            break;
+          }
+        }
+
+        if ( 0 != ( Attributes & EFI_MEMORY_UCE )) {
+          if ( bSomethingDisplayed ) {
+            Status = HttpSendAnsiString ( SocketFD,
+                                          pPort,
+                                          ", " );
+            if ( EFI_ERROR ( Status )) {
+              break;
+            }
+          }
+          bSomethingDisplayed = TRUE;
+          Status = HttpSendAnsiString ( SocketFD,
+                                        pPort,
+                                        "UCE" );
+          if ( EFI_ERROR ( Status )) {
+            break;
+          }
+        }
+
+
+        if ( 0 != ( Attributes & EFI_MEMORY_WB )) {
+          if ( bSomethingDisplayed ) {
+            Status = HttpSendAnsiString ( SocketFD,
+                                          pPort,
+                                          ", " );
+            if ( EFI_ERROR ( Status )) {
+              break;
+            }
+          }
+          bSomethingDisplayed = TRUE;
+          Status = HttpSendAnsiString ( SocketFD,
+                                        pPort,
+                                        "Write Back" );
+          if ( EFI_ERROR ( Status )) {
+            break;
+          }
+        }
+
+        if ( 0 != ( Attributes & EFI_MEMORY_WT )) {
+          if ( bSomethingDisplayed ) {
+            Status = HttpSendAnsiString ( SocketFD,
+                                          pPort,
+                                          ", " );
+            if ( EFI_ERROR ( Status )) {
+              break;
+            }
+          }
+          bSomethingDisplayed = TRUE;
+          Status = HttpSendAnsiString ( SocketFD,
+                                        pPort,
+                                        "Write Through" );
+          if ( EFI_ERROR ( Status )) {
+            break;
+          }
+        }
+
+        if ( 0 != ( Attributes & EFI_MEMORY_WC )) {
+          if ( bSomethingDisplayed ) {
+            Status = HttpSendAnsiString ( SocketFD,
+                                          pPort,
+                                          ", " );
+            if ( EFI_ERROR ( Status )) {
+              break;
+            }
+          }
+          bSomethingDisplayed = TRUE;
+          Status = HttpSendAnsiString ( SocketFD,
+                                        pPort,
+                                        "Write Combining" );
+          if ( EFI_ERROR ( Status )) {
+            break;
+          }
+        }
+
+        if ( 0 != ( Attributes & EFI_MEMORY_UC )) {
+          if ( bSomethingDisplayed ) {
+            Status = HttpSendAnsiString ( SocketFD,
+                                          pPort,
+                                          ", " );
+            if ( EFI_ERROR ( Status )) {
+              break;
+            }
+          }
+          bSomethingDisplayed = TRUE;
+          Status = HttpSendAnsiString ( SocketFD,
+                                        pPort,
+                                        "Uncached" );
+          if ( EFI_ERROR ( Status )) {
+            break;
+          }
+        }
+
+        //
+        //  Finish the row
+        //
+        Status = HttpSendAnsiString ( SocketFD, pPort, "</td></tr>" );
+        if ( EFI_ERROR ( Status )) {
+          break;
+        }
+
+        //
+        //  Set the next memory descriptor
+        //
+        pMemoryDescriptor += 1;
+      }
+    }
+
+    //
+    //  Finish the table
+    //
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "</table>\r\n" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Send the page trailer
+    //
+    Status = HttpPageTrailer ( SocketFD, pPort, pbDone );
+    break;
+  }
+
+  //
+  //  Release the memory descriptors
+  //
+  if ( NULL != pMemoryDescriptorStart ) {
+    FreePool ( pMemoryDescriptorStart );
+  }
+
+  //
+  //  Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Mtrr.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Mtrr.c
new file mode 100644
index 0000000..92f90b0
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Mtrr.c
@@ -0,0 +1,825 @@
+/**
+  @file
+  Display the memory type range registers
+
+  Copyright (c) 2012, Intel Corporation
+  All rights reserved. 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.php
+
+  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 <WebServer.h>
+#include <Library/MtrrLib.h>
+
+#define VARIABLE_MTRR_VALID     0x800
+
+CONST char * mMemoryType [ ] = {
+  "Uncached",
+  "Write Combining",
+  "Reserved",
+  "Reserved",
+  "Write Through",
+  "Write Protected",
+  "Writeback"
+};
+
+
+/**
+  Display a fixed MTRR row
+
+  @param [in] SocketFD      The socket's file descriptor to add to the list.
+  @param [in] pPort         The WSDT_PORT structure address
+  @param [in] Start         Start address for the region
+  @param [in] End           End address for the region
+  @param [in] Type          Memory type
+
+  @retval EFI_SUCCESS       The request was successfully processed
+
+**/
+EFI_STATUS
+MtrrDisplayFixedRow (
+  IN int SocketFD,
+  IN WSDT_PORT * pPort,
+  IN UINT64 Start,
+  IN UINT64 End,
+  IN UINT64 Type
+  )
+{
+  EFI_STATUS Status;
+
+  //
+  //  Use break instead of goto
+  //
+  for ( ; ; ) {
+    //
+    //  Start the row
+    //
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "  <tr><td align=\"right\"><code>0x" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    
+    //
+    //  Start
+    //
+    Status = HttpSendHexValue ( SocketFD,
+                                pPort,
+                                Start );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    
+    //
+    //  End
+    //
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "</code></td><td align=\"right\"><code>0x" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = HttpSendHexValue ( SocketFD,
+                                pPort,
+                                End - 1 );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    
+    //
+    //  Type
+    //
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "</code></td><td>" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Type &= 0xff;
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  ( DIM ( mMemoryType ) > Type )
+                                  ? mMemoryType [ Type ]
+                                  : "Reserved" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    
+    //
+    //  End of row
+    //
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "</td></tr>\r\n" );
+    break;
+  }
+
+  //
+  //  Return the final status
+  //
+  return Status;
+}
+
+
+/**
+  Display the memory type registers
+
+  @param [in] SocketFD      The socket's file descriptor to add to the list.
+  @param [in] pPort         The WSDT_PORT structure address
+  @param [out] pbDone       Address to receive the request completion status
+
+  @retval EFI_SUCCESS       The request was successfully processed
+
+**/
+EFI_STATUS
+MemoryTypeRegistersPage (
+  IN int SocketFD,
+  IN WSDT_PORT * pPort,
+  OUT BOOLEAN * pbDone
+  )
+{
+  UINT64 Addr;
+  BOOLEAN bValid;
+  UINT64 Capabilities;
+  UINTN Count;
+  UINT64 DefType;
+  UINTN Index;
+  UINT64 Mask;
+  UINT64 MaxMtrrs;
+  CONST UINT64 mFixedAddresses [( 8 * MTRR_NUMBER_OF_FIXED_MTRR ) + 1 ] = {
+           0ULL,
+     0x10000ULL,
+     0x20000ULL,
+     0x30000ULL,
+     0x40000ULL,
+     0x50000ULL,
+     0x60000ULL,
+     0x70000ULL,
+
+     0x80000ULL,
+     0x84000ULL,
+     0x88000ULL,
+     0x8c000ULL,
+     0x90000ULL,
+     0x94000ULL,
+     0x98000ULL,
+     0x9c000ULL,
+
+     0xa0000ULL,
+     0xa4000ULL,
+     0xa8000ULL,
+     0xac000ULL,
+     0xb0000ULL,
+     0xb4000ULL,
+     0xb8000ULL,
+     0xbc000ULL,
+
+     0xc0000ULL,
+     0xc1000ULL,
+     0xc2000ULL,
+     0xc3000ULL,
+     0xc4000ULL,
+     0xc5000ULL,
+     0xc6000ULL,
+     0xc7000ULL,
+
+     0xc8000ULL,
+     0xc9000ULL,
+     0xca000ULL,
+     0xcb000ULL,
+     0xcc000ULL,
+     0xcd000ULL,
+     0xce000ULL,
+     0xcf000ULL,
+
+     0xd0000ULL,
+     0xd1000ULL,
+     0xd2000ULL,
+     0xd3000ULL,
+     0xd4000ULL,
+     0xd5000ULL,
+     0xd6000ULL,
+     0xd7000ULL,
+
+     0xd8000ULL,
+     0xd9000ULL,
+     0xda000ULL,
+     0xdb000ULL,
+     0xdc000ULL,
+     0xdd000ULL,
+     0xde000ULL,
+     0xdf000ULL,
+
+     0xe0000ULL,
+     0xe1000ULL,
+     0xe2000ULL,
+     0xe3000ULL,
+     0xe4000ULL,
+     0xe5000ULL,
+     0xe6000ULL,
+     0xe7000ULL,
+
+     0xe8000ULL,
+     0xe9000ULL,
+     0xea000ULL,
+     0xeb000ULL,
+     0xec000ULL,
+     0xed000ULL,
+     0xee000ULL,
+     0xef000ULL,
+
+     0xf0000ULL,
+     0xf1000ULL,
+     0xf2000ULL,
+     0xf3000ULL,
+     0xf4000ULL,
+     0xf5000ULL,
+     0xf6000ULL,
+     0xf7000ULL,
+
+     0xf8000ULL,
+     0xf9000ULL,
+     0xfa000ULL,
+     0xfb000ULL,
+     0xfc000ULL,
+     0xfd000ULL,
+     0xfe000ULL,
+     0xff000ULL,
+
+    0x100000ULL
+  };
+  MTRR_SETTINGS Mtrr;
+  CONST UINT64 * pMemEnd;
+  CONST UINT64 * pMemStart;
+  UINT64 PreviousType;
+  UINT64 ShiftCount;
+  EFI_STATUS Status;
+  UINT64 Type;
+  INT64 Value;
+  
+  DBG_ENTER ( );
+  
+  //
+  //  Send the Memory Type Registers page
+  //
+  for ( ; ; ) {
+    //
+    //  Send the page header
+    //
+    Status = HttpPageHeader ( SocketFD, pPort, L"Memory Type Range Registers" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Send the header
+    //
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "<h1>Memory Type Range Registers</h1>\r\n" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Determine if MTRRs are supported
+    //
+    if ( !IsMtrrSupported ( )) {
+      Status = HttpSendAnsiString ( SocketFD,
+                                    pPort,
+                                    "<p>Memory Type Range Registers are not supported!\r\n" );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+    }
+    else {
+      //
+      //  Get the capabilities
+      //
+      Capabilities = AsmReadMsr64 ( MTRR_LIB_IA32_MTRR_CAP );
+      DefType =  AsmReadMsr64 ( MTRR_LIB_IA32_MTRR_DEF_TYPE );
+
+      //
+      //  Display the capabilities
+      //
+      Status = HttpSendAnsiString ( SocketFD,
+                                    pPort,
+                                    "<p>Capabilities: " );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+      Status = HttpSendHexValue ( SocketFD,
+                                  pPort,
+                                  Capabilities );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+      Status = HttpSendAnsiString ( SocketFD,
+                                    pPort,
+                                    "<br>\r\n" );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+
+      //
+      //  Display the default type
+      //
+      Status = HttpSendAnsiString ( SocketFD,
+                                    pPort,
+                                    "Def Type: " );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+      Status = HttpSendHexValue ( SocketFD,
+                                  pPort,
+                                  DefType );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+      Status = HttpSendAnsiString ( SocketFD,
+                                    pPort,
+                                    ", MTRRs " );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+      Status = HttpSendAnsiString ( SocketFD,
+                                    pPort,
+                                    ( 0 != ( DefType & MTRR_LIB_CACHE_MTRR_ENABLED ))
+                                    ? "Enabled"
+                                    : "Disabled" );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+      Status = HttpSendAnsiString ( SocketFD,
+                                    pPort,
+                                    ", Fixed MTRRs " );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+      Status = HttpSendAnsiString ( SocketFD,
+                                    pPort,
+                                    ( 0 != ( DefType & MTRR_LIB_CACHE_FIXED_MTRR_ENABLED ))
+                                    ? "Enabled"
+                                    : "Disabled" );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+      Status = HttpSendAnsiString ( SocketFD,
+                                    pPort,
+                                    ", " );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+      Type = DefType & 0xff;
+      Status = HttpSendAnsiString ( SocketFD,
+                                    pPort,
+                                    ( DIM ( mMemoryType ) > Type )
+                                    ? mMemoryType [ Type ]
+                                    : "Reserved" );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+      Status = HttpSendAnsiString ( SocketFD,
+                                    pPort,
+                                    "</p>\r\n" );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+
+      //
+      //  Determine if MTRRs are enabled
+      //
+      if ( 0 == ( DefType & MTRR_LIB_CACHE_MTRR_ENABLED )) {
+        Status = HttpSendAnsiString ( SocketFD,
+                                      pPort,
+                                      "<p>All memory is uncached!</p>\r\n" );
+        if ( EFI_ERROR ( Status )) {
+          break;
+        }
+      }
+      else {
+        //
+        //  Get the MTRRs
+        //
+        MtrrGetAllMtrrs ( &Mtrr );
+
+        //
+        //  Determine if the fixed MTRRs are supported
+        //
+        if (( 0 != ( Capabilities & 0x100 ))
+          && ( 0 != ( DefType & MTRR_LIB_CACHE_FIXED_MTRR_ENABLED ))) {
+
+          //
+          //  Beginning of table
+          //
+          Status = HttpSendAnsiString ( SocketFD,
+                                        pPort,
+                                        "<h2>Fixed MTRRs</h2>\r\n"
+                                        "<table>\r\n"
+                                        "  <tr><th>Index</th><th align=\"right\">Value</th><th align=\"right\">Start</th><th align=\"right\">End</th></tr>\r\n" );
+          if ( EFI_ERROR ( Status )) {
+            break;
+          }
+
+          //
+          //  Display the fixed MTRRs
+          //
+          pMemStart = &mFixedAddresses[ 0 ];
+          for ( Count = 0; DIM ( Mtrr.Fixed.Mtrr ) > Count; Count++ ) {
+            //
+            //  Start the row
+            //
+            Status = HttpSendAnsiString ( SocketFD,
+                                          pPort,
+                                          "  <tr><td>" );
+            if ( EFI_ERROR ( Status )) {
+              break;
+            }
+            
+            //
+            //  Index
+            //
+            Status = HttpSendValue ( SocketFD,
+                                     pPort,
+                                     Count );
+            if ( EFI_ERROR ( Status )) {
+              break;
+            }
+            
+            //
+            //  Value
+            //
+            Status = HttpSendAnsiString ( SocketFD,
+                                          pPort,
+                                          "</td><td align=\"right\"><code>0x" );
+            if ( EFI_ERROR ( Status )) {
+              break;
+            }
+            Status = HttpSendHexValue ( SocketFD,
+                                        pPort,
+                                        Mtrr.Fixed.Mtrr[ Count ]);
+            if ( EFI_ERROR ( Status )) {
+              break;
+            }
+
+            //
+            //  Start
+            //
+            Status = HttpSendAnsiString ( SocketFD,
+                                          pPort,
+                                          "</code></td><td align=\"right\"><code>0x" );
+            if ( EFI_ERROR ( Status )) {
+              break;
+            }
+            Status = HttpSendHexValue ( SocketFD,
+                                        pPort,
+                                        *pMemStart );
+            if ( EFI_ERROR ( Status )) {
+              break;
+            }
+            pMemStart += 8;
+
+            //
+            //  Value
+            //
+            Status = HttpSendAnsiString ( SocketFD,
+                                          pPort,
+                                          "</code></td><td align=\"right\"><code>0x" );
+            if ( EFI_ERROR ( Status )) {
+              break;
+            }
+            Status = HttpSendHexValue ( SocketFD,
+                                        pPort,
+                                        *pMemStart - 1 );
+            if ( EFI_ERROR ( Status )) {
+              break;
+            }
+
+            //
+            //  End of row
+            //
+            Status = HttpSendAnsiString ( SocketFD,
+                                          pPort,
+                                          "</code></td></tr>\r\n" );
+            if ( EFI_ERROR ( Status )) {
+              break;
+            }
+          }
+          if ( EFI_ERROR ( Status )) {
+            break;
+          }
+
+          //
+          //  End of table
+          //
+          Status = HttpSendAnsiString ( SocketFD,
+                                        pPort,
+                                        "</table>\r\n" );
+          if ( EFI_ERROR ( Status )) {
+            break;
+          }
+
+          //
+          //  Beginning of table
+          //
+          Status = HttpSendAnsiString ( SocketFD,
+                                        pPort,
+                                        "<table>\r\n"
+                                        "  <tr><th align=\"right\">Start</th><th align=\"right\">End</th><th align=\"left\">Type</th></tr>\r\n" );
+          if ( EFI_ERROR ( Status )) {
+            break;
+          }
+
+          //
+          //  Decode the fixed MTRRs
+          //
+          PreviousType = Mtrr.Fixed.Mtrr[ 0 ] & 0xff;
+          pMemStart = &mFixedAddresses[ 0 ];
+          pMemEnd = pMemStart;
+          for ( Count = 0; DIM ( Mtrr.Fixed.Mtrr ) > Count; Count++ ) {
+            //
+            //  Get the memory types
+            //
+            Type = Mtrr.Fixed.Mtrr[ Count ];
+
+            //
+            //  Walk the memory range
+            //
+            for ( Index = 0; 8 > Index; Index++ ) {
+              //
+              //  Determine if this is the same memory type
+              //
+              if ( PreviousType != ( Type & 0xff )) {
+                //
+                //  Display the row
+                //
+                Status = MtrrDisplayFixedRow ( SocketFD,
+                                               pPort,
+                                               *pMemStart,
+                                               *pMemEnd,
+                                               PreviousType );
+                if ( EFI_ERROR ( Status )) {
+                  break;
+                }
+
+                //
+                //  Start the next range of addresses
+                //
+                pMemStart = pMemEnd;
+                PreviousType = Type & 0xff;
+              }
+
+              //
+              //  Set the next memory range and type
+              //
+              Type >>= 8;
+              pMemEnd += 1;
+            }
+            if ( EFI_ERROR ( Status )) {
+              break;
+            }
+          }
+          if ( EFI_ERROR ( Status )) {
+            break;
+          }
+
+          //
+          //  Display the final row
+          //
+          Status = MtrrDisplayFixedRow ( SocketFD,
+                                         pPort,
+                                         *pMemStart,
+                                         *pMemEnd,
+                                         PreviousType );
+          if ( EFI_ERROR ( Status )) {
+            break;
+          }
+
+          //
+          //  End of table 
+          //
+          Status = HttpSendAnsiString ( SocketFD,
+                                        pPort,
+                                        "</table>\r\n" );
+          if ( EFI_ERROR ( Status )) {
+            break;
+          }
+        }
+
+        //
+        //  Determine if the variable MTRRs are supported
+        //
+        MaxMtrrs = Capabilities & MTRR_LIB_IA32_MTRR_CAP_VCNT_MASK;
+        if ( 0 < MaxMtrrs ) {
+          //
+          //  Beginning of table
+          //
+          Status = HttpSendAnsiString ( SocketFD,
+                                        pPort,
+                                        "<h2>Variable MTRRs</h2>\r\n"
+                                        "<table>\r\n"
+                                        "  <tr><th>Index</th><th align=\"right\">Base</th><th align=\"right\">Mask</th><th align=\"right\">Start</th><th align=\"right\">End</th></tr>\r\n" );
+          if ( EFI_ERROR ( Status )) {
+            break;
+          }
+
+          //
+          //  Display the variable MTRRs
+          //
+          for ( Count = 0; MaxMtrrs > Count; Count++ ) {
+            //
+            //  Start the row
+            //
+            Status = HttpSendAnsiString ( SocketFD,
+                                          pPort,
+                                          "  <tr><td>" );
+            if ( EFI_ERROR ( Status )) {
+              break;
+            }
+            
+            //
+            //  Index
+            //
+            Status = HttpSendValue ( SocketFD,
+                                     pPort,
+                                     Count );
+            if ( EFI_ERROR ( Status )) {
+              break;
+            }
+            
+            //
+            //  Base
+            //
+            Status = HttpSendAnsiString ( SocketFD,
+                                          pPort,
+                                          "</td><td align=\"right\"><code>0x" );
+            if ( EFI_ERROR ( Status )) {
+              break;
+            }
+            Status = HttpSendHexValue ( SocketFD,
+                                        pPort,
+                                        Mtrr.Variables.Mtrr[ Count ].Base );
+            if ( EFI_ERROR ( Status )) {
+              break;
+            }
+
+            //
+            //  Mask
+            //
+            Status = HttpSendAnsiString ( SocketFD,
+                                          pPort,
+                                          "</td><td align=\"right\"><code>0x" );
+            if ( EFI_ERROR ( Status )) {
+              break;
+            }
+            Status = HttpSendHexValue ( SocketFD,
+                                        pPort,
+                                        Mtrr.Variables.Mtrr[ Count ].Mask );
+            if ( EFI_ERROR ( Status )) {
+              break;
+            }
+
+            //
+            //  Determine if the entry is valid
+            //
+            bValid = ( Mtrr.Variables.Mtrr[ Count ].Mask & VARIABLE_MTRR_VALID ) ? TRUE : FALSE;
+
+            //
+            //  Start
+            //
+            Status = HttpSendAnsiString ( SocketFD,
+                                          pPort,
+                                          "</code></td><td align=\"right\"><code>" );
+            if ( EFI_ERROR ( Status )) {
+              break;
+            }
+            Addr = Mtrr.Variables.Mtrr[ Count ].Base & 0xfffffffffffff000ULL;
+            if ( bValid ) {
+              Status = HttpSendAnsiString ( SocketFD,
+                                            pPort,
+                                            "0x" );
+              if ( EFI_ERROR ( Status )) {
+                break;
+              }
+              Status = HttpSendHexValue ( SocketFD,
+                                          pPort,
+                                          Addr );
+            }
+            else {
+              Status = HttpSendAnsiString ( SocketFD,
+                                            pPort,
+                                            "Invalid" );
+            }
+            if ( EFI_ERROR ( Status )) {
+              break;
+            }
+
+            //
+            //  End
+            //
+            Status = HttpSendAnsiString ( SocketFD,
+                                          pPort,
+                                          "</code></td><td align=\"right\"><code>" );
+            if ( EFI_ERROR ( Status )) {
+              break;
+            }
+            if ( bValid ) {
+              //
+              //  Determine the end address
+              //
+              Mask = Mtrr.Variables.Mtrr[ Count ].Mask;
+              Value = Mask;
+              ShiftCount = 0;
+              while ( 0 < Value ) {
+                Value <<= 1;
+                ShiftCount += 1;
+              }
+              Value = 1;
+              Value <<= 64 - ShiftCount;
+              Value -= 1;
+              Value = ~Value;
+              Value |= Mask;
+              Value &= ~VARIABLE_MTRR_VALID;
+              Value = ~Value;
+
+              Status = HttpSendAnsiString ( SocketFD,
+                                            pPort,
+                                            "0x" );
+              if ( EFI_ERROR ( Status )) {
+                break;
+              }
+              Status = HttpSendHexValue ( SocketFD,
+                                          pPort,
+                                          Addr + Value );
+            }
+            if ( EFI_ERROR ( Status )) {
+              break;
+            }
+
+            //
+            //  Type
+            //
+            Status = HttpSendAnsiString ( SocketFD,
+                                          pPort,
+                                          "</code></td><td>" );
+            if ( EFI_ERROR ( Status )) {
+              break;
+            }
+            if ( bValid ) {
+              Type = Mtrr.Variables.Mtrr[ Count ].Base & 0xFF;
+              Status = HttpSendAnsiString ( SocketFD,
+                                            pPort,
+                                            ( DIM ( mMemoryType ) > Type )
+                                            ? mMemoryType [ Type ]
+                                            : "Reserved" );
+            }
+            if ( EFI_ERROR ( Status )) {
+              break;
+            }
+
+            //
+            //  End of row
+            //
+            Status = HttpSendAnsiString ( SocketFD,
+                                          pPort,
+                                          "</td></tr>\r\n" );
+            if ( EFI_ERROR ( Status )) {
+              break;
+            }
+          }
+          if ( EFI_ERROR ( Status )) {
+            break;
+          }
+
+          //
+          //  End of table 
+          //
+          Status = HttpSendAnsiString ( SocketFD,
+                                        pPort,
+                                        "</table>\r\n" );
+          if ( EFI_ERROR ( Status )) {
+            break;
+          }
+        }
+      }
+    }
+
+    //
+    //  Send the page trailer
+    //
+    Status = HttpPageTrailer ( SocketFD, pPort, pbDone );
+    break;
+  }
+    
+  //
+  //  Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/PageList.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/PageList.c
new file mode 100644
index 0000000..1e271e5
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/PageList.c
@@ -0,0 +1,62 @@
+/**
+  @file
+  List of pages to display
+
+  Copyright (c) 2011-2012, Intel Corporation
+  All rights reserved. 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.php
+
+  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 <WebServer.h>
+
+
+/**
+  List of pages in the system
+**/
+CONST DT_PAGE mPageList[] = {
+
+  //
+  //  The index page must be first
+  //
+  { L"/", IndexPage, L"Index of pages" },   ///<  List the pages
+
+  //
+  //  All other pages follow in alphabetical order
+  //
+  { PAGE_BOOT_SERVICES_TABLE, BootServicesTablePage, L"Boot Services Table" },          ///<  Format boot services table
+  { PAGE_CONFIGURATION_TABLE, ConfigurationTablePage, L"Configuration Table" },         ///<  Format configuration table
+  { L"/DhcpOptions", DhcpOptionsPage, L"DHCP Options" },                                ///<  Display the DHCP options
+  { PAGE_ACPI_APIC, AcpiApicPage, L"APIC" },            ///<  Format APIC
+  { PAGE_ACPI_BGRT, AcpiBgrtPage, L"BGRT" },            ///<  Format BGRT
+  { PAGE_ACPI_DSDT, AcpiDsdtPage, L"DSDT - Differentiated System Description Table" },  ///<  Format DSDT
+  { PAGE_DXE_SERVICES_TABLE, DxeServicesTablePage, L"DXE Services Table" },             ///<  Format DXE services table
+  { L"/Exit", ExitPage, L"Exit the web server" },       ///<  Exit the web server application
+  { PAGE_ACPI_FADT, AcpiFadtPage, L"FADT - Fixed ACPI Description Table" },             ///<  Format FADT
+  { L"/Firmware", FirmwarePage, L"Firmware" },          ///<  Firmware status
+  { L"/Handles", HandlePage, L"Display handles and associated protocol GUIDs" },        ///<  Handle database page
+  { L"/Hello", HelloPage, L"Hello World" },             ///<  Hello world page
+  { PAGE_ACPI_HPET, AcpiHpetPage, L"HPET" },            ///<  Format HPET
+  { PAGE_ACPI_MCFG, AcpiMcfgPage, L"MCFG" },            ///<  Format MCFG
+  { L"/MemoryMap", MemoryMapPage, L"Memory Map" },      ///<  Memory list
+#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
+  { L"/MTRRs", MemoryTypeRegistersPage, L"Memory Type Range Registers" }, ///<  Memory type range register table
+#endif  //  Intel
+  { L"/Ports", PortsPage, L"Display web-server ports" },///<  Web-server ports page
+  { L"/Reboot", RebootPage, L"Reboot the sytem" },      ///<  Reboot page
+  { PAGE_ACPI_RSDP_10B, AcpiRsdp10Page, L"RSDP 1.0b - ACPI Root System Description Pointer" },  ///<  Format RSDP 1.0b table
+  { PAGE_ACPI_RSDP_30, AcpiRsdp30Page, L"RSDP 3.0 - ACPI Root System Description Pointer" },    ///<  Format RSDP 3.0 table
+  { PAGE_ACPI_RSDT, AcpiRsdtPage, L"RSDT - ACPI Root System Description Table" },       ///<  Format RSDT
+  { PAGE_RUNTIME_SERVICES_TABLE, RuntimeSservicesTablePage, L"Runtime Services Table" },///<  Format runtime services table
+  { PAGE_ACPI_SSDT, AcpiSsdtPage, L"SSDT" },            ///<  Format SSDT
+  { L"/SystemTable", SystemTablePage, L"System Table" },///<  Format system table
+  { PAGE_ACPI_TCPA, AcpiTcpaPage, L"TCPA" },            ///<  Format TCPA
+  { PAGE_ACPI_UEFI, AcpiUefiPage, L"UEFI" }             ///<  Format UEFI
+};
+
+CONST UINTN mPageCount = DIM ( mPageList );
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Ports.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Ports.c
new file mode 100644
index 0000000..f9b6680
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Ports.c
@@ -0,0 +1,136 @@
+/**
+  @file
+  Ports response page
+
+  Copyright (c) 2011-2012, Intel Corporation
+  All rights reserved. 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.php
+
+  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 <WebServer.h>
+
+
+/**
+  Respond with the Ports page
+
+  @param [in] SocketFD      The socket's file descriptor to add to the list.
+  @param [in] pPort         The WSDT_PORT structure address
+  @param [out] pbDone       Address to receive the request completion status
+
+  @retval EFI_SUCCESS       The request was successfully processed
+
+**/
+EFI_STATUS
+PortsPage (
+  IN int SocketFD,
+  IN WSDT_PORT * pPort,
+  OUT BOOLEAN * pbDone
+  )
+{
+  socklen_t AddressLength;
+  struct sockaddr_in6 LocalAddress;
+  DT_WEB_SERVER * pWebServer;
+  EFI_STATUS Status;
+  
+  DBG_ENTER ( );
+  
+  //
+  //  Send the Hello World page
+  //
+  pWebServer = &mWebServer;
+  for ( ; ; ) {
+    //
+    //  Send the page header
+    //
+    Status = HttpPageHeader ( SocketFD, pPort, L"Ports" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+  
+    //
+    //  Send the page body
+    //
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "<h1>Web-Server Ports</h1>\r\n" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Check for TCP v4
+    //
+    if ( -1 != pWebServer->HttpListenPort ) {
+      AddressLength = sizeof ( LocalAddress );
+      if ( 0 == getsockname ( pWebServer->HttpListenPort,
+                              (struct sockaddr *)&LocalAddress,
+                              &AddressLength )) {
+        Status = HttpSendAnsiString ( SocketFD,
+                                      pPort,
+                                      "<a href=\"http://" );
+        if ( EFI_ERROR ( Status )) {
+          break;
+        }
+        Status = HttpSendIpAddress ( SocketFD,
+                                     pPort,
+                                     &LocalAddress );
+        if ( EFI_ERROR ( Status )) {
+          break;
+        }
+        Status = HttpSendAnsiString ( SocketFD,
+                                      pPort,
+                                      "\">Tcp4</a><br>\r\n" );
+        if ( EFI_ERROR ( Status )) {
+          break;
+        }
+      }
+    }
+
+    //
+    //  Check for TCP v6
+    //
+    if ( -1 != pWebServer->HttpListenPort6 ) {
+      AddressLength = sizeof ( LocalAddress );
+      if ( 0 == getsockname ( pWebServer->HttpListenPort6,
+                              (struct sockaddr *)&LocalAddress,
+                              &AddressLength )) {
+        Status = HttpSendAnsiString ( SocketFD,
+                                      pPort,
+                                      "<a href=\"http://" );
+        if ( EFI_ERROR ( Status )) {
+          break;
+        }
+        Status = HttpSendIpAddress ( SocketFD,
+                                     pPort,
+                                     &LocalAddress );
+        if ( EFI_ERROR ( Status )) {
+          break;
+        }
+        Status = HttpSendAnsiString ( SocketFD,
+                                      pPort,
+                                      "\">Tcp6</a><br>\r\n" );
+        if ( EFI_ERROR ( Status )) {
+          break;
+        }
+      }
+    }
+
+    //
+    //  Send the page trailer
+    //
+    Status = HttpPageTrailer ( SocketFD, pPort, pbDone );
+    break;
+  }
+    
+  //
+  //  Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Reboot.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Reboot.c
new file mode 100644
index 0000000..2fc8fec
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/Reboot.c
@@ -0,0 +1,95 @@
+/**
+  @file
+  Reboot the system
+
+  Copyright (c) 2011-2012, Intel Corporation
+  All rights reserved. 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.php
+
+  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 <WebServer.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+
+/**
+  Page to reboot the system
+
+  @param [in] SocketFD      The socket's file descriptor to add to the list.
+  @param [in] pPort         The WSDT_PORT structure address
+  @param [out] pbDone       Address to receive the request completion status
+
+  @retval EFI_SUCCESS       The request was successfully processed
+
+**/
+EFI_STATUS
+RebootPage (
+  IN int SocketFD,
+  IN WSDT_PORT * pPort,
+  OUT BOOLEAN * pbDone
+  )
+{
+  EFI_STATUS Status;
+  
+  DBG_ENTER ( );
+  
+  //
+  //  Send the Reboot page
+  //
+  for ( ; ; ) {
+    //
+    //  Send the page header
+    //
+    Status = HttpPageHeader ( SocketFD, pPort, L"Reboot" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+  
+    //
+    //  Send the page body
+    //
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "<h1>Reboot</h1>\r\n"
+                                  "<p>\r\n"
+                                  "  Ouch!  The system is rebooting!\r\n" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+  
+    //
+    //  Send the page trailer
+    //
+    Status = HttpPageTrailer ( SocketFD, pPort, pbDone );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Deliver the data to the remote system by
+    //  closing the socket
+    //
+    close ( SocketFD );
+
+    //
+    //  Attempt to reboot the system
+    //
+    DEBUG (( DEBUG_REQUEST, "Reseting System\r\n" ));
+    gRT->ResetSystem ( EfiResetCold,
+                       EFI_SUCCESS,
+                       0,
+                       NULL );
+    break;
+  }
+    
+  //
+  //  Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/RuntimeServicesTable.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/RuntimeServicesTable.c
new file mode 100644
index 0000000..d5fed0c
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/RuntimeServicesTable.c
@@ -0,0 +1,217 @@
+/**
+  @file
+  Display the runtime services table
+
+  Copyright (c) 2011-2012, Intel Corporation
+  All rights reserved. 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.php
+
+  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 <WebServer.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+/**
+  Respond with the runtime services table
+
+  @param [in] SocketFD      The socket's file descriptor to add to the list.
+  @param [in] pPort         The WSDT_PORT structure address
+  @param [out] pbDone       Address to receive the request completion status
+
+  @retval EFI_SUCCESS       The request was successfully processed
+
+**/
+EFI_STATUS
+RuntimeSservicesTablePage (
+  IN int SocketFD,
+  IN WSDT_PORT * pPort,
+  OUT BOOLEAN * pbDone
+  )
+{
+  EFI_STATUS Status;
+
+  DBG_ENTER ( );
+  
+  //
+  //  Send the runtime services page
+  //
+  for ( ; ; ) {
+    //
+    //  Send the page and table header
+    //
+    Status = TableHeader ( SocketFD, pPort, L"Runtime Services Table", gRT );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    ///
+    /// The table header for the EFI Runtime Services Table.
+    ///
+    Status = EfiTableHeader ( SocketFD,
+                              pPort,
+                              &gRT->Hdr );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    
+    //
+    // Time Services
+    //
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "GetTime",
+                          (VOID *)gRT->GetTime,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "SetTime",
+                          (VOID *)gRT->SetTime,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "GetWakeupTime",
+                          (VOID *)gRT->GetWakeupTime,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "SetWakeupTime",
+                          (VOID *)gRT->SetWakeupTime,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    
+    //
+    // Virtual Memory Services
+    //
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "SetVirtualAddressMap",
+                          (VOID *)gRT->SetVirtualAddressMap,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "ConvertPointer",
+                          (VOID *)gRT->ConvertPointer,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    
+    //
+    // Variable Services
+    //
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "GetVariable",
+                          (VOID *)gRT->GetVariable,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "GetNextVariableName",
+                          (VOID *)gRT->GetNextVariableName,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "SetVariable",
+                          (VOID *)gRT->SetVariable,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    
+    //
+    // Miscellaneous Services
+    //
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "GetNextHighNonotonicCount",
+                          (VOID *)gRT->GetNextHighMonotonicCount,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "ResetSystem",
+                          (VOID *)gRT->ResetSystem,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Determine if the structures supports 2.0 services
+    //
+    if ( 2 <= ( gRT->Hdr.Revision >> 16 )) {
+      //
+      // UEFI 2.0 Capsule Services
+      //
+      Status = RowPointer ( SocketFD,
+                            pPort,
+                            "UpdateCapsule",
+                            (VOID *)gRT->UpdateCapsule,
+                            NULL );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+      Status = RowPointer ( SocketFD,
+                            pPort,
+                            "QueryCapsuleCapabilities",
+                            (VOID *)gRT->QueryCapsuleCapabilities,
+                            NULL );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+    
+      //
+      // Miscellaneous UEFI 2.0 Service
+      //
+      Status = RowPointer ( SocketFD,
+                            pPort,
+                            "QueryVariableInfo",
+                            (VOID *)gRT->QueryVariableInfo,
+                            NULL );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+    }
+
+    //
+    //  Build the table trailer
+    //
+    Status = TableTrailer ( SocketFD,
+                            pPort,
+                            pbDone );
+    break;
+  }
+    
+  //
+  //  Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/SystemTable.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/SystemTable.c
new file mode 100644
index 0000000..83f6030
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/SystemTable.c
@@ -0,0 +1,853 @@
+/**
+  @file
+  Display the system table
+
+  Copyright (c) 2011-2012, Intel Corporation
+  All rights reserved. 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.php
+
+  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 <WebServer.h>
+
+
+/**
+  Display the EFI Table Header
+
+  @param [in] SocketFD      The socket's file descriptor to add to the list.
+  @param [in] pPort         The WSDT_PORT structure address
+  @param [in] pHeader       Address of the EFI_TABLE_HEADER structure
+
+  @retval EFI_SUCCESS       The request was successfully processed
+
+**/
+EFI_STATUS
+EfiTableHeader (
+  IN int SocketFD,
+  IN WSDT_PORT * pPort,
+  IN EFI_TABLE_HEADER * pHeader
+  )
+{
+  EFI_STATUS Status;
+
+  DBG_ENTER ( );
+  
+  //
+  //  Send the handles page
+  //
+  for ( ; ; ) {
+    ///
+    /// A 64-bit signature that identifies the type of table that follows.
+    /// Unique signatures have been generated for the EFI System Table,
+    /// the EFI Boot Services Table, and the EFI Runtime Services Table.
+    ///
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "Hdr.Signature",
+                           pHeader->Signature,
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    ///
+    /// The revision of the EFI Specification to which this table
+    /// conforms. The upper 16 bits of this field contain the major
+    /// revision value, and the lower 16 bits contain the minor revision
+    /// value. The minor revision values are limited to the range of 00..99.
+    ///
+    Status = RowRevision ( SocketFD,
+                           pPort,
+                           "Hdr.Revision",
+                           pHeader->Revision );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    ///
+    /// The size, in bytes, of the entire table including the EFI_TABLE_HEADER.
+    ///
+    Status = RowDecimalValue ( SocketFD,
+                               pPort,
+                               "Hdr.HeaderSize",
+                               pHeader->HeaderSize );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    ///
+    /// The 32-bit CRC for the entire table. This value is computed by
+    /// setting this field to 0, and computing the 32-bit CRC for HeaderSize bytes.
+    ///
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "Hdr.CRC",
+                           pHeader->CRC32,
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    ///
+    /// Reserved field that must be set to 0.
+    ///
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "Hdr.Reserved",
+                           pHeader->Reserved,
+                           NULL );
+    break;
+  }
+
+  //
+  //  Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  Display a row containing a decimal value
+
+  @param [in] SocketFD      The socket's file descriptor to add to the list.
+  @param [in] pPort         The WSDT_PORT structure address
+  @param [in] pName         Address of a zero terminated name string
+  @param [in] Value         The value to display
+
+  @retval EFI_SUCCESS       The request was successfully processed
+
+**/
+EFI_STATUS
+RowDecimalValue (
+  IN int SocketFD,
+  IN WSDT_PORT * pPort,
+  IN CONST CHAR8 * pName,
+  IN UINT64 Value
+  )
+{
+  EFI_STATUS Status;
+
+  DBG_ENTER ( );
+
+  //
+  //  Use for/break instead of goto
+  //
+  for ( ; ; ) {
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "<tr><td>" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  pName );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "</td><td><code>" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = HttpSendValue ( SocketFD,
+                             pPort,
+                             Value );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "</code></td></tr>\r\n" );
+    break;
+  }
+
+  //
+  //  Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  Display a row containing a hex value
+
+  @param [in] SocketFD      The socket's file descriptor to add to the list.
+  @param [in] pPort         The WSDT_PORT structure address
+  @param [in] pName         Address of a zero terminated name string
+  @param [in] Value         The value to display
+  @param [in] pWebPage      Address of a zero terminated web page name
+
+  @retval EFI_SUCCESS       The request was successfully processed
+
+**/
+EFI_STATUS
+RowHexValue (
+  IN int SocketFD,
+  IN WSDT_PORT * pPort,
+  IN CONST CHAR8 * pName,
+  IN UINT64 Value,
+  IN CONST CHAR16 * pWebPage
+  )
+{
+  EFI_STATUS Status;
+
+  DBG_ENTER ( );
+
+  //
+  //  Use for/break instead of goto
+  //
+  for ( ; ; ) {
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "<tr><td>" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  pName );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "</td><td><code>0x" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    if ( NULL != pWebPage ) {
+      Status = HttpSendAnsiString ( SocketFD,
+                                    pPort,
+                                    "<a target=\"_blank\" href=\"" );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+      Status = HttpSendUnicodeString ( SocketFD,
+                                       pPort,
+                                       pWebPage );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+      Status = HttpSendAnsiString ( SocketFD,
+                                    pPort,
+                                    "\">" );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+    }
+    Status = HttpSendHexValue ( SocketFD,
+                                pPort,
+                                Value );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    if ( NULL != pWebPage ) {
+      Status = HttpSendAnsiString ( SocketFD,
+                                    pPort,
+                                    "</a>" );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+    }
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "</code></td></tr>\r\n" );
+    break;
+  }
+
+  //
+  //  Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  Display a row containing a pointer
+
+  @param [in] SocketFD      The socket's file descriptor to add to the list.
+  @param [in] pPort         The WSDT_PORT structure address
+  @param [in] pName         Address of a zero terminated name string
+  @param [in] pAddress      The address to display
+  @param [in] pWebPage      Address of a zero terminated web page name
+
+  @retval EFI_SUCCESS       The request was successfully processed
+
+**/
+EFI_STATUS
+RowPointer (
+  IN int SocketFD,
+  IN WSDT_PORT * pPort,
+  IN CONST CHAR8 * pName,
+  IN CONST VOID * pAddress,
+  IN CONST CHAR16 * pWebPage
+  )
+{
+  EFI_STATUS Status;
+
+  DBG_ENTER ( );
+
+  //
+  //  Use for/break instead of goto
+  //
+  for ( ; ; ) {
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "<tr><td>" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  pName );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "</td><td><code>" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    if ( NULL != pWebPage ) {
+      Status = HttpSendAnsiString ( SocketFD,
+                                    pPort,
+                                    "<a target=\"_blank\" href=\"" );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+      Status = HttpSendUnicodeString ( SocketFD,
+                                       pPort,
+                                       pWebPage );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+      Status = HttpSendAnsiString ( SocketFD,
+                                    pPort,
+                                    "\">" );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+    }
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "0x" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = HttpSendHexBits ( SocketFD,
+                               pPort,
+                               sizeof ( pAddress ) * 8,
+                               (UINT64)(UINTN)pAddress );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    if ( NULL != pWebPage ) {
+      Status = HttpSendAnsiString ( SocketFD,
+                                    pPort,
+                                    "</a>" );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+    }
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "</code></td></tr>\r\n" );
+    break;
+  }
+
+  //
+  //  Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  Display a row containing a revision
+
+  @param [in] SocketFD      The socket's file descriptor to add to the list.
+  @param [in] pPort         The WSDT_PORT structure address
+  @param [in] pName         Address of a zero terminated name string
+  @param [in] Revision      The revision to display
+
+  @retval EFI_SUCCESS       The request was successfully processed
+
+**/
+EFI_STATUS
+RowRevision (
+  IN int SocketFD,
+  IN WSDT_PORT * pPort,
+  IN CONST CHAR8 * pName,
+  IN UINT32 Revision
+  )
+{
+  EFI_STATUS Status;
+
+  DBG_ENTER ( );
+
+  //
+  //  Use for/break instead of goto
+  //
+  for ( ; ; ) {
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "<tr><td>" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  pName );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "</td><td><code>" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = HttpSendValue ( SocketFD,
+                             pPort,
+                             Revision >> 16 );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = HttpSendByte ( SocketFD,
+                            pPort,
+                            '.' );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = HttpSendValue ( SocketFD,
+                             pPort,
+                             Revision & 0xFFFF );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "</code></td></tr>\r\n" );
+    break;
+  }
+
+  //
+  //  Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  Display a row containing a unicode string
+
+  @param [in] SocketFD      The socket's file descriptor to add to the list.
+  @param [in] pPort         The WSDT_PORT structure address
+  @param [in] pName         Address of a zero terminated name string
+  @param [in] pString       Address of a zero terminated unicode string
+
+  @retval EFI_SUCCESS       The request was successfully processed
+
+**/
+EFI_STATUS
+RowUnicodeString (
+  IN int SocketFD,
+  IN WSDT_PORT * pPort,
+  IN CONST CHAR8 * pName,
+  IN CONST CHAR16 * pString
+  )
+{
+  EFI_STATUS Status;
+
+  DBG_ENTER ( );
+
+  //
+  //  Use for/break instead of goto
+  //
+  for ( ; ; ) {
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "<tr><td>" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  pName );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "</td><td>" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = HttpSendUnicodeString ( SocketFD,
+                                     pPort,
+                                     pString );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "</td></tr>\r\n" );
+    break;
+  }
+
+  //
+  //  Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  Start the table page
+
+  @param [in] SocketFD      The socket's file descriptor to add to the list.
+  @param [in] pPort         The WSDT_PORT structure address
+  @param [in] pName         Address of a zero terminated name string
+  @param [in] pTable        Address of the table
+
+  @retval EFI_SUCCESS       The request was successfully processed
+
+**/
+EFI_STATUS
+TableHeader (
+  IN int SocketFD,
+  IN WSDT_PORT * pPort,
+  IN CONST CHAR16 * pName,
+  IN CONST VOID * pTable
+  )
+{
+  EFI_STATUS Status;
+
+  DBG_ENTER ( );
+
+  //
+  //  Use for/break instead of goto
+  //
+  for ( ; ; ) {
+    //
+    //  Send the page header
+    //
+    Status = HttpPageHeader ( SocketFD, pPort, pName );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    
+    //
+    //  Build the table header
+    //
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "<h1>" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = HttpSendUnicodeString ( SocketFD,
+                                     pPort,
+                                     pName );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    if ( NULL != pTable ) {
+      Status = HttpSendAnsiString ( SocketFD,
+                                    pPort,
+                                    ": 0x" );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+      Status = HttpSendHexBits ( SocketFD,
+                                 pPort,
+                                 sizeof ( pTable ) *  8,
+                                 (UINT64)(UINTN)pTable );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+    }
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "</h1>\r\n"
+                                  "<table border=\"1\">\r\n"
+                                  "  <tr bgcolor=\"c0c0ff\"><th>Field Name</th><th>Value</th></tr>\r\n" );
+    break;
+  }
+
+  //
+  //  Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  End the table page
+
+  @param [in] SocketFD      The socket's file descriptor to add to the list.
+  @param [in] pPort         The WSDT_PORT structure address
+  @param [out] pbDone       Address to receive the request completion status
+
+  @retval EFI_SUCCESS       The request was successfully processed
+
+**/
+EFI_STATUS
+TableTrailer (
+  IN int SocketFD,
+  IN WSDT_PORT * pPort,
+  OUT BOOLEAN *pbDone
+  )
+{
+  EFI_STATUS Status;
+
+  DBG_ENTER ( );
+
+  //
+  //  Use for/break instead of goto
+  //
+  for ( ; ; ) {
+    //
+    //  Build the table trailer
+    //
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "</table>\r\n" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    
+    //
+    //  Send the page trailer
+    //
+    Status = HttpPageTrailer ( SocketFD, pPort, pbDone );
+    break;
+  }
+
+  //
+  //  Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  Respond with the system table
+
+  @param [in] SocketFD      The socket's file descriptor to add to the list.
+  @param [in] pPort         The WSDT_PORT structure address
+  @param [out] pbDone       Address to receive the request completion status
+
+  @retval EFI_SUCCESS       The request was successfully processed
+
+**/
+EFI_STATUS
+SystemTablePage (
+  IN int SocketFD,
+  IN WSDT_PORT * pPort,
+  OUT BOOLEAN * pbDone
+  )
+{
+  EFI_STATUS Status;
+
+  DBG_ENTER ( );
+  
+  //
+  //  Send the system table page
+  //
+  for ( ; ; ) {
+    //
+    //  Send the page and table header
+    //
+    Status = TableHeader ( SocketFD, pPort, L"System Table", gST );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    ///
+    /// The table header for the EFI System Table.
+    ///
+    Status = EfiTableHeader ( SocketFD,
+                              pPort,
+                              &gST->Hdr );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    ///
+    /// A pointer to a null terminated string that identifies the vendor
+    /// that produces the system firmware for the platform.
+    ///
+    Status = RowUnicodeString ( SocketFD,
+                                pPort,
+                                "FirmwareVendor",
+                                gST->FirmwareVendor );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    ///
+    /// A firmware vendor specific value that identifies the revision
+    /// of the system firmware for the platform.
+    ///
+    Status = RowRevision ( SocketFD,
+                           pPort,
+                           "FirmwareRevision",
+                           gST->FirmwareRevision );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    ///
+    /// The handle for the active console input device. This handle must support
+    /// EFI_SIMPLE_TEXT_INPUT_PROTOCOL and EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.
+    ///
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "ConsoleInHandle",
+                          (VOID *)gST->ConsoleInHandle,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    ///
+    /// A pointer to the EFI_SIMPLE_TEXT_INPUT_PROTOCOL interface that is
+    /// associated with ConsoleInHandle.
+    ///
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "ConIn",
+                          (VOID *)gST->ConIn,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    ///
+    /// The handle for the active console output device.
+    ///
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "ConsoleOutHandle",
+                          (VOID *)gST->ConsoleOutHandle,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    ///
+    /// A pointer to the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL interface
+    /// that is associated with ConsoleOutHandle.
+    ///
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "ConOut",
+                          (VOID *)gST->ConOut,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    ///
+    /// The handle for the active standard error console device.
+    /// This handle must support the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.
+    ///
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "StandardErrorHandle",
+                          (VOID *)gST->StandardErrorHandle,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    ///
+    /// A pointer to the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL interface
+    /// that is associated with StandardErrorHandle.
+    ///
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "StdErr",
+                          (VOID *)gST->StdErr,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    ///
+    /// A pointer to the EFI Runtime Services Table.
+    ///
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "RuntimeServices",
+                          (VOID *)gST->RuntimeServices,
+                          PAGE_RUNTIME_SERVICES_TABLE );
+
+    ///
+    /// A pointer to the EFI Boot Services Table.
+    ///
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "BootServices",
+                          (VOID *)gST->BootServices,
+                          PAGE_BOOT_SERVICES_TABLE );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    ///
+    /// The number of system configuration tables in the buffer ConfigurationTable.
+    ///
+    Status = RowDecimalValue ( SocketFD,
+                               pPort,
+                               "NumberOfTableEntries",
+                               gST->NumberOfTableEntries );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    ///
+    /// A pointer to the system configuration tables.
+    /// The number of entries in the table is NumberOfTableEntries.
+    ///
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "ConfigurationTable",
+                          (VOID *)gST->ConfigurationTable,
+                          PAGE_CONFIGURATION_TABLE );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Build the table trailer
+    //
+    Status = TableTrailer ( SocketFD,
+                            pPort,
+                            pbDone );
+    break;
+  }
+    
+  //
+  //  Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/WebServer.c b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/WebServer.c
new file mode 100644
index 0000000..f8a2d3a
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/WebServer.c
@@ -0,0 +1,782 @@
+/**
+  @file
+  Web server application
+
+  Copyright (c) 2011-2012, Intel Corporation
+  All rights reserved. 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.php
+
+  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 <WebServer.h>
+
+DT_WEB_SERVER mWebServer;   ///<  Web server's control structure
+
+
+/**
+  Add a port to the list of ports to be polled.
+
+  @param [in] pWebServer    The web server control structure address.
+
+  @param [in] SocketFD      The socket's file descriptor to add to the list.
+
+  @retval EFI_SUCCESS       The port was successfully added
+  @retval EFI_NO_RESOURCES  Insufficient memory to add the port
+
+**/
+EFI_STATUS
+PortAdd (
+  IN DT_WEB_SERVER * pWebServer,
+  IN int SocketFD
+  )
+{
+  nfds_t Index;
+  size_t LengthInBytes;
+  nfds_t MaxEntries;
+  nfds_t MaxEntriesNew;
+  struct pollfd * pFdList;
+  struct pollfd * pFdListNew;
+  WSDT_PORT ** ppPortListNew;
+  WSDT_PORT * pPort;
+  EFI_STATUS Status;
+
+  DBG_ENTER ( );
+
+  //
+  //  Use for/break instead of goto
+  //
+  for ( ; ; ) {
+    //
+    //  Assume success
+    //
+    Status = EFI_SUCCESS;
+
+    //
+    //  Create a new list if necessary
+    //
+    pFdList = pWebServer->pFdList;
+    MaxEntries = pWebServer->MaxEntries;
+    if ( pWebServer->Entries >= MaxEntries ) {
+      MaxEntriesNew = 16 + MaxEntries;
+
+      //
+      //  The current FD list is full
+      //  Allocate a new FD list
+      //
+      LengthInBytes = sizeof ( *pFdList ) * MaxEntriesNew;
+      Status = gBS->AllocatePool ( EfiRuntimeServicesData,
+                                   LengthInBytes,
+                                   (VOID **)&pFdListNew );
+      if ( EFI_ERROR ( Status )) {
+        DEBUG (( DEBUG_ERROR | DEBUG_POOL,
+                  "ERROR - Failed to allocate the FD list, Status: %r\r\n",
+                  Status ));
+        break;
+      }
+
+      //
+      //  Allocate a new port list
+      //
+      LengthInBytes = sizeof ( *ppPortListNew ) * MaxEntriesNew;
+      Status = gBS->AllocatePool ( EfiRuntimeServicesData,
+                                   LengthInBytes,
+                                   (VOID **) &ppPortListNew );
+      if ( EFI_ERROR ( Status )) {
+        DEBUG (( DEBUG_ERROR | DEBUG_POOL,
+                  "ERROR - Failed to allocate the port list, Status: %r\r\n",
+                  Status ));
+
+        //
+        //  Free the new FD list
+        //
+        gBS->FreePool ( pFdListNew );
+        break;
+      }
+
+      //
+      //  Duplicate the FD list
+      //
+      Index = MaxEntries;
+      if ( NULL != pFdList ) {
+        CopyMem ( pFdListNew,
+                  pFdList,
+                  Index * sizeof ( *pFdList ));
+      }
+
+      //
+      //  Initialize the new entries in the FD list
+      //
+      for ( ; MaxEntriesNew > Index; Index++ ) {
+        pFdListNew[ Index ].fd = -1;
+        pFdListNew[ Index ].events = 0;
+        pFdListNew[ Index ].revents = 0;
+      }
+
+      //
+      //  Free the old FD list
+      //
+      if ( NULL != pFdList ) {
+        gBS->FreePool ( pFdList );
+      }
+
+      //
+      //  Switch to the new FD list
+      //
+      pWebServer->pFdList = pFdListNew;
+      pFdList = pWebServer->pFdList;
+
+      //
+      //  Duplicate the port list
+      //
+      Index = MaxEntries;
+      if ( NULL != pWebServer->ppPortList ) {
+        CopyMem ( ppPortListNew,
+                  pWebServer->ppPortList,
+                  Index * sizeof ( *ppPortListNew ));
+      }
+      
+      //
+      //  Initialize the new entries in the port list
+      //
+      for ( ; MaxEntriesNew > Index; Index++ ) {
+        ppPortListNew[ Index ] = NULL;
+      }
+      
+      //
+      //  Free the old port list
+      //
+      if ( NULL != pWebServer->ppPortList ) {
+        gBS->FreePool ( pWebServer->ppPortList );
+      }
+      
+      //
+      //  Switch to the new port list
+      //
+      pWebServer->ppPortList = ppPortListNew;
+      
+      //
+      //  Update the list size
+      //
+      pWebServer->MaxEntries = MaxEntriesNew;
+    }
+
+    //
+    //  Allocate a new port
+    //
+    LengthInBytes = sizeof ( *pPort );
+    Status = gBS->AllocatePool ( EfiRuntimeServicesData,
+                                 LengthInBytes,
+                                 (VOID **)&pPort );
+    if ( EFI_ERROR ( Status )) {
+      DEBUG (( DEBUG_ERROR | DEBUG_POOL,
+                "ERROR - Failed to allocate the port, Status: %r\r\n",
+                Status ));
+      break;
+    }
+
+    //
+    //  Initialize the port
+    //
+    pPort->RequestLength = 0;
+    pPort->TxBytes = 0;
+
+    //
+    //  Add the socket to the FD list
+    //
+    pFdList[ pWebServer->Entries ].fd = SocketFD;
+    pFdList[ pWebServer->Entries ].events = POLLRDNORM
+                                             | POLLHUP;
+    pFdList[ pWebServer->Entries ].revents = 0;
+
+    //
+    //  Add the port to the port list
+    //
+    pWebServer->ppPortList[ pWebServer->Entries ] = pPort;
+
+    //
+    //  Account for the new entry
+    //
+    pWebServer->Entries += 1;
+    DEBUG (( DEBUG_PORT_WORK | DEBUG_INFO,
+              "WebServer handling %d ports\r\n",
+              pWebServer->Entries ));
+
+    //
+    //  All done
+    //
+    break;
+  }
+
+  //
+  //  Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  Remove a port from the list of ports to be polled.
+
+  @param [in] pWebServer    The web server control structure address.
+
+  @param [in] SocketFD      The socket's file descriptor to add to the list.
+
+**/
+VOID
+PortRemove (
+  IN DT_WEB_SERVER * pWebServer,
+  IN int SocketFD
+  )
+{
+  nfds_t Entries;
+  nfds_t Index;
+  struct pollfd * pFdList;
+  WSDT_PORT ** ppPortList;
+
+  DBG_ENTER ( );
+
+  //
+  //  Attempt to remove the entry from the list
+  //
+  Entries = pWebServer->Entries;
+  pFdList = pWebServer->pFdList;
+  ppPortList = pWebServer->ppPortList;
+  for ( Index = 0; Entries > Index; Index++ ) {
+    //
+    //  Locate the specified socket file descriptor
+    //
+    if ( SocketFD == pFdList[ Index ].fd ) {
+      //
+      //  Determine if this is the listen port
+      //
+      if ( SocketFD == pWebServer->HttpListenPort ) {
+        pWebServer->HttpListenPort = -1;
+      }
+
+      //
+      //  Close the socket
+      //
+      close ( SocketFD );
+
+      //
+      //  Free the port structure
+      //
+      gBS->FreePool ( ppPortList[ Index ]);
+
+      //
+      //  Remove this port from the list by copying
+      //  the rest of the list down one entry
+      //
+      Entries -= 1;
+      for ( ; Entries > Index; Index++ ) {
+        pFdList[ Index ] = pFdList[ Index + 1 ];
+        ppPortList[ Index ] = ppPortList[ Index + 1 ];
+      }
+      pFdList[ Index ].fd = -1;
+      pFdList[ Index ].events = 0;
+      pFdList[ Index ].revents = 0;
+      ppPortList[ Index ] = NULL;
+
+      //
+      //  Update the number of entries in the list
+      //
+      pWebServer->Entries = Entries;
+      DEBUG (( DEBUG_PORT_WORK | DEBUG_INFO,
+                "WebServer handling %d ports\r\n",
+                pWebServer->Entries ));
+      break;
+    }
+  }
+
+  DBG_EXIT ( );
+}
+
+
+/**
+  Process the work for the sockets.
+
+  @param [in] pWebServer    The web server control structure address.
+
+  @param [in] SocketFD      The socket's file descriptor to add to the list.
+
+  @param [in] events        everts is a bitmask of the work to be done
+
+  @param [in] pPort         The address of a WSDT_PORT structure
+
+  @retval EFI_SUCCESS       The operation was successful
+  @retval EFI_DEVICE_ERROR  Error, close the port
+
+**/
+EFI_STATUS
+PortWork (
+  IN DT_WEB_SERVER * pWebServer,
+  IN int SocketFD,
+  IN INTN events,
+  IN WSDT_PORT * pPort
+  )
+{
+  BOOLEAN bDone;
+  size_t LengthInBytes;
+  int NewSocket;
+  EFI_STATUS OpStatus;
+  struct sockaddr_in6 RemoteAddress;
+  socklen_t RemoteAddressLength;
+  EFI_STATUS Status;
+
+  DEBUG (( DEBUG_PORT_WORK, "Entering PortWork\r\n" ));
+
+  //
+  //  Assume success
+  //
+  OpStatus = EFI_SUCCESS;
+
+  //
+  //  Handle input events
+  //
+  if ( 0 != ( events & POLLRDNORM )) {
+    //
+    //  Determine if this is a connection attempt
+    //
+    if (( SocketFD == pWebServer->HttpListenPort )
+      || ( SocketFD == pWebServer->HttpListenPort6 )) {
+      //
+      //  Handle connection attempts
+      //  Accepts arrive as read events
+      //
+      RemoteAddressLength = sizeof ( RemoteAddress );
+      NewSocket = accept ( SocketFD,
+                           (struct sockaddr *)&RemoteAddress,
+                           &RemoteAddressLength );
+      if ( -1 != NewSocket ) {
+        if ( 0 != NewSocket ) {
+          //
+          //  Add this port to the list monitored by the web server
+          //
+          Status = PortAdd ( pWebServer, NewSocket );
+          if ( EFI_ERROR ( Status )) {
+            DEBUG (( DEBUG_ERROR,
+                      "ERROR - Failed to add the port 0x%08x, Status: %r\r\n",
+                      NewSocket,
+                      Status ));
+
+            //
+            //  Done with the new socket
+            //
+            close ( NewSocket );
+          }
+        }
+        else {
+          DEBUG (( DEBUG_ERROR,
+                    "ERROR - Socket not available!\r\n" ));
+        }
+
+        //
+        //  Leave the listen port open
+        //
+      }
+      else {
+        //
+        //  Listen port error
+        //  Close the listen port by returning error status
+        //
+        OpStatus = EFI_DEVICE_ERROR;
+        DEBUG (( DEBUG_ERROR,
+                  "ERROR - Failed to accept new connection, errno: 0x%08x\r\n",
+                  errno ));
+      }
+    }
+    else {
+      //
+      //  Handle the data received event
+      //
+      if ( 0 == pPort->RequestLength ) {
+        //
+        //  Receive the page request
+        //
+        pPort->RequestLength = recv ( SocketFD,
+                                      &pPort->Request[0],
+                                      DIM ( pPort->Request ),
+                                      0 );
+        if ( -1 == pPort->RequestLength ) {
+          //
+          //  Receive error detected
+          //  Close the port
+          //
+          OpStatus = EFI_DEVICE_ERROR;
+        }
+        else {
+          DEBUG (( DEBUG_REQUEST,
+                    "0x%08x: Socket - Received %d bytes of HTTP request\r\n",
+                    SocketFD,
+                    pPort->RequestLength ));
+
+          //
+          //  Process the request
+          //
+          OpStatus = HttpRequest ( SocketFD, pPort, &bDone );
+          if ( bDone ) {
+            //
+            //  Notify the upper layer to close the socket
+            //
+            OpStatus = EFI_DEVICE_ERROR;
+          }
+        }
+      }
+      else {
+        //
+        //  Receive the file data
+        //
+        LengthInBytes = recv ( SocketFD,
+                               &pPort->RxBuffer[0],
+                               DIM ( pPort->RxBuffer ),
+                               0 );
+        if ( -1 == LengthInBytes ) {
+          //
+          //  Receive error detected
+          //  Close the port
+          //
+          OpStatus = EFI_DEVICE_ERROR;
+        }
+        else {
+          DEBUG (( DEBUG_REQUEST,
+                    "0x%08x: Socket - Received %d bytes of file data\r\n",
+                    SocketFD,
+                    LengthInBytes ));
+
+          //
+          // TODO: Process the file data
+          //
+        }
+      }
+    }
+  }
+
+  //
+  //  Handle the close event
+  //
+  if ( 0 != ( events & POLLHUP )) {
+    //
+    //  Close the port
+    //
+    OpStatus = EFI_DEVICE_ERROR;
+  }
+
+  //
+  //  Return the operation status
+  //
+  DEBUG (( DEBUG_PORT_WORK,
+            "Exiting PortWork, Status: %r\r\n",
+            OpStatus ));
+  return OpStatus;
+}
+
+
+/**
+  Scan the list of sockets and process any pending work
+
+  @param [in] pWebServer    The web server control structure address.
+
+**/
+VOID
+SocketPoll (
+  IN DT_WEB_SERVER * pWebServer
+  )
+{
+  int FDCount;
+  struct pollfd * pPoll;
+  WSDT_PORT ** ppPort;
+  EFI_STATUS Status;
+
+  DEBUG (( DEBUG_SOCKET_POLL, "Entering SocketPoll\r\n" ));
+
+  //
+  //  Determine if any ports are active
+  //
+  FDCount = poll ( pWebServer->pFdList,
+                   pWebServer->Entries,
+                   CLIENT_POLL_DELAY );
+  if ( -1 == FDCount ) {
+    DEBUG (( DEBUG_ERROR | DEBUG_SOCKET_POLL,
+              "ERROR - errno: %d\r\n",
+              errno ));
+  }
+
+  pPoll = pWebServer->pFdList;
+  ppPort = pWebServer->ppPortList;
+  while ( 0 < FDCount ) {
+    //
+    //  Walk the list of ports to determine what work needs to be done
+    //
+    if ( 0 != pPoll->revents ) {
+      //
+      //  Process this port
+      //
+      Status = PortWork ( pWebServer,
+                          pPoll->fd,
+                          pPoll->revents,
+                          *ppPort );
+      pPoll->revents = 0;
+
+      //
+      //  Close the port if necessary
+      //
+      if ( EFI_ERROR ( Status )) {
+        PortRemove ( pWebServer, pPoll->fd );
+        pPoll -= 1;
+        ppPort -= 1;
+      }
+
+      //
+      //  Account for this file descriptor
+      //
+      FDCount -= 1;
+    }
+
+    //
+    //  Set the next port
+    //
+    pPoll += 1;
+    ppPort += 1;
+  }
+
+  DEBUG (( DEBUG_SOCKET_POLL, "Exiting SocketPoll\r\n" ));
+}
+
+
+/**
+  Create an HTTP port for the web server
+
+  This routine polls the network layer to create an HTTP port for the
+  web server.  More than one attempt may be necessary since it may take
+  some time to get the IP address and initialize the upper layers of
+  the network stack.
+
+  After the HTTP port is created, the socket layer will manage the
+  coming and going of the network connections until the last network
+  connection is broken.
+
+  @param [in] pWebServer    The web server control structure address.
+  @param [in] AddressFamily Address family for the network connection
+  @param [in] Protocol      Protocol to use for the network connection
+  @param [in] HttpPort      Port number for the HTTP connection
+  @param [out] pPort        Address of the port
+
+**/
+VOID
+WebServerListen (
+  IN DT_WEB_SERVER * pWebServer,
+  IN sa_family_t AddressFamily,
+  IN int Protocol,
+  IN UINT16 HttpPort,
+  OUT int * pPort
+  )
+{
+  union {
+    struct sockaddr_in v4;
+    struct sockaddr_in6 v6;
+  } WebServerAddress;
+  int SocketStatus;
+  EFI_STATUS Status;
+
+  DEBUG (( DEBUG_SERVER_LISTEN, "Entering WebServerListen\r\n" ));
+
+  //
+  //  Attempt to create the socket for the web server
+  //
+  * pPort = socket ( AddressFamily, SOCK_STREAM, Protocol );
+  if ( -1 != *pPort ) {
+    //
+    //  Build the socket address
+    //
+    ZeroMem ( &WebServerAddress, sizeof ( WebServerAddress ));
+    if ( AF_INET == AddressFamily ) {
+      WebServerAddress.v4.sin_len = sizeof ( WebServerAddress.v4 );
+      WebServerAddress.v4.sin_family = AddressFamily;
+      WebServerAddress.v4.sin_port = htons ( HttpPort );
+    }
+    else {
+      WebServerAddress.v6.sin6_len = sizeof ( WebServerAddress.v6 );
+      WebServerAddress.v6.sin6_family = AddressFamily;
+      WebServerAddress.v6.sin6_port = htons ( HttpPort );
+      WebServerAddress.v6.sin6_scope_id = __IPV6_ADDR_SCOPE_GLOBAL;
+    }
+
+    //
+    //  Bind the socket to the HTTP port
+    //
+    SocketStatus = bind ( *pPort,
+                          (struct sockaddr *) &WebServerAddress,
+                          WebServerAddress.v4.sin_len );
+    if ( -1 != SocketStatus ) {
+      //
+      //  Enable connections to the HTTP port
+      //
+      SocketStatus = listen ( *pPort, SOMAXCONN );
+      if ( -1 != SocketStatus ) {
+        //
+        //  Add the HTTP port to the list of ports to poll
+        //
+        Status = PortAdd ( pWebServer, *pPort );
+        if ( EFI_ERROR ( Status )) {
+          SocketStatus = -1;
+        }
+        else {
+          DEBUG (( DEBUG_PORT_WORK,
+                    "Listening on Tcp%d:%d\r\n",
+                    ( AF_INET == AddressFamily ) ? 4 : 6,
+                    HttpPort ));
+        }
+      }
+    }
+
+    //
+    //  Release the socket if necessary
+    //
+    if ( -1 == SocketStatus ) {
+      close ( *pPort );
+      *pPort = -1;
+    }
+  }
+
+  DEBUG (( DEBUG_SERVER_LISTEN, "Exiting WebServerListen\r\n" ));
+}
+
+
+/**
+  Entry point for the web server application.
+
+  @param [in] Argc  The number of arguments
+  @param [in] Argv  The argument value array
+
+  @retval  0        The application exited normally.
+  @retval  Other    An error occurred.
+**/
+int
+main (
+  IN int Argc,
+  IN char **Argv
+  )
+{
+  UINT16 HttpPort;
+  UINTN Index;
+  DT_WEB_SERVER * pWebServer;
+  EFI_STATUS Status;
+  UINT64 TriggerTime;
+
+  //
+  //  Get the HTTP port
+  //
+  HttpPort = PcdGet16 ( WebServer_HttpPort );
+  DEBUG (( DEBUG_HTTP_PORT,
+            "HTTP Port: %d\r\n",
+            HttpPort ));
+
+  //
+  //  Create a timer event to start HTTP port
+  //
+  pWebServer = &mWebServer;
+  Status = gBS->CreateEvent ( EVT_TIMER,
+                              TPL_WEB_SERVER,
+                              NULL,
+                              NULL,
+                              &pWebServer->TimerEvent );
+  if ( !EFI_ERROR ( Status )) {
+    TriggerTime = HTTP_PORT_POLL_DELAY * ( 1000 * 10 );
+    Status = gBS->SetTimer ( pWebServer->TimerEvent,
+                             TimerPeriodic,
+                             TriggerTime );
+    if ( !EFI_ERROR ( Status )) {
+      //
+      //  Run the web server forever
+      //
+      pWebServer->HttpListenPort = -1;
+      pWebServer->HttpListenPort6 = -1;
+      pWebServer->bRunning = TRUE;
+      do {
+        //
+        //  Poll the network layer to create the HTTP port
+        //  for the web server.  More than one attempt may
+        //  be necessary since it may take some time to get
+        //  the IP address and initialize the upper layers
+        //  of the network stack.
+        //
+        if (( -1 == pWebServer->HttpListenPort )
+          || ( -1 == pWebServer->HttpListenPort6 )) {
+          do {
+            //
+            //  Wait a while before polling for a connection
+            //
+            if ( EFI_SUCCESS != gBS->CheckEvent ( pWebServer->TimerEvent )) {
+              if ( 0 != pWebServer->Entries ) {
+                  break;
+              }
+              gBS->WaitForEvent ( 1, &pWebServer->TimerEvent, &Index );
+            }
+
+            //
+            //  Poll for a network connection
+            //
+            if ( -1 == pWebServer->HttpListenPort ) {
+              WebServerListen ( pWebServer,
+                                AF_INET,
+                                IPPROTO_TCP,
+                                HttpPort,
+                                &pWebServer->HttpListenPort );
+            }
+            if ( -1 == pWebServer->HttpListenPort6 ) {
+              WebServerListen ( pWebServer,
+                                AF_INET6,
+                                IPPROTO_TCP,
+                                HttpPort,
+                                &pWebServer->HttpListenPort6 );
+            }
+
+            //
+            //  Continue polling while both network connections are
+            //  not present
+            //
+          } while ( 0 == pWebServer->Entries );
+        }
+
+        //
+        //  Poll the sockets for activity while both network
+        //  connections are connected
+        //
+        do {
+          SocketPoll ( pWebServer );
+        } while ( pWebServer->bRunning
+                && ( -1 != pWebServer->HttpListenPort )
+                && ( -1 != pWebServer->HttpListenPort6 ));
+
+        //
+        //  Continue polling the network connections until both
+        //  TCP4 and TCP6 are connected
+        //
+      } while ( pWebServer->bRunning );
+
+      //
+      //  Stop the timer
+      //
+      gBS->SetTimer ( pWebServer->TimerEvent,
+                      TimerCancel,
+                      0 );
+    }
+
+    //
+    //  Done with the timer event
+    //
+    gBS->CloseEvent ( pWebServer->TimerEvent );
+  }
+
+  //
+  //  Return the final status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/WebServer.h b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/WebServer.h
new file mode 100644
index 0000000..16c30c8
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/WebServer.h
@@ -0,0 +1,1310 @@
+/** @file

+  Definitions for the web server.

+

+  Copyright (c) 2011-2012, Intel Corporation

+  All rights reserved. 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.php

+

+  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 _WEB_SERVER_H_

+#define _WEB_SERVER_H_

+

+#include <errno.h>

+#include <Uefi.h>

+

+#include <Guid/EventGroup.h>

+

+#include <Library/BaseMemoryLib.h>

+#include <Library/DebugLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/PcdLib.h>

+#include <Library/UefiApplicationEntryPoint.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/UefiLib.h>

+#include <Protocol/BlockIo.h>

+

+#include <netinet/in.h>

+

+#include <sys/EfiSysCall.h>

+#include <sys/poll.h>

+#include <sys/socket.h>

+

+#if defined(_MSC_VER)   //  Handle Microsoft VC++ compiler specifics.

+#pragma warning ( disable : 4054 )

+#pragma warning ( disable : 4152 )

+#endif  //  defined(_MSC_VER)

+

+//------------------------------------------------------------------------------

+//  Pages

+//------------------------------------------------------------------------------

+

+#define PAGE_ACPI_APIC                  L"/APIC"

+#define PAGE_ACPI_BGRT                  L"/BGRT"

+#define PAGE_ACPI_DSDT                  L"/DSDT"

+#define PAGE_ACPI_FADT                  L"/FADT"

+#define PAGE_ACPI_HPET                  L"/HPET"

+#define PAGE_ACPI_MCFG                  L"/MCFG"

+#define PAGE_ACPI_RSDP_10B              L"/RSDP1.0b"

+#define PAGE_ACPI_RSDP_30               L"/RSDP3.0"

+#define PAGE_ACPI_RSDT                  L"/RSDT"

+#define PAGE_ACPI_SSDT                  L"/SSDT"

+#define PAGE_ACPI_TCPA                  L"/TCPA"

+#define PAGE_ACPI_UEFI                  L"/UEFI"

+#define PAGE_BOOT_SERVICES_TABLE        L"/BootServicesTable"

+#define PAGE_CONFIGURATION_TABLE        L"/ConfigurationTable"

+#define PAGE_DXE_SERVICES_TABLE         L"/DxeServicesTable"

+#define PAGE_RUNTIME_SERVICES_TABLE     L"/RuntimeServicesTable"

+

+//------------------------------------------------------------------------------

+//  Signatures

+//------------------------------------------------------------------------------

+

+#define APIC_SIGNATURE        0x43495041

+#define BGRT_SIGNATURE        0x54524742

+#define DSDT_SIGNATURE        0x54445344

+#define FADT_SIGNATURE        0x50434146

+#define HPET_SIGNATURE        0x54455048

+#define MCFG_SIGNATURE        0x4746434d

+#define SSDT_SIGNATURE        0x54445353

+#define TCPA_SIGNATURE        0x41504354

+#define UEFI_SIGNATURE        0x49464555

+

+//------------------------------------------------------------------------------

+//  Macros

+//------------------------------------------------------------------------------

+

+#if defined(_MSC_VER)           /* Handle Microsoft VC++ compiler specifics. */

+#define DBG_ENTER()             DEBUG (( DEBUG_INFO, "Entering " __FUNCTION__ "\n" )) ///<  Display routine entry

+#define DBG_EXIT()              DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ "\n" ))  ///<  Display routine exit

+#define DBG_EXIT_DEC(Status)    DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ ", Status: %d\n", Status ))      ///<  Display routine exit with decimal value

+#define DBG_EXIT_HEX(Status)    DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ ", Status: 0x%08x\n", Status ))  ///<  Display routine exit with hex value

+#define DBG_EXIT_STATUS(Status) DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ ", Status: %r\n", Status ))      ///<  Display routine exit with status value

+#define DBG_EXIT_TF(Status)     DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ ", returning %s\n", (FALSE == Status) ? L"FALSE" : L"TRUE" ))  ///<  Display routine with TRUE/FALSE value

+#else   //  _MSC_VER

+#define DBG_ENTER()

+#define DBG_EXIT()

+#define DBG_EXIT_DEC(Status)

+#define DBG_EXIT_HEX(Status)

+#define DBG_EXIT_STATUS(Status)

+#define DBG_EXIT_TF(Status)

+#endif  //  _MSC_VER

+

+#define DIM(x)    ( sizeof ( x ) / sizeof ( x[0] ))   ///<  Compute the number of entries in an array

+

+//------------------------------------------------------------------------------

+//  Constants

+//------------------------------------------------------------------------------

+

+#define DEBUG_SOCKET_POLL       0x00080000  ///<  Display the socket poll messages

+#define DEBUG_PORT_WORK         0x00040000  ///<  Display the port work messages

+#define DEBUG_SERVER_LISTEN     0x00020000  ///<  Display the socket poll messages

+#define DEBUG_HTTP_PORT         0x00010000  ///<  Display HTTP port related messages

+#define DEBUG_REQUEST           0x00008000  ///<  Display the HTTP request messages

+

+#define HTTP_PORT_POLL_DELAY  ( 2 * 1000 )  ///<  Delay in milliseconds for attempts to open the HTTP port

+#define CLIENT_POLL_DELAY     50            ///<  Delay in milliseconds between client polls

+

+#define TPL_WEB_SERVER        TPL_CALLBACK  ///<  TPL for routine synchronization

+

+/**

+  Verify new TPL value

+

+  This macro which is enabled when debug is enabled verifies that

+  the new TPL value is >= the current TPL value.

+**/

+#ifdef VERIFY_TPL

+#undef VERIFY_TPL

+#endif  //  VERIFY_TPL

+

+#if !defined(MDEPKG_NDEBUG)

+

+#define VERIFY_TPL(tpl)                           \

+{                                                 \

+  EFI_TPL PreviousTpl;                            \

+                                                  \

+  PreviousTpl = gBS->RaiseTPL ( TPL_HIGH_LEVEL ); \

+  gBS->RestoreTPL ( PreviousTpl );                \

+  if ( PreviousTpl > tpl ) {                      \

+    DEBUG (( DEBUG_ERROR, "Current TPL: %d, New TPL: %d\r\n", PreviousTpl, tpl ));  \

+    ASSERT ( PreviousTpl <= tpl );                \

+  }                                               \

+}

+

+#else   //  MDEPKG_NDEBUG

+

+#define VERIFY_TPL(tpl)

+

+#endif  //  MDEPKG_NDEBUG

+

+#define WEB_SERVER_SIGNATURE        SIGNATURE_32 ('W','e','b','S')  ///<  DT_WEB_SERVER memory signature

+

+#define SPACES_ADDRESS_TO_DATA      2

+#define BYTES_ON_A_LINE             16

+#define SPACES_BETWEEN_BYTES        1

+#define SPACES_DATA_TO_ASCII        2

+

+

+//------------------------------------------------------------------------------

+// Protocol Declarations

+//------------------------------------------------------------------------------

+

+extern EFI_COMPONENT_NAME_PROTOCOL gComponentName;    ///<  Component name protocol declaration

+extern EFI_COMPONENT_NAME2_PROTOCOL gComponentName2;  ///<  Component name 2 protocol declaration

+extern EFI_DRIVER_BINDING_PROTOCOL gDriverBinding;    ///<  Driver binding protocol declaration

+

+//------------------------------------------------------------------------------

+//  Data Types

+//------------------------------------------------------------------------------

+

+/**

+  Port control structure

+**/

+typedef struct {

+  //

+  //  Buffer management

+  //

+  size_t    RequestLength;      ///<  Request length in bytes

+  size_t    TxBytes;            ///<  Bytes in the TX buffer

+  UINT8     Request[ 65536 ];   ///<  Page request

+  UINT8     RxBuffer[ 65536 ];  ///<  Receive buffer

+  UINT8     TxBuffer[ 65536 ];  ///<  Transmit buffer

+} WSDT_PORT;

+

+/**

+  Web server control structure

+**/

+typedef struct {

+  UINTN Signature;              ///<  Structure identification

+

+  //

+  //  Image attributes

+  //

+  EFI_HANDLE ImageHandle;       ///<  Image handle

+

+  //

+  //  HTTP port management

+  //

+  BOOLEAN   bRunning;           ///<  Web server running

+  EFI_EVENT TimerEvent;         ///<  Timer to open HTTP port

+  int       HttpListenPort;     ///<  File descriptor for the HTTP listen port over TCP4

+  int       HttpListenPort6;    ///<  File descriptor for the HTTP listen port over TCP6

+

+  //

+  //  Client port management

+  //

+  nfds_t    MaxEntries;         ///<  Maximum entries in the PortList array

+  nfds_t    Entries;            ///<  The current number of entries in the PortList array

+  struct pollfd * pFdList;      ///<  List of socket file descriptors

+  WSDT_PORT ** ppPortList;      ///<  List of port management structures

+} DT_WEB_SERVER;

+

+//#define SERVER_FROM_SERVICE(a) CR (a, DT_WEB_SERVER, ServiceBinding, WEB_SERVER_SIGNATURE)  ///< Locate DT_LAYER from service binding

+

+extern DT_WEB_SERVER mWebServer;

+

+/**

+  Process an HTTP request

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+typedef

+EFI_STATUS

+(* PFN_RESPONSE) (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN BOOLEAN * pbDone

+  );

+

+/**

+  Data structure to delcare page support routines

+**/

+typedef struct {

+  UINT16 * pPageName;         ///<  Name of the page

+  PFN_RESPONSE pfnResponse;   ///<  Routine to generate the response

+  UINT16 * pDescription;      ///<  Description of the page

+} DT_PAGE;

+

+extern CONST DT_PAGE mPageList[];   ///<  List of pages

+extern CONST UINTN mPageCount;      ///<  Number of pages

+

+//------------------------------------------------------------------------------

+// Web Pages

+//------------------------------------------------------------------------------

+

+/**

+  Respond with the APIC table

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+AcpiApicPage (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  );

+

+/**

+  Respond with the BGRT table

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+AcpiBgrtPage (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  );

+

+/**

+  Respond with the ACPI DSDT table

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+AcpiDsdtPage (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  );

+

+/**

+  Respond with the ACPI FADT table

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+AcpiFadtPage (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  );

+

+/**

+  Respond with the HPET table

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+AcpiHpetPage (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  );

+

+/**

+  Respond with the MCFG table

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+AcpiMcfgPage (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  );

+

+/**

+  Respond with the ACPI RSDP 1.0b table

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+AcpiRsdp10Page (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  );

+

+/**

+  Respond with the ACPI RSDP 3.0 table

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+AcpiRsdp30Page (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  );

+

+/**

+  Respond with the ACPI RSDT table

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+AcpiRsdtPage (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  );

+

+/**

+  Respond with the SSDT table

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+AcpiSsdtPage (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  );

+

+/**

+  Respond with the TCPA table

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+AcpiTcpaPage (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  );

+

+/**

+  Respond with the UEFI table

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+AcpiUefiPage (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  );

+

+/**

+  Respond with the boot services table

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+BootServicesTablePage (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  );

+

+/**

+  Respond with the configuration tables

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+ConfigurationTablePage (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  );

+

+/**

+  Respond with the DHCP options

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+DhcpOptionsPage (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  );

+

+/**

+  Respond with the DXE services table

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+DxeServicesTablePage (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  );

+

+/**

+  Respond with the Exit page

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+ExitPage (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  );

+

+/**

+  Respond with the firmware status

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+FirmwarePage (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  );

+

+/**

+  Respond with the handles in the system

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+HandlePage (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  );

+

+/**

+  Respond with the Hello World page

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+HelloPage (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  );

+

+/**

+  Respond with the list of known pages

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+IndexPage (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  );

+

+/**

+  Page to display the memory map

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+MemoryMapPage (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  );

+

+/**

+  Display the memory type registers

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+MemoryTypeRegistersPage (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  );

+

+/**

+  Respond with the Ports page

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+PortsPage (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  );

+

+/**

+  Page to reboot the system

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+RebootPage (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  );

+

+/**

+  Respond with the runtime services table

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+RuntimeSservicesTablePage (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  );

+

+/**

+  Respond with the system table

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+SystemTablePage (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN * pbDone

+  );

+

+//------------------------------------------------------------------------------

+// Support routines

+//------------------------------------------------------------------------------

+

+/**

+  Display the EFI Table Header

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [in] pHeader       Address of the EFI_TABLE_HEADER structure

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+EfiTableHeader (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN EFI_TABLE_HEADER * pHeader

+  );

+

+/**

+  Buffer the HTTP page header

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [in] pTitle        A zero terminated Unicode title string

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+HttpPageHeader (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN CONST CHAR16 * pTitle

+  );

+

+/**

+  Buffer and send the HTTP page trailer

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+HttpPageTrailer (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN BOOLEAN * pbDone

+  );

+

+/**

+  Process an HTTP request

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+HttpRequest (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN BOOLEAN * pbDone

+  );

+

+/**

+  Buffer data for sending

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [in] LengthInBytes Length of valid data in the buffer

+  @param [in] pBuffer       Buffer of data to send

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+HttpSend (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN size_t LengthInBytes,

+  IN CONST UINT8 * pBuffer

+  );

+

+/**

+  Send an ANSI string

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [in] pString       A zero terminated Unicode string

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+HttpSendAnsiString (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN CONST char * pString

+  );

+

+/**

+  Buffer a single byte

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [in] Data          The data byte to send

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+HttpSendByte (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN UINT8 Data

+  );

+

+/**

+  Display a character

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [in] Character     Character to display

+  @param [in] pReplacement  Replacement character string

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+HttpSendCharacter (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN CHAR8 Character,

+  IN CHAR8 * pReplacement

+  );

+

+/**

+  Send a buffer dump

+  

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [in] ByteCount     The number of bytes to display

+  @param [in] pData         Address of the byte array

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+HttpSendDump (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN UINTN ByteCount,

+  IN CONST UINT8 * pData

+  );

+

+/**

+  Display a row containing a GUID value

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [in] pGuid         Address of the GUID to display

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+HttpSendGuid (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN CONST EFI_GUID * pGuid

+  );

+

+/**

+  Output a hex value to the HTML page

+

+  @param [in] SocketFD    Socket file descriptor

+  @param [in] pPort       The WSDT_PORT structure address

+  @param [in] Bits        Number of bits to display

+  @param [in] Value       Value to display

+

+  @retval EFI_SUCCESS Successfully displayed the address

+**/

+EFI_STATUS

+HttpSendHexBits (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN INT32 Bits,

+  IN UINT64 Value

+  );

+

+/**

+  Output a hex value to the HTML page

+

+  @param [in] SocketFD    Socket file descriptor

+  @param [in] pPort       The WSDT_PORT structure address

+  @param [in] Value       Value to display

+

+  @retval EFI_SUCCESS Successfully displayed the address

+**/

+EFI_STATUS

+HttpSendHexValue (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN UINT64 Value

+  );

+

+/**

+  Output an IP address to the HTML page

+

+  @param [in] SocketFD    Socket file descriptor

+  @param [in] pPort       The WSDT_PORT structure address

+  @param [in] pAddress    Address of the socket address

+

+  @retval EFI_SUCCESS Successfully displayed the address

+**/

+EFI_STATUS

+HttpSendIpAddress (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN struct sockaddr_in6 * pAddress

+  );

+

+/**

+  Send a Unicode string

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [in] pString       A zero terminated Unicode string

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+HttpSendUnicodeString (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN CONST UINT16 * pString

+  );

+

+/**

+  Output a value to the HTML page

+

+  @param [in] SocketFD    Socket file descriptor

+  @param [in] pPort       The WSDT_PORT structure address

+  @param [in] Value       Value to display

+

+  @retval EFI_SUCCESS Successfully displayed the address

+**/

+EFI_STATUS

+HttpSendValue (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN UINT64 Value

+  );

+

+/**

+  Display a row containing a decimal value

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [in] pName         Address of a zero terminated name string

+  @param [in] Value         The value to display

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+RowDecimalValue (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN CONST CHAR8 * pName,

+  IN UINT64 Value

+  );

+

+/**

+  Display a row containing a GUID value

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [in] pName         Address of a zero terminated name string

+  @param [in] pGuid         Address of the GUID to display

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+RowGuid (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN CONST CHAR8 * pName,

+  IN CONST EFI_GUID * pGuid

+  );

+

+/**

+  Display a row containing a hex value

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [in] pName         Address of a zero terminated name string

+  @param [in] Value         The value to display

+  @param [in] pWebPage      Address of a zero terminated web page name

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+RowHexValue (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN CONST CHAR8 * pName,

+  IN UINT64 Value,

+  IN CONST CHAR16 * pWebPage

+  );

+

+/**

+  Display a row containing a pointer

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [in] pName         Address of a zero terminated name string

+  @param [in] pAddress      The address to display

+  @param [in] pWebPage      Address of a zero terminated web page name

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+RowPointer (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN CONST CHAR8 * pName,

+  IN CONST VOID * pAddress,

+  IN CONST CHAR16 * pWebPage

+  );

+

+/**

+  Display a row containing a revision

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [in] pName         Address of a zero terminated name string

+  @param [in] Revision      The revision to display

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+RowRevision (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN CONST CHAR8 * pName,

+  IN UINT32 Revision

+  );

+

+/**

+  Display a row containing a unicode string

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [in] pName         Address of a zero terminated name string

+  @param [in] pString       Address of a zero terminated unicode string

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+RowUnicodeString (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN CONST CHAR8 * pName,

+  IN CONST CHAR16 * pString

+  );

+

+/**

+  Start the table page

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [in] pName         Address of a zero terminated name string

+  @param [in] pTable        Address of the table

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+TableHeader (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  IN CONST CHAR16 * pName,

+  IN CONST VOID * pTable

+  );

+

+/**

+  End the table page

+

+  @param [in] SocketFD      The socket's file descriptor to add to the list.

+  @param [in] pPort         The WSDT_PORT structure address

+  @param [out] pbDone       Address to receive the request completion status

+

+  @retval EFI_SUCCESS       The request was successfully processed

+

+**/

+EFI_STATUS

+TableTrailer (

+  IN int SocketFD,

+  IN WSDT_PORT * pPort,

+  OUT BOOLEAN *pbDone

+  );

+

+/**

+  HTTP port creation timer routine

+

+  This routine polls the socket layer waiting for the initial network connection

+  which will enable the creation of the HTTP port.  The socket layer will manage

+  the coming and going of the network connections after that until the last network

+  connection is broken.

+

+  @param [in] pWebServer  The web server control structure address.

+

+**/

+VOID

+WebServerTimer (

+  IN DT_WEB_SERVER * pWebServer

+  );

+

+/**

+  Start the web server port creation timer

+

+  @param [in] pWebServer  The web server control structure address.

+

+  @retval EFI_SUCCESS         The timer was successfully started.

+  @retval EFI_ALREADY_STARTED The timer is already running.

+  @retval Other               The timer failed to start.

+

+**/

+EFI_STATUS

+WebServerTimerStart (

+  IN DT_WEB_SERVER * pWebServer

+  );

+

+/**

+  Stop the web server port creation timer

+

+  @param [in] pWebServer  The web server control structure address.

+

+  @retval EFI_SUCCESS   The HTTP port timer is stopped

+  @retval Other         Failed to stop the HTTP port timer

+

+**/

+EFI_STATUS

+WebServerTimerStop (

+  IN DT_WEB_SERVER * pWebServer

+  );

+

+//------------------------------------------------------------------------------

+// Driver Binding Protocol Support

+//------------------------------------------------------------------------------

+

+/**

+  Stop this driver on Controller by removing NetworkInterfaceIdentifier protocol and

+  closing the DevicePath and PciIo protocols on Controller.

+

+  @param [in] pThis                Protocol instance pointer.

+  @param [in] Controller           Handle of device to stop driver on.

+  @param [in] NumberOfChildren     How many children need to be stopped.

+  @param [in] pChildHandleBuffer   Not used.

+

+  @retval EFI_SUCCESS          This driver is removed Controller.

+  @retval EFI_DEVICE_ERROR     The device could not be stopped due to a device error.

+  @retval other                This driver was not removed from this device.

+

+**/

+EFI_STATUS

+EFIAPI

+DriverStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL * pThis,

+  IN  EFI_HANDLE Controller,

+  IN  UINTN NumberOfChildren,

+  IN  EFI_HANDLE * pChildHandleBuffer

+  );

+

+//------------------------------------------------------------------------------

+// EFI Component Name Protocol Support

+//------------------------------------------------------------------------------

+

+/**

+  Retrieves a Unicode string that is the user readable name of the driver.

+

+  This function retrieves the user readable name of a driver in the form of a

+  Unicode string. If the driver specified by This has a user readable name in

+  the language specified by Language, then a pointer to the driver name is

+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified

+  by This does not support the language specified by Language,

+  then EFI_UNSUPPORTED is returned.

+

+  @param [in] pThis             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or

+                                EFI_COMPONENT_NAME_PROTOCOL instance.

+  @param [in] pLanguage         A pointer to a Null-terminated ASCII string

+                                array indicating the language. This is the

+                                language of the driver name that the caller is

+                                requesting, and it must match one of the

+                                languages specified in SupportedLanguages. The

+                                number of languages supported by a driver is up

+                                to the driver writer. Language is specified

+                                in RFC 3066 or ISO 639-2 language code format.

+  @param [out] ppDriverName     A pointer to the Unicode string to return.

+                                This Unicode string is the name of the

+                                driver specified by This in the language

+                                specified by Language.

+

+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by

+                                This and the language specified by Language was

+                                returned in DriverName.

+  @retval EFI_INVALID_PARAMETER Language is NULL.

+  @retval EFI_INVALID_PARAMETER DriverName is NULL.

+  @retval EFI_UNSUPPORTED       The driver specified by This does not support

+                                the language specified by Language.

+

+**/

+EFI_STATUS

+EFIAPI

+GetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL * pThis,

+  IN  CHAR8 * pLanguage,

+  OUT CHAR16 ** ppDriverName

+  );

+

+

+/**

+  Retrieves a Unicode string that is the user readable name of the controller

+  that is being managed by a driver.

+

+  This function retrieves the user readable name of the controller specified by

+  ControllerHandle and ChildHandle in the form of a Unicode string. If the

+  driver specified by This has a user readable name in the language specified by

+  Language, then a pointer to the controller name is returned in ControllerName,

+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently

+  managing the controller specified by ControllerHandle and ChildHandle,

+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not

+  support the language specified by Language, then EFI_UNSUPPORTED is returned.

+

+  @param [in] pThis             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or

+                                EFI_COMPONENT_NAME_PROTOCOL instance.

+  @param [in] ControllerHandle  The handle of a controller that the driver

+                                specified by This is managing.  This handle

+                                specifies the controller whose name is to be

+                                returned.

+  @param [in] ChildHandle       The handle of the child controller to retrieve

+                                the name of.  This is an optional parameter that

+                                may be NULL.  It will be NULL for device

+                                drivers.  It will also be NULL for a bus drivers

+                                that wish to retrieve the name of the bus

+                                controller.  It will not be NULL for a bus

+                                driver that wishes to retrieve the name of a

+                                child controller.

+  @param [in] pLanguage         A pointer to a Null-terminated ASCII string

+                                array indicating the language.  This is the

+                                language of the driver name that the caller is

+                                requesting, and it must match one of the

+                                languages specified in SupportedLanguages. The

+                                number of languages supported by a driver is up

+                                to the driver writer. Language is specified in

+                                RFC 3066 or ISO 639-2 language code format.

+  @param [out] ppControllerName A pointer to the Unicode string to return.

+                                This Unicode string is the name of the

+                                controller specified by ControllerHandle and

+                                ChildHandle in the language specified by

+                                Language from the point of view of the driver

+                                specified by This.

+

+  @retval EFI_SUCCESS           The Unicode string for the user readable name in

+                                the language specified by Language for the

+                                driver specified by This was returned in

+                                DriverName.

+  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.

+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid

+                                EFI_HANDLE.

+  @retval EFI_INVALID_PARAMETER Language is NULL.

+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.

+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently

+                                managing the controller specified by

+                                ControllerHandle and ChildHandle.

+  @retval EFI_UNSUPPORTED       The driver specified by This does not support

+                                the language specified by Language.

+

+**/

+EFI_STATUS

+EFIAPI

+GetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL * pThis,

+  IN  EFI_HANDLE ControllerHandle,

+  IN OPTIONAL EFI_HANDLE ChildHandle,

+  IN  CHAR8 * pLanguage,

+  OUT CHAR16 ** ppControllerName

+  );

+

+//------------------------------------------------------------------------------

+

+#endif  //  _WEB_SERVER_H_

diff --git a/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/WebServer.inf b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/WebServer.inf
new file mode 100644
index 0000000..27faefb
--- /dev/null
+++ b/uefi/linaro-edk2/AppPkg/Applications/Sockets/WebServer/WebServer.inf
@@ -0,0 +1,113 @@
+## @file

+#  Web Server Application

+#

+#  Copyright (c) 2011-2012, Intel Corporation

+#  All rights reserved. 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.php

+#

+#  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                    = 0x00010005

+  BASE_NAME                      = WebServer

+  FILE_GUID                      = 99E87DCF-6162-40c5-9FA1-32111F5197F7

+  MODULE_TYPE                    = UEFI_APPLICATION

+  VERSION_STRING                 = 1.0

+  ENTRY_POINT                    = ShellCEntryLib

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  ACPI.c

+  BootServicesTable.c

+  ConfigurationTable.c

+  DhcpOptions.c

+  DxeServicesTable.c

+  Exit.c

+  Firmware.c

+  Handles.c

+  Hello.c

+  HTTP.c

+  Index.c

+  MemoryMap.c

+  PageList.c

+  Ports.c

+  Reboot.c

+  RuntimeServicesTable.c

+  SystemTable.c

+  WebServer.c

+

+[Sources.IA32]

+  Mtrr.c

+

+[Sources.X64]

+  Mtrr.c

+

+

+[Pcd]

+  gAppPkgTokenSpaceGuid.WebServer_HttpPort

+

+[Packages]

+  AppPkg/AppPkg.dec

+  MdePkg/MdePkg.dec

+  MdeModulePkg/MdeModulePkg.dec

+  ShellPkg/ShellPkg.dec

+  StdLib/StdLib.dec

+

+[Packages.IA32]

+  UefiCpuPkg/UefiCpuPkg.dec

+

+[Packages.X64]

+  UefiCpuPkg/UefiCpuPkg.dec

+

+

+[LibraryClasses]

+  BaseMemoryLib

+  BsdSocketLib

+  DebugLib

+  DevMedia

+  DxeServicesTableLib

+  EfiSocketLib

+  LibC

+  ShellLib

+  ShellCEntryLib

+  UefiBootServicesTableLib

+  UefiLib

+  UefiRuntimeServicesTableLib

+#  UseSocketDxe

+

+[LibraryClasses.IA32]

+  MtrrLib

+

+[LibraryClasses.X64]

+  MtrrLib

+

+

+[Guids]

+  gEfiAcpi10TableGuid

+  gEfiAcpiTableGuid

+  gEfiDebugImageInfoTableGuid

+  gEfiDxeServicesTableGuid

+  gEfiHobListGuid

+  gEfiMemoryTypeInformationGuid

+  gLoadFixedAddressConfigurationTableGuid

+

+[Protocols]

+  gEfiDhcp4ServiceBindingProtocolGuid           # PROTOCOL ALWAYS_CONSUMED

+  gEfiDhcp4ProtocolGuid                         # PROTOCOL ALWAYS_CONSUMED

+

+[BuildOptions]

+  INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186

+   MSFT:*_*_*_CC_FLAGS = /Od

+    GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable

+