2022-06-27 10:58:48 +02:00
/** @file
Unit tests of the CpuPageTableLib instance of the CpuPageTableLib class
2023-02-24 08:25:09 +01:00
Copyright ( c ) 2022 - 2023 , Intel Corporation . All rights reserved . < BR >
2022-06-27 10:58:48 +02:00
SPDX - License - Identifier : BSD - 2 - Clause - Patent
* */
# include "CpuPageTableLibUnitTest.h"
// ----------------------------------------------------------------------- PageMode--TestCount-TestRangeCount---RandomOptions
2023-03-31 20:19:20 +02:00
// static CPU_PAGE_TABLE_LIB_RANDOM_TEST_CONTEXT mTestContextPaging4Level = { Paging4Level, 30, 20, USE_RANDOM_ARRAY };
// static CPU_PAGE_TABLE_LIB_RANDOM_TEST_CONTEXT mTestContextPaging4Level1GB = { Paging4Level1GB, 30, 20, USE_RANDOM_ARRAY };
// static CPU_PAGE_TABLE_LIB_RANDOM_TEST_CONTEXT mTestContextPaging5Level = { Paging5Level, 30, 20, USE_RANDOM_ARRAY };
// static CPU_PAGE_TABLE_LIB_RANDOM_TEST_CONTEXT mTestContextPaging5Level1GB = { Paging5Level1GB, 30, 20, USE_RANDOM_ARRAY };
// static CPU_PAGE_TABLE_LIB_RANDOM_TEST_CONTEXT mTestContextPagingPae = { PagingPae, 30, 20, USE_RANDOM_ARRAY };
2022-06-27 10:58:48 +02:00
/**
Check if the input parameters are not supported .
@ param [ in ] Context [ Optional ] An optional parameter that enables :
1 ) test - case reuse with varied parameters and
2 ) test - case re - entry for Target tests that need a
reboot . This parameter is a VOID * and it is the
responsibility of the test author to ensure that the
contents are well understood by all test cases that may
consume it .
@ retval UNIT_TEST_PASSED The Unit test has completed and the test
case was successful .
@ retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed .
* */
UNIT_TEST_STATUS
EFIAPI
TestCaseForParameter (
IN UNIT_TEST_CONTEXT Context
)
{
UINTN PageTable ;
PAGING_MODE PagingMode ;
UINTN Buffer ;
UINTN PageTableBufferSize ;
IA32_MAP_ATTRIBUTE MapAttribute ;
IA32_MAP_ATTRIBUTE MapMask ;
MapAttribute . Uint64 = 0 ;
MapMask . Uint64 = 0 ;
PagingMode = Paging5Level1GB ;
PageTableBufferSize = 0 ;
PageTable = 0 ;
//
// If the input linear address is not 4K align, it should return invalid parameter
//
2022-12-09 03:36:37 +01:00
UT_ASSERT_EQUAL ( PageTableMap ( & PageTable , PagingMode , & Buffer , & PageTableBufferSize , 1 , SIZE_4KB , & MapAttribute , & MapMask , NULL ) , RETURN_INVALID_PARAMETER ) ;
2022-06-27 10:58:48 +02:00
//
// If the input PageTableBufferSize is not 4K align, it should return invalid parameter
//
PageTableBufferSize = 10 ;
2022-12-09 03:36:37 +01:00
UT_ASSERT_EQUAL ( PageTableMap ( & PageTable , PagingMode , & Buffer , & PageTableBufferSize , 0 , SIZE_4KB , & MapAttribute , & MapMask , NULL ) , RETURN_INVALID_PARAMETER ) ;
2022-06-27 10:58:48 +02:00
//
// If the input PagingMode is Paging32bit, it should return invalid parameter
//
PageTableBufferSize = 0 ;
PagingMode = Paging32bit ;
2022-12-09 03:36:37 +01:00
UT_ASSERT_EQUAL ( PageTableMap ( & PageTable , PagingMode , & Buffer , & PageTableBufferSize , 1 , SIZE_4KB , & MapAttribute , & MapMask , NULL ) , RETURN_UNSUPPORTED ) ;
2022-06-27 10:58:48 +02:00
//
// If the input MapMask is NULL, it should return invalid parameter
//
PagingMode = Paging5Level1GB ;
2022-12-09 03:36:37 +01:00
UT_ASSERT_EQUAL ( PageTableMap ( & PageTable , PagingMode , & Buffer , & PageTableBufferSize , 1 , SIZE_4KB , & MapAttribute , NULL , NULL ) , RETURN_INVALID_PARAMETER ) ;
2022-06-27 10:58:48 +02:00
return UNIT_TEST_PASSED ;
}
/**
Check the case that modifying page table doesn ' t need extra buffe
@ param [ in ] Context [ Optional ] An optional parameter that enables :
1 ) test - case reuse with varied parameters and
2 ) test - case re - entry for Target tests that need a
reboot . This parameter is a VOID * and it is the
responsibility of the test author to ensure that the
contents are well understood by all test cases that may
consume it .
@ retval UNIT_TEST_PASSED The Unit test has completed and the test
case was successful .
@ retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed .
* */
UNIT_TEST_STATUS
EFIAPI
TestCaseWhichNoNeedExtraSize (
IN UNIT_TEST_CONTEXT Context
)
{
UINTN PageTable ;
PAGING_MODE PagingMode ;
VOID * Buffer ;
UINTN PageTableBufferSize ;
IA32_MAP_ATTRIBUTE MapAttribute ;
IA32_MAP_ATTRIBUTE MapMask ;
RETURN_STATUS Status ;
UNIT_TEST_STATUS TestStatus ;
MapAttribute . Uint64 = 0 ;
MapMask . Uint64 = 0 ;
PagingMode = Paging4Level1GB ;
PageTableBufferSize = 0 ;
PageTable = 0 ;
Buffer = NULL ;
MapAttribute . Bits . Present = 1 ;
MapAttribute . Bits . Nx = 1 ;
MapMask . Bits . Present = 1 ;
MapMask . Uint64 = MAX_UINT64 ;
//
// Create page table to cover [0, 10M], it should have 5 PTE
//
2022-12-09 03:36:37 +01:00
Status = PageTableMap ( & PageTable , PagingMode , Buffer , & PageTableBufferSize , 0 , ( UINT64 ) SIZE_2MB * 5 , & MapAttribute , & MapMask , NULL ) ;
2022-06-27 10:58:48 +02:00
UT_ASSERT_EQUAL ( Status , RETURN_BUFFER_TOO_SMALL ) ;
Buffer = AllocatePages ( EFI_SIZE_TO_PAGES ( PageTableBufferSize ) ) ;
2022-12-09 03:36:37 +01:00
Status = PageTableMap ( & PageTable , PagingMode , Buffer , & PageTableBufferSize , 0 , ( UINT64 ) SIZE_2MB * 5 , & MapAttribute , & MapMask , NULL ) ;
2022-06-27 10:58:48 +02:00
UT_ASSERT_EQUAL ( Status , RETURN_SUCCESS ) ;
TestStatus = IsPageTableValid ( PageTable , PagingMode ) ;
if ( TestStatus ! = UNIT_TEST_PASSED ) {
return TestStatus ;
}
//
// call library to cover [0, 4K], because the page table is already cover [0, 10M], and no attribute change,
// We assume the fucntion doesn't need to change page table, return success and output BufferSize is 0
//
Buffer = NULL ;
2022-12-09 03:36:37 +01:00
Status = PageTableMap ( & PageTable , PagingMode , Buffer , & PageTableBufferSize , 0 , ( UINT64 ) SIZE_4KB , & MapAttribute , & MapMask , NULL ) ;
2022-06-27 10:58:48 +02:00
UT_ASSERT_EQUAL ( PageTableBufferSize , 0 ) ;
UT_ASSERT_EQUAL ( Status , RETURN_SUCCESS ) ;
TestStatus = IsPageTableValid ( PageTable , PagingMode ) ;
if ( TestStatus ! = UNIT_TEST_PASSED ) {
return TestStatus ;
}
//
// Same range and same attribute, only clear one mask attribute bit
// We assume the fucntion doesn't need to change page table, return success and output BufferSize is 0
//
MapMask . Bits . Nx = 0 ;
PageTableBufferSize = 0 ;
2022-12-09 03:36:37 +01:00
Status = PageTableMap ( & PageTable , PagingMode , NULL , & PageTableBufferSize , 0 , ( UINT64 ) SIZE_4KB , & MapAttribute , & MapMask , NULL ) ;
2022-06-27 10:58:48 +02:00
UT_ASSERT_EQUAL ( Status , RETURN_SUCCESS ) ;
UT_ASSERT_EQUAL ( PageTableBufferSize , 0 ) ;
TestStatus = IsPageTableValid ( PageTable , PagingMode ) ;
if ( TestStatus ! = UNIT_TEST_PASSED ) {
return TestStatus ;
}
//
// call library to cover [2M, 4M], while the page table is already cover [0, 10M],
// only change one attribute bit, we assume the page table change be modified even if the
// input Buffer is NULL, and BufferSize is 0
//
MapAttribute . Bits . Accessed = 1 ;
MapMask . Bits . Accessed = 1 ;
PageTableBufferSize = 0 ;
2022-12-09 03:36:37 +01:00
Status = PageTableMap ( & PageTable , PagingMode , NULL , & PageTableBufferSize , ( UINT64 ) SIZE_2MB , ( UINT64 ) SIZE_2MB , & MapAttribute , & MapMask , NULL ) ;
2022-06-27 10:58:48 +02:00
UT_ASSERT_EQUAL ( Status , RETURN_SUCCESS ) ;
UT_ASSERT_EQUAL ( PageTableBufferSize , 0 ) ;
TestStatus = IsPageTableValid ( PageTable , PagingMode ) ;
if ( TestStatus ! = UNIT_TEST_PASSED ) {
return TestStatus ;
}
return UNIT_TEST_PASSED ;
}
/**
Test Case that check the case to map [ 0 , 1 G ] to [ 8 K , 1 G + 8 K ]
@ param [ in ] Context [ Optional ] An optional parameter that enables :
1 ) test - case reuse with varied parameters and
2 ) test - case re - entry for Target tests that need a
reboot . This parameter is a VOID * and it is the
responsibility of the test author to ensure that the
contents are well understood by all test cases that may
consume it .
@ retval UNIT_TEST_PASSED The Unit test has completed and the test
case was successful .
@ retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed .
* */
UNIT_TEST_STATUS
EFIAPI
TestCase1Gmapto4K (
IN UNIT_TEST_CONTEXT Context
)
{
UINTN PageTable ;
PAGING_MODE PagingMode ;
VOID * Buffer ;
UINTN PageTableBufferSize ;
IA32_MAP_ATTRIBUTE MapAttribute ;
IA32_MAP_ATTRIBUTE MapMask ;
RETURN_STATUS Status ;
UNIT_TEST_STATUS TestStatus ;
//
// Create Page table to map [0,1G] to [8K, 1G+8K]
//
PagingMode = Paging4Level1GB ;
PageTableBufferSize = 0 ;
PageTable = 0 ;
Buffer = NULL ;
MapAttribute . Uint64 = ( UINT64 ) SIZE_4KB * 2 ;
MapMask . Uint64 = ( UINT64 ) SIZE_4KB * 2 ;
MapAttribute . Bits . Present = 1 ;
MapMask . Bits . Present = 1 ;
MapMask . Uint64 = MAX_UINT64 ;
2022-12-09 03:36:37 +01:00
Status = PageTableMap ( & PageTable , PagingMode , Buffer , & PageTableBufferSize , ( UINT64 ) 0 , ( UINT64 ) SIZE_1GB , & MapAttribute , & MapMask , NULL ) ;
2022-06-27 10:58:48 +02:00
UT_ASSERT_EQUAL ( Status , RETURN_BUFFER_TOO_SMALL ) ;
Buffer = AllocatePages ( EFI_SIZE_TO_PAGES ( PageTableBufferSize ) ) ;
2022-12-09 03:36:37 +01:00
Status = PageTableMap ( & PageTable , PagingMode , Buffer , & PageTableBufferSize , ( UINT64 ) 0 , ( UINT64 ) SIZE_1GB , & MapAttribute , & MapMask , NULL ) ;
2022-06-27 10:58:48 +02:00
UT_ASSERT_EQUAL ( Status , RETURN_SUCCESS ) ;
//
// Page table should be valid. (All reserved bits are zero)
//
TestStatus = IsPageTableValid ( PageTable , PagingMode ) ;
if ( TestStatus ! = UNIT_TEST_PASSED ) {
return TestStatus ;
}
return UNIT_TEST_PASSED ;
}
/**
Check if the parent entry has different R / W attribute
@ param [ in ] Context [ Optional ] An optional parameter that enables :
1 ) test - case reuse with varied parameters and
2 ) test - case re - entry for Target tests that need a
reboot . This parameter is a VOID * and it is the
responsibility of the test author to ensure that the
contents are well understood by all test cases that may
consume it .
@ retval UNIT_TEST_PASSED The Unit test has completed and the test
case was successful .
@ retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed .
* */
UNIT_TEST_STATUS
EFIAPI
TestCaseManualChangeReadWrite (
IN UNIT_TEST_CONTEXT Context
)
{
UINTN PageTable ;
PAGING_MODE PagingMode ;
VOID * Buffer ;
UINTN PageTableBufferSize ;
IA32_MAP_ATTRIBUTE MapAttribute ;
IA32_MAP_ATTRIBUTE ExpectedMapAttribute ;
IA32_MAP_ATTRIBUTE MapMask ;
RETURN_STATUS Status ;
IA32_MAP_ENTRY * Map ;
UINTN MapCount ;
IA32_PAGING_ENTRY * PagingEntry ;
VOID * BackupBuffer ;
UINTN BackupPageTableBufferSize ;
PagingMode = Paging4Level ;
PageTableBufferSize = 0 ;
PageTable = 0 ;
Buffer = NULL ;
MapAttribute . Uint64 = 0 ;
MapMask . Uint64 = MAX_UINT64 ;
MapAttribute . Bits . Present = 1 ;
MapAttribute . Bits . ReadWrite = 1 ;
//
// Create Page table to cover [0,2G], with ReadWrite = 1
//
2022-12-09 03:36:37 +01:00
Status = PageTableMap ( & PageTable , PagingMode , Buffer , & PageTableBufferSize , 0 , SIZE_2GB , & MapAttribute , & MapMask , NULL ) ;
2022-06-27 10:58:48 +02:00
UT_ASSERT_EQUAL ( Status , RETURN_BUFFER_TOO_SMALL ) ;
BackupPageTableBufferSize = PageTableBufferSize ;
Buffer = AllocatePages ( EFI_SIZE_TO_PAGES ( PageTableBufferSize ) ) ;
2022-12-09 03:36:37 +01:00
Status = PageTableMap ( & PageTable , PagingMode , Buffer , & PageTableBufferSize , 0 , SIZE_2GB , & MapAttribute , & MapMask , NULL ) ;
2022-06-27 10:58:48 +02:00
UT_ASSERT_EQUAL ( Status , RETURN_SUCCESS ) ;
IsPageTableValid ( PageTable , PagingMode ) ;
MapCount = 0 ;
Status = PageTableParse ( PageTable , PagingMode , NULL , & MapCount ) ;
UT_ASSERT_EQUAL ( Status , RETURN_BUFFER_TOO_SMALL ) ;
IsPageTableValid ( PageTable , PagingMode ) ;
Map = AllocatePages ( EFI_SIZE_TO_PAGES ( MapCount ) ) ;
Status = PageTableParse ( PageTable , PagingMode , Map , & MapCount ) ;
UT_ASSERT_EQUAL ( Status , RETURN_SUCCESS ) ;
UT_ASSERT_EQUAL ( MapCount , 1 ) ;
UT_ASSERT_EQUAL ( Map [ 0 ] . LinearAddress , 0 ) ;
UT_ASSERT_EQUAL ( Map [ 0 ] . Length , SIZE_2GB ) ;
ExpectedMapAttribute . Uint64 = MapAttribute . Uint64 ;
UT_ASSERT_EQUAL ( Map [ 0 ] . Attribute . Uint64 , ExpectedMapAttribute . Uint64 ) ;
//
// Manually change ReadWrite to 0 for non-leaf entry, which covers [0,2G]
//
PagingEntry = ( IA32_PAGING_ENTRY * ) ( UINTN ) PageTable ;
PagingEntry - > Uint64 = PagingEntry - > Uint64 & ( ~ ( UINT64 ) 0x2 ) ;
MapCount = 0 ;
Status = PageTableParse ( PageTable , PagingMode , NULL , & MapCount ) ;
UT_ASSERT_EQUAL ( Status , RETURN_BUFFER_TOO_SMALL ) ;
Map = AllocatePages ( EFI_SIZE_TO_PAGES ( MapCount ) ) ;
Status = PageTableParse ( PageTable , PagingMode , Map , & MapCount ) ;
UT_ASSERT_EQUAL ( Status , RETURN_SUCCESS ) ;
UT_ASSERT_EQUAL ( MapCount , 1 ) ;
UT_ASSERT_EQUAL ( Map [ 0 ] . LinearAddress , 0 ) ;
UT_ASSERT_EQUAL ( Map [ 0 ] . Length , SIZE_2GB ) ;
ExpectedMapAttribute . Uint64 = MapAttribute . Uint64 ;
ExpectedMapAttribute . Bits . ReadWrite = 0 ;
UT_ASSERT_EQUAL ( Map [ 0 ] . Attribute . Uint64 , ExpectedMapAttribute . Uint64 ) ;
//
// Copy the page entry structure memory for future compare
//
BackupBuffer = AllocateCopyPool ( BackupPageTableBufferSize , Buffer ) ;
UT_ASSERT_MEM_EQUAL ( Buffer , BackupBuffer , BackupPageTableBufferSize ) ;
//
// Call library to change ReadWrite to 0 for [0,2M]
//
MapAttribute . Bits . ReadWrite = 0 ;
2022-12-09 03:36:37 +01:00
Status = PageTableMap ( & PageTable , PagingMode , NULL , & PageTableBufferSize , 0 , SIZE_2MB , & MapAttribute , & MapMask , NULL ) ;
2022-06-27 10:58:48 +02:00
UT_ASSERT_EQUAL ( Status , RETURN_SUCCESS ) ;
IsPageTableValid ( PageTable , PagingMode ) ;
MapCount = 0 ;
Status = PageTableParse ( PageTable , PagingMode , NULL , & MapCount ) ;
UT_ASSERT_EQUAL ( Status , RETURN_BUFFER_TOO_SMALL ) ;
Map = AllocatePages ( EFI_SIZE_TO_PAGES ( MapCount ) ) ;
Status = PageTableParse ( PageTable , PagingMode , Map , & MapCount ) ;
//
// There should be 1 range [0, 2G] with ReadWrite = 0
//
UT_ASSERT_EQUAL ( Status , RETURN_SUCCESS ) ;
UT_ASSERT_EQUAL ( MapCount , 1 ) ;
UT_ASSERT_EQUAL ( Map [ 0 ] . LinearAddress , 0 ) ;
UT_ASSERT_EQUAL ( Map [ 0 ] . Length , SIZE_2GB ) ;
ExpectedMapAttribute . Uint64 = MapAttribute . Uint64 ;
UT_ASSERT_EQUAL ( Map [ 0 ] . Attribute . Uint64 , ExpectedMapAttribute . Uint64 ) ;
//
// The latest PageTableMap call should change nothing.
// The memory should be identical before and after the funtion is called.
//
UT_ASSERT_MEM_EQUAL ( Buffer , BackupBuffer , BackupPageTableBufferSize ) ;
//
// Call library to change ReadWrite to 1 for [0, 2M]
//
MapAttribute . Bits . ReadWrite = 1 ;
PageTableBufferSize = 0 ;
2022-12-09 03:36:37 +01:00
Status = PageTableMap ( & PageTable , PagingMode , NULL , & PageTableBufferSize , 0 , SIZE_2MB , & MapAttribute , & MapMask , NULL ) ;
2022-06-27 10:58:48 +02:00
UT_ASSERT_EQUAL ( Status , RETURN_SUCCESS ) ;
IsPageTableValid ( PageTable , PagingMode ) ;
MapCount = 0 ;
Status = PageTableParse ( PageTable , PagingMode , NULL , & MapCount ) ;
UT_ASSERT_EQUAL ( Status , RETURN_BUFFER_TOO_SMALL ) ;
Map = AllocatePages ( EFI_SIZE_TO_PAGES ( MapCount ) ) ;
Status = PageTableParse ( PageTable , PagingMode , Map , & MapCount ) ;
//
// There should be 2 range [0, 2M] with ReadWrite = 1 and [2M, 2G] with ReadWrite = 0
//
UT_ASSERT_EQUAL ( Status , RETURN_SUCCESS ) ;
UT_ASSERT_EQUAL ( MapCount , 2 ) ;
UT_ASSERT_EQUAL ( Map [ 0 ] . LinearAddress , 0 ) ;
UT_ASSERT_EQUAL ( Map [ 0 ] . Length , SIZE_2MB ) ;
ExpectedMapAttribute . Uint64 = MapAttribute . Uint64 ;
UT_ASSERT_EQUAL ( Map [ 0 ] . Attribute . Uint64 , ExpectedMapAttribute . Uint64 ) ;
UT_ASSERT_EQUAL ( Map [ 1 ] . LinearAddress , SIZE_2MB ) ;
UT_ASSERT_EQUAL ( Map [ 1 ] . Length , SIZE_2GB - SIZE_2MB ) ;
ExpectedMapAttribute . Uint64 = SIZE_2MB ;
ExpectedMapAttribute . Bits . ReadWrite = 0 ;
ExpectedMapAttribute . Bits . Present = 1 ;
UT_ASSERT_EQUAL ( Map [ 1 ] . Attribute . Uint64 , ExpectedMapAttribute . Uint64 ) ;
return UNIT_TEST_PASSED ;
}
/**
Check if the needed size is expected
@ param [ in ] Context [ Optional ] An optional parameter that enables :
1 ) test - case reuse with varied parameters and
2 ) test - case re - entry for Target tests that need a
reboot . This parameter is a VOID * and it is the
responsibility of the test author to ensure that the
contents are well understood by all test cases that may
consume it .
@ retval UNIT_TEST_PASSED The Unit test has completed and the test
case was successful .
@ retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed .
* */
UNIT_TEST_STATUS
EFIAPI
TestCaseManualSizeNotMatch (
IN UNIT_TEST_CONTEXT Context
)
{
UINTN PageTable ;
PAGING_MODE PagingMode ;
VOID * Buffer ;
UINTN PageTableBufferSize ;
IA32_MAP_ATTRIBUTE MapAttribute ;
IA32_MAP_ATTRIBUTE ExpectedMapAttribute ;
IA32_MAP_ATTRIBUTE MapMask ;
RETURN_STATUS Status ;
IA32_MAP_ENTRY * Map ;
UINTN MapCount ;
IA32_PAGING_ENTRY * PagingEntry ;
2023-03-07 07:21:54 +01:00
PagingMode = Paging4Level ;
PageTableBufferSize = 0 ;
PageTable = 0 ;
Buffer = NULL ;
MapMask . Uint64 = MAX_UINT64 ;
MapAttribute . Uint64 = ( SIZE_2MB - SIZE_4KB ) ;
MapAttribute . Bits . Present = 1 ;
MapAttribute . Bits . ReadWrite = 1 ;
2022-06-27 10:58:48 +02:00
//
// Create Page table to cover [2M-4K, 4M], with ReadWrite = 1
//
2022-12-09 03:36:37 +01:00
Status = PageTableMap ( & PageTable , PagingMode , Buffer , & PageTableBufferSize , SIZE_2MB - SIZE_4KB , SIZE_4KB + SIZE_2MB , & MapAttribute , & MapMask , NULL ) ;
2022-06-27 10:58:48 +02:00
UT_ASSERT_EQUAL ( Status , RETURN_BUFFER_TOO_SMALL ) ;
Buffer = AllocatePages ( EFI_SIZE_TO_PAGES ( PageTableBufferSize ) ) ;
2022-12-09 03:36:37 +01:00
Status = PageTableMap ( & PageTable , PagingMode , Buffer , & PageTableBufferSize , SIZE_2MB - SIZE_4KB , SIZE_4KB + SIZE_2MB , & MapAttribute , & MapMask , NULL ) ;
2022-06-27 10:58:48 +02:00
UT_ASSERT_EQUAL ( Status , RETURN_SUCCESS ) ;
IsPageTableValid ( PageTable , PagingMode ) ;
MapCount = 0 ;
Status = PageTableParse ( PageTable , PagingMode , NULL , & MapCount ) ;
UT_ASSERT_EQUAL ( Status , RETURN_BUFFER_TOO_SMALL ) ;
IsPageTableValid ( PageTable , PagingMode ) ;
Map = AllocatePages ( EFI_SIZE_TO_PAGES ( MapCount ) ) ;
Status = PageTableParse ( PageTable , PagingMode , Map , & MapCount ) ;
UT_ASSERT_EQUAL ( Status , RETURN_SUCCESS ) ;
UT_ASSERT_EQUAL ( MapCount , 1 ) ;
UT_ASSERT_EQUAL ( Map [ 0 ] . LinearAddress , SIZE_2MB - SIZE_4KB ) ;
UT_ASSERT_EQUAL ( Map [ 0 ] . Length , SIZE_4KB + SIZE_2MB ) ;
ExpectedMapAttribute . Uint64 = MapAttribute . Uint64 ;
UT_ASSERT_EQUAL ( Map [ 0 ] . Attribute . Uint64 , ExpectedMapAttribute . Uint64 ) ;
//
// Manually change ReadWrite to 0 for 3 level non-leaf entry, which covers [0,2M]
// Then the map is:
// [2M-4K,2M], R/W = 0
// [2M ,4M], R/W = 1
//
2023-03-07 07:21:54 +01:00
PagingEntry = ( IA32_PAGING_ENTRY * ) ( UINTN ) PageTable ; // Get 4 level entry
PagingEntry = ( IA32_PAGING_ENTRY * ) ( UINTN ) IA32_PNLE_PAGE_TABLE_BASE_ADDRESS ( PagingEntry ) ; // Get 3 level entry
PagingEntry = ( IA32_PAGING_ENTRY * ) ( UINTN ) IA32_PNLE_PAGE_TABLE_BASE_ADDRESS ( PagingEntry ) ; // Get 2 level entry
2022-06-27 10:58:48 +02:00
PagingEntry - > Uint64 = PagingEntry - > Uint64 & ( ~ ( UINT64 ) 0x2 ) ;
MapCount = 0 ;
Status = PageTableParse ( PageTable , PagingMode , NULL , & MapCount ) ;
UT_ASSERT_EQUAL ( Status , RETURN_BUFFER_TOO_SMALL ) ;
Map = AllocatePages ( EFI_SIZE_TO_PAGES ( MapCount ) ) ;
Status = PageTableParse ( PageTable , PagingMode , Map , & MapCount ) ;
UT_ASSERT_EQUAL ( Status , RETURN_SUCCESS ) ;
UT_ASSERT_EQUAL ( MapCount , 2 ) ;
UT_ASSERT_EQUAL ( Map [ 0 ] . LinearAddress , SIZE_2MB - SIZE_4KB ) ;
UT_ASSERT_EQUAL ( Map [ 0 ] . Length , SIZE_4KB ) ;
ExpectedMapAttribute . Uint64 = MapAttribute . Uint64 ;
ExpectedMapAttribute . Bits . ReadWrite = 0 ;
UT_ASSERT_EQUAL ( Map [ 0 ] . Attribute . Uint64 , ExpectedMapAttribute . Uint64 ) ;
UT_ASSERT_EQUAL ( Map [ 1 ] . LinearAddress , SIZE_2MB ) ;
UT_ASSERT_EQUAL ( Map [ 1 ] . Length , SIZE_2MB ) ;
2023-03-07 07:21:54 +01:00
ExpectedMapAttribute . Uint64 = MapAttribute . Uint64 + SIZE_4KB ;
ExpectedMapAttribute . Bits . ReadWrite = 1 ;
2022-06-27 10:58:48 +02:00
UT_ASSERT_EQUAL ( Map [ 1 ] . Attribute . Uint64 , ExpectedMapAttribute . Uint64 ) ;
//
// Set Page table [2M-4K, 2M+4K]'s ReadWrite = 1, [2M,2M+4K]'s ReadWrite is already 1
// Just need to set [2M-4K,2M], won't need extra size, so the status should be success
//
2023-03-07 07:21:54 +01:00
MapAttribute . Uint64 = SIZE_2MB - SIZE_4KB ;
MapAttribute . Bits . Present = 1 ;
MapAttribute . Bits . ReadWrite = 1 ;
PageTableBufferSize = 0 ;
Status = PageTableMap ( & PageTable , PagingMode , Buffer , & PageTableBufferSize , SIZE_2MB - SIZE_4KB , SIZE_4KB * 2 , & MapAttribute , & MapMask , NULL ) ;
2022-06-27 10:58:48 +02:00
UT_ASSERT_EQUAL ( Status , RETURN_SUCCESS ) ;
return UNIT_TEST_PASSED ;
}
/**
Check that won ' t merge entries
@ param [ in ] Context [ Optional ] An optional parameter that enables :
1 ) test - case reuse with varied parameters and
2 ) test - case re - entry for Target tests that need a
reboot . This parameter is a VOID * and it is the
responsibility of the test author to ensure that the
contents are well understood by all test cases that may
consume it .
@ retval UNIT_TEST_PASSED The Unit test has completed and the test
case was successful .
@ retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed .
* */
UNIT_TEST_STATUS
EFIAPI
TestCaseManualNotMergeEntry (
IN UNIT_TEST_CONTEXT Context
)
{
UINTN PageTable ;
PAGING_MODE PagingMode ;
VOID * Buffer ;
UINTN PageTableBufferSize ;
IA32_MAP_ATTRIBUTE MapAttribute ;
IA32_MAP_ATTRIBUTE MapMask ;
RETURN_STATUS Status ;
UNIT_TEST_STATUS TestStatus ;
PagingMode = Paging4Level1GB ;
PageTableBufferSize = 0 ;
PageTable = 0 ;
Buffer = NULL ;
MapAttribute . Uint64 = 0 ;
MapMask . Uint64 = MAX_UINT64 ;
MapAttribute . Bits . Present = 1 ;
MapMask . Bits . Present = 1 ;
//
// Create Page table to cover [0,4M], and [4M, 1G] is not present
//
2022-12-09 03:36:37 +01:00
Status = PageTableMap ( & PageTable , PagingMode , Buffer , & PageTableBufferSize , ( UINT64 ) 0 , ( UINT64 ) SIZE_2MB * 2 , & MapAttribute , & MapMask , NULL ) ;
2022-06-27 10:58:48 +02:00
UT_ASSERT_EQUAL ( Status , RETURN_BUFFER_TOO_SMALL ) ;
Buffer = AllocatePages ( EFI_SIZE_TO_PAGES ( PageTableBufferSize ) ) ;
2022-12-09 03:36:37 +01:00
Status = PageTableMap ( & PageTable , PagingMode , Buffer , & PageTableBufferSize , ( UINT64 ) 0 , ( UINT64 ) SIZE_2MB * 2 , & MapAttribute , & MapMask , NULL ) ;
2022-06-27 10:58:48 +02:00
UT_ASSERT_EQUAL ( Status , RETURN_SUCCESS ) ;
TestStatus = IsPageTableValid ( PageTable , PagingMode ) ;
if ( TestStatus ! = UNIT_TEST_PASSED ) {
return TestStatus ;
}
//
// Let Page table to cover [0,1G], we assume it won't use a big 1G entry to cover whole range
// It looks like the chioce is not bad, but sometime, we need to keep some small entry
//
PageTableBufferSize = 0 ;
2022-12-09 03:36:37 +01:00
Status = PageTableMap ( & PageTable , PagingMode , NULL , & PageTableBufferSize , ( UINT64 ) 0 , ( UINT64 ) SIZE_1GB , & MapAttribute , & MapMask , NULL ) ;
2022-06-27 10:58:48 +02:00
UT_ASSERT_EQUAL ( Status , RETURN_SUCCESS ) ;
TestStatus = IsPageTableValid ( PageTable , PagingMode ) ;
if ( TestStatus ! = UNIT_TEST_PASSED ) {
return TestStatus ;
}
MapAttribute . Bits . Accessed = 1 ;
PageTableBufferSize = 0 ;
2022-12-09 03:36:37 +01:00
Status = PageTableMap ( & PageTable , PagingMode , NULL , & PageTableBufferSize , ( UINT64 ) 0 , ( UINT64 ) SIZE_2MB , & MapAttribute , & MapMask , NULL ) ;
2022-06-27 10:58:48 +02:00
//
// If it didn't use a big 1G entry to cover whole range, only change [0,2M] for some attribute won't need extra memory
//
UT_ASSERT_EQUAL ( Status , RETURN_SUCCESS ) ;
return UNIT_TEST_PASSED ;
}
/**
Check if the parent entry has different Nx attribute
@ param [ in ] Context [ Optional ] An optional parameter that enables :
1 ) test - case reuse with varied parameters and
2 ) test - case re - entry for Target tests that need a
reboot . This parameter is a VOID * and it is the
responsibility of the test author to ensure that the
contents are well understood by all test cases that may
consume it .
@ retval UNIT_TEST_PASSED The Unit test has completed and the test
case was successful .
@ retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed .
* */
UNIT_TEST_STATUS
EFIAPI
TestCaseManualChangeNx (
IN UNIT_TEST_CONTEXT Context
)
{
UINTN PageTable ;
PAGING_MODE PagingMode ;
VOID * Buffer ;
UINTN PageTableBufferSize ;
IA32_MAP_ATTRIBUTE MapAttribute ;
IA32_MAP_ATTRIBUTE ExpectedMapAttribute ;
IA32_MAP_ATTRIBUTE MapMask ;
RETURN_STATUS Status ;
IA32_MAP_ENTRY * Map ;
UINTN MapCount ;
IA32_PAGING_ENTRY * PagingEntry ;
UNIT_TEST_STATUS TestStatus ;
PagingMode = Paging4Level1GB ;
PageTableBufferSize = 0 ;
PageTable = 0 ;
Buffer = NULL ;
MapAttribute . Uint64 = 0 ;
MapMask . Uint64 = MAX_UINT64 ;
MapAttribute . Bits . Present = 1 ;
MapAttribute . Bits . Nx = 0 ;
//
// Create Page table to cover [0,2G], with Nx = 0
//
2022-12-09 03:36:37 +01:00
Status = PageTableMap ( & PageTable , PagingMode , Buffer , & PageTableBufferSize , ( UINT64 ) 0 , ( UINT64 ) SIZE_1GB * 2 , & MapAttribute , & MapMask , NULL ) ;
2022-06-27 10:58:48 +02:00
UT_ASSERT_EQUAL ( Status , RETURN_BUFFER_TOO_SMALL ) ;
Buffer = AllocatePages ( EFI_SIZE_TO_PAGES ( PageTableBufferSize ) ) ;
2022-12-09 03:36:37 +01:00
Status = PageTableMap ( & PageTable , PagingMode , Buffer , & PageTableBufferSize , ( UINT64 ) 0 , ( UINT64 ) SIZE_1GB * 2 , & MapAttribute , & MapMask , NULL ) ;
2022-06-27 10:58:48 +02:00
UT_ASSERT_EQUAL ( Status , RETURN_SUCCESS ) ;
TestStatus = IsPageTableValid ( PageTable , PagingMode ) ;
if ( TestStatus ! = UNIT_TEST_PASSED ) {
return TestStatus ;
}
MapCount = 0 ;
Status = PageTableParse ( PageTable , PagingMode , NULL , & MapCount ) ;
UT_ASSERT_EQUAL ( Status , RETURN_BUFFER_TOO_SMALL ) ;
TestStatus = IsPageTableValid ( PageTable , PagingMode ) ;
if ( TestStatus ! = UNIT_TEST_PASSED ) {
return TestStatus ;
}
Map = AllocatePages ( EFI_SIZE_TO_PAGES ( MapCount * sizeof ( IA32_MAP_ENTRY ) ) ) ;
Status = PageTableParse ( PageTable , PagingMode , Map , & MapCount ) ;
UT_ASSERT_EQUAL ( Status , RETURN_SUCCESS ) ;
UT_ASSERT_EQUAL ( MapCount , 1 ) ;
UT_ASSERT_EQUAL ( Map [ 0 ] . LinearAddress , 0 ) ;
UT_ASSERT_EQUAL ( Map [ 0 ] . Length , SIZE_2GB ) ;
ExpectedMapAttribute . Uint64 = MapAttribute . Uint64 ;
UT_ASSERT_EQUAL ( Map [ 0 ] . Attribute . Uint64 , ExpectedMapAttribute . Uint64 ) ;
//
// Manually change Nx to 1 for non-leaf entry, which covers [0,2G]
//
PagingEntry = ( IA32_PAGING_ENTRY * ) ( UINTN ) PageTable ;
PagingEntry - > Uint64 = PagingEntry - > Uint64 | BIT63 ;
MapCount = 0 ;
Status = PageTableParse ( PageTable , PagingMode , NULL , & MapCount ) ;
UT_ASSERT_EQUAL ( Status , RETURN_BUFFER_TOO_SMALL ) ;
Map = AllocatePages ( EFI_SIZE_TO_PAGES ( MapCount * sizeof ( IA32_MAP_ENTRY ) ) ) ;
Status = PageTableParse ( PageTable , PagingMode , Map , & MapCount ) ;
UT_ASSERT_EQUAL ( Status , RETURN_SUCCESS ) ;
UT_ASSERT_EQUAL ( MapCount , 1 ) ;
UT_ASSERT_EQUAL ( Map [ 0 ] . LinearAddress , 0 ) ;
UT_ASSERT_EQUAL ( Map [ 0 ] . Length , SIZE_2GB ) ;
ExpectedMapAttribute . Bits . Nx = 1 ;
UT_ASSERT_EQUAL ( Map [ 0 ] . Attribute . Uint64 , ExpectedMapAttribute . Uint64 ) ;
//
// Call library to change Nx to 0 for [0,1G]
//
2022-12-09 03:36:37 +01:00
Status = PageTableMap ( & PageTable , PagingMode , NULL , & PageTableBufferSize , ( UINT64 ) 0 , ( UINT64 ) SIZE_1GB , & MapAttribute , & MapMask , NULL ) ;
2022-06-27 10:58:48 +02:00
UT_ASSERT_EQUAL ( Status , RETURN_SUCCESS ) ;
TestStatus = IsPageTableValid ( PageTable , PagingMode ) ;
if ( TestStatus ! = UNIT_TEST_PASSED ) {
return TestStatus ;
}
MapCount = 0 ;
Status = PageTableParse ( PageTable , PagingMode , NULL , & MapCount ) ;
UT_ASSERT_EQUAL ( Status , RETURN_BUFFER_TOO_SMALL ) ;
Map = AllocatePages ( EFI_SIZE_TO_PAGES ( MapCount * sizeof ( IA32_MAP_ENTRY ) ) ) ;
Status = PageTableParse ( PageTable , PagingMode , Map , & MapCount ) ;
UT_ASSERT_EQUAL ( Status , RETURN_SUCCESS ) ;
//
// There should be two ranges [0, 1G] with Nx = 0 and [1G, 2G] with Nx = 1
//
UT_ASSERT_EQUAL ( MapCount , 2 ) ;
UT_ASSERT_EQUAL ( Map [ 0 ] . LinearAddress , 0 ) ;
UT_ASSERT_EQUAL ( Map [ 0 ] . Length , SIZE_1GB ) ;
ExpectedMapAttribute . Uint64 = MapAttribute . Uint64 ;
UT_ASSERT_EQUAL ( Map [ 0 ] . Attribute . Uint64 , ExpectedMapAttribute . Uint64 ) ;
UT_ASSERT_EQUAL ( Map [ 1 ] . LinearAddress , SIZE_1GB ) ;
UT_ASSERT_EQUAL ( Map [ 1 ] . Length , SIZE_1GB ) ;
ExpectedMapAttribute . Uint64 = SIZE_1GB ;
ExpectedMapAttribute . Bits . Present = 1 ;
ExpectedMapAttribute . Bits . Nx = 1 ;
UT_ASSERT_EQUAL ( Map [ 1 ] . Attribute . Uint64 , ExpectedMapAttribute . Uint64 ) ;
return UNIT_TEST_PASSED ;
}
2023-02-24 08:25:09 +01:00
/**
Check if the input Mask and Attribute is as expected when creating new page table or
updating existing page table .
@ param [ in ] Context [ Optional ] An optional parameter that enables :
1 ) test - case reuse with varied parameters and
2 ) test - case re - entry for Target tests that need a
reboot . This parameter is a VOID * and it is the
responsibility of the test author to ensure that the
contents are well understood by all test cases that may
consume it .
@ retval UNIT_TEST_PASSED The Unit test has completed and the test
case was successful .
@ retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed .
* */
UNIT_TEST_STATUS
EFIAPI
TestCaseToCheckMapMaskAndAttr (
IN UNIT_TEST_CONTEXT Context
)
{
UINTN PageTable ;
PAGING_MODE PagingMode ;
VOID * Buffer ;
UINTN PageTableBufferSize ;
IA32_MAP_ATTRIBUTE MapAttribute ;
IA32_MAP_ATTRIBUTE ExpectedMapAttribute ;
IA32_MAP_ATTRIBUTE MapMask ;
RETURN_STATUS Status ;
IA32_MAP_ENTRY * Map ;
UINTN MapCount ;
PagingMode = Paging4Level ;
PageTableBufferSize = 0 ;
PageTable = 0 ;
Buffer = NULL ;
MapAttribute . Uint64 = 0 ;
MapAttribute . Bits . Present = 1 ;
MapMask . Uint64 = 0 ;
MapMask . Bits . Present = 1 ;
//
// Create Page table to cover [0, 2G]. All fields of MapMask should be set.
//
2022-12-09 03:36:37 +01:00
Status = PageTableMap ( & PageTable , PagingMode , Buffer , & PageTableBufferSize , 0 , SIZE_2GB , & MapAttribute , & MapMask , NULL ) ;
2023-02-24 08:25:09 +01:00
UT_ASSERT_EQUAL ( Status , RETURN_INVALID_PARAMETER ) ;
MapMask . Uint64 = MAX_UINT64 ;
2022-12-09 03:36:37 +01:00
Status = PageTableMap ( & PageTable , PagingMode , Buffer , & PageTableBufferSize , 0 , SIZE_2GB , & MapAttribute , & MapMask , NULL ) ;
2023-02-24 08:25:09 +01:00
UT_ASSERT_EQUAL ( Status , RETURN_BUFFER_TOO_SMALL ) ;
Buffer = AllocatePages ( EFI_SIZE_TO_PAGES ( PageTableBufferSize ) ) ;
2022-12-09 03:36:37 +01:00
Status = PageTableMap ( & PageTable , PagingMode , Buffer , & PageTableBufferSize , 0 , SIZE_2GB , & MapAttribute , & MapMask , NULL ) ;
2023-02-24 08:25:09 +01:00
UT_ASSERT_EQUAL ( Status , RETURN_SUCCESS ) ;
//
// Update Page table to set [2G - 8K, 2G] from present to non-present. All fields of MapMask except present should not be set.
//
PageTableBufferSize = 0 ;
2022-12-09 03:36:37 +01:00
MapAttribute . Uint64 = 0 ;
2023-02-24 08:25:09 +01:00
MapMask . Uint64 = 0 ;
MapMask . Bits . Present = 1 ;
MapMask . Bits . ReadWrite = 1 ;
2022-12-09 03:36:37 +01:00
Status = PageTableMap ( & PageTable , PagingMode , Buffer , & PageTableBufferSize , SIZE_2GB - SIZE_8KB , SIZE_8KB , & MapAttribute , & MapMask , NULL ) ;
2023-02-24 08:25:09 +01:00
UT_ASSERT_EQUAL ( Status , RETURN_INVALID_PARAMETER ) ;
MapMask . Bits . ReadWrite = 0 ;
2022-12-09 03:36:37 +01:00
Status = PageTableMap ( & PageTable , PagingMode , Buffer , & PageTableBufferSize , SIZE_2GB - SIZE_8KB , SIZE_8KB , & MapAttribute , & MapMask , NULL ) ;
2023-02-24 08:25:09 +01:00
UT_ASSERT_EQUAL ( Status , RETURN_BUFFER_TOO_SMALL ) ;
Buffer = AllocatePages ( EFI_SIZE_TO_PAGES ( PageTableBufferSize ) ) ;
2022-12-09 03:36:37 +01:00
Status = PageTableMap ( & PageTable , PagingMode , Buffer , & PageTableBufferSize , SIZE_2GB - SIZE_8KB , SIZE_8KB , & MapAttribute , & MapMask , NULL ) ;
2023-02-24 08:25:09 +01:00
UT_ASSERT_EQUAL ( Status , RETURN_SUCCESS ) ;
//
// Still set [2G - 8K, 2G] as not present, this case is permitted. But set [2G - 8K, 2G] as RW is not permitted.
//
PageTableBufferSize = 0 ;
MapAttribute . Uint64 = 0 ;
MapMask . Uint64 = 0 ;
MapMask . Bits . Present = 1 ;
2022-12-09 03:36:37 +01:00
Status = PageTableMap ( & PageTable , PagingMode , Buffer , & PageTableBufferSize , SIZE_2GB - SIZE_8KB , SIZE_8KB , & MapAttribute , & MapMask , NULL ) ;
2023-02-24 08:25:09 +01:00
UT_ASSERT_EQUAL ( Status , RETURN_SUCCESS ) ;
MapAttribute . Bits . ReadWrite = 1 ;
MapMask . Bits . ReadWrite = 1 ;
2022-12-09 03:36:37 +01:00
Status = PageTableMap ( & PageTable , PagingMode , Buffer , & PageTableBufferSize , SIZE_2GB - SIZE_8KB , SIZE_8KB , & MapAttribute , & MapMask , NULL ) ;
2023-02-24 08:25:09 +01:00
UT_ASSERT_EQUAL ( Status , RETURN_INVALID_PARAMETER ) ;
//
// Update Page table to set [2G - 8K, 2G] as present and RW. All fields of MapMask should be set.
//
PageTableBufferSize = 0 ;
MapAttribute . Uint64 = SIZE_2GB - SIZE_8KB ;
MapAttribute . Bits . ReadWrite = 1 ;
MapAttribute . Bits . Present = 1 ;
MapMask . Uint64 = 0 ;
MapMask . Bits . ReadWrite = 1 ;
MapMask . Bits . Present = 1 ;
2022-12-09 03:36:37 +01:00
Status = PageTableMap ( & PageTable , PagingMode , Buffer , & PageTableBufferSize , SIZE_2GB - SIZE_8KB , SIZE_8KB , & MapAttribute , & MapMask , NULL ) ;
2023-02-24 08:25:09 +01:00
UT_ASSERT_EQUAL ( Status , RETURN_INVALID_PARAMETER ) ;
MapMask . Uint64 = MAX_UINT64 ;
2022-12-09 03:36:37 +01:00
Status = PageTableMap ( & PageTable , PagingMode , Buffer , & PageTableBufferSize , SIZE_2GB - SIZE_8KB , SIZE_8KB , & MapAttribute , & MapMask , NULL ) ;
2023-02-24 08:25:09 +01:00
UT_ASSERT_EQUAL ( Status , RETURN_SUCCESS ) ;
MapCount = 0 ;
Status = PageTableParse ( PageTable , PagingMode , NULL , & MapCount ) ;
UT_ASSERT_EQUAL ( Status , RETURN_BUFFER_TOO_SMALL ) ;
Map = AllocatePages ( EFI_SIZE_TO_PAGES ( MapCount * sizeof ( IA32_MAP_ENTRY ) ) ) ;
Status = PageTableParse ( PageTable , PagingMode , Map , & MapCount ) ;
UT_ASSERT_EQUAL ( Status , RETURN_SUCCESS ) ;
//
// There should be two ranges [0, 2G-8k] with RW = 0 and [2G-8k, 2G] with RW = 1
//
UT_ASSERT_EQUAL ( MapCount , 2 ) ;
UT_ASSERT_EQUAL ( Map [ 0 ] . LinearAddress , 0 ) ;
UT_ASSERT_EQUAL ( Map [ 0 ] . Length , SIZE_2GB - SIZE_8KB ) ;
ExpectedMapAttribute . Uint64 = 0 ;
ExpectedMapAttribute . Bits . Present = 1 ;
UT_ASSERT_EQUAL ( Map [ 0 ] . Attribute . Uint64 , ExpectedMapAttribute . Uint64 ) ;
UT_ASSERT_EQUAL ( Map [ 1 ] . LinearAddress , SIZE_2GB - SIZE_8KB ) ;
UT_ASSERT_EQUAL ( Map [ 1 ] . Length , SIZE_8KB ) ;
ExpectedMapAttribute . Uint64 = SIZE_2GB - SIZE_8KB ;
ExpectedMapAttribute . Bits . Present = 1 ;
ExpectedMapAttribute . Bits . ReadWrite = 1 ;
UT_ASSERT_EQUAL ( Map [ 1 ] . Attribute . Uint64 , ExpectedMapAttribute . Uint64 ) ;
return UNIT_TEST_PASSED ;
}
2022-06-27 10:58:48 +02:00
/**
Initialize the unit test framework , suite , and unit tests for the
sample unit tests and run the unit tests .
@ retval EFI_SUCCESS All test cases were dispatched .
@ retval EFI_OUT_OF_RESOURCES There are not enough resources available to
initialize the unit tests .
* */
EFI_STATUS
EFIAPI
UefiTestMain (
VOID
)
{
EFI_STATUS Status ;
UNIT_TEST_FRAMEWORK_HANDLE Framework ;
UNIT_TEST_SUITE_HANDLE ManualTestCase ;
2024-08-23 23:47:55 +02:00
// UNIT_TEST_SUITE_HANDLE RandomTestCase;
2022-06-27 10:58:48 +02:00
Framework = NULL ;
DEBUG ( ( DEBUG_INFO , " %a v%a \n " , UNIT_TEST_APP_NAME , UNIT_TEST_APP_VERSION ) ) ;
//
// Start setting up the test framework for running the tests.
//
Status = InitUnitTestFramework ( & Framework , UNIT_TEST_APP_NAME , gEfiCallerBaseName , UNIT_TEST_APP_VERSION ) ;
if ( EFI_ERROR ( Status ) ) {
DEBUG ( ( DEBUG_ERROR , " Failed in InitUnitTestFramework. Status = %r \n " , Status ) ) ;
goto EXIT ;
}
//
// Populate the Manual Test Cases.
//
Status = CreateUnitTestSuite ( & ManualTestCase , Framework , " Manual Test Cases " , " CpuPageTableLib.Manual " , NULL , NULL ) ;
if ( EFI_ERROR ( Status ) ) {
DEBUG ( ( DEBUG_ERROR , " Failed in CreateUnitTestSuite for Manual Test Cases \n " ) ) ;
Status = EFI_OUT_OF_RESOURCES ;
goto EXIT ;
}
AddTestCase ( ManualTestCase , " Check if the input parameters are not supported. " , " Manual Test Case1 " , TestCaseForParameter , NULL , NULL , NULL ) ;
AddTestCase ( ManualTestCase , " Check the case that modifying page table doesn't need extra buffer " , " Manual Test Case2 " , TestCaseWhichNoNeedExtraSize , NULL , NULL , NULL ) ;
AddTestCase ( ManualTestCase , " Check the case to map [0, 1G] to [8K, 1G+8K] " , " Manual Test Case3 " , TestCase1Gmapto4K , NULL , NULL , NULL ) ;
AddTestCase ( ManualTestCase , " Check won't merge entries " , " Manual Test Case4 " , TestCaseManualNotMergeEntry , NULL , NULL , NULL ) ;
AddTestCase ( ManualTestCase , " Check if the parent entry has different ReadWrite attribute " , " Manual Test Case5 " , TestCaseManualChangeReadWrite , NULL , NULL , NULL ) ;
AddTestCase ( ManualTestCase , " Check if the parent entry has different Nx attribute " , " Manual Test Case6 " , TestCaseManualChangeNx , NULL , NULL , NULL ) ;
AddTestCase ( ManualTestCase , " Check if the needed size is expected " , " Manual Test Case7 " , TestCaseManualSizeNotMatch , NULL , NULL , NULL ) ;
2023-02-24 08:25:09 +01:00
AddTestCase ( ManualTestCase , " Check MapMask when creating new page table or mapping not-present range " , " Manual Test Case8 " , TestCaseToCheckMapMaskAndAttr , NULL , NULL , NULL ) ;
2022-06-27 10:58:48 +02:00
//
// Populate the Random Test Cases.
//
2024-08-23 23:47:55 +02:00
// Status = CreateUnitTestSuite (&RandomTestCase, Framework, "Random Test Cases", "CpuPageTableLib.Random", NULL, NULL);
// if (EFI_ERROR (Status)) {
// DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for Random Test Cases\n"));
// Status = EFI_OUT_OF_RESOURCES;
// goto EXIT;
// }
2022-06-27 10:58:48 +02:00
2023-03-31 20:19:20 +02:00
// AddTestCase (RandomTestCase, "Random Test for Paging4Level", "Random Test Case1", TestCaseforRandomTest, NULL, NULL, &mTestContextPaging4Level);
// AddTestCase (RandomTestCase, "Random Test for Paging4Level1G", "Random Test Case2", TestCaseforRandomTest, NULL, NULL, &mTestContextPaging4Level1GB);
// AddTestCase (RandomTestCase, "Random Test for Paging5Level", "Random Test Case3", TestCaseforRandomTest, NULL, NULL, &mTestContextPaging5Level);
// AddTestCase (RandomTestCase, "Random Test for Paging5Level1G", "Random Test Case4", TestCaseforRandomTest, NULL, NULL, &mTestContextPaging5Level1GB);
// AddTestCase (RandomTestCase, "Random Test for PagingPae", "Random Test Case5", TestCaseforRandomTest, NULL, NULL, &mTestContextPagingPae);
2022-06-27 10:58:48 +02:00
//
// Execute the tests.
//
Status = RunAllTestSuites ( Framework ) ;
EXIT :
if ( Framework ) {
FreeUnitTestFramework ( Framework ) ;
}
return Status ;
}
/**
Standard POSIX C entry point for host based unit test execution .
@ param Argc Number of arguments .
@ param Argv Array of arguments .
@ return Test application exit code .
* */
INT32
main (
INT32 Argc ,
CHAR8 * Argv [ ]
)
{
InitGlobalData ( 52 ) ;
return UefiTestMain ( ) ;
}