]> git.proxmox.com Git - mirror_edk2.git/blob - AppPkg/Applications/Sockets/WebServer/Mtrr.c
92f90b0ae0fca0406d8d16a743dcd3238380cbc8
[mirror_edk2.git] / AppPkg / Applications / Sockets / WebServer / Mtrr.c
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 }