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