]> git.proxmox.com Git - mirror_edk2.git/blame - AppPkg/Applications/Sockets/WebServer/Mtrr.c
AppPkg/WebServer: Fix build failure.
[mirror_edk2.git] / AppPkg / Applications / Sockets / WebServer / Mtrr.c
CommitLineData
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
21CONST 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**/
44EFI_STATUS
45MtrrDisplayFixedRow (
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**/
140EFI_STATUS
141MemoryTypeRegistersPage (
142 IN int SocketFD,
143 IN WSDT_PORT * pPort,
144 OUT BOOLEAN * pbDone
145 )
146{
147 UINT64 Addr;
148 BOOLEAN bValid;
b30abe7d 149 MSR_IA32_MTRRCAP_REGISTER Capabilities;
9f7f5161 150 UINTN Count;
b30abe7d 151 MSR_IA32_MTRR_DEF_TYPE_REGISTER DefType;
9f7f5161 152 UINTN Index;
153 UINT64 Mask;
b30abe7d 154
9f7f5161 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 //
b30abe7d
ED
305 Capabilities.Uint64 = AsmReadMsr64 ( MSR_IA32_MTRRCAP );
306 DefType.Uint64 = AsmReadMsr64 ( MSR_IA32_MTRR_DEF_TYPE );
9f7f5161 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,
b30abe7d 319 Capabilities.Uint64 );
9f7f5161 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,
b30abe7d 341 DefType.Uint64);
9f7f5161 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,
b30abe7d 353 ( 0 != DefType.Bits.E )
9f7f5161 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,
b30abe7d 367 ( 0 != DefType.Bits.FE )
9f7f5161 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 }
b30abe7d 379 Type = DefType.Uint64 & 0xff;
9f7f5161 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 //
b30abe7d 398 if ( 0 == DefType.Bits.E ) {
9f7f5161 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 //
b30abe7d
ED
415 if (( 0 != Capabilities.Bits.FIX )
416 && ( 0 != DefType.Bits.FE)) {
9f7f5161 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 //
b30abe7d 618 if ( 0 < Capabilities.Bits.VCNT ) {
9f7f5161 619 //
620 // Beginning of table
621 //
622 Status = HttpSendAnsiString ( SocketFD,
623 pPort,
624 "<h2>Variable MTRRs</h2>\r\n"
625 "<table>\r\n"
626 " <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" );
627 if ( EFI_ERROR ( Status )) {
628 break;
629 }
630
631 //
632 // Display the variable MTRRs
633 //
b30abe7d 634 for ( Count = 0; Capabilities.Bits.VCNT > Count; Count++ ) {
9f7f5161 635 //
636 // Start the row
637 //
638 Status = HttpSendAnsiString ( SocketFD,
639 pPort,
640 " <tr><td>" );
641 if ( EFI_ERROR ( Status )) {
642 break;
643 }
644
645 //
646 // Index
647 //
648 Status = HttpSendValue ( SocketFD,
649 pPort,
650 Count );
651 if ( EFI_ERROR ( Status )) {
652 break;
653 }
654
655 //
656 // Base
657 //
658 Status = HttpSendAnsiString ( SocketFD,
659 pPort,
660 "</td><td align=\"right\"><code>0x" );
661 if ( EFI_ERROR ( Status )) {
662 break;
663 }
664 Status = HttpSendHexValue ( SocketFD,
665 pPort,
666 Mtrr.Variables.Mtrr[ Count ].Base );
667 if ( EFI_ERROR ( Status )) {
668 break;
669 }
670
671 //
672 // Mask
673 //
674 Status = HttpSendAnsiString ( SocketFD,
675 pPort,
676 "</td><td align=\"right\"><code>0x" );
677 if ( EFI_ERROR ( Status )) {
678 break;
679 }
680 Status = HttpSendHexValue ( SocketFD,
681 pPort,
682 Mtrr.Variables.Mtrr[ Count ].Mask );
683 if ( EFI_ERROR ( Status )) {
684 break;
685 }
686
687 //
688 // Determine if the entry is valid
689 //
690 bValid = ( Mtrr.Variables.Mtrr[ Count ].Mask & VARIABLE_MTRR_VALID ) ? TRUE : FALSE;
691
692 //
693 // Start
694 //
695 Status = HttpSendAnsiString ( SocketFD,
696 pPort,
697 "</code></td><td align=\"right\"><code>" );
698 if ( EFI_ERROR ( Status )) {
699 break;
700 }
701 Addr = Mtrr.Variables.Mtrr[ Count ].Base & 0xfffffffffffff000ULL;
702 if ( bValid ) {
703 Status = HttpSendAnsiString ( SocketFD,
704 pPort,
705 "0x" );
706 if ( EFI_ERROR ( Status )) {
707 break;
708 }
709 Status = HttpSendHexValue ( SocketFD,
710 pPort,
711 Addr );
712 }
713 else {
714 Status = HttpSendAnsiString ( SocketFD,
715 pPort,
716 "Invalid" );
717 }
718 if ( EFI_ERROR ( Status )) {
719 break;
720 }
721
722 //
723 // End
724 //
725 Status = HttpSendAnsiString ( SocketFD,
726 pPort,
727 "</code></td><td align=\"right\"><code>" );
728 if ( EFI_ERROR ( Status )) {
729 break;
730 }
731 if ( bValid ) {
732 //
733 // Determine the end address
734 //
735 Mask = Mtrr.Variables.Mtrr[ Count ].Mask;
736 Value = Mask;
737 ShiftCount = 0;
738 while ( 0 < Value ) {
739 Value <<= 1;
740 ShiftCount += 1;
741 }
742 Value = 1;
743 Value <<= 64 - ShiftCount;
744 Value -= 1;
745 Value = ~Value;
746 Value |= Mask;
747 Value &= ~VARIABLE_MTRR_VALID;
748 Value = ~Value;
749
750 Status = HttpSendAnsiString ( SocketFD,
751 pPort,
752 "0x" );
753 if ( EFI_ERROR ( Status )) {
754 break;
755 }
756 Status = HttpSendHexValue ( SocketFD,
757 pPort,
758 Addr + Value );
759 }
760 if ( EFI_ERROR ( Status )) {
761 break;
762 }
763
764 //
765 // Type
766 //
767 Status = HttpSendAnsiString ( SocketFD,
768 pPort,
769 "</code></td><td>" );
770 if ( EFI_ERROR ( Status )) {
771 break;
772 }
773 if ( bValid ) {
774 Type = Mtrr.Variables.Mtrr[ Count ].Base & 0xFF;
775 Status = HttpSendAnsiString ( SocketFD,
776 pPort,
777 ( DIM ( mMemoryType ) > Type )
778 ? mMemoryType [ Type ]
779 : "Reserved" );
780 }
781 if ( EFI_ERROR ( Status )) {
782 break;
783 }
784
785 //
786 // End of row
787 //
788 Status = HttpSendAnsiString ( SocketFD,
789 pPort,
790 "</td></tr>\r\n" );
791 if ( EFI_ERROR ( Status )) {
792 break;
793 }
794 }
795 if ( EFI_ERROR ( Status )) {
796 break;
797 }
798
799 //
800 // End of table
801 //
802 Status = HttpSendAnsiString ( SocketFD,
803 pPort,
804 "</table>\r\n" );
805 if ( EFI_ERROR ( Status )) {
806 break;
807 }
808 }
809 }
810 }
811
812 //
813 // Send the page trailer
814 //
815 Status = HttpPageTrailer ( SocketFD, pPort, pbDone );
816 break;
817 }
818
819 //
820 // Return the operation status
821 //
822 DBG_EXIT_STATUS ( Status );
823 return Status;
824}