/**
@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;
}