summaryrefslogtreecommitdiff
path: root/AppPkg/Applications/Sockets/WebServer/Mtrr.c
diff options
context:
space:
mode:
Diffstat (limited to 'AppPkg/Applications/Sockets/WebServer/Mtrr.c')
-rw-r--r--AppPkg/Applications/Sockets/WebServer/Mtrr.c825
1 files changed, 825 insertions, 0 deletions
diff --git a/AppPkg/Applications/Sockets/WebServer/Mtrr.c b/AppPkg/Applications/Sockets/WebServer/Mtrr.c
new file mode 100644
index 0000000000..92f90b0ae0
--- /dev/null
+++ b/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;
+}