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