]>
Commit | Line | Data |
---|---|---|
9f7f5161 | 1 | /** |
2 | @file | |
3 | Display the memory type range registers | |
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 <Library/MtrrLib.h> | |
18 | ||
19 | #define VARIABLE_MTRR_VALID 0x800 | |
20 | ||
21 | CONST char * mMemoryType [ ] = { | |
22 | "Uncached", | |
23 | "Write Combining", | |
24 | "Reserved", | |
25 | "Reserved", | |
26 | "Write Through", | |
27 | "Write Protected", | |
28 | "Writeback" | |
29 | }; | |
30 | ||
31 | ||
32 | /** | |
33 | Display a fixed MTRR row | |
34 | ||
35 | @param [in] SocketFD The socket's file descriptor to add to the list. | |
36 | @param [in] pPort The WSDT_PORT structure address | |
37 | @param [in] Start Start address for the region | |
38 | @param [in] End End address for the region | |
39 | @param [in] Type Memory type | |
40 | ||
41 | @retval EFI_SUCCESS The request was successfully processed | |
42 | ||
43 | **/ | |
44 | EFI_STATUS | |
45 | MtrrDisplayFixedRow ( | |
46 | IN int SocketFD, | |
47 | IN WSDT_PORT * pPort, | |
48 | IN UINT64 Start, | |
49 | IN UINT64 End, | |
50 | IN UINT64 Type | |
51 | ) | |
52 | { | |
53 | EFI_STATUS Status; | |
54 | ||
55 | // | |
56 | // Use break instead of goto | |
57 | // | |
58 | for ( ; ; ) { | |
59 | // | |
60 | // Start the row | |
61 | // | |
62 | Status = HttpSendAnsiString ( SocketFD, | |
63 | pPort, | |
64 | " <tr><td align=\"right\"><code>0x" ); | |
65 | if ( EFI_ERROR ( Status )) { | |
66 | break; | |
67 | } | |
68 | ||
69 | // | |
70 | // Start | |
71 | // | |
72 | Status = HttpSendHexValue ( SocketFD, | |
73 | pPort, | |
74 | Start ); | |
75 | if ( EFI_ERROR ( Status )) { | |
76 | break; | |
77 | } | |
78 | ||
79 | // | |
80 | // End | |
81 | // | |
82 | Status = HttpSendAnsiString ( SocketFD, | |
83 | pPort, | |
84 | "</code></td><td align=\"right\"><code>0x" ); | |
85 | if ( EFI_ERROR ( Status )) { | |
86 | break; | |
87 | } | |
88 | Status = HttpSendHexValue ( SocketFD, | |
89 | pPort, | |
90 | End - 1 ); | |
91 | if ( EFI_ERROR ( Status )) { | |
92 | break; | |
93 | } | |
94 | ||
95 | // | |
96 | // Type | |
97 | // | |
98 | Status = HttpSendAnsiString ( SocketFD, | |
99 | pPort, | |
100 | "</code></td><td>" ); | |
101 | if ( EFI_ERROR ( Status )) { | |
102 | break; | |
103 | } | |
104 | Type &= 0xff; | |
105 | Status = HttpSendAnsiString ( SocketFD, | |
106 | pPort, | |
107 | ( DIM ( mMemoryType ) > Type ) | |
108 | ? mMemoryType [ Type ] | |
109 | : "Reserved" ); | |
110 | if ( EFI_ERROR ( Status )) { | |
111 | break; | |
112 | } | |
113 | ||
114 | // | |
115 | // End of row | |
116 | // | |
117 | Status = HttpSendAnsiString ( SocketFD, | |
118 | pPort, | |
119 | "</td></tr>\r\n" ); | |
120 | break; | |
121 | } | |
122 | ||
123 | // | |
124 | // Return the final status | |
125 | // | |
126 | return Status; | |
127 | } | |
128 | ||
129 | ||
130 | /** | |
131 | Display the memory type registers | |
132 | ||
133 | @param [in] SocketFD The socket's file descriptor to add to the list. | |
134 | @param [in] pPort The WSDT_PORT structure address | |
135 | @param [out] pbDone Address to receive the request completion status | |
136 | ||
137 | @retval EFI_SUCCESS The request was successfully processed | |
138 | ||
139 | **/ | |
140 | EFI_STATUS | |
141 | MemoryTypeRegistersPage ( | |
142 | IN int SocketFD, | |
143 | IN WSDT_PORT * pPort, | |
144 | OUT BOOLEAN * pbDone | |
145 | ) | |
146 | { | |
147 | UINT64 Addr; | |
148 | BOOLEAN bValid; | |
149 | UINT64 Capabilities; | |
150 | UINTN Count; | |
151 | UINT64 DefType; | |
152 | UINTN Index; | |
153 | UINT64 Mask; | |
154 | UINT64 MaxMtrrs; | |
155 | CONST UINT64 mFixedAddresses [( 8 * MTRR_NUMBER_OF_FIXED_MTRR ) + 1 ] = { | |
156 | 0ULL, | |
157 | 0x10000ULL, | |
158 | 0x20000ULL, | |
159 | 0x30000ULL, | |
160 | 0x40000ULL, | |
161 | 0x50000ULL, | |
162 | 0x60000ULL, | |
163 | 0x70000ULL, | |
164 | ||
165 | 0x80000ULL, | |
166 | 0x84000ULL, | |
167 | 0x88000ULL, | |
168 | 0x8c000ULL, | |
169 | 0x90000ULL, | |
170 | 0x94000ULL, | |
171 | 0x98000ULL, | |
172 | 0x9c000ULL, | |
173 | ||
174 | 0xa0000ULL, | |
175 | 0xa4000ULL, | |
176 | 0xa8000ULL, | |
177 | 0xac000ULL, | |
178 | 0xb0000ULL, | |
179 | 0xb4000ULL, | |
180 | 0xb8000ULL, | |
181 | 0xbc000ULL, | |
182 | ||
183 | 0xc0000ULL, | |
184 | 0xc1000ULL, | |
185 | 0xc2000ULL, | |
186 | 0xc3000ULL, | |
187 | 0xc4000ULL, | |
188 | 0xc5000ULL, | |
189 | 0xc6000ULL, | |
190 | 0xc7000ULL, | |
191 | ||
192 | 0xc8000ULL, | |
193 | 0xc9000ULL, | |
194 | 0xca000ULL, | |
195 | 0xcb000ULL, | |
196 | 0xcc000ULL, | |
197 | 0xcd000ULL, | |
198 | 0xce000ULL, | |
199 | 0xcf000ULL, | |
200 | ||
201 | 0xd0000ULL, | |
202 | 0xd1000ULL, | |
203 | 0xd2000ULL, | |
204 | 0xd3000ULL, | |
205 | 0xd4000ULL, | |
206 | 0xd5000ULL, | |
207 | 0xd6000ULL, | |
208 | 0xd7000ULL, | |
209 | ||
210 | 0xd8000ULL, | |
211 | 0xd9000ULL, | |
212 | 0xda000ULL, | |
213 | 0xdb000ULL, | |
214 | 0xdc000ULL, | |
215 | 0xdd000ULL, | |
216 | 0xde000ULL, | |
217 | 0xdf000ULL, | |
218 | ||
219 | 0xe0000ULL, | |
220 | 0xe1000ULL, | |
221 | 0xe2000ULL, | |
222 | 0xe3000ULL, | |
223 | 0xe4000ULL, | |
224 | 0xe5000ULL, | |
225 | 0xe6000ULL, | |
226 | 0xe7000ULL, | |
227 | ||
228 | 0xe8000ULL, | |
229 | 0xe9000ULL, | |
230 | 0xea000ULL, | |
231 | 0xeb000ULL, | |
232 | 0xec000ULL, | |
233 | 0xed000ULL, | |
234 | 0xee000ULL, | |
235 | 0xef000ULL, | |
236 | ||
237 | 0xf0000ULL, | |
238 | 0xf1000ULL, | |
239 | 0xf2000ULL, | |
240 | 0xf3000ULL, | |
241 | 0xf4000ULL, | |
242 | 0xf5000ULL, | |
243 | 0xf6000ULL, | |
244 | 0xf7000ULL, | |
245 | ||
246 | 0xf8000ULL, | |
247 | 0xf9000ULL, | |
248 | 0xfa000ULL, | |
249 | 0xfb000ULL, | |
250 | 0xfc000ULL, | |
251 | 0xfd000ULL, | |
252 | 0xfe000ULL, | |
253 | 0xff000ULL, | |
254 | ||
255 | 0x100000ULL | |
256 | }; | |
257 | MTRR_SETTINGS Mtrr; | |
258 | CONST UINT64 * pMemEnd; | |
259 | CONST UINT64 * pMemStart; | |
260 | UINT64 PreviousType; | |
261 | UINT64 ShiftCount; | |
262 | EFI_STATUS Status; | |
263 | UINT64 Type; | |
264 | INT64 Value; | |
265 | ||
266 | DBG_ENTER ( ); | |
267 | ||
268 | // | |
269 | // Send the Memory Type Registers page | |
270 | // | |
271 | for ( ; ; ) { | |
272 | // | |
273 | // Send the page header | |
274 | // | |
275 | Status = HttpPageHeader ( SocketFD, pPort, L"Memory Type Range Registers" ); | |
276 | if ( EFI_ERROR ( Status )) { | |
277 | break; | |
278 | } | |
279 | ||
280 | // | |
281 | // Send the header | |
282 | // | |
283 | Status = HttpSendAnsiString ( SocketFD, | |
284 | pPort, | |
285 | "<h1>Memory Type Range Registers</h1>\r\n" ); | |
286 | if ( EFI_ERROR ( Status )) { | |
287 | break; | |
288 | } | |
289 | ||
290 | // | |
291 | // Determine if MTRRs are supported | |
292 | // | |
293 | if ( !IsMtrrSupported ( )) { | |
294 | Status = HttpSendAnsiString ( SocketFD, | |
295 | pPort, | |
296 | "<p>Memory Type Range Registers are not supported!\r\n" ); | |
297 | if ( EFI_ERROR ( Status )) { | |
298 | break; | |
299 | } | |
300 | } | |
301 | else { | |
302 | // | |
303 | // Get the capabilities | |
304 | // | |
305 | Capabilities = AsmReadMsr64 ( MTRR_LIB_IA32_MTRR_CAP ); | |
306 | DefType = AsmReadMsr64 ( MTRR_LIB_IA32_MTRR_DEF_TYPE ); | |
307 | ||
308 | // | |
309 | // Display the capabilities | |
310 | // | |
311 | Status = HttpSendAnsiString ( SocketFD, | |
312 | pPort, | |
313 | "<p>Capabilities: " ); | |
314 | if ( EFI_ERROR ( Status )) { | |
315 | break; | |
316 | } | |
317 | Status = HttpSendHexValue ( SocketFD, | |
318 | pPort, | |
319 | Capabilities ); | |
320 | if ( EFI_ERROR ( Status )) { | |
321 | break; | |
322 | } | |
323 | Status = HttpSendAnsiString ( SocketFD, | |
324 | pPort, | |
325 | "<br>\r\n" ); | |
326 | if ( EFI_ERROR ( Status )) { | |
327 | break; | |
328 | } | |
329 | ||
330 | // | |
331 | // Display the default type | |
332 | // | |
333 | Status = HttpSendAnsiString ( SocketFD, | |
334 | pPort, | |
335 | "Def Type: " ); | |
336 | if ( EFI_ERROR ( Status )) { | |
337 | break; | |
338 | } | |
339 | Status = HttpSendHexValue ( SocketFD, | |
340 | pPort, | |
341 | DefType ); | |
342 | if ( EFI_ERROR ( Status )) { | |
343 | break; | |
344 | } | |
345 | Status = HttpSendAnsiString ( SocketFD, | |
346 | pPort, | |
347 | ", MTRRs " ); | |
348 | if ( EFI_ERROR ( Status )) { | |
349 | break; | |
350 | } | |
351 | Status = HttpSendAnsiString ( SocketFD, | |
352 | pPort, | |
353 | ( 0 != ( DefType & MTRR_LIB_CACHE_MTRR_ENABLED )) | |
354 | ? "Enabled" | |
355 | : "Disabled" ); | |
356 | if ( EFI_ERROR ( Status )) { | |
357 | break; | |
358 | } | |
359 | Status = HttpSendAnsiString ( SocketFD, | |
360 | pPort, | |
361 | ", Fixed MTRRs " ); | |
362 | if ( EFI_ERROR ( Status )) { | |
363 | break; | |
364 | } | |
365 | Status = HttpSendAnsiString ( SocketFD, | |
366 | pPort, | |
367 | ( 0 != ( DefType & MTRR_LIB_CACHE_FIXED_MTRR_ENABLED )) | |
368 | ? "Enabled" | |
369 | : "Disabled" ); | |
370 | if ( EFI_ERROR ( Status )) { | |
371 | break; | |
372 | } | |
373 | Status = HttpSendAnsiString ( SocketFD, | |
374 | pPort, | |
375 | ", " ); | |
376 | if ( EFI_ERROR ( Status )) { | |
377 | break; | |
378 | } | |
379 | Type = DefType & 0xff; | |
380 | Status = HttpSendAnsiString ( SocketFD, | |
381 | pPort, | |
382 | ( DIM ( mMemoryType ) > Type ) | |
383 | ? mMemoryType [ Type ] | |
384 | : "Reserved" ); | |
385 | if ( EFI_ERROR ( Status )) { | |
386 | break; | |
387 | } | |
388 | Status = HttpSendAnsiString ( SocketFD, | |
389 | pPort, | |
390 | "</p>\r\n" ); | |
391 | if ( EFI_ERROR ( Status )) { | |
392 | break; | |
393 | } | |
394 | ||
395 | // | |
396 | // Determine if MTRRs are enabled | |
397 | // | |
398 | if ( 0 == ( DefType & MTRR_LIB_CACHE_MTRR_ENABLED )) { | |
399 | Status = HttpSendAnsiString ( SocketFD, | |
400 | pPort, | |
401 | "<p>All memory is uncached!</p>\r\n" ); | |
402 | if ( EFI_ERROR ( Status )) { | |
403 | break; | |
404 | } | |
405 | } | |
406 | else { | |
407 | // | |
408 | // Get the MTRRs | |
409 | // | |
410 | MtrrGetAllMtrrs ( &Mtrr ); | |
411 | ||
412 | // | |
413 | // Determine if the fixed MTRRs are supported | |
414 | // | |
415 | if (( 0 != ( Capabilities & 0x100 )) | |
416 | && ( 0 != ( DefType & MTRR_LIB_CACHE_FIXED_MTRR_ENABLED ))) { | |
417 | ||
418 | // | |
419 | // Beginning of table | |
420 | // | |
421 | Status = HttpSendAnsiString ( SocketFD, | |
422 | pPort, | |
423 | "<h2>Fixed MTRRs</h2>\r\n" | |
424 | "<table>\r\n" | |
425 | " <tr><th>Index</th><th align=\"right\">Value</th><th align=\"right\">Start</th><th align=\"right\">End</th></tr>\r\n" ); | |
426 | if ( EFI_ERROR ( Status )) { | |
427 | break; | |
428 | } | |
429 | ||
430 | // | |
431 | // Display the fixed MTRRs | |
432 | // | |
433 | pMemStart = &mFixedAddresses[ 0 ]; | |
434 | for ( Count = 0; DIM ( Mtrr.Fixed.Mtrr ) > Count; Count++ ) { | |
435 | // | |
436 | // Start the row | |
437 | // | |
438 | Status = HttpSendAnsiString ( SocketFD, | |
439 | pPort, | |
440 | " <tr><td>" ); | |
441 | if ( EFI_ERROR ( Status )) { | |
442 | break; | |
443 | } | |
444 | ||
445 | // | |
446 | // Index | |
447 | // | |
448 | Status = HttpSendValue ( SocketFD, | |
449 | pPort, | |
450 | Count ); | |
451 | if ( EFI_ERROR ( Status )) { | |
452 | break; | |
453 | } | |
454 | ||
455 | // | |
456 | // Value | |
457 | // | |
458 | Status = HttpSendAnsiString ( SocketFD, | |
459 | pPort, | |
460 | "</td><td align=\"right\"><code>0x" ); | |
461 | if ( EFI_ERROR ( Status )) { | |
462 | break; | |
463 | } | |
464 | Status = HttpSendHexValue ( SocketFD, | |
465 | pPort, | |
466 | Mtrr.Fixed.Mtrr[ Count ]); | |
467 | if ( EFI_ERROR ( Status )) { | |
468 | break; | |
469 | } | |
470 | ||
471 | // | |
472 | // Start | |
473 | // | |
474 | Status = HttpSendAnsiString ( SocketFD, | |
475 | pPort, | |
476 | "</code></td><td align=\"right\"><code>0x" ); | |
477 | if ( EFI_ERROR ( Status )) { | |
478 | break; | |
479 | } | |
480 | Status = HttpSendHexValue ( SocketFD, | |
481 | pPort, | |
482 | *pMemStart ); | |
483 | if ( EFI_ERROR ( Status )) { | |
484 | break; | |
485 | } | |
486 | pMemStart += 8; | |
487 | ||
488 | // | |
489 | // Value | |
490 | // | |
491 | Status = HttpSendAnsiString ( SocketFD, | |
492 | pPort, | |
493 | "</code></td><td align=\"right\"><code>0x" ); | |
494 | if ( EFI_ERROR ( Status )) { | |
495 | break; | |
496 | } | |
497 | Status = HttpSendHexValue ( SocketFD, | |
498 | pPort, | |
499 | *pMemStart - 1 ); | |
500 | if ( EFI_ERROR ( Status )) { | |
501 | break; | |
502 | } | |
503 | ||
504 | // | |
505 | // End of row | |
506 | // | |
507 | Status = HttpSendAnsiString ( SocketFD, | |
508 | pPort, | |
509 | "</code></td></tr>\r\n" ); | |
510 | if ( EFI_ERROR ( Status )) { | |
511 | break; | |
512 | } | |
513 | } | |
514 | if ( EFI_ERROR ( Status )) { | |
515 | break; | |
516 | } | |
517 | ||
518 | // | |
519 | // End of table | |
520 | // | |
521 | Status = HttpSendAnsiString ( SocketFD, | |
522 | pPort, | |
523 | "</table>\r\n" ); | |
524 | if ( EFI_ERROR ( Status )) { | |
525 | break; | |
526 | } | |
527 | ||
528 | // | |
529 | // Beginning of table | |
530 | // | |
531 | Status = HttpSendAnsiString ( SocketFD, | |
532 | pPort, | |
533 | "<table>\r\n" | |
534 | " <tr><th align=\"right\">Start</th><th align=\"right\">End</th><th align=\"left\">Type</th></tr>\r\n" ); | |
535 | if ( EFI_ERROR ( Status )) { | |
536 | break; | |
537 | } | |
538 | ||
539 | // | |
540 | // Decode the fixed MTRRs | |
541 | // | |
542 | PreviousType = Mtrr.Fixed.Mtrr[ 0 ] & 0xff; | |
543 | pMemStart = &mFixedAddresses[ 0 ]; | |
544 | pMemEnd = pMemStart; | |
545 | for ( Count = 0; DIM ( Mtrr.Fixed.Mtrr ) > Count; Count++ ) { | |
546 | // | |
547 | // Get the memory types | |
548 | // | |
549 | Type = Mtrr.Fixed.Mtrr[ Count ]; | |
550 | ||
551 | // | |
552 | // Walk the memory range | |
553 | // | |
554 | for ( Index = 0; 8 > Index; Index++ ) { | |
555 | // | |
556 | // Determine if this is the same memory type | |
557 | // | |
558 | if ( PreviousType != ( Type & 0xff )) { | |
559 | // | |
560 | // Display the row | |
561 | // | |
562 | Status = MtrrDisplayFixedRow ( SocketFD, | |
563 | pPort, | |
564 | *pMemStart, | |
565 | *pMemEnd, | |
566 | PreviousType ); | |
567 | if ( EFI_ERROR ( Status )) { | |
568 | break; | |
569 | } | |
570 | ||
571 | // | |
572 | // Start the next range of addresses | |
573 | // | |
574 | pMemStart = pMemEnd; | |
575 | PreviousType = Type & 0xff; | |
576 | } | |
577 | ||
578 | // | |
579 | // Set the next memory range and type | |
580 | // | |
581 | Type >>= 8; | |
582 | pMemEnd += 1; | |
583 | } | |
584 | if ( EFI_ERROR ( Status )) { | |
585 | break; | |
586 | } | |
587 | } | |
588 | if ( EFI_ERROR ( Status )) { | |
589 | break; | |
590 | } | |
591 | ||
592 | // | |
593 | // Display the final row | |
594 | // | |
595 | Status = MtrrDisplayFixedRow ( SocketFD, | |
596 | pPort, | |
597 | *pMemStart, | |
598 | *pMemEnd, | |
599 | PreviousType ); | |
600 | if ( EFI_ERROR ( Status )) { | |
601 | break; | |
602 | } | |
603 | ||
604 | // | |
605 | // End of table | |
606 | // | |
607 | Status = HttpSendAnsiString ( SocketFD, | |
608 | pPort, | |
609 | "</table>\r\n" ); | |
610 | if ( EFI_ERROR ( Status )) { | |
611 | break; | |
612 | } | |
613 | } | |
614 | ||
615 | // | |
616 | // Determine if the variable MTRRs are supported | |
617 | // | |
618 | MaxMtrrs = Capabilities & MTRR_LIB_IA32_MTRR_CAP_VCNT_MASK; | |
619 | if ( 0 < MaxMtrrs ) { | |
620 | // | |
621 | // Beginning of table | |
622 | // | |
623 | Status = HttpSendAnsiString ( SocketFD, | |
624 | pPort, | |
625 | "<h2>Variable MTRRs</h2>\r\n" | |
626 | "<table>\r\n" | |
627 | " <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" ); | |
628 | if ( EFI_ERROR ( Status )) { | |
629 | break; | |
630 | } | |
631 | ||
632 | // | |
633 | // Display the variable MTRRs | |
634 | // | |
635 | for ( Count = 0; MaxMtrrs > Count; Count++ ) { | |
636 | // | |
637 | // Start the row | |
638 | // | |
639 | Status = HttpSendAnsiString ( SocketFD, | |
640 | pPort, | |
641 | " <tr><td>" ); | |
642 | if ( EFI_ERROR ( Status )) { | |
643 | break; | |
644 | } | |
645 | ||
646 | // | |
647 | // Index | |
648 | // | |
649 | Status = HttpSendValue ( SocketFD, | |
650 | pPort, | |
651 | Count ); | |
652 | if ( EFI_ERROR ( Status )) { | |
653 | break; | |
654 | } | |
655 | ||
656 | // | |
657 | // Base | |
658 | // | |
659 | Status = HttpSendAnsiString ( SocketFD, | |
660 | pPort, | |
661 | "</td><td align=\"right\"><code>0x" ); | |
662 | if ( EFI_ERROR ( Status )) { | |
663 | break; | |
664 | } | |
665 | Status = HttpSendHexValue ( SocketFD, | |
666 | pPort, | |
667 | Mtrr.Variables.Mtrr[ Count ].Base ); | |
668 | if ( EFI_ERROR ( Status )) { | |
669 | break; | |
670 | } | |
671 | ||
672 | // | |
673 | // Mask | |
674 | // | |
675 | Status = HttpSendAnsiString ( SocketFD, | |
676 | pPort, | |
677 | "</td><td align=\"right\"><code>0x" ); | |
678 | if ( EFI_ERROR ( Status )) { | |
679 | break; | |
680 | } | |
681 | Status = HttpSendHexValue ( SocketFD, | |
682 | pPort, | |
683 | Mtrr.Variables.Mtrr[ Count ].Mask ); | |
684 | if ( EFI_ERROR ( Status )) { | |
685 | break; | |
686 | } | |
687 | ||
688 | // | |
689 | // Determine if the entry is valid | |
690 | // | |
691 | bValid = ( Mtrr.Variables.Mtrr[ Count ].Mask & VARIABLE_MTRR_VALID ) ? TRUE : FALSE; | |
692 | ||
693 | // | |
694 | // Start | |
695 | // | |
696 | Status = HttpSendAnsiString ( SocketFD, | |
697 | pPort, | |
698 | "</code></td><td align=\"right\"><code>" ); | |
699 | if ( EFI_ERROR ( Status )) { | |
700 | break; | |
701 | } | |
702 | Addr = Mtrr.Variables.Mtrr[ Count ].Base & 0xfffffffffffff000ULL; | |
703 | if ( bValid ) { | |
704 | Status = HttpSendAnsiString ( SocketFD, | |
705 | pPort, | |
706 | "0x" ); | |
707 | if ( EFI_ERROR ( Status )) { | |
708 | break; | |
709 | } | |
710 | Status = HttpSendHexValue ( SocketFD, | |
711 | pPort, | |
712 | Addr ); | |
713 | } | |
714 | else { | |
715 | Status = HttpSendAnsiString ( SocketFD, | |
716 | pPort, | |
717 | "Invalid" ); | |
718 | } | |
719 | if ( EFI_ERROR ( Status )) { | |
720 | break; | |
721 | } | |
722 | ||
723 | // | |
724 | // End | |
725 | // | |
726 | Status = HttpSendAnsiString ( SocketFD, | |
727 | pPort, | |
728 | "</code></td><td align=\"right\"><code>" ); | |
729 | if ( EFI_ERROR ( Status )) { | |
730 | break; | |
731 | } | |
732 | if ( bValid ) { | |
733 | // | |
734 | // Determine the end address | |
735 | // | |
736 | Mask = Mtrr.Variables.Mtrr[ Count ].Mask; | |
737 | Value = Mask; | |
738 | ShiftCount = 0; | |
739 | while ( 0 < Value ) { | |
740 | Value <<= 1; | |
741 | ShiftCount += 1; | |
742 | } | |
743 | Value = 1; | |
744 | Value <<= 64 - ShiftCount; | |
745 | Value -= 1; | |
746 | Value = ~Value; | |
747 | Value |= Mask; | |
748 | Value &= ~VARIABLE_MTRR_VALID; | |
749 | Value = ~Value; | |
750 | ||
751 | Status = HttpSendAnsiString ( SocketFD, | |
752 | pPort, | |
753 | "0x" ); | |
754 | if ( EFI_ERROR ( Status )) { | |
755 | break; | |
756 | } | |
757 | Status = HttpSendHexValue ( SocketFD, | |
758 | pPort, | |
759 | Addr + Value ); | |
760 | } | |
761 | if ( EFI_ERROR ( Status )) { | |
762 | break; | |
763 | } | |
764 | ||
765 | // | |
766 | // Type | |
767 | // | |
768 | Status = HttpSendAnsiString ( SocketFD, | |
769 | pPort, | |
770 | "</code></td><td>" ); | |
771 | if ( EFI_ERROR ( Status )) { | |
772 | break; | |
773 | } | |
774 | if ( bValid ) { | |
775 | Type = Mtrr.Variables.Mtrr[ Count ].Base & 0xFF; | |
776 | Status = HttpSendAnsiString ( SocketFD, | |
777 | pPort, | |
778 | ( DIM ( mMemoryType ) > Type ) | |
779 | ? mMemoryType [ Type ] | |
780 | : "Reserved" ); | |
781 | } | |
782 | if ( EFI_ERROR ( Status )) { | |
783 | break; | |
784 | } | |
785 | ||
786 | // | |
787 | // End of row | |
788 | // | |
789 | Status = HttpSendAnsiString ( SocketFD, | |
790 | pPort, | |
791 | "</td></tr>\r\n" ); | |
792 | if ( EFI_ERROR ( Status )) { | |
793 | break; | |
794 | } | |
795 | } | |
796 | if ( EFI_ERROR ( Status )) { | |
797 | break; | |
798 | } | |
799 | ||
800 | // | |
801 | // End of table | |
802 | // | |
803 | Status = HttpSendAnsiString ( SocketFD, | |
804 | pPort, | |
805 | "</table>\r\n" ); | |
806 | if ( EFI_ERROR ( Status )) { | |
807 | break; | |
808 | } | |
809 | } | |
810 | } | |
811 | } | |
812 | ||
813 | // | |
814 | // Send the page trailer | |
815 | // | |
816 | Status = HttpPageTrailer ( SocketFD, pPort, pbDone ); | |
817 | break; | |
818 | } | |
819 | ||
820 | // | |
821 | // Return the operation status | |
822 | // | |
823 | DBG_EXIT_STATUS ( Status ); | |
824 | return Status; | |
825 | } |