3 Display the memory type range registers
5 Copyright (c) 2012, Intel Corporation. All rights reserved.
6 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include <WebServer.h>
11 #include <Library/MtrrLib.h>
12 #include <Register/Msr.h>
14 #define VARIABLE_MTRR_VALID 0x800
16 CONST
char * mMemoryType
[ ] = {
28 Display a fixed MTRR row
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
36 @retval EFI_SUCCESS The request was successfully processed
51 // Use break instead of goto
57 Status
= HttpSendAnsiString ( SocketFD
,
59 " <tr><td align=\"right\"><code>0x" );
60 if ( EFI_ERROR ( Status
)) {
67 Status
= HttpSendHexValue ( SocketFD
,
70 if ( EFI_ERROR ( Status
)) {
77 Status
= HttpSendAnsiString ( SocketFD
,
79 "</code></td><td align=\"right\"><code>0x" );
80 if ( EFI_ERROR ( Status
)) {
83 Status
= HttpSendHexValue ( SocketFD
,
86 if ( EFI_ERROR ( Status
)) {
93 Status
= HttpSendAnsiString ( SocketFD
,
96 if ( EFI_ERROR ( Status
)) {
100 Status
= HttpSendAnsiString ( SocketFD
,
102 ( DIM ( mMemoryType
) > Type
)
103 ? mMemoryType
[ Type
]
105 if ( EFI_ERROR ( Status
)) {
112 Status
= HttpSendAnsiString ( SocketFD
,
119 // Return the final status
126 Display the memory type registers
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
132 @retval EFI_SUCCESS The request was successfully processed
136 MemoryTypeRegistersPage (
138 IN WSDT_PORT
* pPort
,
144 MSR_IA32_MTRRCAP_REGISTER Capabilities
;
146 MSR_IA32_MTRR_DEF_TYPE_REGISTER DefType
;
150 CONST UINT64 mFixedAddresses
[( 8 * MTRR_NUMBER_OF_FIXED_MTRR
) + 1 ] = {
253 CONST UINT64
* pMemEnd
;
254 CONST UINT64
* pMemStart
;
264 // Send the Memory Type Registers page
268 // Send the page header
270 Status
= HttpPageHeader ( SocketFD
, pPort
, L
"Memory Type Range Registers" );
271 if ( EFI_ERROR ( Status
)) {
278 Status
= HttpSendAnsiString ( SocketFD
,
280 "<h1>Memory Type Range Registers</h1>\r\n" );
281 if ( EFI_ERROR ( Status
)) {
286 // Determine if MTRRs are supported
288 if ( !IsMtrrSupported ( )) {
289 Status
= HttpSendAnsiString ( SocketFD
,
291 "<p>Memory Type Range Registers are not supported!\r\n" );
292 if ( EFI_ERROR ( Status
)) {
298 // Get the capabilities
300 Capabilities
.Uint64
= AsmReadMsr64 ( MSR_IA32_MTRRCAP
);
301 DefType
.Uint64
= AsmReadMsr64 ( MSR_IA32_MTRR_DEF_TYPE
);
304 // Display the capabilities
306 Status
= HttpSendAnsiString ( SocketFD
,
308 "<p>Capabilities: " );
309 if ( EFI_ERROR ( Status
)) {
312 Status
= HttpSendHexValue ( SocketFD
,
314 Capabilities
.Uint64
);
315 if ( EFI_ERROR ( Status
)) {
318 Status
= HttpSendAnsiString ( SocketFD
,
321 if ( EFI_ERROR ( Status
)) {
326 // Display the default type
328 Status
= HttpSendAnsiString ( SocketFD
,
331 if ( EFI_ERROR ( Status
)) {
334 Status
= HttpSendHexValue ( SocketFD
,
337 if ( EFI_ERROR ( Status
)) {
340 Status
= HttpSendAnsiString ( SocketFD
,
343 if ( EFI_ERROR ( Status
)) {
346 Status
= HttpSendAnsiString ( SocketFD
,
348 ( 0 != DefType
.Bits
.E
)
351 if ( EFI_ERROR ( Status
)) {
354 Status
= HttpSendAnsiString ( SocketFD
,
357 if ( EFI_ERROR ( Status
)) {
360 Status
= HttpSendAnsiString ( SocketFD
,
362 ( 0 != DefType
.Bits
.FE
)
365 if ( EFI_ERROR ( Status
)) {
368 Status
= HttpSendAnsiString ( SocketFD
,
371 if ( EFI_ERROR ( Status
)) {
374 Type
= DefType
.Uint64
& 0xff;
375 Status
= HttpSendAnsiString ( SocketFD
,
377 ( DIM ( mMemoryType
) > Type
)
378 ? mMemoryType
[ Type
]
380 if ( EFI_ERROR ( Status
)) {
383 Status
= HttpSendAnsiString ( SocketFD
,
386 if ( EFI_ERROR ( Status
)) {
391 // Determine if MTRRs are enabled
393 if ( 0 == DefType
.Bits
.E
) {
394 Status
= HttpSendAnsiString ( SocketFD
,
396 "<p>All memory is uncached!</p>\r\n" );
397 if ( EFI_ERROR ( Status
)) {
405 MtrrGetAllMtrrs ( &Mtrr
);
408 // Determine if the fixed MTRRs are supported
410 if (( 0 != Capabilities
.Bits
.FIX
)
411 && ( 0 != DefType
.Bits
.FE
)) {
414 // Beginning of table
416 Status
= HttpSendAnsiString ( SocketFD
,
418 "<h2>Fixed MTRRs</h2>\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
)) {
426 // Display the fixed MTRRs
428 pMemStart
= &mFixedAddresses
[ 0 ];
429 for ( Count
= 0; DIM ( Mtrr
.Fixed
.Mtrr
) > Count
; Count
++ ) {
433 Status
= HttpSendAnsiString ( SocketFD
,
436 if ( EFI_ERROR ( Status
)) {
443 Status
= HttpSendValue ( SocketFD
,
446 if ( EFI_ERROR ( Status
)) {
453 Status
= HttpSendAnsiString ( SocketFD
,
455 "</td><td align=\"right\"><code>0x" );
456 if ( EFI_ERROR ( Status
)) {
459 Status
= HttpSendHexValue ( SocketFD
,
461 Mtrr
.Fixed
.Mtrr
[ Count
]);
462 if ( EFI_ERROR ( Status
)) {
469 Status
= HttpSendAnsiString ( SocketFD
,
471 "</code></td><td align=\"right\"><code>0x" );
472 if ( EFI_ERROR ( Status
)) {
475 Status
= HttpSendHexValue ( SocketFD
,
478 if ( EFI_ERROR ( Status
)) {
486 Status
= HttpSendAnsiString ( SocketFD
,
488 "</code></td><td align=\"right\"><code>0x" );
489 if ( EFI_ERROR ( Status
)) {
492 Status
= HttpSendHexValue ( SocketFD
,
495 if ( EFI_ERROR ( Status
)) {
502 Status
= HttpSendAnsiString ( SocketFD
,
504 "</code></td></tr>\r\n" );
505 if ( EFI_ERROR ( Status
)) {
509 if ( EFI_ERROR ( Status
)) {
516 Status
= HttpSendAnsiString ( SocketFD
,
519 if ( EFI_ERROR ( Status
)) {
524 // Beginning of table
526 Status
= HttpSendAnsiString ( SocketFD
,
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
)) {
535 // Decode the fixed MTRRs
537 PreviousType
= Mtrr
.Fixed
.Mtrr
[ 0 ] & 0xff;
538 pMemStart
= &mFixedAddresses
[ 0 ];
540 for ( Count
= 0; DIM ( Mtrr
.Fixed
.Mtrr
) > Count
; Count
++ ) {
542 // Get the memory types
544 Type
= Mtrr
.Fixed
.Mtrr
[ Count
];
547 // Walk the memory range
549 for ( Index
= 0; 8 > Index
; Index
++ ) {
551 // Determine if this is the same memory type
553 if ( PreviousType
!= ( Type
& 0xff )) {
557 Status
= MtrrDisplayFixedRow ( SocketFD
,
562 if ( EFI_ERROR ( Status
)) {
567 // Start the next range of addresses
570 PreviousType
= Type
& 0xff;
574 // Set the next memory range and type
579 if ( EFI_ERROR ( Status
)) {
583 if ( EFI_ERROR ( Status
)) {
588 // Display the final row
590 Status
= MtrrDisplayFixedRow ( SocketFD
,
595 if ( EFI_ERROR ( Status
)) {
602 Status
= HttpSendAnsiString ( SocketFD
,
605 if ( EFI_ERROR ( Status
)) {
611 // Determine if the variable MTRRs are supported
613 if ( 0 < Capabilities
.Bits
.VCNT
) {
615 // Beginning of table
617 Status
= HttpSendAnsiString ( SocketFD
,
619 "<h2>Variable MTRRs</h2>\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
)) {
627 // Display the variable MTRRs
629 for ( Count
= 0; Capabilities
.Bits
.VCNT
> Count
; Count
++ ) {
633 Status
= HttpSendAnsiString ( SocketFD
,
636 if ( EFI_ERROR ( Status
)) {
643 Status
= HttpSendValue ( SocketFD
,
646 if ( EFI_ERROR ( Status
)) {
653 Status
= HttpSendAnsiString ( SocketFD
,
655 "</td><td align=\"right\"><code>0x" );
656 if ( EFI_ERROR ( Status
)) {
659 Status
= HttpSendHexValue ( SocketFD
,
661 Mtrr
.Variables
.Mtrr
[ Count
].Base
);
662 if ( EFI_ERROR ( Status
)) {
669 Status
= HttpSendAnsiString ( SocketFD
,
671 "</td><td align=\"right\"><code>0x" );
672 if ( EFI_ERROR ( Status
)) {
675 Status
= HttpSendHexValue ( SocketFD
,
677 Mtrr
.Variables
.Mtrr
[ Count
].Mask
);
678 if ( EFI_ERROR ( Status
)) {
683 // Determine if the entry is valid
685 bValid
= ( Mtrr
.Variables
.Mtrr
[ Count
].Mask
& VARIABLE_MTRR_VALID
) ? TRUE
: FALSE
;
690 Status
= HttpSendAnsiString ( SocketFD
,
692 "</code></td><td align=\"right\"><code>" );
693 if ( EFI_ERROR ( Status
)) {
696 Addr
= Mtrr
.Variables
.Mtrr
[ Count
].Base
& 0xfffffffffffff000ULL
;
698 Status
= HttpSendAnsiString ( SocketFD
,
701 if ( EFI_ERROR ( Status
)) {
704 Status
= HttpSendHexValue ( SocketFD
,
709 Status
= HttpSendAnsiString ( SocketFD
,
713 if ( EFI_ERROR ( Status
)) {
720 Status
= HttpSendAnsiString ( SocketFD
,
722 "</code></td><td align=\"right\"><code>" );
723 if ( EFI_ERROR ( Status
)) {
728 // Determine the end address
730 Mask
= Mtrr
.Variables
.Mtrr
[ Count
].Mask
;
733 while ( 0 < Value
) {
738 Value
<<= 64 - ShiftCount
;
742 Value
&= ~VARIABLE_MTRR_VALID
;
745 Status
= HttpSendAnsiString ( SocketFD
,
748 if ( EFI_ERROR ( Status
)) {
751 Status
= HttpSendHexValue ( SocketFD
,
755 if ( EFI_ERROR ( Status
)) {
762 Status
= HttpSendAnsiString ( SocketFD
,
764 "</code></td><td>" );
765 if ( EFI_ERROR ( Status
)) {
769 Type
= Mtrr
.Variables
.Mtrr
[ Count
].Base
& 0xFF;
770 Status
= HttpSendAnsiString ( SocketFD
,
772 ( DIM ( mMemoryType
) > Type
)
773 ? mMemoryType
[ Type
]
776 if ( EFI_ERROR ( Status
)) {
783 Status
= HttpSendAnsiString ( SocketFD
,
786 if ( EFI_ERROR ( Status
)) {
790 if ( EFI_ERROR ( Status
)) {
797 Status
= HttpSendAnsiString ( SocketFD
,
800 if ( EFI_ERROR ( Status
)) {
808 // Send the page trailer
810 Status
= HttpPageTrailer ( SocketFD
, pPort
, pbDone
);
815 // Return the operation status
817 DBG_EXIT_STATUS ( Status
);