Skip to content

Commit 08ca318

Browse files
kenlautnerProjectMuBot
authored andcommitted
Add new MTRR Test Point test (#314)
## Description Add a new MTRR Test Point test that runs at Ready to Boot. This test checks the systems MTRRs at Ready to Boot versus the expected MTRR settings the platform publishes. Additional refactoring was done so that in the future MTRRs can be tested at other stages of boot if desired. - [ ] Impacts functionality? - [ ] Impacts security? - [ ] Breaking change? - [x] Includes tests? - [ ] Includes documentation? - [x] Backport to release branch? ## How This Was Tested Tested on Intel physical platforms. MTRRs were correctly read and validated at Ready to Boot. ## Integration Instructions Enable bit 6 in byte 4 of the `gMinPlatformPkgTokenSpaceGuid.PcdTestPointIbvPlatformFeature` PCD to actually run the test. Additionally, a platform will need to create their version of the function `GetPlatformMtrrCacheData`. This returns the expected MTRR cache settings will be at ready to boot which will be used for verification.
1 parent b0dda71 commit 08ca318

File tree

15 files changed

+697
-251
lines changed

15 files changed

+697
-251
lines changed

MinPlatformPkg/Include/Library/TestPointCheckLib.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,25 @@ TestPointReadyToBootTcgMorEnabled (
522522
VOID
523523
);
524524

525+
/**
526+
This service verifies MTRR settings at Ready to Boot
527+
528+
Test subject: MTRRs at Ready to Boot
529+
Test overview: Verifies MTRR settings.
530+
Reporting mechanism: Set ADAPTER_INFO_PLATFORM_TEST_POINT_STRUCT.
531+
Dumps results to the debug log.
532+
533+
Examples of settings verified: No MTRR overlap, DXE data memory is writeback, flash region may be UC, MMIO is UC, etc.
534+
535+
@retval EFI_SUCCESS The test point check was performed successfully.
536+
@retval EFI_UNSUPPORTED The test point check is not supported on this platform.
537+
**/
538+
EFI_STATUS
539+
EFIAPI
540+
TestPointReadyToBootMtrrFunctional (
541+
VOID
542+
);
543+
525544
/**
526545
This service verifies SMI handler profiling.
527546
@@ -771,6 +790,7 @@ TestPointPciEnumerationDonePcieGenSpeed (
771790
#define TEST_POINT_BYTE4_READY_TO_BOOT_UEFI_CONSOLE_VARIABLE_FUNCTIONAL BIT3
772791
#define TEST_POINT_BYTE4_READY_TO_BOOT_ACPI_TABLE_FUNCTIONAL BIT4
773792
#define TEST_POINT_BYTE4_READY_TO_BOOT_GCD_RESOURCE_FUNCTIONAL BIT5
793+
#define TEST_POINT_BYTE4_READY_TO_BOOT_MTRR_CACHE_VALID BIT6
774794
#define TEST_POINT_BYTE4_READY_TO_BOOT_MEMORY_TYPE_INFORMATION_FUNCTIONAL_ERROR_CODE L"0x04000000"
775795
#define TEST_POINT_BYTE4_READY_TO_BOOT_MEMORY_TYPE_INFORMATION_FUNCTIONAL_ERROR_STRING L"Invalid Memory Type Information\r\n"
776796
#define TEST_POINT_BYTE4_READY_TO_BOOT_UEFI_MEMORY_ATTRIBUTE_TABLE_FUNCTIONAL_ERROR_CODE L"0x04010000"
@@ -783,6 +803,8 @@ TestPointPciEnumerationDonePcieGenSpeed (
783803
#define TEST_POINT_BYTE4_READY_TO_BOOT_ACPI_TABLE_FUNCTIONAL_ERROR_STRING L"Invalid ACPI Table\r\n"
784804
#define TEST_POINT_BYTE4_READY_TO_BOOT_GCD_RESOURCE_FUNCTIONAL_ERROR_CODE L"0x04050000"
785805
#define TEST_POINT_BYTE4_READY_TO_BOOT_GCD_RESOURCE_FUNCTIONAL_ERROR_STRING L"Invalid GCD Resource\r\n"
806+
#define TEST_POINT_BYTE4_READY_TO_BOOT_MTRR_CACHE_VALID_ERROR_CODE L"0x04060000"
807+
#define TEST_POINT_BYTE4_READY_TO_BOOT_MTRR_CACHE_VALID_ERROR_STRING L"Invalid MTRR cache type\r\n"
786808

787809
#define TEST_POINT_BYTE5_READY_TO_BOOT_UEFI_SECURE_BOOT_ENABLED BIT0
788810
#define TEST_POINT_BYTE5_READY_TO_BOOT_PI_SIGNED_FV_BOOT_ENABLED BIT1
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/** @file
2+
TestPointMtrrInfoLib.h
3+
4+
An interface for platforms to define the expected MTRR cache types for specific
5+
regions. Create an array of VARIABLE_MTRR_INFO structures for every MTRR range
6+
that you want to validate. If any of the checked regions don't have the matching
7+
caching type the test will report an error for the failing range and return.
8+
9+
Copyright (c) Microsoft Corporation. All rights reserved.
10+
SPDX-License-Identifier: BSD-2-Clause-Patent
11+
12+
**/
13+
14+
#ifndef TEST_POINT_MTRR_INFO_LIB_H_
15+
#define TEST_POINT_MTRR_INFO_LIB_H_
16+
17+
#include <Uefi.h>
18+
19+
typedef struct {
20+
UINT64 BaseAddress;
21+
UINT64 Type;
22+
} VARIABLE_MTRR_INFO;
23+
24+
typedef enum {
25+
EndOfDxe,
26+
ReadyToLock,
27+
ReadyToBoot,
28+
ExitBootServices,
29+
MaxBootPoint
30+
} BOOT_POINT;
31+
32+
/**
33+
Assigns the input parameter pointer to a static array of VARIABLE_MTRR_INFO structures and returns
34+
the length of the array.
35+
36+
@param[out] CheckedMtrrs Pointer to the head of an array of VARIABLE_MTRR_INFO structures.
37+
The caller shall not free this array.
38+
@param[in] Boot Enum value that represents the stage of boot which we want the comparisons
39+
to be made.
40+
41+
@retval UINTN Length of the returned array.
42+
43+
**/
44+
UINTN
45+
EFIAPI
46+
GetPlatformMtrrCacheData (
47+
OUT VARIABLE_MTRR_INFO **CheckedMtrrs,
48+
IN BOOT_POINT Boot
49+
);
50+
51+
#endif
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/** @file
2+
TestPointMtrrInfoLibNull.c
3+
4+
An interface for platforms to define the expected MTRR cache types for specific
5+
regions. Create an array of VARIABLE_MTRR_INFO structures for every MTRR range
6+
that you want to validate. If any of the checked regions don't have the matching
7+
caching type the test will report an error for the failing range and return.
8+
9+
Copyright (c) Microsoft Corporation. All rights reserved.
10+
SPDX-License-Identifier: BSD-2-Clause-Patent
11+
12+
**/
13+
14+
#include <Uefi.h>
15+
16+
#include <Library/TestPointMtrrInfoLib.h>
17+
18+
/**
19+
Assigns the input parameter pointer to a static array of VARIABLE_MTRR_INFO structures and returns
20+
the length of the array.
21+
22+
@param[out] CheckedMtrrs Pointer to the head of an array of VARIABLE_MTRR_INFO structures.
23+
The caller shall not free this array.
24+
@param[in] Boot Enum value that represents the stage of boot which we want the comparisons
25+
to be made.
26+
27+
@retval UINTN Length of the returned array.
28+
29+
**/
30+
UINTN
31+
EFIAPI
32+
GetPlatformMtrrCacheData (
33+
OUT VARIABLE_MTRR_INFO **CheckedMtrrs,
34+
IN BOOT_POINT Boot
35+
36+
)
37+
{
38+
return 0;
39+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
## @file
2+
# TestPointMtrrInfoLibNull.inf
3+
#
4+
# Null implementation of the TestPointMtrrInfoLib class that doesn't return any MTRRs that we want to check.
5+
# This is for compatibility purposes.
6+
#
7+
##
8+
# Copyright (c) Microsoft Corporation. All rights reserved.
9+
# SPDX-License-Identifier: BSD-2-Clause-Patent
10+
##
11+
12+
[Defines]
13+
INF_VERSION = 0x00010006
14+
BASE_NAME = TestPointMtrrInfoLibNull
15+
FILE_GUID = b015a43a-7ca3-4c68-80dd-5a9840bbf2bb
16+
VERSION_STRING = 1.0
17+
MODULE_TYPE = BASE
18+
LIBRARY_CLASS = TestPointMtrrInfoLib
19+
20+
[Sources]
21+
TestPointMtrrInfoLibNull.c
22+
23+
[Packages]
24+
MdePkg/MdePkg.dec
25+
MinPlatformPkg/MinPlatformPkg.dec

MinPlatformPkg/MinPlatformPkg.dec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
LargeVariableReadLib|Include/Library/LargeVariableReadLib.h
9292
LargeVariableWriteLib|Include/Library/LargeVariableWriteLib.h
9393
TestPointPciSpeedInfoLib|Include/Library/TestPointPciSpeedInfoLib.h
94+
TestPointMtrrInfoLib|Include/Library/TestPointMtrrInfoLib.h
9495

9596
PhatAcpiLib|Include/Library/PhatAcpiLib.h
9697

MinPlatformPkg/MinPlatformPkg.dsc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@
8888
NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf # MU_CHANGE: /GS and -fstack-protector support
8989
TestPointCheckLib|MinPlatformPkg/Test/Library/TestPointCheckLibNull/TestPointCheckLibNull.inf
9090
TestPointPciSpeedInfoLib|MinPlatformPkg/Library/TestPointPciSpeedInfoLibNull/TestPointPciSpeedInfoLibNull.inf
91+
TestPointMtrrInfoLib|MinPlatformPkg/Library/TestPointMtrrInfoLibNull/TestPointMtrrInfoLibNull.inf
9192

9293
[LibraryClasses.common.SEC]
9394
TestPointCheckLib|MinPlatformPkg/Test/Library/TestPointCheckLib/SecTestPointCheckLib.inf
@@ -225,6 +226,7 @@
225226
MinPlatformPkg/Test/TestPointStubDxe/TestPointStubDxeMm.inf
226227
MinPlatformPkg/Test/TestPointDumpApp/TestPointDumpApp.inf
227228
MinPlatformPkg/Library/TestPointPciSpeedInfoLibNull/TestPointPciSpeedInfoLibNull.inf
229+
MinPlatformPkg/Library/TestPointMtrrInfoLibNull/TestPointMtrrInfoLibNull.inf
228230

229231
MinPlatformPkg/Library/BaseVariableReadLibNull/BaseVariableReadLibNull.inf
230232
MinPlatformPkg/Library/SmmVariableReadLib/StandaloneMmVariableReadLib.inf

MinPlatformPkg/PlatformInit/PlatformInitDxe/PlatformInitDxe.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ OnReadyToBootLater (
147147
TestPointReadyToBootHstiTableFunctional ();
148148
TestPointReadyToBootAcpiTableFunctional ();
149149
TestPointReadyToBootGcdResourceFunctional ();
150+
TestPointReadyToBootMtrrFunctional (); // MU_CHANGE
150151

151152
TestPointDxeSmmReadyToBootSmiHandlerInstrument ();
152153
TestPointDxeSmmReadyToBootSmmPageProtection ();
@@ -155,6 +156,7 @@ OnReadyToBootLater (
155156
TestPointReadyToBootPiSignedFvBootEnabled ();
156157
TestPointReadyToBootTcgTrustedBootEnabled ();
157158
TestPointReadyToBootTcgMorEnabled ();
159+
158160
TestPointReadyToBootEsrtTableFunctional ();
159161
}
160162

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
/** @file
2+
3+
Copyright (c) Microsoft Corporation. All rights reserved.
4+
SPDX-License-Identifier: BSD-2-Clause-Patent
5+
6+
**/
7+
8+
#include <Uefi.h>
9+
#include <Library/TestPointCheckLib.h>
10+
#include <Library/TestPointLib.h>
11+
#include <Library/DebugLib.h>
12+
#include <Library/HobLib.h>
13+
#include <Library/BaseMemoryLib.h>
14+
#include <Library/MtrrLib.h>
15+
#include <Library/TestPointMtrrInfoLib.h>
16+
#include "TestPointCheckMtrr.h"
17+
18+
EFI_STATUS
19+
TestPointCheckMtrrForDxe (
20+
IN MTRR_SETTINGS *Mtrrs,
21+
IN VARIABLE_MTRR *VariableMtrr
22+
)
23+
{
24+
UINTN VariableMtrrIndex;
25+
UINTN VariableMtrrCount;
26+
VARIABLE_MTRR_INFO *ExpectedMtrrs;
27+
UINTN ExpectedMtrrsIndex;
28+
UINTN ExpectedMtrrsCount;
29+
BOOLEAN Found;
30+
31+
ExpectedMtrrsCount = GetPlatformMtrrCacheData (&ExpectedMtrrs, ReadyToBoot);
32+
VariableMtrrCount = GetVariableMtrrCount ();
33+
34+
if ((ExpectedMtrrs == NULL) || (ExpectedMtrrsCount == 0)) {
35+
return EFI_NOT_FOUND;
36+
}
37+
38+
//
39+
// Check if the MTRR types match
40+
//
41+
for (VariableMtrrIndex = 0; VariableMtrrIndex < VariableMtrrCount; VariableMtrrIndex++) {
42+
Found = FALSE;
43+
if (!VariableMtrr[VariableMtrrIndex].Valid) {
44+
continue;
45+
}
46+
47+
for (ExpectedMtrrsIndex = 0; ExpectedMtrrsIndex < ExpectedMtrrsCount; ExpectedMtrrsIndex++) {
48+
if (ExpectedMtrrs[ExpectedMtrrsIndex].BaseAddress == VariableMtrr[VariableMtrrIndex].BaseAddress) {
49+
if (ExpectedMtrrs[ExpectedMtrrsIndex].Type != VariableMtrr[VariableMtrrIndex].Type) {
50+
DEBUG ((
51+
DEBUG_ERROR,
52+
"The Mtrr with BaseAddress: 0x%016lx has the incorrect cache type: %d! Expected: %d\n",
53+
VariableMtrr[VariableMtrrIndex].BaseAddress,
54+
VariableMtrr[VariableMtrrIndex].Type,
55+
ExpectedMtrrs[ExpectedMtrrsIndex].Type
56+
));
57+
return EFI_SECURITY_VIOLATION;
58+
}
59+
60+
Found = TRUE;
61+
DEBUG ((DEBUG_INFO, "Found MTRR at address %016lx and it has the expected caching type\n", VariableMtrr[VariableMtrrIndex].BaseAddress));
62+
break;
63+
}
64+
}
65+
66+
if (!Found) {
67+
DEBUG ((
68+
DEBUG_INFO,
69+
"The Mtrr with BaseAddress: 0x%016lx did not have a policy to check against.\n",
70+
VariableMtrr[VariableMtrrIndex].BaseAddress
71+
));
72+
}
73+
}
74+
75+
return EFI_SUCCESS;
76+
}
77+
78+
EFI_STATUS
79+
TestPointCheckMtrr (
80+
VOID
81+
)
82+
{
83+
EFI_STATUS Status;
84+
MTRR_SETTINGS LocalMtrrs;
85+
MTRR_SETTINGS *Mtrrs;
86+
UINTN Index;
87+
UINTN VariableMtrrCount;
88+
BOOLEAN Result;
89+
VARIABLE_MTRR VariableMtrr[MTRR_NUMBER_OF_VARIABLE_MTRR];
90+
91+
DEBUG ((DEBUG_INFO, "==== TestPointCheckMtrr - Enter\n"));
92+
93+
MtrrGetAllMtrrs (&LocalMtrrs);
94+
Mtrrs = &LocalMtrrs;
95+
DEBUG ((DEBUG_INFO, "MTRR Default Type: %016lx\n", Mtrrs->MtrrDefType));
96+
for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {
97+
DEBUG ((DEBUG_INFO, "Fixed MTRR[%02d] : %016lx\n", Index, Mtrrs->Fixed.Mtrr[Index]));
98+
}
99+
100+
VariableMtrrCount = GetVariableMtrrCount ();
101+
for (Index = 0; Index < VariableMtrrCount; Index++) {
102+
DEBUG ((
103+
DEBUG_INFO,
104+
"Variable MTRR[%02d]: Base=%016lx Mask=%016lx\n",
105+
Index,
106+
Mtrrs->Variables.Mtrr[Index].Base,
107+
Mtrrs->Variables.Mtrr[Index].Mask
108+
));
109+
}
110+
111+
DEBUG ((DEBUG_INFO, "\n"));
112+
DEBUG ((DEBUG_INFO, "==== TestPointCheckMtrr - Exit\n"));
113+
114+
//
115+
// Check Mask
116+
//
117+
Status = TestPointCheckMtrrMask (Mtrrs);
118+
if (EFI_ERROR (Status)) {
119+
Result = FALSE;
120+
} else {
121+
ZeroMem (VariableMtrr, sizeof (VariableMtrr));
122+
TestPointMtrrConvert (Mtrrs, VariableMtrr);
123+
124+
Status = TestPointCheckMtrrForDxe (Mtrrs, VariableMtrr);
125+
126+
if (EFI_ERROR (Status)) {
127+
Result = FALSE;
128+
} else {
129+
Result = TRUE;
130+
}
131+
}
132+
133+
// Print error string if we failed
134+
if (!Result) {
135+
TestPointLibAppendErrorString (
136+
PLATFORM_TEST_POINT_ROLE_PLATFORM_IBV,
137+
TEST_POINT_IMPLEMENTATION_ID_PLATFORM_PEI,
138+
TEST_POINT_BYTE4_READY_TO_BOOT_MTRR_CACHE_VALID_ERROR_CODE \
139+
TEST_POINT_READY_TO_BOOT \
140+
TEST_POINT_BYTE4_READY_TO_BOOT_MTRR_CACHE_VALID_ERROR_STRING
141+
);
142+
}
143+
144+
return Status;
145+
}

0 commit comments

Comments
 (0)