/** @file\r
Unit tests of the CpuPageTableLib instance of the CpuPageTableLib class\r
\r
- Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2022 - 2023, Intel Corporation. All rights reserved.<BR>\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
return UNIT_TEST_PASSED;\r
}\r
\r
+/**\r
+ Check if the input Mask and Attribute is as expected when creating new page table or\r
+ updating existing page table.\r
+\r
+ @param[in] Context [Optional] An optional parameter that enables:\r
+ 1) test-case reuse with varied parameters and\r
+ 2) test-case re-entry for Target tests that need a\r
+ reboot. This parameter is a VOID* and it is the\r
+ responsibility of the test author to ensure that the\r
+ contents are well understood by all test cases that may\r
+ consume it.\r
+\r
+ @retval UNIT_TEST_PASSED The Unit test has completed and the test\r
+ case was successful.\r
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.\r
+**/\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+TestCaseToCheckMapMaskAndAttr (\r
+ IN UNIT_TEST_CONTEXT Context\r
+ )\r
+{\r
+ UINTN PageTable;\r
+ PAGING_MODE PagingMode;\r
+ VOID *Buffer;\r
+ UINTN PageTableBufferSize;\r
+ IA32_MAP_ATTRIBUTE MapAttribute;\r
+ IA32_MAP_ATTRIBUTE ExpectedMapAttribute;\r
+ IA32_MAP_ATTRIBUTE MapMask;\r
+ RETURN_STATUS Status;\r
+ IA32_MAP_ENTRY *Map;\r
+ UINTN MapCount;\r
+\r
+ PagingMode = Paging4Level;\r
+ PageTableBufferSize = 0;\r
+ PageTable = 0;\r
+ Buffer = NULL;\r
+ MapAttribute.Uint64 = 0;\r
+ MapAttribute.Bits.Present = 1;\r
+ MapMask.Uint64 = 0;\r
+ MapMask.Bits.Present = 1;\r
+ //\r
+ // Create Page table to cover [0, 2G]. All fields of MapMask should be set.\r
+ //\r
+ Status = PageTableMap (&PageTable, PagingMode, Buffer, &PageTableBufferSize, 0, SIZE_2GB, &MapAttribute, &MapMask);\r
+ UT_ASSERT_EQUAL (Status, RETURN_INVALID_PARAMETER);\r
+ MapMask.Uint64 = MAX_UINT64;\r
+ Status = PageTableMap (&PageTable, PagingMode, Buffer, &PageTableBufferSize, 0, SIZE_2GB, &MapAttribute, &MapMask);\r
+ UT_ASSERT_EQUAL (Status, RETURN_BUFFER_TOO_SMALL);\r
+ Buffer = AllocatePages (EFI_SIZE_TO_PAGES (PageTableBufferSize));\r
+ Status = PageTableMap (&PageTable, PagingMode, Buffer, &PageTableBufferSize, 0, SIZE_2GB, &MapAttribute, &MapMask);\r
+ UT_ASSERT_EQUAL (Status, RETURN_SUCCESS);\r
+\r
+ //\r
+ // Update Page table to set [2G - 8K, 2G] from present to non-present. All fields of MapMask except present should not be set.\r
+ //\r
+ PageTableBufferSize = 0;\r
+ MapAttribute.Uint64 = SIZE_2GB - SIZE_8KB;\r
+ MapMask.Uint64 = 0;\r
+ MapMask.Bits.Present = 1;\r
+ MapMask.Bits.ReadWrite = 1;\r
+ Status = PageTableMap (&PageTable, PagingMode, Buffer, &PageTableBufferSize, SIZE_2GB - SIZE_8KB, SIZE_8KB, &MapAttribute, &MapMask);\r
+ UT_ASSERT_EQUAL (Status, RETURN_INVALID_PARAMETER);\r
+ MapMask.Bits.ReadWrite = 0;\r
+ Status = PageTableMap (&PageTable, PagingMode, Buffer, &PageTableBufferSize, SIZE_2GB - SIZE_8KB, SIZE_8KB, &MapAttribute, &MapMask);\r
+ UT_ASSERT_EQUAL (Status, RETURN_BUFFER_TOO_SMALL);\r
+ Buffer = AllocatePages (EFI_SIZE_TO_PAGES (PageTableBufferSize));\r
+ Status = PageTableMap (&PageTable, PagingMode, Buffer, &PageTableBufferSize, 0, SIZE_2GB, &MapAttribute, &MapMask);\r
+ UT_ASSERT_EQUAL (Status, RETURN_SUCCESS);\r
+\r
+ //\r
+ // Still set [2G - 8K, 2G] as not present, this case is permitted. But set [2G - 8K, 2G] as RW is not permitted.\r
+ //\r
+ PageTableBufferSize = 0;\r
+ MapAttribute.Uint64 = 0;\r
+ MapMask.Uint64 = 0;\r
+ MapMask.Bits.Present = 1;\r
+ Status = PageTableMap (&PageTable, PagingMode, Buffer, &PageTableBufferSize, SIZE_2GB - SIZE_8KB, SIZE_8KB, &MapAttribute, &MapMask);\r
+ UT_ASSERT_EQUAL (Status, RETURN_SUCCESS);\r
+ MapAttribute.Bits.ReadWrite = 1;\r
+ MapMask.Bits.ReadWrite = 1;\r
+ Status = PageTableMap (&PageTable, PagingMode, Buffer, &PageTableBufferSize, SIZE_2GB - SIZE_8KB, SIZE_8KB, &MapAttribute, &MapMask);\r
+ UT_ASSERT_EQUAL (Status, RETURN_INVALID_PARAMETER);\r
+\r
+ //\r
+ // Update Page table to set [2G - 8K, 2G] as present and RW. All fields of MapMask should be set.\r
+ //\r
+ PageTableBufferSize = 0;\r
+ MapAttribute.Uint64 = SIZE_2GB - SIZE_8KB;\r
+ MapAttribute.Bits.ReadWrite = 1;\r
+ MapAttribute.Bits.Present = 1;\r
+ MapMask.Uint64 = 0;\r
+ MapMask.Bits.ReadWrite = 1;\r
+ MapMask.Bits.Present = 1;\r
+ Status = PageTableMap (&PageTable, PagingMode, Buffer, &PageTableBufferSize, SIZE_2GB - SIZE_8KB, SIZE_8KB, &MapAttribute, &MapMask);\r
+ UT_ASSERT_EQUAL (Status, RETURN_INVALID_PARAMETER);\r
+ MapMask.Uint64 = MAX_UINT64;\r
+ Status = PageTableMap (&PageTable, PagingMode, Buffer, &PageTableBufferSize, SIZE_2GB - SIZE_8KB, SIZE_8KB, &MapAttribute, &MapMask);\r
+ UT_ASSERT_EQUAL (Status, RETURN_SUCCESS);\r
+\r
+ MapCount = 0;\r
+ Status = PageTableParse (PageTable, PagingMode, NULL, &MapCount);\r
+ UT_ASSERT_EQUAL (Status, RETURN_BUFFER_TOO_SMALL);\r
+ Map = AllocatePages (EFI_SIZE_TO_PAGES (MapCount* sizeof (IA32_MAP_ENTRY)));\r
+ Status = PageTableParse (PageTable, PagingMode, Map, &MapCount);\r
+ UT_ASSERT_EQUAL (Status, RETURN_SUCCESS);\r
+\r
+ //\r
+ // There should be two ranges [0, 2G-8k] with RW = 0 and [2G-8k, 2G] with RW = 1\r
+ //\r
+ UT_ASSERT_EQUAL (MapCount, 2);\r
+ UT_ASSERT_EQUAL (Map[0].LinearAddress, 0);\r
+ UT_ASSERT_EQUAL (Map[0].Length, SIZE_2GB - SIZE_8KB);\r
+ ExpectedMapAttribute.Uint64 = 0;\r
+ ExpectedMapAttribute.Bits.Present = 1;\r
+ UT_ASSERT_EQUAL (Map[0].Attribute.Uint64, ExpectedMapAttribute.Uint64);\r
+ UT_ASSERT_EQUAL (Map[1].LinearAddress, SIZE_2GB - SIZE_8KB);\r
+ UT_ASSERT_EQUAL (Map[1].Length, SIZE_8KB);\r
+ ExpectedMapAttribute.Uint64 = SIZE_2GB - SIZE_8KB;\r
+ ExpectedMapAttribute.Bits.Present = 1;\r
+ ExpectedMapAttribute.Bits.ReadWrite = 1;\r
+ UT_ASSERT_EQUAL (Map[1].Attribute.Uint64, ExpectedMapAttribute.Uint64);\r
+ return UNIT_TEST_PASSED;\r
+}\r
+\r
/**\r
Initialize the unit test framework, suite, and unit tests for the\r
sample unit tests and run the unit tests.\r
AddTestCase (ManualTestCase, "Check if the parent entry has different ReadWrite attribute", "Manual Test Case5", TestCaseManualChangeReadWrite, NULL, NULL, NULL);\r
AddTestCase (ManualTestCase, "Check if the parent entry has different Nx attribute", "Manual Test Case6", TestCaseManualChangeNx, NULL, NULL, NULL);\r
AddTestCase (ManualTestCase, "Check if the needed size is expected", "Manual Test Case7", TestCaseManualSizeNotMatch, NULL, NULL, NULL);\r
-\r
+ AddTestCase (ManualTestCase, "Check MapMask when creating new page table or mapping not-present range", "Manual Test Case8", TestCaseToCheckMapMaskAndAttr, NULL, NULL, NULL);\r
//\r
// Populate the Random Test Cases.\r
//\r