]> git.proxmox.com Git - mirror_edk2.git/blame - AppPkg/Applications/Sockets/WebServer/Mtrr.c
AppPkg: fix webserver build for !Ia32/X64
[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>
3e583d34 18#include <Register/Msr.h>
9f7f5161 19
20#define VARIABLE_MTRR_VALID 0x800
21
22CONST char * mMemoryType [ ] = {
23 "Uncached",
24 "Write Combining",
25 "Reserved",
26 "Reserved",
27 "Write Through",
28 "Write Protected",
29 "Writeback"
30};
31
32
33/**
34 Display a fixed MTRR row
35
36 @param [in] SocketFD The socket's file descriptor to add to the list.
37 @param [in] pPort The WSDT_PORT structure address
38 @param [in] Start Start address for the region
39 @param [in] End End address for the region
40 @param [in] Type Memory type
41
42 @retval EFI_SUCCESS The request was successfully processed
43
44**/
45EFI_STATUS
46MtrrDisplayFixedRow (
47 IN int SocketFD,
48 IN WSDT_PORT * pPort,
49 IN UINT64 Start,
50 IN UINT64 End,
51 IN UINT64 Type
52 )
53{
54 EFI_STATUS Status;
55
56 //
57 // Use break instead of goto
58 //
59 for ( ; ; ) {
60 //
61 // Start the row
62 //
63 Status = HttpSendAnsiString ( SocketFD,
64 pPort,
65 " <tr><td align=\"right\"><code>0x" );
66 if ( EFI_ERROR ( Status )) {
67 break;
68 }
69
70 //
71 // Start
72 //
73 Status = HttpSendHexValue ( SocketFD,
74 pPort,
75 Start );
76 if ( EFI_ERROR ( Status )) {
77 break;
78 }
79
80 //
81 // End
82 //
83 Status = HttpSendAnsiString ( SocketFD,
84 pPort,
85 "</code></td><td align=\"right\"><code>0x" );
86 if ( EFI_ERROR ( Status )) {
87 break;
88 }
89 Status = HttpSendHexValue ( SocketFD,
90 pPort,
91 End - 1 );
92 if ( EFI_ERROR ( Status )) {
93 break;
94 }
95
96 //
97 // Type
98 //
99 Status = HttpSendAnsiString ( SocketFD,
100 pPort,
101 "</code></td><td>" );
102 if ( EFI_ERROR ( Status )) {
103 break;
104 }
105 Type &= 0xff;
106 Status = HttpSendAnsiString ( SocketFD,
107 pPort,
108 ( DIM ( mMemoryType ) > Type )
109 ? mMemoryType [ Type ]
110 : "Reserved" );
111 if ( EFI_ERROR ( Status )) {
112 break;
113 }
114
115 //
116 // End of row
117 //
118 Status = HttpSendAnsiString ( SocketFD,
119 pPort,
120 "</td></tr>\r\n" );
121 break;
122 }
123
124 //
125 // Return the final status
126 //
127 return Status;
128}
129
130
131/**
132 Display the memory type registers
133
134 @param [in] SocketFD The socket's file descriptor to add to the list.
135 @param [in] pPort The WSDT_PORT structure address
136 @param [out] pbDone Address to receive the request completion status
137
138 @retval EFI_SUCCESS The request was successfully processed
139
140**/
141EFI_STATUS
142MemoryTypeRegistersPage (
143 IN int SocketFD,
144 IN WSDT_PORT * pPort,
145 OUT BOOLEAN * pbDone
146 )
147{
148 UINT64 Addr;
149 BOOLEAN bValid;
b30abe7d 150 MSR_IA32_MTRRCAP_REGISTER Capabilities;
9f7f5161 151 UINTN Count;
b30abe7d 152 MSR_IA32_MTRR_DEF_TYPE_REGISTER DefType;
9f7f5161 153 UINTN Index;
154 UINT64 Mask;
b30abe7d 155
9f7f5161 156 CONST UINT64 mFixedAddresses [( 8 * MTRR_NUMBER_OF_FIXED_MTRR ) + 1 ] = {
157 0ULL,
158 0x10000ULL,
159 0x20000ULL,
160 0x30000ULL,
161 0x40000ULL,
162 0x50000ULL,
163 0x60000ULL,
164 0x70000ULL,
165
166 0x80000ULL,
167 0x84000ULL,
168 0x88000ULL,
169 0x8c000ULL,
170 0x90000ULL,
171 0x94000ULL,
172 0x98000ULL,
173 0x9c000ULL,
174
175 0xa0000ULL,
176 0xa4000ULL,
177 0xa8000ULL,
178 0xac000ULL,
179 0xb0000ULL,
180 0xb4000ULL,
181 0xb8000ULL,
182 0xbc000ULL,
183
184 0xc0000ULL,
185 0xc1000ULL,
186 0xc2000ULL,
187 0xc3000ULL,
188 0xc4000ULL,
189 0xc5000ULL,
190 0xc6000ULL,
191 0xc7000ULL,
192
193 0xc8000ULL,
194 0xc9000ULL,
195 0xca000ULL,
196 0xcb000ULL,
197 0xcc000ULL,
198 0xcd000ULL,
199 0xce000ULL,
200 0xcf000ULL,
201
202 0xd0000ULL,
203 0xd1000ULL,
204 0xd2000ULL,
205 0xd3000ULL,
206 0xd4000ULL,
207 0xd5000ULL,
208 0xd6000ULL,
209 0xd7000ULL,
210
211 0xd8000ULL,
212 0xd9000ULL,
213 0xda000ULL,
214 0xdb000ULL,
215 0xdc000ULL,
216 0xdd000ULL,
217 0xde000ULL,
218 0xdf000ULL,
219
220 0xe0000ULL,
221 0xe1000ULL,
222 0xe2000ULL,
223 0xe3000ULL,
224 0xe4000ULL,
225 0xe5000ULL,
226 0xe6000ULL,
227 0xe7000ULL,
228
229 0xe8000ULL,
230 0xe9000ULL,
231 0xea000ULL,
232 0xeb000ULL,
233 0xec000ULL,
234 0xed000ULL,
235 0xee000ULL,
236 0xef000ULL,
237
238 0xf0000ULL,
239 0xf1000ULL,
240 0xf2000ULL,
241 0xf3000ULL,
242 0xf4000ULL,
243 0xf5000ULL,
244 0xf6000ULL,
245 0xf7000ULL,
246
247 0xf8000ULL,
248 0xf9000ULL,
249 0xfa000ULL,
250 0xfb000ULL,
251 0xfc000ULL,
252 0xfd000ULL,
253 0xfe000ULL,
254 0xff000ULL,
255
256 0x100000ULL
257 };
258 MTRR_SETTINGS Mtrr;
259 CONST UINT64 * pMemEnd;
260 CONST UINT64 * pMemStart;
261 UINT64 PreviousType;
262 UINT64 ShiftCount;
263 EFI_STATUS Status;
264 UINT64 Type;
265 INT64 Value;
266
267 DBG_ENTER ( );
268
269 //
270 // Send the Memory Type Registers page
271 //
272 for ( ; ; ) {
273 //
274 // Send the page header
275 //
276 Status = HttpPageHeader ( SocketFD, pPort, L"Memory Type Range Registers" );
277 if ( EFI_ERROR ( Status )) {
278 break;
279 }
280
281 //
282 // Send the header
283 //
284 Status = HttpSendAnsiString ( SocketFD,
285 pPort,
286 "<h1>Memory Type Range Registers</h1>\r\n" );
287 if ( EFI_ERROR ( Status )) {
288 break;
289 }
290
291 //
292 // Determine if MTRRs are supported
293 //
294 if ( !IsMtrrSupported ( )) {
295 Status = HttpSendAnsiString ( SocketFD,
296 pPort,
297 "<p>Memory Type Range Registers are not supported!\r\n" );
298 if ( EFI_ERROR ( Status )) {
299 break;
300 }
301 }
302 else {
303 //
304 // Get the capabilities
305 //
b30abe7d
ED
306 Capabilities.Uint64 = AsmReadMsr64 ( MSR_IA32_MTRRCAP );
307 DefType.Uint64 = AsmReadMsr64 ( MSR_IA32_MTRR_DEF_TYPE );
9f7f5161 308
309 //
310 // Display the capabilities
311 //
312 Status = HttpSendAnsiString ( SocketFD,
313 pPort,
314 "<p>Capabilities: " );
315 if ( EFI_ERROR ( Status )) {
316 break;
317 }
318 Status = HttpSendHexValue ( SocketFD,
319 pPort,
b30abe7d 320 Capabilities.Uint64 );
9f7f5161 321 if ( EFI_ERROR ( Status )) {
322 break;
323 }
324 Status = HttpSendAnsiString ( SocketFD,
325 pPort,
326 "<br>\r\n" );
327 if ( EFI_ERROR ( Status )) {
328 break;
329 }
330
331 //
332 // Display the default type
333 //
334 Status = HttpSendAnsiString ( SocketFD,
335 pPort,
336 "Def Type: " );
337 if ( EFI_ERROR ( Status )) {
338 break;
339 }
340 Status = HttpSendHexValue ( SocketFD,
341 pPort,
b30abe7d 342 DefType.Uint64);
9f7f5161 343 if ( EFI_ERROR ( Status )) {
344 break;
345 }
346 Status = HttpSendAnsiString ( SocketFD,
347 pPort,
348 ", MTRRs " );
349 if ( EFI_ERROR ( Status )) {
350 break;
351 }
352 Status = HttpSendAnsiString ( SocketFD,
353 pPort,
b30abe7d 354 ( 0 != DefType.Bits.E )
9f7f5161 355 ? "Enabled"
356 : "Disabled" );
357 if ( EFI_ERROR ( Status )) {
358 break;
359 }
360 Status = HttpSendAnsiString ( SocketFD,
361 pPort,
362 ", Fixed MTRRs " );
363 if ( EFI_ERROR ( Status )) {
364 break;
365 }
366 Status = HttpSendAnsiString ( SocketFD,
367 pPort,
b30abe7d 368 ( 0 != DefType.Bits.FE )
9f7f5161 369 ? "Enabled"
370 : "Disabled" );
371 if ( EFI_ERROR ( Status )) {
372 break;
373 }
374 Status = HttpSendAnsiString ( SocketFD,
375 pPort,
376 ", " );
377 if ( EFI_ERROR ( Status )) {
378 break;
379 }
b30abe7d 380 Type = DefType.Uint64 & 0xff;
9f7f5161 381 Status = HttpSendAnsiString ( SocketFD,
382 pPort,
383 ( DIM ( mMemoryType ) > Type )
384 ? mMemoryType [ Type ]
385 : "Reserved" );
386 if ( EFI_ERROR ( Status )) {
387 break;
388 }
389 Status = HttpSendAnsiString ( SocketFD,
390 pPort,
391 "</p>\r\n" );
392 if ( EFI_ERROR ( Status )) {
393 break;
394 }
395
396 //
397 // Determine if MTRRs are enabled
398 //
b30abe7d 399 if ( 0 == DefType.Bits.E ) {
9f7f5161 400 Status = HttpSendAnsiString ( SocketFD,
401 pPort,
402 "<p>All memory is uncached!</p>\r\n" );
403 if ( EFI_ERROR ( Status )) {
404 break;
405 }
406 }
407 else {
408 //
409 // Get the MTRRs
410 //
411 MtrrGetAllMtrrs ( &Mtrr );
412
413 //
414 // Determine if the fixed MTRRs are supported
415 //
b30abe7d
ED
416 if (( 0 != Capabilities.Bits.FIX )
417 && ( 0 != DefType.Bits.FE)) {
9f7f5161 418
419 //
420 // Beginning of table
421 //
422 Status = HttpSendAnsiString ( SocketFD,
423 pPort,
424 "<h2>Fixed MTRRs</h2>\r\n"
425 "<table>\r\n"
426 " <tr><th>Index</th><th align=\"right\">Value</th><th align=\"right\">Start</th><th align=\"right\">End</th></tr>\r\n" );
427 if ( EFI_ERROR ( Status )) {
428 break;
429 }
430
431 //
432 // Display the fixed MTRRs
433 //
434 pMemStart = &mFixedAddresses[ 0 ];
435 for ( Count = 0; DIM ( Mtrr.Fixed.Mtrr ) > Count; Count++ ) {
436 //
437 // Start the row
438 //
439 Status = HttpSendAnsiString ( SocketFD,
440 pPort,
441 " <tr><td>" );
442 if ( EFI_ERROR ( Status )) {
443 break;
444 }
445
446 //
447 // Index
448 //
449 Status = HttpSendValue ( SocketFD,
450 pPort,
451 Count );
452 if ( EFI_ERROR ( Status )) {
453 break;
454 }
455
456 //
457 // Value
458 //
459 Status = HttpSendAnsiString ( SocketFD,
460 pPort,
461 "</td><td align=\"right\"><code>0x" );
462 if ( EFI_ERROR ( Status )) {
463 break;
464 }
465 Status = HttpSendHexValue ( SocketFD,
466 pPort,
467 Mtrr.Fixed.Mtrr[ Count ]);
468 if ( EFI_ERROR ( Status )) {
469 break;
470 }
471
472 //
473 // Start
474 //
475 Status = HttpSendAnsiString ( SocketFD,
476 pPort,
477 "</code></td><td align=\"right\"><code>0x" );
478 if ( EFI_ERROR ( Status )) {
479 break;
480 }
481 Status = HttpSendHexValue ( SocketFD,
482 pPort,
483 *pMemStart );
484 if ( EFI_ERROR ( Status )) {
485 break;
486 }
487 pMemStart += 8;
488
489 //
490 // Value
491 //
492 Status = HttpSendAnsiString ( SocketFD,
493 pPort,
494 "</code></td><td align=\"right\"><code>0x" );
495 if ( EFI_ERROR ( Status )) {
496 break;
497 }
498 Status = HttpSendHexValue ( SocketFD,
499 pPort,
500 *pMemStart - 1 );
501 if ( EFI_ERROR ( Status )) {
502 break;
503 }
504
505 //
506 // End of row
507 //
508 Status = HttpSendAnsiString ( SocketFD,
509 pPort,
510 "</code></td></tr>\r\n" );
511 if ( EFI_ERROR ( Status )) {
512 break;
513 }
514 }
515 if ( EFI_ERROR ( Status )) {
516 break;
517 }
518
519 //
520 // End of table
521 //
522 Status = HttpSendAnsiString ( SocketFD,
523 pPort,
524 "</table>\r\n" );
525 if ( EFI_ERROR ( Status )) {
526 break;
527 }
528
529 //
530 // Beginning of table
531 //
532 Status = HttpSendAnsiString ( SocketFD,
533 pPort,
534 "<table>\r\n"
535 " <tr><th align=\"right\">Start</th><th align=\"right\">End</th><th align=\"left\">Type</th></tr>\r\n" );
536 if ( EFI_ERROR ( Status )) {
537 break;
538 }
539
540 //
541 // Decode the fixed MTRRs
542 //
543 PreviousType = Mtrr.Fixed.Mtrr[ 0 ] & 0xff;
544 pMemStart = &mFixedAddresses[ 0 ];
545 pMemEnd = pMemStart;
546 for ( Count = 0; DIM ( Mtrr.Fixed.Mtrr ) > Count; Count++ ) {
547 //
548 // Get the memory types
549 //
550 Type = Mtrr.Fixed.Mtrr[ Count ];
551
552 //
553 // Walk the memory range
554 //
555 for ( Index = 0; 8 > Index; Index++ ) {
556 //
557 // Determine if this is the same memory type
558 //
559 if ( PreviousType != ( Type & 0xff )) {
560 //
561 // Display the row
562 //
563 Status = MtrrDisplayFixedRow ( SocketFD,
564 pPort,
565 *pMemStart,
566 *pMemEnd,
567 PreviousType );
568 if ( EFI_ERROR ( Status )) {
569 break;
570 }
571
572 //
573 // Start the next range of addresses
574 //
575 pMemStart = pMemEnd;
576 PreviousType = Type & 0xff;
577 }
578
579 //
580 // Set the next memory range and type
581 //
582 Type >>= 8;
583 pMemEnd += 1;
584 }
585 if ( EFI_ERROR ( Status )) {
586 break;
587 }
588 }
589 if ( EFI_ERROR ( Status )) {
590 break;
591 }
592
593 //
594 // Display the final row
595 //
596 Status = MtrrDisplayFixedRow ( SocketFD,
597 pPort,
598 *pMemStart,
599 *pMemEnd,
600 PreviousType );
601 if ( EFI_ERROR ( Status )) {
602 break;
603 }
604
605 //
606 // End of table
607 //
608 Status = HttpSendAnsiString ( SocketFD,
609 pPort,
610 "</table>\r\n" );
611 if ( EFI_ERROR ( Status )) {
612 break;
613 }
614 }
615
616 //
617 // Determine if the variable MTRRs are supported
618 //
b30abe7d 619 if ( 0 < Capabilities.Bits.VCNT ) {
9f7f5161 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 //
b30abe7d 635 for ( Count = 0; Capabilities.Bits.VCNT > Count; Count++ ) {
9f7f5161 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}