]> git.proxmox.com Git - mirror_edk2.git/blobdiff - AppPkg/Applications/Sockets/WebServer/Mtrr.c
Update the license dates
[mirror_edk2.git] / AppPkg / Applications / Sockets / WebServer / Mtrr.c
diff --git a/AppPkg/Applications/Sockets/WebServer/Mtrr.c b/AppPkg/Applications/Sockets/WebServer/Mtrr.c
new file mode 100644 (file)
index 0000000..92f90b0
--- /dev/null
@@ -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;
+}