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
MemoryMapPage(IN int SocketFD,IN WSDT_PORT * pPort,OUT BOOLEAN * pbDone)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