1 /** 2 @file 3 Display the memory map 4 5 Copyright (c) 2012, Intel Corporation 6 All rights reserved. This program and the accompanying materials 7 are licensed and made available under the terms and conditions of the BSD License 8 which accompanies this distribution. The full text of the license may be found at 9 http://opensource.org/licenses/bsd-license.php 10 11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13 14 **/ 15 16 #include <WebServer.h> 17 #include <PiDxe.h> 18 #include <Library/DxeServicesTableLib.h> 19 20 21 CONST char * mpMemoryType[ ] = { 22 "Non-existent", 23 "Reserved", 24 "System Memory", 25 "Memory Mapped I/O" 26 }; 27 28 29 /** 30 Page to display the memory map 31 32 @param [in] SocketFD The socket's file descriptor to add to the list. 33 @param [in] pPort The WSDT_PORT structure address 34 @param [out] pbDone Address to receive the request completion status 35 36 @retval EFI_SUCCESS The request was successfully processed 37 38 **/ 39 EFI_STATUS 40 MemoryMapPage ( 41 IN int SocketFD, 42 IN WSDT_PORT * pPort, 43 OUT BOOLEAN * pbDone 44 ) 45 { 46 UINT64 Attributes; 47 BOOLEAN bSomethingDisplayed; 48 UINTN Count; 49 EFI_GCD_MEMORY_SPACE_DESCRIPTOR * pMemoryEnd; 50 EFI_GCD_MEMORY_SPACE_DESCRIPTOR * pMemoryDescriptor; 51 EFI_GCD_MEMORY_SPACE_DESCRIPTOR * pMemoryDescriptorStart; 52 EFI_STATUS Status; 53 54 DBG_ENTER ( ); 55 56 // 57 // Send the memory map page 58 // 59 pMemoryDescriptorStart = NULL; 60 for ( ; ; ) { 61 // 62 // Send the page header 63 // 64 Status = HttpPageHeader ( SocketFD, pPort, L"Memory Map" ); 65 if ( EFI_ERROR ( Status )) { 66 break; 67 } 68 69 // 70 // Start the table 71 // 72 Status = HttpSendAnsiString ( SocketFD, 73 pPort, 74 "<h1>Memory Map</h1>\r\n" 75 "<table>\r\n" 76 " <tr><th align=\"right\">Type</th><th align=\"right\">Start</th><th align=\"right\">End</th><th align=\"right\">Attributes</th></tr>\r\n" ); 77 if ( EFI_ERROR ( Status )) { 78 break; 79 } 80 81 // 82 // Get the memory map 83 // 84 Status = gDS->GetMemorySpaceMap ( &Count, 85 &pMemoryDescriptor ); 86 if ( !EFI_ERROR ( Status )) { 87 pMemoryDescriptorStart = pMemoryDescriptor; 88 pMemoryEnd = &pMemoryDescriptor[ Count ]; 89 while ( pMemoryEnd > pMemoryDescriptor ) { 90 // 91 // Display the type 92 // 93 Status = HttpSendAnsiString ( SocketFD, pPort, "<tr><td align=\"right\"><code>" ); 94 if ( EFI_ERROR ( Status )) { 95 break; 96 } 97 if ( DIM ( mpMemoryType ) > pMemoryDescriptor->GcdMemoryType ) { 98 Status = HttpSendAnsiString ( SocketFD, 99 pPort, 100 mpMemoryType[ pMemoryDescriptor->GcdMemoryType ]); 101 } 102 else { 103 Status = HttpSendValue ( SocketFD, 104 pPort, 105 pMemoryDescriptor->GcdMemoryType ); 106 } 107 if ( EFI_ERROR ( Status )) { 108 break; 109 } 110 111 // 112 // Display the start address 113 // 114 Status = HttpSendAnsiString ( SocketFD, pPort, "</code></td><td align=\"right\"><code>0x" ); 115 if ( EFI_ERROR ( Status )) { 116 break; 117 } 118 Status = HttpSendHexValue ( SocketFD, 119 pPort, 120 pMemoryDescriptor->BaseAddress ); 121 if ( EFI_ERROR ( Status )) { 122 break; 123 } 124 125 // 126 // Display the end address 127 // 128 Status = HttpSendAnsiString ( SocketFD, pPort, "</code></td><td align=\"right\"><code>0x" ); 129 if ( EFI_ERROR ( Status )) { 130 break; 131 } 132 Status = HttpSendHexValue ( SocketFD, 133 pPort, 134 pMemoryDescriptor->BaseAddress 135 + pMemoryDescriptor->Length 136 - 1 ); 137 if ( EFI_ERROR ( Status )) { 138 break; 139 } 140 141 // 142 // Display the attributes 143 // 144 Status = HttpSendAnsiString ( SocketFD, pPort, "</code></td><td align=\"right\"><code>0x" ); 145 if ( EFI_ERROR ( Status )) { 146 break; 147 } 148 Status = HttpSendHexValue ( SocketFD, 149 pPort, 150 pMemoryDescriptor->Attributes ); 151 if ( EFI_ERROR ( Status )) { 152 break; 153 } 154 155 // 156 // Decode the attributes 157 // 158 Status = HttpSendAnsiString ( SocketFD, pPort, "</code></td><td>" ); 159 if ( EFI_ERROR ( Status )) { 160 break; 161 } 162 bSomethingDisplayed = FALSE; 163 Attributes = pMemoryDescriptor->Attributes; 164 165 if ( 0 != ( Attributes & EFI_MEMORY_RUNTIME )) { 166 bSomethingDisplayed = TRUE; 167 Status = HttpSendAnsiString ( SocketFD, 168 pPort, 169 "Runtime" ); 170 if ( EFI_ERROR ( Status )) { 171 break; 172 } 173 } 174 175 if ( 0 != ( Attributes & EFI_MEMORY_XP )) { 176 if ( bSomethingDisplayed ) { 177 Status = HttpSendAnsiString ( SocketFD, 178 pPort, 179 ", " ); 180 if ( EFI_ERROR ( Status )) { 181 break; 182 } 183 } 184 bSomethingDisplayed = TRUE; 185 Status = HttpSendAnsiString ( SocketFD, 186 pPort, 187 "No Execute" ); 188 if ( EFI_ERROR ( Status )) { 189 break; 190 } 191 } 192 193 if ( 0 != ( Attributes & EFI_MEMORY_RP )) { 194 if ( bSomethingDisplayed ) { 195 Status = HttpSendAnsiString ( SocketFD, 196 pPort, 197 ", " ); 198 if ( EFI_ERROR ( Status )) { 199 break; 200 } 201 } 202 bSomethingDisplayed = TRUE; 203 Status = HttpSendAnsiString ( SocketFD, 204 pPort, 205 "No Read" ); 206 if ( EFI_ERROR ( Status )) { 207 break; 208 } 209 } 210 211 if ( 0 != ( Attributes & EFI_MEMORY_WP )) { 212 if ( bSomethingDisplayed ) { 213 Status = HttpSendAnsiString ( SocketFD, 214 pPort, 215 ", " ); 216 if ( EFI_ERROR ( Status )) { 217 break; 218 } 219 } 220 bSomethingDisplayed = TRUE; 221 Status = HttpSendAnsiString ( SocketFD, 222 pPort, 223 "No Write" ); 224 if ( EFI_ERROR ( Status )) { 225 break; 226 } 227 } 228 229 if ( 0 != ( Attributes & EFI_MEMORY_UCE )) { 230 if ( bSomethingDisplayed ) { 231 Status = HttpSendAnsiString ( SocketFD, 232 pPort, 233 ", " ); 234 if ( EFI_ERROR ( Status )) { 235 break; 236 } 237 } 238 bSomethingDisplayed = TRUE; 239 Status = HttpSendAnsiString ( SocketFD, 240 pPort, 241 "UCE" ); 242 if ( EFI_ERROR ( Status )) { 243 break; 244 } 245 } 246 247 248 if ( 0 != ( Attributes & EFI_MEMORY_WB )) { 249 if ( bSomethingDisplayed ) { 250 Status = HttpSendAnsiString ( SocketFD, 251 pPort, 252 ", " ); 253 if ( EFI_ERROR ( Status )) { 254 break; 255 } 256 } 257 bSomethingDisplayed = TRUE; 258 Status = HttpSendAnsiString ( SocketFD, 259 pPort, 260 "Write Back" ); 261 if ( EFI_ERROR ( Status )) { 262 break; 263 } 264 } 265 266 if ( 0 != ( Attributes & EFI_MEMORY_WT )) { 267 if ( bSomethingDisplayed ) { 268 Status = HttpSendAnsiString ( SocketFD, 269 pPort, 270 ", " ); 271 if ( EFI_ERROR ( Status )) { 272 break; 273 } 274 } 275 bSomethingDisplayed = TRUE; 276 Status = HttpSendAnsiString ( SocketFD, 277 pPort, 278 "Write Through" ); 279 if ( EFI_ERROR ( Status )) { 280 break; 281 } 282 } 283 284 if ( 0 != ( Attributes & EFI_MEMORY_WC )) { 285 if ( bSomethingDisplayed ) { 286 Status = HttpSendAnsiString ( SocketFD, 287 pPort, 288 ", " ); 289 if ( EFI_ERROR ( Status )) { 290 break; 291 } 292 } 293 bSomethingDisplayed = TRUE; 294 Status = HttpSendAnsiString ( SocketFD, 295 pPort, 296 "Write Combining" ); 297 if ( EFI_ERROR ( Status )) { 298 break; 299 } 300 } 301 302 if ( 0 != ( Attributes & EFI_MEMORY_UC )) { 303 if ( bSomethingDisplayed ) { 304 Status = HttpSendAnsiString ( SocketFD, 305 pPort, 306 ", " ); 307 if ( EFI_ERROR ( Status )) { 308 break; 309 } 310 } 311 bSomethingDisplayed = TRUE; 312 Status = HttpSendAnsiString ( SocketFD, 313 pPort, 314 "Uncached" ); 315 if ( EFI_ERROR ( Status )) { 316 break; 317 } 318 } 319 320 // 321 // Finish the row 322 // 323 Status = HttpSendAnsiString ( SocketFD, pPort, "</td></tr>" ); 324 if ( EFI_ERROR ( Status )) { 325 break; 326 } 327 328 // 329 // Set the next memory descriptor 330 // 331 pMemoryDescriptor += 1; 332 } 333 } 334 335 // 336 // Finish the table 337 // 338 Status = HttpSendAnsiString ( SocketFD, 339 pPort, 340 "</table>\r\n" ); 341 if ( EFI_ERROR ( Status )) { 342 break; 343 } 344 345 // 346 // Send the page trailer 347 // 348 Status = HttpPageTrailer ( SocketFD, pPort, pbDone ); 349 break; 350 } 351 352 // 353 // Release the memory descriptors 354 // 355 if ( NULL != pMemoryDescriptorStart ) { 356 FreePool ( pMemoryDescriptorStart ); 357 } 358 359 // 360 // Return the operation status 361 // 362 DBG_EXIT_STATUS ( Status ); 363 return Status; 364 } 365