MtrrLibUnitTest.c 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212
  1. /** @file
  2. Unit tests of the MtrrLib instance of the MtrrLib class
  3. Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include "MtrrLibUnitTest.h"
  7. STATIC CONST MTRR_LIB_SYSTEM_PARAMETER mDefaultSystemParameter = {
  8. 42, TRUE, TRUE, CacheUncacheable, 12
  9. };
  10. STATIC MTRR_LIB_SYSTEM_PARAMETER mSystemParameters[] = {
  11. { 38, TRUE, TRUE, CacheUncacheable, 12 },
  12. { 38, TRUE, TRUE, CacheWriteBack, 12 },
  13. { 38, TRUE, TRUE, CacheWriteThrough, 12 },
  14. { 38, TRUE, TRUE, CacheWriteProtected, 12 },
  15. { 38, TRUE, TRUE, CacheWriteCombining, 12 },
  16. { 42, TRUE, TRUE, CacheUncacheable, 12 },
  17. { 42, TRUE, TRUE, CacheWriteBack, 12 },
  18. { 42, TRUE, TRUE, CacheWriteThrough, 12 },
  19. { 42, TRUE, TRUE, CacheWriteProtected, 12 },
  20. { 42, TRUE, TRUE, CacheWriteCombining, 12 },
  21. { 48, TRUE, TRUE, CacheUncacheable, 12 },
  22. { 48, TRUE, TRUE, CacheWriteBack, 12 },
  23. { 48, TRUE, TRUE, CacheWriteThrough, 12 },
  24. { 48, TRUE, TRUE, CacheWriteProtected, 12 },
  25. { 48, TRUE, TRUE, CacheWriteCombining, 12 },
  26. };
  27. UINT32 mFixedMtrrsIndex[] = {
  28. MSR_IA32_MTRR_FIX64K_00000,
  29. MSR_IA32_MTRR_FIX16K_80000,
  30. MSR_IA32_MTRR_FIX16K_A0000,
  31. MSR_IA32_MTRR_FIX4K_C0000,
  32. MSR_IA32_MTRR_FIX4K_C8000,
  33. MSR_IA32_MTRR_FIX4K_D0000,
  34. MSR_IA32_MTRR_FIX4K_D8000,
  35. MSR_IA32_MTRR_FIX4K_E0000,
  36. MSR_IA32_MTRR_FIX4K_E8000,
  37. MSR_IA32_MTRR_FIX4K_F0000,
  38. MSR_IA32_MTRR_FIX4K_F8000
  39. };
  40. STATIC_ASSERT (
  41. (ARRAY_SIZE (mFixedMtrrsIndex) == MTRR_NUMBER_OF_FIXED_MTRR),
  42. "gFixedMtrrIndex does NOT contain all the fixed MTRRs!"
  43. );
  44. //
  45. // Context structure to be used for most of the test cases.
  46. //
  47. typedef struct {
  48. CONST MTRR_LIB_SYSTEM_PARAMETER *SystemParameter;
  49. } MTRR_LIB_TEST_CONTEXT;
  50. //
  51. // Context structure to be used for GetFirmwareVariableMtrrCount() test.
  52. //
  53. typedef struct {
  54. UINT32 NumberOfReservedVariableMtrrs;
  55. CONST MTRR_LIB_SYSTEM_PARAMETER *SystemParameter;
  56. } MTRR_LIB_GET_FIRMWARE_VARIABLE_MTRR_COUNT_CONTEXT;
  57. STATIC CHAR8 *mCacheDescription[] = { "UC", "WC", "N/A", "N/A", "WT", "WP", "WB" };
  58. /**
  59. Compare the actual memory ranges against expected memory ranges and return PASS when they match.
  60. @param ExpectedMemoryRanges Expected memory ranges.
  61. @param ExpectedMemoryRangeCount Count of expected memory ranges.
  62. @param ActualRanges Actual memory ranges.
  63. @param ActualRangeCount Count of actual memory ranges.
  64. @retval UNIT_TEST_PASSED Test passed.
  65. @retval others Test failed.
  66. **/
  67. UNIT_TEST_STATUS
  68. VerifyMemoryRanges (
  69. IN MTRR_MEMORY_RANGE *ExpectedMemoryRanges,
  70. IN UINTN ExpectedMemoryRangeCount,
  71. IN MTRR_MEMORY_RANGE *ActualRanges,
  72. IN UINTN ActualRangeCount
  73. )
  74. {
  75. UINTN Index;
  76. UT_ASSERT_EQUAL (ExpectedMemoryRangeCount, ActualRangeCount);
  77. for (Index = 0; Index < ExpectedMemoryRangeCount; Index++) {
  78. UT_ASSERT_EQUAL (ExpectedMemoryRanges[Index].BaseAddress, ActualRanges[Index].BaseAddress);
  79. UT_ASSERT_EQUAL (ExpectedMemoryRanges[Index].Length, ActualRanges[Index].Length);
  80. UT_ASSERT_EQUAL (ExpectedMemoryRanges[Index].Type, ActualRanges[Index].Type);
  81. }
  82. return UNIT_TEST_PASSED;
  83. }
  84. /**
  85. Dump the memory ranges.
  86. @param Ranges Memory ranges to dump.
  87. @param RangeCount Count of memory ranges.
  88. **/
  89. VOID
  90. DumpMemoryRanges (
  91. MTRR_MEMORY_RANGE *Ranges,
  92. UINTN RangeCount
  93. )
  94. {
  95. UINTN Index;
  96. for (Index = 0; Index < RangeCount; Index++) {
  97. UT_LOG_INFO ("\t{ 0x%016llx, 0x%016llx, %a },\n", Ranges[Index].BaseAddress, Ranges[Index].Length, mCacheDescription[Ranges[Index].Type]);
  98. }
  99. }
  100. /**
  101. **/
  102. /**
  103. Generate random count of MTRRs for each cache type.
  104. @param TotalCount Total MTRR count.
  105. @param UcCount Return count of Uncacheable type.
  106. @param WtCount Return count of Write Through type.
  107. @param WbCount Return count of Write Back type.
  108. @param WpCount Return count of Write Protected type.
  109. @param WcCount Return count of Write Combining type.
  110. **/
  111. VOID
  112. GenerateRandomMemoryTypeCombination (
  113. IN UINT32 TotalCount,
  114. OUT UINT32 *UcCount,
  115. OUT UINT32 *WtCount,
  116. OUT UINT32 *WbCount,
  117. OUT UINT32 *WpCount,
  118. OUT UINT32 *WcCount
  119. )
  120. {
  121. UINTN Index;
  122. UINT32 TotalMtrrCount;
  123. UINT32 *CountPerType[5];
  124. CountPerType[0] = UcCount;
  125. CountPerType[1] = WtCount;
  126. CountPerType[2] = WbCount;
  127. CountPerType[3] = WpCount;
  128. CountPerType[4] = WcCount;
  129. //
  130. // Initialize the count of each cache type to 0.
  131. //
  132. for (Index = 0; Index < ARRAY_SIZE (CountPerType); Index++) {
  133. *(CountPerType[Index]) = 0;
  134. }
  135. //
  136. // Pick a random count of MTRRs
  137. //
  138. TotalMtrrCount = Random32 (1, TotalCount);
  139. for (Index = 0; Index < TotalMtrrCount; Index++) {
  140. //
  141. // For each of them, pick a random cache type.
  142. //
  143. (*(CountPerType[Random32 (0, ARRAY_SIZE (CountPerType) - 1)]))++;
  144. }
  145. }
  146. /**
  147. Unit test of MtrrLib service MtrrSetMemoryAttribute()
  148. @param[in] Context Ignored
  149. @retval UNIT_TEST_PASSED The Unit test has completed and the test
  150. case was successful.
  151. @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
  152. **/
  153. UNIT_TEST_STATUS
  154. EFIAPI
  155. UnitTestMtrrSetMemoryAttributesInMtrrSettings (
  156. IN UNIT_TEST_CONTEXT Context
  157. )
  158. {
  159. CONST MTRR_LIB_SYSTEM_PARAMETER *SystemParameter;
  160. RETURN_STATUS Status;
  161. UINT32 UcCount;
  162. UINT32 WtCount;
  163. UINT32 WbCount;
  164. UINT32 WpCount;
  165. UINT32 WcCount;
  166. UINT32 MtrrIndex;
  167. UINT8 *Scratch;
  168. UINTN ScratchSize;
  169. MTRR_SETTINGS LocalMtrrs;
  170. MTRR_MEMORY_RANGE RawMtrrRange[MTRR_NUMBER_OF_VARIABLE_MTRR];
  171. MTRR_MEMORY_RANGE ExpectedMemoryRanges[MTRR_NUMBER_OF_FIXED_MTRR * sizeof (UINT64) + 2 * MTRR_NUMBER_OF_VARIABLE_MTRR + 1];
  172. UINT32 ExpectedVariableMtrrUsage;
  173. UINTN ExpectedMemoryRangesCount;
  174. MTRR_MEMORY_RANGE ActualMemoryRanges[MTRR_NUMBER_OF_FIXED_MTRR * sizeof (UINT64) + 2 * MTRR_NUMBER_OF_VARIABLE_MTRR + 1];
  175. UINT32 ActualVariableMtrrUsage;
  176. UINTN ActualMemoryRangesCount;
  177. MTRR_SETTINGS *Mtrrs[2];
  178. SystemParameter = (MTRR_LIB_SYSTEM_PARAMETER *)Context;
  179. GenerateRandomMemoryTypeCombination (
  180. SystemParameter->VariableMtrrCount - PatchPcdGet32 (PcdCpuNumberOfReservedVariableMtrrs),
  181. &UcCount,
  182. &WtCount,
  183. &WbCount,
  184. &WpCount,
  185. &WcCount
  186. );
  187. GenerateValidAndConfigurableMtrrPairs (
  188. SystemParameter->PhysicalAddressBits,
  189. RawMtrrRange,
  190. UcCount,
  191. WtCount,
  192. WbCount,
  193. WpCount,
  194. WcCount
  195. );
  196. ExpectedVariableMtrrUsage = UcCount + WtCount + WbCount + WpCount + WcCount;
  197. ExpectedMemoryRangesCount = ARRAY_SIZE (ExpectedMemoryRanges);
  198. GetEffectiveMemoryRanges (
  199. SystemParameter->DefaultCacheType,
  200. SystemParameter->PhysicalAddressBits,
  201. RawMtrrRange,
  202. ExpectedVariableMtrrUsage,
  203. ExpectedMemoryRanges,
  204. &ExpectedMemoryRangesCount
  205. );
  206. UT_LOG_INFO (
  207. "Total MTRR [%d]: UC=%d, WT=%d, WB=%d, WP=%d, WC=%d\n",
  208. ExpectedVariableMtrrUsage,
  209. UcCount,
  210. WtCount,
  211. WbCount,
  212. WpCount,
  213. WcCount
  214. );
  215. UT_LOG_INFO ("--- Expected Memory Ranges [%d] ---\n", ExpectedMemoryRangesCount);
  216. DumpMemoryRanges (ExpectedMemoryRanges, ExpectedMemoryRangesCount);
  217. //
  218. // Default cache type is always an INPUT
  219. //
  220. ZeroMem (&LocalMtrrs, sizeof (LocalMtrrs));
  221. LocalMtrrs.MtrrDefType = MtrrGetDefaultMemoryType ();
  222. ScratchSize = SCRATCH_BUFFER_SIZE;
  223. Mtrrs[0] = &LocalMtrrs;
  224. Mtrrs[1] = NULL;
  225. for (MtrrIndex = 0; MtrrIndex < ARRAY_SIZE (Mtrrs); MtrrIndex++) {
  226. Scratch = calloc (ScratchSize, sizeof (UINT8));
  227. Status = MtrrSetMemoryAttributesInMtrrSettings (Mtrrs[MtrrIndex], Scratch, &ScratchSize, ExpectedMemoryRanges, ExpectedMemoryRangesCount);
  228. if (Status == RETURN_BUFFER_TOO_SMALL) {
  229. Scratch = realloc (Scratch, ScratchSize);
  230. Status = MtrrSetMemoryAttributesInMtrrSettings (Mtrrs[MtrrIndex], Scratch, &ScratchSize, ExpectedMemoryRanges, ExpectedMemoryRangesCount);
  231. }
  232. UT_ASSERT_STATUS_EQUAL (Status, RETURN_SUCCESS);
  233. if (Mtrrs[MtrrIndex] == NULL) {
  234. ZeroMem (&LocalMtrrs, sizeof (LocalMtrrs));
  235. MtrrGetAllMtrrs (&LocalMtrrs);
  236. }
  237. ActualMemoryRangesCount = ARRAY_SIZE (ActualMemoryRanges);
  238. CollectTestResult (
  239. SystemParameter->DefaultCacheType,
  240. SystemParameter->PhysicalAddressBits,
  241. SystemParameter->VariableMtrrCount,
  242. &LocalMtrrs,
  243. ActualMemoryRanges,
  244. &ActualMemoryRangesCount,
  245. &ActualVariableMtrrUsage
  246. );
  247. UT_LOG_INFO ("--- Actual Memory Ranges [%d] ---\n", ActualMemoryRangesCount);
  248. DumpMemoryRanges (ActualMemoryRanges, ActualMemoryRangesCount);
  249. VerifyMemoryRanges (ExpectedMemoryRanges, ExpectedMemoryRangesCount, ActualMemoryRanges, ActualMemoryRangesCount);
  250. UT_ASSERT_TRUE (ExpectedVariableMtrrUsage >= ActualVariableMtrrUsage);
  251. ZeroMem (&LocalMtrrs, sizeof (LocalMtrrs));
  252. }
  253. free (Scratch);
  254. return UNIT_TEST_PASSED;
  255. }
  256. /**
  257. Test routine to check whether invalid base/size can be rejected.
  258. @param Context Pointer to MTRR_LIB_SYSTEM_PARAMETER.
  259. @return Test status.
  260. **/
  261. UNIT_TEST_STATUS
  262. EFIAPI
  263. UnitTestInvalidMemoryLayouts (
  264. IN UNIT_TEST_CONTEXT Context
  265. )
  266. {
  267. CONST MTRR_LIB_SYSTEM_PARAMETER *SystemParameter;
  268. MTRR_MEMORY_RANGE Ranges[MTRR_NUMBER_OF_VARIABLE_MTRR * 2 + 1];
  269. UINTN RangeCount;
  270. UINT64 MaxAddress;
  271. UINT32 Index;
  272. UINT64 BaseAddress;
  273. UINT64 Length;
  274. RETURN_STATUS Status;
  275. UINTN ScratchSize;
  276. SystemParameter = (MTRR_LIB_SYSTEM_PARAMETER *)Context;
  277. RangeCount = Random32 (1, ARRAY_SIZE (Ranges));
  278. MaxAddress = 1ull << SystemParameter->PhysicalAddressBits;
  279. for (Index = 0; Index < RangeCount; Index++) {
  280. do {
  281. BaseAddress = Random64 (0, MaxAddress);
  282. Length = Random64 (1, MaxAddress - BaseAddress);
  283. } while (((BaseAddress & 0xFFF) == 0) || ((Length & 0xFFF) == 0));
  284. Ranges[Index].BaseAddress = BaseAddress;
  285. Ranges[Index].Length = Length;
  286. Ranges[Index].Type = GenerateRandomCacheType ();
  287. Status = MtrrSetMemoryAttribute (
  288. Ranges[Index].BaseAddress,
  289. Ranges[Index].Length,
  290. Ranges[Index].Type
  291. );
  292. UT_ASSERT_TRUE (RETURN_ERROR (Status));
  293. }
  294. ScratchSize = 0;
  295. Status = MtrrSetMemoryAttributesInMtrrSettings (NULL, NULL, &ScratchSize, Ranges, RangeCount);
  296. UT_ASSERT_TRUE (RETURN_ERROR (Status));
  297. return UNIT_TEST_PASSED;
  298. }
  299. /**
  300. Unit test of MtrrLib service IsMtrrSupported()
  301. @param[in] Context Ignored
  302. @retval UNIT_TEST_PASSED The Unit test has completed and the test
  303. case was successful.
  304. @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
  305. **/
  306. UNIT_TEST_STATUS
  307. EFIAPI
  308. UnitTestIsMtrrSupported (
  309. IN UNIT_TEST_CONTEXT Context
  310. )
  311. {
  312. MTRR_LIB_SYSTEM_PARAMETER SystemParameter;
  313. MTRR_LIB_TEST_CONTEXT *LocalContext;
  314. LocalContext = (MTRR_LIB_TEST_CONTEXT *)Context;
  315. CopyMem (&SystemParameter, LocalContext->SystemParameter, sizeof (SystemParameter));
  316. //
  317. // MTRR capability off in CPUID leaf.
  318. //
  319. SystemParameter.MtrrSupported = FALSE;
  320. InitializeMtrrRegs (&SystemParameter);
  321. UT_ASSERT_FALSE (IsMtrrSupported ());
  322. //
  323. // MTRR capability on in CPUID leaf, but no variable or fixed MTRRs.
  324. //
  325. SystemParameter.MtrrSupported = TRUE;
  326. SystemParameter.VariableMtrrCount = 0;
  327. SystemParameter.FixedMtrrSupported = FALSE;
  328. InitializeMtrrRegs (&SystemParameter);
  329. UT_ASSERT_FALSE (IsMtrrSupported ());
  330. //
  331. // MTRR capability on in CPUID leaf, but no variable MTRRs.
  332. //
  333. SystemParameter.MtrrSupported = TRUE;
  334. SystemParameter.VariableMtrrCount = 0;
  335. SystemParameter.FixedMtrrSupported = TRUE;
  336. InitializeMtrrRegs (&SystemParameter);
  337. UT_ASSERT_FALSE (IsMtrrSupported ());
  338. //
  339. // MTRR capability on in CPUID leaf, but no fixed MTRRs.
  340. //
  341. SystemParameter.MtrrSupported = TRUE;
  342. SystemParameter.VariableMtrrCount = 7;
  343. SystemParameter.FixedMtrrSupported = FALSE;
  344. InitializeMtrrRegs (&SystemParameter);
  345. UT_ASSERT_FALSE (IsMtrrSupported ());
  346. //
  347. // MTRR capability on in CPUID leaf with both variable and fixed MTRRs.
  348. //
  349. SystemParameter.MtrrSupported = TRUE;
  350. SystemParameter.VariableMtrrCount = 7;
  351. SystemParameter.FixedMtrrSupported = TRUE;
  352. InitializeMtrrRegs (&SystemParameter);
  353. UT_ASSERT_TRUE (IsMtrrSupported ());
  354. return UNIT_TEST_PASSED;
  355. }
  356. /**
  357. Unit test of MtrrLib service GetVariableMtrrCount()
  358. @param[in] Context Ignored
  359. @retval UNIT_TEST_PASSED The Unit test has completed and the test
  360. case was successful.
  361. @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
  362. **/
  363. UNIT_TEST_STATUS
  364. EFIAPI
  365. UnitTestGetVariableMtrrCount (
  366. IN UNIT_TEST_CONTEXT Context
  367. )
  368. {
  369. UINT32 Result;
  370. MTRR_LIB_SYSTEM_PARAMETER SystemParameter;
  371. MTRR_LIB_TEST_CONTEXT *LocalContext;
  372. LocalContext = (MTRR_LIB_TEST_CONTEXT *)Context;
  373. CopyMem (&SystemParameter, LocalContext->SystemParameter, sizeof (SystemParameter));
  374. //
  375. // If MTRR capability off in CPUID leaf, then the count is always 0.
  376. //
  377. SystemParameter.MtrrSupported = FALSE;
  378. for (SystemParameter.VariableMtrrCount = 1; SystemParameter.VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR; SystemParameter.VariableMtrrCount++) {
  379. InitializeMtrrRegs (&SystemParameter);
  380. Result = GetVariableMtrrCount ();
  381. UT_ASSERT_EQUAL (Result, 0);
  382. }
  383. //
  384. // Try all supported variable MTRR counts.
  385. // If variable MTRR count is > MTRR_NUMBER_OF_VARIABLE_MTRR, then an ASSERT()
  386. // is generated.
  387. //
  388. SystemParameter.MtrrSupported = TRUE;
  389. for (SystemParameter.VariableMtrrCount = 1; SystemParameter.VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR; SystemParameter.VariableMtrrCount++) {
  390. InitializeMtrrRegs (&SystemParameter);
  391. Result = GetVariableMtrrCount ();
  392. UT_ASSERT_EQUAL (Result, SystemParameter.VariableMtrrCount);
  393. }
  394. //
  395. // Expect ASSERT() if variable MTRR count is > MTRR_NUMBER_OF_VARIABLE_MTRR
  396. //
  397. SystemParameter.VariableMtrrCount = MTRR_NUMBER_OF_VARIABLE_MTRR + 1;
  398. InitializeMtrrRegs (&SystemParameter);
  399. UT_EXPECT_ASSERT_FAILURE (GetVariableMtrrCount (), NULL);
  400. SystemParameter.MtrrSupported = TRUE;
  401. SystemParameter.VariableMtrrCount = MAX_UINT8;
  402. InitializeMtrrRegs (&SystemParameter);
  403. UT_EXPECT_ASSERT_FAILURE (GetVariableMtrrCount (), NULL);
  404. return UNIT_TEST_PASSED;
  405. }
  406. /**
  407. Unit test of MtrrLib service GetFirmwareVariableMtrrCount()
  408. @param[in] Context Ignored
  409. @retval UNIT_TEST_PASSED The Unit test has completed and the test
  410. case was successful.
  411. @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
  412. **/
  413. UNIT_TEST_STATUS
  414. EFIAPI
  415. UnitTestGetFirmwareVariableMtrrCount (
  416. IN UNIT_TEST_CONTEXT Context
  417. )
  418. {
  419. UINT32 Result;
  420. UINT32 ReservedMtrrs;
  421. MTRR_LIB_SYSTEM_PARAMETER SystemParameter;
  422. MTRR_LIB_GET_FIRMWARE_VARIABLE_MTRR_COUNT_CONTEXT *LocalContext;
  423. LocalContext = (MTRR_LIB_GET_FIRMWARE_VARIABLE_MTRR_COUNT_CONTEXT *)Context;
  424. CopyMem (&SystemParameter, LocalContext->SystemParameter, sizeof (SystemParameter));
  425. InitializeMtrrRegs (&SystemParameter);
  426. //
  427. // Positive test cases for VCNT = 10 and Reserved PCD in range 0..10
  428. //
  429. for (ReservedMtrrs = 0; ReservedMtrrs <= SystemParameter.VariableMtrrCount; ReservedMtrrs++) {
  430. PatchPcdSet32 (PcdCpuNumberOfReservedVariableMtrrs, ReservedMtrrs);
  431. Result = GetFirmwareVariableMtrrCount ();
  432. UT_ASSERT_EQUAL (Result, SystemParameter.VariableMtrrCount - ReservedMtrrs);
  433. }
  434. //
  435. // Negative test cases when Reserved PCD is larger than VCNT
  436. //
  437. for (ReservedMtrrs = SystemParameter.VariableMtrrCount + 1; ReservedMtrrs <= 255; ReservedMtrrs++) {
  438. PatchPcdSet32 (PcdCpuNumberOfReservedVariableMtrrs, ReservedMtrrs);
  439. Result = GetFirmwareVariableMtrrCount ();
  440. UT_ASSERT_EQUAL (Result, 0);
  441. }
  442. //
  443. // Negative test cases when Reserved PCD is larger than VCNT
  444. //
  445. PatchPcdSet32 (PcdCpuNumberOfReservedVariableMtrrs, MAX_UINT32);
  446. Result = GetFirmwareVariableMtrrCount ();
  447. UT_ASSERT_EQUAL (Result, 0);
  448. //
  449. // Negative test case when MTRRs are not supported
  450. //
  451. SystemParameter.MtrrSupported = FALSE;
  452. InitializeMtrrRegs (&SystemParameter);
  453. PatchPcdSet32 (PcdCpuNumberOfReservedVariableMtrrs, 2);
  454. Result = GetFirmwareVariableMtrrCount ();
  455. UT_ASSERT_EQUAL (Result, 0);
  456. //
  457. // Negative test case when Fixed MTRRs are not supported
  458. //
  459. SystemParameter.MtrrSupported = TRUE;
  460. SystemParameter.FixedMtrrSupported = FALSE;
  461. InitializeMtrrRegs (&SystemParameter);
  462. PatchPcdSet32 (PcdCpuNumberOfReservedVariableMtrrs, 2);
  463. Result = GetFirmwareVariableMtrrCount ();
  464. UT_ASSERT_EQUAL (Result, 0);
  465. //
  466. // Expect ASSERT() if variable MTRR count is > MTRR_NUMBER_OF_VARIABLE_MTRR
  467. //
  468. SystemParameter.FixedMtrrSupported = TRUE;
  469. SystemParameter.VariableMtrrCount = MTRR_NUMBER_OF_VARIABLE_MTRR + 1;
  470. InitializeMtrrRegs (&SystemParameter);
  471. UT_EXPECT_ASSERT_FAILURE (GetFirmwareVariableMtrrCount (), NULL);
  472. return UNIT_TEST_PASSED;
  473. }
  474. /**
  475. Unit test of MtrrLib service MtrrGetMemoryAttribute()
  476. @param[in] Context Ignored
  477. @retval UNIT_TEST_PASSED The Unit test has completed and the test
  478. case was successful.
  479. @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
  480. **/
  481. UNIT_TEST_STATUS
  482. EFIAPI
  483. UnitTestMtrrGetMemoryAttribute (
  484. IN UNIT_TEST_CONTEXT Context
  485. )
  486. {
  487. return UNIT_TEST_PASSED;
  488. }
  489. /**
  490. Unit test of MtrrLib service MtrrGetFixedMtrr()
  491. @param[in] Context Ignored
  492. @retval UNIT_TEST_PASSED The Unit test has completed and the test
  493. case was successful.
  494. @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
  495. **/
  496. UNIT_TEST_STATUS
  497. EFIAPI
  498. UnitTestMtrrGetFixedMtrr (
  499. IN UNIT_TEST_CONTEXT Context
  500. )
  501. {
  502. MTRR_FIXED_SETTINGS *Result;
  503. MTRR_FIXED_SETTINGS ExpectedFixedSettings;
  504. MTRR_FIXED_SETTINGS FixedSettings;
  505. UINTN Index;
  506. UINTN MsrIndex;
  507. UINTN ByteIndex;
  508. UINT64 MsrValue;
  509. MTRR_LIB_SYSTEM_PARAMETER SystemParameter;
  510. MTRR_LIB_TEST_CONTEXT *LocalContext;
  511. LocalContext = (MTRR_LIB_TEST_CONTEXT *)Context;
  512. CopyMem (&SystemParameter, LocalContext->SystemParameter, sizeof (SystemParameter));
  513. InitializeMtrrRegs (&SystemParameter);
  514. //
  515. // Set random cache type to different ranges under 1MB and make sure
  516. // the fixed MTRR settings are expected.
  517. // Try 100 times.
  518. //
  519. for (Index = 0; Index < 100; Index++) {
  520. for (MsrIndex = 0; MsrIndex < ARRAY_SIZE (mFixedMtrrsIndex); MsrIndex++) {
  521. MsrValue = 0;
  522. for (ByteIndex = 0; ByteIndex < sizeof (UINT64); ByteIndex++) {
  523. MsrValue = MsrValue | LShiftU64 (GenerateRandomCacheType (), ByteIndex * 8);
  524. }
  525. ExpectedFixedSettings.Mtrr[MsrIndex] = MsrValue;
  526. AsmWriteMsr64 (mFixedMtrrsIndex[MsrIndex], MsrValue);
  527. }
  528. Result = MtrrGetFixedMtrr (&FixedSettings);
  529. UT_ASSERT_EQUAL ((UINTN)Result, (UINTN)&FixedSettings);
  530. UT_ASSERT_MEM_EQUAL (&FixedSettings, &ExpectedFixedSettings, sizeof (FixedSettings));
  531. }
  532. //
  533. // Negative test case when MTRRs are not supported
  534. //
  535. SystemParameter.MtrrSupported = FALSE;
  536. InitializeMtrrRegs (&SystemParameter);
  537. ZeroMem (&FixedSettings, sizeof (FixedSettings));
  538. ZeroMem (&ExpectedFixedSettings, sizeof (ExpectedFixedSettings));
  539. Result = MtrrGetFixedMtrr (&FixedSettings);
  540. UT_ASSERT_EQUAL ((UINTN)Result, (UINTN)&FixedSettings);
  541. UT_ASSERT_MEM_EQUAL (&ExpectedFixedSettings, &FixedSettings, sizeof (ExpectedFixedSettings));
  542. return UNIT_TEST_PASSED;
  543. }
  544. /**
  545. Unit test of MtrrLib service MtrrGetAllMtrrs()
  546. @param[in] Context Ignored
  547. @retval UNIT_TEST_PASSED The Unit test has completed and the test
  548. case was successful.
  549. @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
  550. **/
  551. UNIT_TEST_STATUS
  552. EFIAPI
  553. UnitTestMtrrGetAllMtrrs (
  554. IN UNIT_TEST_CONTEXT Context
  555. )
  556. {
  557. MTRR_SETTINGS *Result;
  558. MTRR_SETTINGS Mtrrs;
  559. MTRR_SETTINGS ExpectedMtrrs;
  560. MTRR_VARIABLE_SETTING VariableMtrr[MTRR_NUMBER_OF_VARIABLE_MTRR];
  561. UINT32 Index;
  562. MTRR_LIB_SYSTEM_PARAMETER SystemParameter;
  563. MTRR_LIB_TEST_CONTEXT *LocalContext;
  564. LocalContext = (MTRR_LIB_TEST_CONTEXT *)Context;
  565. CopyMem (&SystemParameter, LocalContext->SystemParameter, sizeof (SystemParameter));
  566. InitializeMtrrRegs (&SystemParameter);
  567. for (Index = 0; Index < SystemParameter.VariableMtrrCount; Index++) {
  568. GenerateRandomMtrrPair (SystemParameter.PhysicalAddressBits, GenerateRandomCacheType (), &VariableMtrr[Index], NULL);
  569. AsmWriteMsr64 (MSR_IA32_MTRR_PHYSBASE0 + (Index << 1), VariableMtrr[Index].Base);
  570. AsmWriteMsr64 (MSR_IA32_MTRR_PHYSMASK0 + (Index << 1), VariableMtrr[Index].Mask);
  571. }
  572. Result = MtrrGetAllMtrrs (&Mtrrs);
  573. UT_ASSERT_EQUAL ((UINTN)Result, (UINTN)&Mtrrs);
  574. UT_ASSERT_MEM_EQUAL (Mtrrs.Variables.Mtrr, VariableMtrr, sizeof (MTRR_VARIABLE_SETTING) * SystemParameter.VariableMtrrCount);
  575. //
  576. // Negative test case when MTRRs are not supported
  577. //
  578. ZeroMem (&ExpectedMtrrs, sizeof (ExpectedMtrrs));
  579. ZeroMem (&Mtrrs, sizeof (Mtrrs));
  580. SystemParameter.MtrrSupported = FALSE;
  581. InitializeMtrrRegs (&SystemParameter);
  582. Result = MtrrGetAllMtrrs (&Mtrrs);
  583. UT_ASSERT_EQUAL ((UINTN)Result, (UINTN)&Mtrrs);
  584. UT_ASSERT_MEM_EQUAL (&ExpectedMtrrs, &Mtrrs, sizeof (ExpectedMtrrs));
  585. //
  586. // Expect ASSERT() if variable MTRR count is > MTRR_NUMBER_OF_VARIABLE_MTRR
  587. //
  588. SystemParameter.MtrrSupported = TRUE;
  589. SystemParameter.VariableMtrrCount = MTRR_NUMBER_OF_VARIABLE_MTRR + 1;
  590. InitializeMtrrRegs (&SystemParameter);
  591. UT_EXPECT_ASSERT_FAILURE (MtrrGetAllMtrrs (&Mtrrs), NULL);
  592. return UNIT_TEST_PASSED;
  593. }
  594. /**
  595. Unit test of MtrrLib service MtrrSetAllMtrrs()
  596. @param[in] Context Ignored
  597. @retval UNIT_TEST_PASSED The Unit test has completed and the test
  598. case was successful.
  599. @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
  600. **/
  601. UNIT_TEST_STATUS
  602. EFIAPI
  603. UnitTestMtrrSetAllMtrrs (
  604. IN UNIT_TEST_CONTEXT Context
  605. )
  606. {
  607. MTRR_SETTINGS *Result;
  608. MTRR_SETTINGS Mtrrs;
  609. UINT32 Index;
  610. MSR_IA32_MTRR_DEF_TYPE_REGISTER Default;
  611. MTRR_LIB_SYSTEM_PARAMETER SystemParameter;
  612. MTRR_LIB_TEST_CONTEXT *LocalContext;
  613. LocalContext = (MTRR_LIB_TEST_CONTEXT *)Context;
  614. CopyMem (&SystemParameter, LocalContext->SystemParameter, sizeof (SystemParameter));
  615. InitializeMtrrRegs (&SystemParameter);
  616. Default.Uint64 = 0;
  617. Default.Bits.E = 1;
  618. Default.Bits.FE = 1;
  619. Default.Bits.Type = GenerateRandomCacheType ();
  620. ZeroMem (&Mtrrs, sizeof (Mtrrs));
  621. Mtrrs.MtrrDefType = Default.Uint64;
  622. for (Index = 0; Index < SystemParameter.VariableMtrrCount; Index++) {
  623. GenerateRandomMtrrPair (SystemParameter.PhysicalAddressBits, GenerateRandomCacheType (), &Mtrrs.Variables.Mtrr[Index], NULL);
  624. }
  625. Result = MtrrSetAllMtrrs (&Mtrrs);
  626. UT_ASSERT_EQUAL ((UINTN)Result, (UINTN)&Mtrrs);
  627. UT_ASSERT_EQUAL (AsmReadMsr64 (MSR_IA32_MTRR_DEF_TYPE), Mtrrs.MtrrDefType);
  628. for (Index = 0; Index < SystemParameter.VariableMtrrCount; Index++) {
  629. UT_ASSERT_EQUAL (AsmReadMsr64 (MSR_IA32_MTRR_PHYSBASE0 + (Index << 1)), Mtrrs.Variables.Mtrr[Index].Base);
  630. UT_ASSERT_EQUAL (AsmReadMsr64 (MSR_IA32_MTRR_PHYSMASK0 + (Index << 1)), Mtrrs.Variables.Mtrr[Index].Mask);
  631. }
  632. return UNIT_TEST_PASSED;
  633. }
  634. /**
  635. Unit test of MtrrLib service MtrrGetMemoryAttributeInVariableMtrr()
  636. @param[in] Context Ignored
  637. @retval UNIT_TEST_PASSED The Unit test has completed and the test
  638. case was successful.
  639. @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
  640. **/
  641. UNIT_TEST_STATUS
  642. EFIAPI
  643. UnitTestMtrrGetMemoryAttributeInVariableMtrr (
  644. IN UNIT_TEST_CONTEXT Context
  645. )
  646. {
  647. MTRR_LIB_TEST_CONTEXT *LocalContext;
  648. MTRR_LIB_SYSTEM_PARAMETER SystemParameter;
  649. UINT32 Result;
  650. MTRR_VARIABLE_SETTING VariableSetting[MTRR_NUMBER_OF_VARIABLE_MTRR];
  651. VARIABLE_MTRR VariableMtrr[MTRR_NUMBER_OF_VARIABLE_MTRR];
  652. UINT64 ValidMtrrBitsMask;
  653. UINT64 ValidMtrrAddressMask;
  654. UINT32 Index;
  655. MSR_IA32_MTRR_PHYSBASE_REGISTER Base;
  656. MSR_IA32_MTRR_PHYSMASK_REGISTER Mask;
  657. LocalContext = (MTRR_LIB_TEST_CONTEXT *)Context;
  658. CopyMem (&SystemParameter, LocalContext->SystemParameter, sizeof (SystemParameter));
  659. InitializeMtrrRegs (&SystemParameter);
  660. ValidMtrrBitsMask = (1ull << SystemParameter.PhysicalAddressBits) - 1;
  661. ValidMtrrAddressMask = ValidMtrrBitsMask & 0xfffffffffffff000ULL;
  662. for (Index = 0; Index < SystemParameter.VariableMtrrCount; Index++) {
  663. GenerateRandomMtrrPair (SystemParameter.PhysicalAddressBits, GenerateRandomCacheType (), &VariableSetting[Index], NULL);
  664. AsmWriteMsr64 (MSR_IA32_MTRR_PHYSBASE0 + (Index << 1), VariableSetting[Index].Base);
  665. AsmWriteMsr64 (MSR_IA32_MTRR_PHYSMASK0 + (Index << 1), VariableSetting[Index].Mask);
  666. }
  667. Result = MtrrGetMemoryAttributeInVariableMtrr (ValidMtrrBitsMask, ValidMtrrAddressMask, VariableMtrr);
  668. UT_ASSERT_EQUAL (Result, SystemParameter.VariableMtrrCount);
  669. for (Index = 0; Index < SystemParameter.VariableMtrrCount; Index++) {
  670. Base.Uint64 = VariableMtrr[Index].BaseAddress;
  671. Base.Bits.Type = (UINT32)VariableMtrr[Index].Type;
  672. UT_ASSERT_EQUAL (Base.Uint64, VariableSetting[Index].Base);
  673. Mask.Uint64 = ~(VariableMtrr[Index].Length - 1) & ValidMtrrBitsMask;
  674. Mask.Bits.V = 1;
  675. UT_ASSERT_EQUAL (Mask.Uint64, VariableSetting[Index].Mask);
  676. }
  677. //
  678. // Negative test case when MTRRs are not supported
  679. //
  680. SystemParameter.MtrrSupported = FALSE;
  681. InitializeMtrrRegs (&SystemParameter);
  682. Result = MtrrGetMemoryAttributeInVariableMtrr (ValidMtrrBitsMask, ValidMtrrAddressMask, VariableMtrr);
  683. UT_ASSERT_EQUAL (Result, 0);
  684. //
  685. // Expect ASSERT() if variable MTRR count is > MTRR_NUMBER_OF_VARIABLE_MTRR
  686. //
  687. SystemParameter.MtrrSupported = TRUE;
  688. SystemParameter.VariableMtrrCount = MTRR_NUMBER_OF_VARIABLE_MTRR + 1;
  689. InitializeMtrrRegs (&SystemParameter);
  690. UT_EXPECT_ASSERT_FAILURE (MtrrGetMemoryAttributeInVariableMtrr (ValidMtrrBitsMask, ValidMtrrAddressMask, VariableMtrr), NULL);
  691. return UNIT_TEST_PASSED;
  692. }
  693. /**
  694. Unit test of MtrrLib service MtrrDebugPrintAllMtrrs()
  695. @param[in] Context Ignored
  696. @retval UNIT_TEST_PASSED The Unit test has completed and the test
  697. case was successful.
  698. @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
  699. **/
  700. UNIT_TEST_STATUS
  701. EFIAPI
  702. UnitTestMtrrDebugPrintAllMtrrs (
  703. IN UNIT_TEST_CONTEXT Context
  704. )
  705. {
  706. return UNIT_TEST_PASSED;
  707. }
  708. /**
  709. Unit test of MtrrLib service MtrrGetDefaultMemoryType().
  710. @param[in] Context Ignored
  711. @retval UNIT_TEST_PASSED The Unit test has completed and the test
  712. case was successful.
  713. @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
  714. **/
  715. UNIT_TEST_STATUS
  716. EFIAPI
  717. UnitTestMtrrGetDefaultMemoryType (
  718. IN UNIT_TEST_CONTEXT Context
  719. )
  720. {
  721. MTRR_LIB_TEST_CONTEXT *LocalContext;
  722. UINTN Index;
  723. MTRR_MEMORY_CACHE_TYPE Result;
  724. MTRR_LIB_SYSTEM_PARAMETER SystemParameter;
  725. MTRR_MEMORY_CACHE_TYPE CacheType[5];
  726. CacheType[0] = CacheUncacheable;
  727. CacheType[1] = CacheWriteCombining;
  728. CacheType[2] = CacheWriteThrough;
  729. CacheType[3] = CacheWriteProtected;
  730. CacheType[4] = CacheWriteBack;
  731. LocalContext = (MTRR_LIB_TEST_CONTEXT *)Context;
  732. CopyMem (&SystemParameter, LocalContext->SystemParameter, sizeof (SystemParameter));
  733. //
  734. // If MTRRs are supported, then always return the cache type in the MSR
  735. // MSR_IA32_MTRR_DEF_TYPE
  736. //
  737. for (Index = 0; Index < ARRAY_SIZE (CacheType); Index++) {
  738. SystemParameter.DefaultCacheType = CacheType[Index];
  739. InitializeMtrrRegs (&SystemParameter);
  740. Result = MtrrGetDefaultMemoryType ();
  741. UT_ASSERT_EQUAL (Result, SystemParameter.DefaultCacheType);
  742. }
  743. //
  744. // If MTRRs are not supported, then always return CacheUncacheable
  745. //
  746. SystemParameter.MtrrSupported = FALSE;
  747. InitializeMtrrRegs (&SystemParameter);
  748. Result = MtrrGetDefaultMemoryType ();
  749. UT_ASSERT_EQUAL (Result, CacheUncacheable);
  750. SystemParameter.MtrrSupported = TRUE;
  751. SystemParameter.FixedMtrrSupported = FALSE;
  752. InitializeMtrrRegs (&SystemParameter);
  753. Result = MtrrGetDefaultMemoryType ();
  754. UT_ASSERT_EQUAL (Result, CacheUncacheable);
  755. SystemParameter.MtrrSupported = TRUE;
  756. SystemParameter.FixedMtrrSupported = TRUE;
  757. SystemParameter.VariableMtrrCount = 0;
  758. InitializeMtrrRegs (&SystemParameter);
  759. Result = MtrrGetDefaultMemoryType ();
  760. UT_ASSERT_EQUAL (Result, CacheUncacheable);
  761. return UNIT_TEST_PASSED;
  762. }
  763. /**
  764. Unit test of MtrrLib service MtrrSetMemoryAttributeInMtrrSettings().
  765. @param[in] Context Ignored
  766. @retval UNIT_TEST_PASSED The Unit test has completed and the test
  767. case was successful.
  768. @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
  769. **/
  770. UNIT_TEST_STATUS
  771. EFIAPI
  772. UnitTestMtrrSetMemoryAttributeInMtrrSettings (
  773. IN UNIT_TEST_CONTEXT Context
  774. )
  775. {
  776. CONST MTRR_LIB_SYSTEM_PARAMETER *SystemParameter;
  777. RETURN_STATUS Status;
  778. UINT32 UcCount;
  779. UINT32 WtCount;
  780. UINT32 WbCount;
  781. UINT32 WpCount;
  782. UINT32 WcCount;
  783. UINTN MtrrIndex;
  784. UINTN Index;
  785. MTRR_SETTINGS LocalMtrrs;
  786. MTRR_MEMORY_RANGE RawMtrrRange[MTRR_NUMBER_OF_VARIABLE_MTRR];
  787. MTRR_MEMORY_RANGE ExpectedMemoryRanges[MTRR_NUMBER_OF_FIXED_MTRR * sizeof (UINT64) + 2 * MTRR_NUMBER_OF_VARIABLE_MTRR + 1];
  788. UINT32 ExpectedVariableMtrrUsage;
  789. UINTN ExpectedMemoryRangesCount;
  790. MTRR_MEMORY_RANGE ActualMemoryRanges[MTRR_NUMBER_OF_FIXED_MTRR * sizeof (UINT64) + 2 * MTRR_NUMBER_OF_VARIABLE_MTRR + 1];
  791. UINT32 ActualVariableMtrrUsage;
  792. UINTN ActualMemoryRangesCount;
  793. MTRR_SETTINGS *Mtrrs[2];
  794. SystemParameter = (MTRR_LIB_SYSTEM_PARAMETER *)Context;
  795. GenerateRandomMemoryTypeCombination (
  796. SystemParameter->VariableMtrrCount - PatchPcdGet32 (PcdCpuNumberOfReservedVariableMtrrs),
  797. &UcCount,
  798. &WtCount,
  799. &WbCount,
  800. &WpCount,
  801. &WcCount
  802. );
  803. GenerateValidAndConfigurableMtrrPairs (
  804. SystemParameter->PhysicalAddressBits,
  805. RawMtrrRange,
  806. UcCount,
  807. WtCount,
  808. WbCount,
  809. WpCount,
  810. WcCount
  811. );
  812. ExpectedVariableMtrrUsage = UcCount + WtCount + WbCount + WpCount + WcCount;
  813. ExpectedMemoryRangesCount = ARRAY_SIZE (ExpectedMemoryRanges);
  814. GetEffectiveMemoryRanges (
  815. SystemParameter->DefaultCacheType,
  816. SystemParameter->PhysicalAddressBits,
  817. RawMtrrRange,
  818. ExpectedVariableMtrrUsage,
  819. ExpectedMemoryRanges,
  820. &ExpectedMemoryRangesCount
  821. );
  822. UT_LOG_INFO ("--- Expected Memory Ranges [%d] ---\n", ExpectedMemoryRangesCount);
  823. DumpMemoryRanges (ExpectedMemoryRanges, ExpectedMemoryRangesCount);
  824. //
  825. // Default cache type is always an INPUT
  826. //
  827. ZeroMem (&LocalMtrrs, sizeof (LocalMtrrs));
  828. LocalMtrrs.MtrrDefType = MtrrGetDefaultMemoryType ();
  829. Mtrrs[0] = &LocalMtrrs;
  830. Mtrrs[1] = NULL;
  831. for (MtrrIndex = 0; MtrrIndex < ARRAY_SIZE (Mtrrs); MtrrIndex++) {
  832. for (Index = 0; Index < ExpectedMemoryRangesCount; Index++) {
  833. Status = MtrrSetMemoryAttributeInMtrrSettings (
  834. Mtrrs[MtrrIndex],
  835. ExpectedMemoryRanges[Index].BaseAddress,
  836. ExpectedMemoryRanges[Index].Length,
  837. ExpectedMemoryRanges[Index].Type
  838. );
  839. UT_ASSERT_TRUE (Status == RETURN_SUCCESS || Status == RETURN_OUT_OF_RESOURCES || Status == RETURN_BUFFER_TOO_SMALL);
  840. if ((Status == RETURN_OUT_OF_RESOURCES) || (Status == RETURN_BUFFER_TOO_SMALL)) {
  841. return UNIT_TEST_SKIPPED;
  842. }
  843. }
  844. if (Mtrrs[MtrrIndex] == NULL) {
  845. ZeroMem (&LocalMtrrs, sizeof (LocalMtrrs));
  846. MtrrGetAllMtrrs (&LocalMtrrs);
  847. }
  848. ActualMemoryRangesCount = ARRAY_SIZE (ActualMemoryRanges);
  849. CollectTestResult (
  850. SystemParameter->DefaultCacheType,
  851. SystemParameter->PhysicalAddressBits,
  852. SystemParameter->VariableMtrrCount,
  853. &LocalMtrrs,
  854. ActualMemoryRanges,
  855. &ActualMemoryRangesCount,
  856. &ActualVariableMtrrUsage
  857. );
  858. UT_LOG_INFO ("--- Actual Memory Ranges [%d] ---\n", ActualMemoryRangesCount);
  859. DumpMemoryRanges (ActualMemoryRanges, ActualMemoryRangesCount);
  860. VerifyMemoryRanges (ExpectedMemoryRanges, ExpectedMemoryRangesCount, ActualMemoryRanges, ActualMemoryRangesCount);
  861. UT_ASSERT_TRUE (ExpectedVariableMtrrUsage >= ActualVariableMtrrUsage);
  862. ZeroMem (&LocalMtrrs, sizeof (LocalMtrrs));
  863. }
  864. return UNIT_TEST_PASSED;
  865. }
  866. /**
  867. Prep routine for UnitTestGetFirmwareVariableMtrrCount().
  868. @param Context Point to a UINT32 data to save the PcdCpuNumberOfReservedVariableMtrrs.
  869. **/
  870. UNIT_TEST_STATUS
  871. EFIAPI
  872. SavePcdValue (
  873. UNIT_TEST_CONTEXT Context
  874. )
  875. {
  876. MTRR_LIB_GET_FIRMWARE_VARIABLE_MTRR_COUNT_CONTEXT *LocalContext;
  877. LocalContext = (MTRR_LIB_GET_FIRMWARE_VARIABLE_MTRR_COUNT_CONTEXT *)Context;
  878. LocalContext->NumberOfReservedVariableMtrrs = PatchPcdGet32 (PcdCpuNumberOfReservedVariableMtrrs);
  879. return UNIT_TEST_PASSED;
  880. }
  881. /**
  882. Clean up routine for UnitTestGetFirmwareVariableMtrrCount().
  883. @param Context Point to a UINT32 data to save the PcdCpuNumberOfReservedVariableMtrrs.
  884. **/
  885. VOID
  886. EFIAPI
  887. RestorePcdValue (
  888. UNIT_TEST_CONTEXT Context
  889. )
  890. {
  891. MTRR_LIB_GET_FIRMWARE_VARIABLE_MTRR_COUNT_CONTEXT *LocalContext;
  892. LocalContext = (MTRR_LIB_GET_FIRMWARE_VARIABLE_MTRR_COUNT_CONTEXT *)Context;
  893. PatchPcdSet32 (PcdCpuNumberOfReservedVariableMtrrs, LocalContext->NumberOfReservedVariableMtrrs);
  894. }
  895. /**
  896. Initialize the unit test framework, suite, and unit tests for the
  897. ResetSystemLib and run the ResetSystemLib unit test.
  898. @param Iteration Iteration of testing MtrrSetMemoryAttributeInMtrrSettings
  899. and MtrrSetMemoryAttributesInMtrrSettings using random inputs.
  900. @retval EFI_SUCCESS All test cases were dispatched.
  901. @retval EFI_OUT_OF_RESOURCES There are not enough resources available to
  902. initialize the unit tests.
  903. **/
  904. STATIC
  905. EFI_STATUS
  906. EFIAPI
  907. UnitTestingEntry (
  908. UINTN Iteration
  909. )
  910. {
  911. EFI_STATUS Status;
  912. UNIT_TEST_FRAMEWORK_HANDLE Framework;
  913. UNIT_TEST_SUITE_HANDLE MtrrApiTests;
  914. UINTN Index;
  915. UINTN SystemIndex;
  916. MTRR_LIB_TEST_CONTEXT Context;
  917. MTRR_LIB_GET_FIRMWARE_VARIABLE_MTRR_COUNT_CONTEXT GetFirmwareVariableMtrrCountContext;
  918. Context.SystemParameter = &mDefaultSystemParameter;
  919. GetFirmwareVariableMtrrCountContext.SystemParameter = &mDefaultSystemParameter;
  920. Framework = NULL;
  921. //
  922. // Setup the test framework for running the tests.
  923. //
  924. Status = InitUnitTestFramework (&Framework, UNIT_TEST_APP_NAME, gEfiCallerBaseName, UNIT_TEST_APP_VERSION);
  925. if (EFI_ERROR (Status)) {
  926. DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status = %r\n", Status));
  927. goto EXIT;
  928. }
  929. //
  930. // --------------Suite-----------Description--------------Name----------Function--------Pre---Post-------------------Context-----------
  931. //
  932. //
  933. // Populate the MtrrLib API Unit Test Suite.
  934. //
  935. Status = CreateUnitTestSuite (&MtrrApiTests, Framework, "MtrrLib API Tests", "MtrrLib.MtrrLib", NULL, NULL);
  936. if (EFI_ERROR (Status)) {
  937. DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for MtrrLib API Tests\n"));
  938. Status = EFI_OUT_OF_RESOURCES;
  939. goto EXIT;
  940. }
  941. AddTestCase (MtrrApiTests, "Test IsMtrrSupported", "MtrrSupported", UnitTestIsMtrrSupported, NULL, NULL, &Context);
  942. AddTestCase (MtrrApiTests, "Test GetVariableMtrrCount", "GetVariableMtrrCount", UnitTestGetVariableMtrrCount, NULL, NULL, &Context);
  943. AddTestCase (MtrrApiTests, "Test GetFirmwareVariableMtrrCount", "GetFirmwareVariableMtrrCount", UnitTestGetFirmwareVariableMtrrCount, SavePcdValue, RestorePcdValue, &GetFirmwareVariableMtrrCountContext);
  944. AddTestCase (MtrrApiTests, "Test MtrrGetMemoryAttribute", "MtrrGetMemoryAttribute", UnitTestMtrrGetMemoryAttribute, NULL, NULL, &Context);
  945. AddTestCase (MtrrApiTests, "Test MtrrGetFixedMtrr", "MtrrGetFixedMtrr", UnitTestMtrrGetFixedMtrr, NULL, NULL, &Context);
  946. AddTestCase (MtrrApiTests, "Test MtrrGetAllMtrrs", "MtrrGetAllMtrrs", UnitTestMtrrGetAllMtrrs, NULL, NULL, &Context);
  947. AddTestCase (MtrrApiTests, "Test MtrrSetAllMtrrs", "MtrrSetAllMtrrs", UnitTestMtrrSetAllMtrrs, NULL, NULL, &Context);
  948. AddTestCase (MtrrApiTests, "Test MtrrGetMemoryAttributeInVariableMtrr", "MtrrGetMemoryAttributeInVariableMtrr", UnitTestMtrrGetMemoryAttributeInVariableMtrr, NULL, NULL, &Context);
  949. AddTestCase (MtrrApiTests, "Test MtrrDebugPrintAllMtrrs", "MtrrDebugPrintAllMtrrs", UnitTestMtrrDebugPrintAllMtrrs, NULL, NULL, &Context);
  950. AddTestCase (MtrrApiTests, "Test MtrrGetDefaultMemoryType", "MtrrGetDefaultMemoryType", UnitTestMtrrGetDefaultMemoryType, NULL, NULL, &Context);
  951. for (SystemIndex = 0; SystemIndex < ARRAY_SIZE (mSystemParameters); SystemIndex++) {
  952. for (Index = 0; Index < Iteration; Index++) {
  953. AddTestCase (MtrrApiTests, "Test InvalidMemoryLayouts", "InvalidMemoryLayouts", UnitTestInvalidMemoryLayouts, InitializeSystem, NULL, &mSystemParameters[SystemIndex]);
  954. AddTestCase (MtrrApiTests, "Test MtrrSetMemoryAttributeInMtrrSettings", "MtrrSetMemoryAttributeInMtrrSettings", UnitTestMtrrSetMemoryAttributeInMtrrSettings, InitializeSystem, NULL, &mSystemParameters[SystemIndex]);
  955. AddTestCase (MtrrApiTests, "Test MtrrSetMemoryAttributesInMtrrSettings", "MtrrSetMemoryAttributesInMtrrSettings", UnitTestMtrrSetMemoryAttributesInMtrrSettings, InitializeSystem, NULL, &mSystemParameters[SystemIndex]);
  956. }
  957. }
  958. //
  959. // Execute the tests.
  960. //
  961. Status = RunAllTestSuites (Framework);
  962. EXIT:
  963. if (Framework != NULL) {
  964. FreeUnitTestFramework (Framework);
  965. }
  966. return Status;
  967. }
  968. /**
  969. Standard POSIX C entry point for host based unit test execution.
  970. @param Argc Number of arguments.
  971. @param Argv Array of arguments.
  972. @return Test application exit code.
  973. **/
  974. INT32
  975. main (
  976. INT32 Argc,
  977. CHAR8 *Argv[]
  978. )
  979. {
  980. UINTN Count;
  981. DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_APP_NAME, UNIT_TEST_APP_VERSION));
  982. srand ((unsigned int)time (NULL));
  983. //
  984. // MtrrLibUnitTest generate-random-numbers <path to MtrrLib/UnitTest/RandomNumber.c> <random-number count>
  985. //
  986. if ((Argc == 4) && (AsciiStriCmp ("generate-random-numbers", Argv[1]) == 0)) {
  987. Count = atoi (Argv[3]);
  988. DEBUG ((DEBUG_INFO, "Generate %d random numbers to %a.\n", Count, Argv[2]));
  989. GenerateRandomNumbers (Argv[2], Count);
  990. return 0;
  991. }
  992. //
  993. // MtrrLibUnitTest [<iterations>]
  994. // <iterations> [fixed|random]
  995. // Default <iterations> is 10.
  996. // Default uses fixed inputs.
  997. //
  998. Count = 10;
  999. mRandomInput = FALSE;
  1000. if ((Argc == 2) || (Argc == 3)) {
  1001. Count = atoi (Argv[1]);
  1002. if (Argc == 3) {
  1003. if (AsciiStriCmp ("fixed", Argv[2]) == 0) {
  1004. mRandomInput = FALSE;
  1005. } else if (AsciiStriCmp ("random", Argv[2]) == 0) {
  1006. mRandomInput = TRUE;
  1007. }
  1008. }
  1009. }
  1010. DEBUG ((DEBUG_INFO, "Iterations = %d\n", Count));
  1011. DEBUG ((DEBUG_INFO, "Input = %a\n", mRandomInput ? "random" : "fixed"));
  1012. return UnitTestingEntry (Count);
  1013. }