3 Display the memory type range registers
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
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.
16 #include <WebServer.h>
17 #include <Library/MtrrLib.h>
18 #include <Register/Msr.h>
20 #define VARIABLE_MTRR_VALID 0x800
22 CONST
char * mMemoryType
[ ] = {
34 Display a fixed MTRR row
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
42 @retval EFI_SUCCESS The request was successfully processed
57 // Use break instead of goto
63 Status
= HttpSendAnsiString ( SocketFD
,
65 " <tr><td align=\"right\"><code>0x" );
66 if ( EFI_ERROR ( Status
)) {
73 Status
= HttpSendHexValue ( SocketFD
,
76 if ( EFI_ERROR ( Status
)) {
83 Status
= HttpSendAnsiString ( SocketFD
,
85 "</code></td><td align=\"right\"><code>0x" );
86 if ( EFI_ERROR ( Status
)) {
89 Status
= HttpSendHexValue ( SocketFD
,
92 if ( EFI_ERROR ( Status
)) {
99 Status
= HttpSendAnsiString ( SocketFD
,
101 "</code></td><td>" );
102 if ( EFI_ERROR ( Status
)) {
106 Status
= HttpSendAnsiString ( SocketFD
,
108 ( DIM ( mMemoryType
) > Type
)
109 ? mMemoryType
[ Type
]
111 if ( EFI_ERROR ( Status
)) {
118 Status
= HttpSendAnsiString ( SocketFD
,
125 // Return the final status
132 Display the memory type registers
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
138 @retval EFI_SUCCESS The request was successfully processed
142 MemoryTypeRegistersPage (
144 IN WSDT_PORT
* pPort
,
150 MSR_IA32_MTRRCAP_REGISTER Capabilities
;
152 MSR_IA32_MTRR_DEF_TYPE_REGISTER DefType
;
156 CONST UINT64 mFixedAddresses
[( 8 * MTRR_NUMBER_OF_FIXED_MTRR
) + 1 ] = {
259 CONST UINT64
* pMemEnd
;
260 CONST UINT64
* pMemStart
;
270 // Send the Memory Type Registers page
274 // Send the page header
276 Status
= HttpPageHeader ( SocketFD
, pPort
, L
"Memory Type Range Registers" );
277 if ( EFI_ERROR ( Status
)) {
284 Status
= HttpSendAnsiString ( SocketFD
,
286 "<h1>Memory Type Range Registers</h1>\r\n" );
287 if ( EFI_ERROR ( Status
)) {
292 // Determine if MTRRs are supported
294 if ( !IsMtrrSupported ( )) {
295 Status
= HttpSendAnsiString ( SocketFD
,
297 "<p>Memory Type Range Registers are not supported!\r\n" );
298 if ( EFI_ERROR ( Status
)) {
304 // Get the capabilities
306 Capabilities
.Uint64
= AsmReadMsr64 ( MSR_IA32_MTRRCAP
);
307 DefType
.Uint64
= AsmReadMsr64 ( MSR_IA32_MTRR_DEF_TYPE
);
310 // Display the capabilities
312 Status
= HttpSendAnsiString ( SocketFD
,
314 "<p>Capabilities: " );
315 if ( EFI_ERROR ( Status
)) {
318 Status
= HttpSendHexValue ( SocketFD
,
320 Capabilities
.Uint64
);
321 if ( EFI_ERROR ( Status
)) {
324 Status
= HttpSendAnsiString ( SocketFD
,
327 if ( EFI_ERROR ( Status
)) {
332 // Display the default type
334 Status
= HttpSendAnsiString ( SocketFD
,
337 if ( EFI_ERROR ( Status
)) {
340 Status
= HttpSendHexValue ( SocketFD
,
343 if ( EFI_ERROR ( Status
)) {
346 Status
= HttpSendAnsiString ( SocketFD
,
349 if ( EFI_ERROR ( Status
)) {
352 Status
= HttpSendAnsiString ( SocketFD
,
354 ( 0 != DefType
.Bits
.E
)
357 if ( EFI_ERROR ( Status
)) {
360 Status
= HttpSendAnsiString ( SocketFD
,
363 if ( EFI_ERROR ( Status
)) {
366 Status
= HttpSendAnsiString ( SocketFD
,
368 ( 0 != DefType
.Bits
.FE
)
371 if ( EFI_ERROR ( Status
)) {
374 Status
= HttpSendAnsiString ( SocketFD
,
377 if ( EFI_ERROR ( Status
)) {
380 Type
= DefType
.Uint64
& 0xff;
381 Status
= HttpSendAnsiString ( SocketFD
,
383 ( DIM ( mMemoryType
) > Type
)
384 ? mMemoryType
[ Type
]
386 if ( EFI_ERROR ( Status
)) {
389 Status
= HttpSendAnsiString ( SocketFD
,
392 if ( EFI_ERROR ( Status
)) {
397 // Determine if MTRRs are enabled
399 if ( 0 == DefType
.Bits
.E
) {
400 Status
= HttpSendAnsiString ( SocketFD
,
402 "<p>All memory is uncached!</p>\r\n" );
403 if ( EFI_ERROR ( Status
)) {
411 MtrrGetAllMtrrs ( &Mtrr
);
414 // Determine if the fixed MTRRs are supported
416 if (( 0 != Capabilities
.Bits
.FIX
)
417 && ( 0 != DefType
.Bits
.FE
)) {
420 // Beginning of table
422 Status
= HttpSendAnsiString ( SocketFD
,
424 "<h2>Fixed MTRRs</h2>\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
)) {
432 // Display the fixed MTRRs
434 pMemStart
= &mFixedAddresses
[ 0 ];
435 for ( Count
= 0; DIM ( Mtrr
.Fixed
.Mtrr
) > Count
; Count
++ ) {
439 Status
= HttpSendAnsiString ( SocketFD
,
442 if ( EFI_ERROR ( Status
)) {
449 Status
= HttpSendValue ( SocketFD
,
452 if ( EFI_ERROR ( Status
)) {
459 Status
= HttpSendAnsiString ( SocketFD
,
461 "</td><td align=\"right\"><code>0x" );
462 if ( EFI_ERROR ( Status
)) {
465 Status
= HttpSendHexValue ( SocketFD
,
467 Mtrr
.Fixed
.Mtrr
[ Count
]);
468 if ( EFI_ERROR ( Status
)) {
475 Status
= HttpSendAnsiString ( SocketFD
,
477 "</code></td><td align=\"right\"><code>0x" );
478 if ( EFI_ERROR ( Status
)) {
481 Status
= HttpSendHexValue ( SocketFD
,
484 if ( EFI_ERROR ( Status
)) {
492 Status
= HttpSendAnsiString ( SocketFD
,
494 "</code></td><td align=\"right\"><code>0x" );
495 if ( EFI_ERROR ( Status
)) {
498 Status
= HttpSendHexValue ( SocketFD
,
501 if ( EFI_ERROR ( Status
)) {
508 Status
= HttpSendAnsiString ( SocketFD
,
510 "</code></td></tr>\r\n" );
511 if ( EFI_ERROR ( Status
)) {
515 if ( EFI_ERROR ( Status
)) {
522 Status
= HttpSendAnsiString ( SocketFD
,
525 if ( EFI_ERROR ( Status
)) {
530 // Beginning of table
532 Status
= HttpSendAnsiString ( SocketFD
,
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
)) {
541 // Decode the fixed MTRRs
543 PreviousType
= Mtrr
.Fixed
.Mtrr
[ 0 ] & 0xff;
544 pMemStart
= &mFixedAddresses
[ 0 ];
546 for ( Count
= 0; DIM ( Mtrr
.Fixed
.Mtrr
) > Count
; Count
++ ) {
548 // Get the memory types
550 Type
= Mtrr
.Fixed
.Mtrr
[ Count
];
553 // Walk the memory range
555 for ( Index
= 0; 8 > Index
; Index
++ ) {
557 // Determine if this is the same memory type
559 if ( PreviousType
!= ( Type
& 0xff )) {
563 Status
= MtrrDisplayFixedRow ( SocketFD
,
568 if ( EFI_ERROR ( Status
)) {
573 // Start the next range of addresses
576 PreviousType
= Type
& 0xff;
580 // Set the next memory range and type
585 if ( EFI_ERROR ( Status
)) {
589 if ( EFI_ERROR ( Status
)) {
594 // Display the final row
596 Status
= MtrrDisplayFixedRow ( SocketFD
,
601 if ( EFI_ERROR ( Status
)) {
608 Status
= HttpSendAnsiString ( SocketFD
,
611 if ( EFI_ERROR ( Status
)) {
617 // Determine if the variable MTRRs are supported
619 if ( 0 < Capabilities
.Bits
.VCNT
) {
621 // Beginning of table
623 Status
= HttpSendAnsiString ( SocketFD
,
625 "<h2>Variable MTRRs</h2>\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
)) {
633 // Display the variable MTRRs
635 for ( Count
= 0; Capabilities
.Bits
.VCNT
> Count
; Count
++ ) {
639 Status
= HttpSendAnsiString ( SocketFD
,
642 if ( EFI_ERROR ( Status
)) {
649 Status
= HttpSendValue ( SocketFD
,
652 if ( EFI_ERROR ( Status
)) {
659 Status
= HttpSendAnsiString ( SocketFD
,
661 "</td><td align=\"right\"><code>0x" );
662 if ( EFI_ERROR ( Status
)) {
665 Status
= HttpSendHexValue ( SocketFD
,
667 Mtrr
.Variables
.Mtrr
[ Count
].Base
);
668 if ( EFI_ERROR ( Status
)) {
675 Status
= HttpSendAnsiString ( SocketFD
,
677 "</td><td align=\"right\"><code>0x" );
678 if ( EFI_ERROR ( Status
)) {
681 Status
= HttpSendHexValue ( SocketFD
,
683 Mtrr
.Variables
.Mtrr
[ Count
].Mask
);
684 if ( EFI_ERROR ( Status
)) {
689 // Determine if the entry is valid
691 bValid
= ( Mtrr
.Variables
.Mtrr
[ Count
].Mask
& VARIABLE_MTRR_VALID
) ? TRUE
: FALSE
;
696 Status
= HttpSendAnsiString ( SocketFD
,
698 "</code></td><td align=\"right\"><code>" );
699 if ( EFI_ERROR ( Status
)) {
702 Addr
= Mtrr
.Variables
.Mtrr
[ Count
].Base
& 0xfffffffffffff000ULL
;
704 Status
= HttpSendAnsiString ( SocketFD
,
707 if ( EFI_ERROR ( Status
)) {
710 Status
= HttpSendHexValue ( SocketFD
,
715 Status
= HttpSendAnsiString ( SocketFD
,
719 if ( EFI_ERROR ( Status
)) {
726 Status
= HttpSendAnsiString ( SocketFD
,
728 "</code></td><td align=\"right\"><code>" );
729 if ( EFI_ERROR ( Status
)) {
734 // Determine the end address
736 Mask
= Mtrr
.Variables
.Mtrr
[ Count
].Mask
;
739 while ( 0 < Value
) {
744 Value
<<= 64 - ShiftCount
;
748 Value
&= ~VARIABLE_MTRR_VALID
;
751 Status
= HttpSendAnsiString ( SocketFD
,
754 if ( EFI_ERROR ( Status
)) {
757 Status
= HttpSendHexValue ( SocketFD
,
761 if ( EFI_ERROR ( Status
)) {
768 Status
= HttpSendAnsiString ( SocketFD
,
770 "</code></td><td>" );
771 if ( EFI_ERROR ( Status
)) {
775 Type
= Mtrr
.Variables
.Mtrr
[ Count
].Base
& 0xFF;
776 Status
= HttpSendAnsiString ( SocketFD
,
778 ( DIM ( mMemoryType
) > Type
)
779 ? mMemoryType
[ Type
]
782 if ( EFI_ERROR ( Status
)) {
789 Status
= HttpSendAnsiString ( SocketFD
,
792 if ( EFI_ERROR ( Status
)) {
796 if ( EFI_ERROR ( Status
)) {
803 Status
= HttpSendAnsiString ( SocketFD
,
806 if ( EFI_ERROR ( Status
)) {
814 // Send the page trailer
816 Status
= HttpPageTrailer ( SocketFD
, pPort
, pbDone
);
821 // Return the operation status
823 DBG_EXIT_STATUS ( Status
);