2022-10-10 15:52:42 +02:00
/** @file
Common code to test EdkiiPeiMpServices2Ppi and EfiMpServiceProtocol .
Copyright ( c ) 2022 , Intel Corporation . All rights reserved . < BR >
SPDX - License - Identifier : BSD - 2 - Clause - Patent
* */
# include "EfiMpServicesUnitTestCommom.h"
/**
Prep routine for Unit test function .
To save the ProcessorNumber of disabled AP and temporarily enable it .
@ param [ in ] Context Context pointer for this test .
@ retval UNIT_TEST_PASSED Prep routine runs successful .
@ retval UNIT_TEST_ERROR_TEST_FAILED Prep routine runs unsuccessful .
* */
UNIT_TEST_STATUS
EFIAPI
InitUTContext (
IN UNIT_TEST_CONTEXT Context
)
{
EFI_STATUS Status ;
UINTN NumberOfProcessors ;
UINTN NumberOfEnabledProcessors ;
UINTN NumberOfDisabledAPs ;
UINTN IndexOfDisabledAPs ;
UINTN BspNumber ;
UINTN ProcessorNumber ;
EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer ;
MP_SERVICE_UT_CONTEXT * LocalContext ;
LocalContext = ( MP_SERVICE_UT_CONTEXT * ) Context ;
if ( LocalContext - > MpServices . Ppi ! = NULL ) {
return UNIT_TEST_PASSED ;
}
Status = MpServicesUnitTestGetMpServices ( & LocalContext - > MpServices ) ;
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
Status = MpServicesUnitTestWhoAmI ( LocalContext - > MpServices , & BspNumber ) ;
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
2023-04-06 21:49:10 +02:00
DEBUG ( ( DEBUG_INFO , " %a: BspNumber = 0x%x \n " , __func__ , BspNumber ) ) ;
2022-10-10 15:52:42 +02:00
Status = MpServicesUnitTestGetNumberOfProcessors (
LocalContext - > MpServices ,
& NumberOfProcessors ,
& NumberOfEnabledProcessors
) ;
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
DEBUG ( (
DEBUG_INFO ,
" %a: NumberOfProcessors = 0x%x, NumberOfEnabledProcessors = 0x%x \n " ,
2023-04-06 21:49:10 +02:00
__func__ ,
2022-10-10 15:52:42 +02:00
NumberOfProcessors ,
NumberOfEnabledProcessors
) ) ;
LocalContext - > BspNumber = BspNumber ;
LocalContext - > NumberOfProcessors = NumberOfProcessors ;
LocalContext - > NumberOfEnabledProcessors = NumberOfEnabledProcessors ;
LocalContext - > CommonBuffer = AllocatePages ( EFI_SIZE_TO_PAGES ( NumberOfProcessors * sizeof ( * LocalContext - > CommonBuffer ) ) ) ;
UT_ASSERT_NOT_NULL ( LocalContext - > CommonBuffer ) ;
NumberOfDisabledAPs = NumberOfProcessors - NumberOfEnabledProcessors ;
if ( ( NumberOfDisabledAPs > 0 ) & & ( LocalContext - > DisabledApNumber = = NULL ) ) {
LocalContext - > DisabledApNumber = AllocatePages ( EFI_SIZE_TO_PAGES ( NumberOfDisabledAPs * sizeof ( * LocalContext - > DisabledApNumber ) ) ) ;
UT_ASSERT_NOT_NULL ( LocalContext - > DisabledApNumber ) ;
ZeroMem ( LocalContext - > DisabledApNumber , NumberOfDisabledAPs * sizeof ( * LocalContext - > DisabledApNumber ) ) ;
for ( ProcessorNumber = 0 , IndexOfDisabledAPs = 0 ; ProcessorNumber < LocalContext - > NumberOfProcessors ; ProcessorNumber + + ) {
Status = MpServicesUnitTestGetProcessorInfo (
LocalContext - > MpServices ,
ProcessorNumber ,
& ProcessorInfoBuffer
) ;
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
if ( ! ( ProcessorInfoBuffer . StatusFlag & PROCESSOR_ENABLED_BIT ) ) {
//
// Save ProcessorNumber of disabled AP.
//
LocalContext - > DisabledApNumber [ IndexOfDisabledAPs ] = ProcessorNumber ;
IndexOfDisabledAPs + + ;
2023-04-06 21:49:10 +02:00
DEBUG ( ( DEBUG_INFO , " %a: AP(0x%x) is disabled and temporarily enable it. \n " , __func__ , ProcessorNumber ) ) ;
2022-10-10 15:52:42 +02:00
Status = MpServicesUnitTestEnableDisableAP (
LocalContext - > MpServices ,
ProcessorNumber ,
TRUE ,
NULL
) ;
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
}
}
UT_ASSERT_TRUE ( IndexOfDisabledAPs = = NumberOfDisabledAPs ) ;
}
return UNIT_TEST_PASSED ;
}
/**
Cleanup routine for Unit test function .
If any processor is disabled unexpectedly then reenable it .
@ param [ in ] Context Context pointer for this test .
* */
VOID
EFIAPI
CheckUTContext (
IN UNIT_TEST_CONTEXT Context
)
{
EFI_STATUS Status ;
UINTN NumberOfProcessors ;
UINTN NumberOfEnabledProcessors ;
UINTN BspNumber ;
UINTN ProcessorNumber ;
EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer ;
MP_SERVICE_UT_CONTEXT * LocalContext ;
LocalContext = ( MP_SERVICE_UT_CONTEXT * ) Context ;
ASSERT ( LocalContext - > MpServices . Ppi ! = NULL ) ;
Status = MpServicesUnitTestWhoAmI ( LocalContext - > MpServices , & BspNumber ) ;
ASSERT_EFI_ERROR ( Status ) ;
if ( BspNumber ! = LocalContext - > BspNumber ) {
LocalContext - > BspNumber = BspNumber ;
2023-04-06 21:49:10 +02:00
DEBUG ( ( DEBUG_INFO , " %a: New BspNumber = 0x%x \n " , __func__ , BspNumber ) ) ;
2022-10-10 15:52:42 +02:00
}
ASSERT ( BspNumber = = LocalContext - > BspNumber ) ;
Status = MpServicesUnitTestGetNumberOfProcessors (
LocalContext - > MpServices ,
& NumberOfProcessors ,
& NumberOfEnabledProcessors
) ;
ASSERT_EFI_ERROR ( Status ) ;
if ( NumberOfProcessors ! = LocalContext - > NumberOfProcessors ) {
LocalContext - > NumberOfProcessors = NumberOfProcessors ;
2023-04-06 21:49:10 +02:00
DEBUG ( ( DEBUG_INFO , " %a: New NumberOfProcessors = 0x%x \n " , __func__ , NumberOfProcessors ) ) ;
2022-10-10 15:52:42 +02:00
}
if ( NumberOfEnabledProcessors ! = LocalContext - > NumberOfProcessors ) {
2023-04-06 21:49:10 +02:00
DEBUG ( ( DEBUG_INFO , " %a: New NumberOfEnabledProcessors = 0x%x \n " , __func__ , NumberOfEnabledProcessors ) ) ;
2022-10-10 15:52:42 +02:00
for ( ProcessorNumber = 0 ; ProcessorNumber < LocalContext - > NumberOfProcessors ; ProcessorNumber + + ) {
Status = MpServicesUnitTestGetProcessorInfo (
LocalContext - > MpServices ,
ProcessorNumber ,
& ProcessorInfoBuffer
) ;
ASSERT_EFI_ERROR ( Status ) ;
if ( ! ( ProcessorInfoBuffer . StatusFlag & PROCESSOR_ENABLED_BIT ) ) {
2023-04-06 21:49:10 +02:00
DEBUG ( ( DEBUG_INFO , " %a: AP(0x%x) is disabled unexpectedly and reenable it. \n " , __func__ , ProcessorNumber ) ) ;
2022-10-10 15:52:42 +02:00
Status = MpServicesUnitTestEnableDisableAP (
LocalContext - > MpServices ,
ProcessorNumber ,
TRUE ,
NULL
) ;
ASSERT_EFI_ERROR ( Status ) ;
}
}
}
}
/**
Cleanup routine for Unit test function .
It will be called by the last " AddTestCase " to restore AP state and free pointer .
@ param [ in ] Context Context pointer for this test .
* */
VOID
EFIAPI
FreeUTContext (
IN UNIT_TEST_CONTEXT Context
)
{
EFI_STATUS Status ;
UINTN NumberOfDisabledAPs ;
UINTN IndexOfDisabledAPs ;
MP_SERVICE_UT_CONTEXT * LocalContext ;
CheckUTContext ( Context ) ;
LocalContext = ( MP_SERVICE_UT_CONTEXT * ) Context ;
ASSERT ( LocalContext - > MpServices . Ppi ! = NULL ) ;
if ( LocalContext - > DisabledApNumber ! = NULL ) {
NumberOfDisabledAPs = LocalContext - > NumberOfProcessors - LocalContext - > NumberOfEnabledProcessors ;
for ( IndexOfDisabledAPs = 0 ; IndexOfDisabledAPs < NumberOfDisabledAPs ; IndexOfDisabledAPs + + ) {
DEBUG ( (
DEBUG_INFO ,
" %a: Disable AP(0x%x) to restore its state. \n " ,
2023-04-06 21:49:10 +02:00
__func__ ,
2022-10-10 15:52:42 +02:00
LocalContext - > DisabledApNumber [ IndexOfDisabledAPs ]
) ) ;
Status = MpServicesUnitTestEnableDisableAP (
LocalContext - > MpServices ,
LocalContext - > DisabledApNumber [ IndexOfDisabledAPs ] ,
FALSE ,
NULL
) ;
ASSERT_EFI_ERROR ( Status ) ;
}
FreePages ( LocalContext - > DisabledApNumber , EFI_SIZE_TO_PAGES ( NumberOfDisabledAPs * sizeof ( * LocalContext - > DisabledApNumber ) ) ) ;
}
if ( LocalContext - > CommonBuffer ! = NULL ) {
FreePages ( LocalContext - > CommonBuffer , EFI_SIZE_TO_PAGES ( LocalContext - > NumberOfProcessors * sizeof ( * LocalContext - > CommonBuffer ) ) ) ;
}
}
/**
Produce to store ProcessorNumber in the corresponding location of CommonBuffer .
@ param [ in , out ] Buffer The pointer to private data buffer .
* */
VOID
StoreCpuNumbers (
IN OUT VOID * Buffer
)
{
EFI_STATUS Status ;
UINTN ProcessorNumber ;
MP_SERVICE_UT_CONTEXT * LocalContext ;
LocalContext = ( MP_SERVICE_UT_CONTEXT * ) Buffer ;
Status = MpServicesUnitTestWhoAmI ( LocalContext - > MpServices , & ProcessorNumber ) ;
ASSERT_EFI_ERROR ( Status ) ;
//
// The layout of CommonBuffer (E.g. BspNumber = 2 and NumberOfProcessors = 6)
// Index 00 01 02 03 04 05
// Value 00 01 02 03 04 05
//
if ( ProcessorNumber < LocalContext - > NumberOfProcessors ) {
LocalContext - > CommonBuffer [ ProcessorNumber ] = ProcessorNumber ;
}
}
/**
Produce to store the ProcessorNumber of AP execution order in CommonBuffer .
@ param [ in , out ] Buffer The pointer to private data buffer .
* */
VOID
StoreAPsExecutionOrder (
IN OUT VOID * Buffer
)
{
EFI_STATUS Status ;
UINTN ProcessorNumber ;
UINTN * ApCounter ;
MP_SERVICE_UT_CONTEXT * LocalContext ;
LocalContext = ( MP_SERVICE_UT_CONTEXT * ) Buffer ;
Status = MpServicesUnitTestWhoAmI ( LocalContext - > MpServices , & ProcessorNumber ) ;
ASSERT_EFI_ERROR ( Status ) ;
//
// The layout of CommonBuffer (E.g. BspNumber = 2 and NumberOfProcessors = 6)
// Index 00 01 02 03 04 05
// Value 00 01 03 04 05 ApCounter(5)
//
ApCounter = & ( LocalContext - > CommonBuffer [ LocalContext - > NumberOfProcessors - 1 ] ) ;
LocalContext - > CommonBuffer [ * ApCounter ] = ProcessorNumber ;
( * ApCounter ) + + ;
}
/**
Infinite loop procedure to be run on specified CPU .
@ param [ in , out ] Buffer The pointer to private data buffer .
* */
VOID
InfiniteLoopProcedure (
IN OUT VOID * Buffer
)
{
volatile BOOLEAN InfiniteLoop ;
InfiniteLoop = TRUE ;
while ( InfiniteLoop ) {
}
}
/**
Empty procedure to be run on specified CPU .
@ param [ in , out ] Buffer The pointer to private data buffer .
* */
VOID
EmptyProcedure (
IN OUT VOID * Buffer
)
{
}
/**
Procedure to run MP service GetNumberOfProcessors on AP .
@ param [ in , out ] Buffer The pointer to private data buffer .
* */
VOID
RunMpServiceGetNumberOfProcessorsOnAp (
IN OUT VOID * Buffer
)
{
UINTN NumberOfProcessors ;
UINTN NumberOfEnabledProcessors ;
MP_SERVICE_UT_CONTEXT * LocalContext ;
LocalContext = ( MP_SERVICE_UT_CONTEXT * ) Buffer ;
LocalContext - > ApProcedureReturnStatus = MpServicesUnitTestGetNumberOfProcessors (
LocalContext - > MpServices ,
& NumberOfProcessors ,
& NumberOfEnabledProcessors
) ;
}
/**
Procedure to run MP service GetProcessorInfo on AP .
@ param [ in , out ] Buffer The pointer to private data buffer .
* */
VOID
RunMpServiceGetProcessorInfoOnAp (
IN OUT VOID * Buffer
)
{
EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer ;
MP_SERVICE_UT_CONTEXT * LocalContext ;
LocalContext = ( MP_SERVICE_UT_CONTEXT * ) Buffer ;
LocalContext - > ApProcedureReturnStatus = MpServicesUnitTestGetProcessorInfo (
LocalContext - > MpServices ,
LocalContext - > ApNumber ,
& ProcessorInfoBuffer
) ;
}
/**
Procedure to run MP service EnableDisableAP on AP .
@ param [ in , out ] Buffer The pointer to private data buffer .
* */
VOID
RunMpServiceEnableDisableAPOnAp (
IN OUT VOID * Buffer
)
{
MP_SERVICE_UT_CONTEXT * LocalContext ;
LocalContext = ( MP_SERVICE_UT_CONTEXT * ) Buffer ;
LocalContext - > ApProcedureReturnStatus = MpServicesUnitTestEnableDisableAP (
LocalContext - > MpServices ,
LocalContext - > ApNumber ,
FALSE ,
NULL
) ;
}
/**
Procedure to run MP service StartupThisAP on AP .
@ param [ in , out ] Buffer The pointer to private data buffer .
* */
VOID
RunMpServiceStartupThisAPOnAp (
IN OUT VOID * Buffer
)
{
MP_SERVICE_UT_CONTEXT * LocalContext ;
LocalContext = ( MP_SERVICE_UT_CONTEXT * ) Buffer ;
LocalContext - > ApProcedureReturnStatus = MpServicesUnitTestStartupThisAP (
LocalContext - > MpServices ,
( EFI_AP_PROCEDURE ) EmptyProcedure ,
LocalContext - > ApNumber ,
0 ,
NULL
) ;
}
/**
Procedure to run MP service StartupAllAPs on AP .
@ param [ in , out ] Buffer The pointer to private data buffer .
* */
VOID
RunMpServiceStartupAllAPsOnAp (
IN OUT VOID * Buffer
)
{
MP_SERVICE_UT_CONTEXT * LocalContext ;
LocalContext = ( MP_SERVICE_UT_CONTEXT * ) Buffer ;
LocalContext - > ApProcedureReturnStatus = MpServicesUnitTestStartupAllAPs (
LocalContext - > MpServices ,
( EFI_AP_PROCEDURE ) EmptyProcedure ,
FALSE ,
0 ,
NULL
) ;
}
/**
Procedure to run MP service SwitchBSP on AP .
@ param [ in , out ] Buffer The pointer to private data buffer .
* */
VOID
RunMpServiceSwitchBSPOnAp (
IN OUT VOID * Buffer
)
{
MP_SERVICE_UT_CONTEXT * LocalContext ;
LocalContext = ( MP_SERVICE_UT_CONTEXT * ) Buffer ;
LocalContext - > ApProcedureReturnStatus = MpServicesUnitTestSwitchBSP (
LocalContext - > MpServices ,
LocalContext - > ApNumber ,
TRUE
) ;
}
/**
Unit test of MP service WhoAmI .
The range of ProcessorNumber should be from 0 to NumberOfCPUs minus 1.
The ProcessorNumbers of all CPUs are unique .
@ param [ in ] Context Context pointer for this test .
@ 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
TestWhoAmI1 (
IN UNIT_TEST_CONTEXT Context
)
{
EFI_STATUS Status ;
UINTN ProcessorNumber ;
UINTN ProcessorIndex ;
MP_SERVICE_UT_CONTEXT * LocalContext ;
LocalContext = ( MP_SERVICE_UT_CONTEXT * ) Context ;
Status = MpServicesUnitTestWhoAmI (
LocalContext - > MpServices ,
& ProcessorNumber
) ;
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
UT_ASSERT_TRUE ( ProcessorNumber < LocalContext - > NumberOfProcessors ) ;
SetMem ( LocalContext - > CommonBuffer , LocalContext - > NumberOfProcessors * sizeof ( * LocalContext - > CommonBuffer ) , 0xFF ) ;
LocalContext - > CommonBuffer [ ProcessorNumber ] = ProcessorNumber ;
Status = MpServicesUnitTestStartupAllAPs (
LocalContext - > MpServices ,
( EFI_AP_PROCEDURE ) StoreCpuNumbers ,
FALSE ,
0 ,
( VOID * ) LocalContext
) ;
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
//
// The layout of CommonBuffer (E.g. BspNumber = 2 and NumberOfProcessors = 6)
// Index 00 01 02 03 04 05
// Value 00 01 02 03 04 05
//
for ( ProcessorIndex = 0 ; ProcessorIndex < LocalContext - > NumberOfProcessors ; ProcessorIndex + + ) {
UT_ASSERT_TRUE ( LocalContext - > CommonBuffer [ ProcessorIndex ] = = ProcessorIndex ) ;
}
return UNIT_TEST_PASSED ;
}
/**
Unit test of MP service GetNumberOfProcessors .
NumberOfProcessors should be greater that 0 and not less than NumberOfEnabledProcessors .
@ param [ in ] Context Context pointer for this test .
@ 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
TestGetNumberOfProcessors1 (
IN UNIT_TEST_CONTEXT Context
)
{
EFI_STATUS Status ;
UINTN NumberOfProcessors ;
UINTN NumberOfEnabledProcessors ;
MP_SERVICE_UT_CONTEXT * LocalContext ;
LocalContext = ( MP_SERVICE_UT_CONTEXT * ) Context ;
Status = MpServicesUnitTestGetNumberOfProcessors (
LocalContext - > MpServices ,
& NumberOfProcessors ,
& NumberOfEnabledProcessors
) ;
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
UT_ASSERT_TRUE ( NumberOfProcessors > 0 & & NumberOfProcessors > = NumberOfEnabledProcessors ) ;
return UNIT_TEST_PASSED ;
}
/**
Unit test of MP service GetNumberOfProcessors .
When this service is called from an AP , the return status should be EFI_DEVICE_ERROR .
@ param [ in ] Context Context pointer for this test .
@ 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
TestGetNumberOfProcessors2 (
IN UNIT_TEST_CONTEXT Context
)
{
EFI_STATUS Status ;
UINTN ApNumber ;
MP_SERVICE_UT_CONTEXT * LocalContext ;
LocalContext = ( MP_SERVICE_UT_CONTEXT * ) Context ;
for ( ApNumber = 0 ; ApNumber < LocalContext - > NumberOfProcessors ; ApNumber + + ) {
LocalContext - > ApNumber = ApNumber ;
Status = MpServicesUnitTestStartupThisAP (
LocalContext - > MpServices ,
( EFI_AP_PROCEDURE ) RunMpServiceGetNumberOfProcessorsOnAp ,
ApNumber ,
0 ,
( VOID * ) LocalContext
) ;
if ( ApNumber = = LocalContext - > BspNumber ) {
UT_ASSERT_STATUS_EQUAL ( Status , EFI_INVALID_PARAMETER ) ;
} else {
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
UT_ASSERT_STATUS_EQUAL ( LocalContext - > ApProcedureReturnStatus , EFI_DEVICE_ERROR ) ;
}
}
return UNIT_TEST_PASSED ;
}
/**
Unit test of MP service GetNumberOfProcessors .
Call EnableDisableAP ( ) to change the number of enabled AP .
@ param [ in ] Context Context pointer for this test .
@ 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
TestGetNumberOfProcessors3 (
IN UNIT_TEST_CONTEXT Context
)
{
EFI_STATUS Status ;
UINTN ApNumber ;
UINTN NumberOfProcessors ;
UINTN NumberOfEnabledProcessors ;
MP_SERVICE_UT_CONTEXT * LocalContext ;
LocalContext = ( MP_SERVICE_UT_CONTEXT * ) Context ;
for ( ApNumber = 0 ; ApNumber < LocalContext - > NumberOfProcessors ; ApNumber + + ) {
Status = MpServicesUnitTestEnableDisableAP (
LocalContext - > MpServices ,
ApNumber ,
FALSE ,
NULL
) ;
if ( ApNumber = = LocalContext - > BspNumber ) {
UT_ASSERT_STATUS_EQUAL ( Status , EFI_INVALID_PARAMETER ) ;
} else {
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
Status = MpServicesUnitTestGetNumberOfProcessors (
LocalContext - > MpServices ,
& NumberOfProcessors ,
& NumberOfEnabledProcessors
) ;
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
UT_ASSERT_TRUE ( NumberOfProcessors = = LocalContext - > NumberOfProcessors ) ;
if ( ApNumber < LocalContext - > BspNumber ) {
UT_ASSERT_TRUE ( NumberOfEnabledProcessors = = LocalContext - > NumberOfProcessors - ( ApNumber + 1 ) ) ;
} else {
UT_ASSERT_TRUE ( NumberOfEnabledProcessors = = LocalContext - > NumberOfProcessors - ApNumber ) ;
}
}
}
for ( ApNumber = 0 ; ApNumber < LocalContext - > NumberOfProcessors ; ApNumber + + ) {
Status = MpServicesUnitTestEnableDisableAP (
LocalContext - > MpServices ,
ApNumber ,
TRUE ,
NULL
) ;
if ( ApNumber = = LocalContext - > BspNumber ) {
UT_ASSERT_STATUS_EQUAL ( Status , EFI_INVALID_PARAMETER ) ;
} else {
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
Status = MpServicesUnitTestGetNumberOfProcessors (
LocalContext - > MpServices ,
& NumberOfProcessors ,
& NumberOfEnabledProcessors
) ;
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
UT_ASSERT_TRUE ( NumberOfProcessors = = LocalContext - > NumberOfProcessors ) ;
if ( ApNumber < LocalContext - > BspNumber ) {
UT_ASSERT_TRUE ( NumberOfEnabledProcessors = = ApNumber + 2 ) ;
} else {
UT_ASSERT_TRUE ( NumberOfEnabledProcessors = = ApNumber + 1 ) ;
}
}
}
return UNIT_TEST_PASSED ;
}
/**
Unit test of MP service GetProcessorInfo .
When all the parameters are valid , all reserved bits of StatusFlag in ProcessorInfoBuffer should be set to zero .
When all the parameters are valid , the StatusFlag should not have an invalid value ( The BSP can never be in the disabled state . ) .
When called with nonexistent processor handle , the return status should be EFI_NOT_FOUND .
@ param [ in ] Context Context pointer for this test .
@ 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
TestGetProcessorInfo1 (
IN UNIT_TEST_CONTEXT Context
)
{
EFI_STATUS Status ;
UINTN ProcessorNumber ;
EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer ;
MP_SERVICE_UT_CONTEXT * LocalContext ;
LocalContext = ( MP_SERVICE_UT_CONTEXT * ) Context ;
for ( ProcessorNumber = 0 ; ProcessorNumber < = LocalContext - > NumberOfProcessors ; ProcessorNumber + + ) {
Status = MpServicesUnitTestGetProcessorInfo (
LocalContext - > MpServices ,
ProcessorNumber ,
& ProcessorInfoBuffer
) ;
if ( ProcessorNumber = = LocalContext - > NumberOfProcessors ) {
UT_ASSERT_STATUS_EQUAL ( Status , EFI_NOT_FOUND ) ;
} else {
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
UT_ASSERT_TRUE ( ( ProcessorInfoBuffer . StatusFlag & ( UINT32 ) ~ ( PROCESSOR_AS_BSP_BIT | PROCESSOR_ENABLED_BIT | PROCESSOR_HEALTH_STATUS_BIT ) ) = = 0 ) ;
if ( ProcessorNumber = = LocalContext - > BspNumber ) {
UT_ASSERT_TRUE ( ( ProcessorInfoBuffer . StatusFlag & PROCESSOR_AS_BSP_BIT ) & & ( ProcessorInfoBuffer . StatusFlag & PROCESSOR_ENABLED_BIT ) ) ;
} else {
UT_ASSERT_TRUE ( ! ( ProcessorInfoBuffer . StatusFlag & PROCESSOR_AS_BSP_BIT ) ) ;
}
}
}
return UNIT_TEST_PASSED ;
}
/**
Unit test of MP service GetProcessorInfo .
When this service is called from an AP , the return status should be EFI_DEVICE_ERROR .
@ param [ in ] Context Context pointer for this test .
@ 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
TestGetProcessorInfo2 (
IN UNIT_TEST_CONTEXT Context
)
{
EFI_STATUS Status ;
UINTN ApNumber ;
MP_SERVICE_UT_CONTEXT * LocalContext ;
LocalContext = ( MP_SERVICE_UT_CONTEXT * ) Context ;
for ( ApNumber = 0 ; ApNumber < LocalContext - > NumberOfProcessors ; ApNumber + + ) {
LocalContext - > ApNumber = ApNumber ;
Status = MpServicesUnitTestStartupThisAP (
LocalContext - > MpServices ,
( EFI_AP_PROCEDURE ) RunMpServiceGetProcessorInfoOnAp ,
ApNumber ,
0 ,
( VOID * ) LocalContext
) ;
if ( ApNumber = = LocalContext - > BspNumber ) {
UT_ASSERT_STATUS_EQUAL ( Status , EFI_INVALID_PARAMETER ) ;
} else {
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
UT_ASSERT_STATUS_EQUAL ( LocalContext - > ApProcedureReturnStatus , EFI_DEVICE_ERROR ) ;
}
}
return UNIT_TEST_PASSED ;
}
/**
Unit test of MP service EnableDisableAP .
When called with BSP number , the return status should be EFI_INVALID_PARAMETER .
When called with a nonexistent processor handle , the return status should be EFI_NOT_FOUND .
The AP should be really Enable / Disabled .
@ param [ in ] Context Context pointer for this test .
@ 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
TestEnableDisableAP1 (
IN UNIT_TEST_CONTEXT Context
)
{
EFI_STATUS Status ;
UINTN ApNumber ;
MP_SERVICE_UT_CONTEXT * LocalContext ;
LocalContext = ( MP_SERVICE_UT_CONTEXT * ) Context ;
for ( ApNumber = 0 ; ApNumber < = LocalContext - > NumberOfProcessors ; ApNumber + + ) {
Status = MpServicesUnitTestEnableDisableAP (
LocalContext - > MpServices ,
ApNumber ,
FALSE ,
NULL
) ;
if ( ApNumber = = LocalContext - > BspNumber ) {
UT_ASSERT_STATUS_EQUAL ( Status , EFI_INVALID_PARAMETER ) ;
} else if ( ApNumber = = LocalContext - > NumberOfProcessors ) {
UT_ASSERT_STATUS_EQUAL ( Status , EFI_NOT_FOUND ) ;
} else {
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
Status = MpServicesUnitTestStartupThisAP (
LocalContext - > MpServices ,
( EFI_AP_PROCEDURE ) EmptyProcedure ,
ApNumber ,
0 ,
NULL
) ;
UT_ASSERT_STATUS_EQUAL ( Status , EFI_INVALID_PARAMETER ) ;
Status = MpServicesUnitTestEnableDisableAP (
LocalContext - > MpServices ,
ApNumber ,
TRUE ,
NULL
) ;
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
Status = MpServicesUnitTestStartupThisAP (
LocalContext - > MpServices ,
( EFI_AP_PROCEDURE ) EmptyProcedure ,
ApNumber ,
0 ,
NULL
) ;
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
}
}
return UNIT_TEST_PASSED ;
}
/**
Unit test of MP service EnableDisableAP .
When run this procedure on AP , the return status should be EFI_DEVICE_ERROR .
@ param [ in ] Context Context pointer for this test .
@ 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
TestEnableDisableAP2 (
IN UNIT_TEST_CONTEXT Context
)
{
EFI_STATUS Status ;
UINTN ApNumber ;
MP_SERVICE_UT_CONTEXT * LocalContext ;
LocalContext = ( MP_SERVICE_UT_CONTEXT * ) Context ;
for ( ApNumber = 0 ; ApNumber < LocalContext - > NumberOfProcessors ; ApNumber + + ) {
LocalContext - > ApNumber = ApNumber ;
Status = MpServicesUnitTestStartupThisAP (
LocalContext - > MpServices ,
( EFI_AP_PROCEDURE ) RunMpServiceEnableDisableAPOnAp ,
ApNumber ,
0 ,
( VOID * ) LocalContext
) ;
if ( ApNumber = = LocalContext - > BspNumber ) {
UT_ASSERT_STATUS_EQUAL ( Status , EFI_INVALID_PARAMETER ) ;
} else {
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
UT_ASSERT_STATUS_EQUAL ( LocalContext - > ApProcedureReturnStatus , EFI_DEVICE_ERROR ) ;
}
}
return UNIT_TEST_PASSED ;
}
/**
Unit test of MP service EnableDisableAP .
When run this procedure on AP , the return status should be EFI_DEVICE_ERROR .
@ param [ in ] Context Context pointer for this test .
@ 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
TestEnableDisableAP3 (
IN UNIT_TEST_CONTEXT Context
)
{
EFI_STATUS Status ;
UINTN ApNumber ;
EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer ;
UINT32 OldHealthFlag ;
UINT32 NewHealthFlag ;
MP_SERVICE_UT_CONTEXT * LocalContext ;
LocalContext = ( MP_SERVICE_UT_CONTEXT * ) Context ;
for ( ApNumber = 0 ; ApNumber < LocalContext - > NumberOfProcessors ; ApNumber + + ) {
Status = MpServicesUnitTestGetProcessorInfo (
LocalContext - > MpServices ,
ApNumber ,
& ProcessorInfoBuffer
) ;
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
OldHealthFlag = ProcessorInfoBuffer . StatusFlag & PROCESSOR_HEALTH_STATUS_BIT ;
NewHealthFlag = OldHealthFlag ^ PROCESSOR_HEALTH_STATUS_BIT ;
Status = MpServicesUnitTestEnableDisableAP (
LocalContext - > MpServices ,
ApNumber ,
TRUE ,
& NewHealthFlag
) ;
if ( ApNumber = = LocalContext - > BspNumber ) {
UT_ASSERT_STATUS_EQUAL ( Status , EFI_INVALID_PARAMETER ) ;
} else {
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
Status = MpServicesUnitTestGetProcessorInfo (
LocalContext - > MpServices ,
ApNumber ,
& ProcessorInfoBuffer
) ;
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
UT_ASSERT_TRUE ( ( ProcessorInfoBuffer . StatusFlag & PROCESSOR_HEALTH_STATUS_BIT ) = = NewHealthFlag ) ;
Status = MpServicesUnitTestEnableDisableAP (
LocalContext - > MpServices ,
ApNumber ,
TRUE ,
& OldHealthFlag
) ;
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
}
}
return UNIT_TEST_PASSED ;
}
/**
Unit test of MP service StartupThisAP .
When called to startup a BSP , the return status should be EFI_INVALID_PARAMETER .
When called with a nonexistent processor handle , the return status should be EFI_NOT_FOUND .
The requested AP should execute the Procedure when called by StartupThisAP .
@ param [ in ] Context Context pointer for this test .
@ 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
TestStartupThisAP1 (
IN UNIT_TEST_CONTEXT Context
)
{
EFI_STATUS Status ;
UINTN ApNumber ;
UINTN ProcessorIndex ;
MP_SERVICE_UT_CONTEXT * LocalContext ;
LocalContext = ( MP_SERVICE_UT_CONTEXT * ) Context ;
for ( ApNumber = 0 ; ApNumber < = LocalContext - > NumberOfProcessors ; ApNumber + + ) {
SetMem ( LocalContext - > CommonBuffer , LocalContext - > NumberOfProcessors * sizeof ( * LocalContext - > CommonBuffer ) , 0xFF ) ;
Status = MpServicesUnitTestStartupThisAP (
LocalContext - > MpServices ,
( EFI_AP_PROCEDURE ) StoreCpuNumbers ,
ApNumber ,
0 ,
( VOID * ) LocalContext
) ;
if ( ApNumber = = LocalContext - > BspNumber ) {
UT_ASSERT_STATUS_EQUAL ( Status , EFI_INVALID_PARAMETER ) ;
} else if ( ApNumber = = LocalContext - > NumberOfProcessors ) {
UT_ASSERT_STATUS_EQUAL ( Status , EFI_NOT_FOUND ) ;
} else {
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
for ( ProcessorIndex = 0 ; ProcessorIndex < LocalContext - > NumberOfProcessors ; ProcessorIndex + + ) {
UT_ASSERT_TRUE (
( ( ProcessorIndex = = ApNumber ) & & ( LocalContext - > CommonBuffer [ ProcessorIndex ] = = ProcessorIndex ) ) | |
( ( ProcessorIndex ! = ApNumber ) & & ( LocalContext - > CommonBuffer [ ProcessorIndex ] = = ( UINTN ) ~ 0 ) )
) ;
}
}
}
return UNIT_TEST_PASSED ;
}
/**
Unit test of MP service StartupThisAP .
When this service is called from an AP , the return status should be EFI_DEVICE_ERROR .
@ param [ in ] Context Context pointer for this test .
@ 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
TestStartupThisAP2 (
IN UNIT_TEST_CONTEXT Context
)
{
EFI_STATUS Status ;
UINTN ApNumber ;
MP_SERVICE_UT_CONTEXT * LocalContext ;
LocalContext = ( MP_SERVICE_UT_CONTEXT * ) Context ;
for ( ApNumber = 0 ; ApNumber < LocalContext - > NumberOfProcessors ; ApNumber + + ) {
LocalContext - > ApNumber = ApNumber ;
Status = MpServicesUnitTestStartupThisAP (
LocalContext - > MpServices ,
( EFI_AP_PROCEDURE ) RunMpServiceStartupThisAPOnAp ,
ApNumber ,
0 ,
( VOID * ) LocalContext
) ;
if ( ApNumber = = LocalContext - > BspNumber ) {
UT_ASSERT_STATUS_EQUAL ( Status , EFI_INVALID_PARAMETER ) ;
} else {
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
UT_ASSERT_STATUS_EQUAL ( LocalContext - > ApProcedureReturnStatus , EFI_DEVICE_ERROR ) ;
}
}
return UNIT_TEST_PASSED ;
}
/**
Unit test of MP service StartupThisAP .
When timeout expired before the requested AP has finished , the return status should be EFI_TIMEOUT .
@ param [ in ] Context Context pointer for this test .
@ 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
TestStartupThisAP3 (
IN UNIT_TEST_CONTEXT Context
)
{
EFI_STATUS Status ;
UINTN ApNumber ;
MP_SERVICE_UT_CONTEXT * LocalContext ;
LocalContext = ( MP_SERVICE_UT_CONTEXT * ) Context ;
for ( ApNumber = 0 ; ApNumber < LocalContext - > NumberOfProcessors ; ApNumber + + ) {
Status = MpServicesUnitTestStartupThisAP (
LocalContext - > MpServices ,
( EFI_AP_PROCEDURE ) InfiniteLoopProcedure ,
ApNumber ,
RUN_PROCEDURE_TIMEOUT_VALUE ,
NULL
) ;
if ( ApNumber = = LocalContext - > BspNumber ) {
UT_ASSERT_STATUS_EQUAL ( Status , EFI_INVALID_PARAMETER ) ;
} else {
UT_ASSERT_STATUS_EQUAL ( Status , EFI_TIMEOUT ) ;
}
}
return UNIT_TEST_PASSED ;
}
/**
Unit test of MP service StartupThisAP .
When called with disabled AP , the return status should be EFI_INVALID_PARAMETER .
@ param [ in ] Context Context pointer for this test .
@ 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
TestStartupThisAP4 (
IN UNIT_TEST_CONTEXT Context
)
{
EFI_STATUS Status ;
UINTN ApNumber ;
MP_SERVICE_UT_CONTEXT * LocalContext ;
LocalContext = ( MP_SERVICE_UT_CONTEXT * ) Context ;
for ( ApNumber = 0 ; ApNumber < LocalContext - > NumberOfProcessors ; ApNumber + + ) {
Status = MpServicesUnitTestEnableDisableAP (
LocalContext - > MpServices ,
ApNumber ,
FALSE ,
NULL
) ;
if ( ApNumber = = LocalContext - > BspNumber ) {
UT_ASSERT_STATUS_EQUAL ( Status , EFI_INVALID_PARAMETER ) ;
} else {
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
Status = MpServicesUnitTestStartupThisAP (
LocalContext - > MpServices ,
( EFI_AP_PROCEDURE ) EmptyProcedure ,
ApNumber ,
0 ,
NULL
) ;
UT_ASSERT_STATUS_EQUAL ( Status , EFI_INVALID_PARAMETER ) ;
Status = MpServicesUnitTestEnableDisableAP (
LocalContext - > MpServices ,
ApNumber ,
TRUE ,
NULL
) ;
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
Status = MpServicesUnitTestStartupThisAP (
LocalContext - > MpServices ,
( EFI_AP_PROCEDURE ) EmptyProcedure ,
ApNumber ,
0 ,
NULL
) ;
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
}
}
return UNIT_TEST_PASSED ;
}
/**
Unit test of MP service StartupAllAPs .
All APs should execute the Procedure when called by StartupAllAPs .
@ param [ in ] Context Context pointer for this test .
@ 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
TestStartupAllAPs1 (
IN UNIT_TEST_CONTEXT Context
)
{
EFI_STATUS Status ;
UINTN ProcessorIndex ;
MP_SERVICE_UT_CONTEXT * LocalContext ;
LocalContext = ( MP_SERVICE_UT_CONTEXT * ) Context ;
SetMem ( LocalContext - > CommonBuffer , LocalContext - > NumberOfProcessors * sizeof ( * LocalContext - > CommonBuffer ) , 0xFF ) ;
Status = MpServicesUnitTestStartupAllAPs (
LocalContext - > MpServices ,
( EFI_AP_PROCEDURE ) StoreCpuNumbers ,
FALSE ,
0 ,
( VOID * ) LocalContext
) ;
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
for ( ProcessorIndex = 0 ; ProcessorIndex < LocalContext - > NumberOfProcessors ; ProcessorIndex + + ) {
UT_ASSERT_TRUE (
( ( ProcessorIndex = = LocalContext - > BspNumber ) & & ( LocalContext - > CommonBuffer [ ProcessorIndex ] = = ( UINTN ) ~ 0 ) ) | |
( ( ProcessorIndex ! = LocalContext - > BspNumber ) & & ( LocalContext - > CommonBuffer [ ProcessorIndex ] = = ProcessorIndex ) )
) ;
}
return UNIT_TEST_PASSED ;
}
/**
Unit test of MP service StartupAllAPs .
When called in single thread , the return status should be EFI_SUCCESS and AP executes in ascending order
of processor handle number .
@ param [ in ] Context Context pointer for this test .
@ 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
TestStartupAllAPs2 (
IN UNIT_TEST_CONTEXT Context
)
{
EFI_STATUS Status ;
UINTN ProcessorIndex ;
MP_SERVICE_UT_CONTEXT * LocalContext ;
LocalContext = ( MP_SERVICE_UT_CONTEXT * ) Context ;
ZeroMem ( LocalContext - > CommonBuffer , LocalContext - > NumberOfProcessors * sizeof ( * LocalContext - > CommonBuffer ) ) ;
Status = MpServicesUnitTestStartupAllAPs (
LocalContext - > MpServices ,
( EFI_AP_PROCEDURE ) StoreAPsExecutionOrder ,
TRUE ,
0 ,
( VOID * ) LocalContext
) ;
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
//
// The layout of CommonBuffer (E.g. BspNumber = 2 and NumberOfProcessors = 6)
// Index 00 01 02 03 04 05
// Value 00 01 03 04 05 ApCounter(5)
//
for ( ProcessorIndex = 0 ; ProcessorIndex < LocalContext - > NumberOfProcessors - 2 ; ProcessorIndex + + ) {
UT_ASSERT_TRUE ( LocalContext - > CommonBuffer [ ProcessorIndex ] < LocalContext - > CommonBuffer [ ProcessorIndex + 1 ] ) ;
}
UT_ASSERT_EQUAL ( LocalContext - > CommonBuffer [ LocalContext - > NumberOfProcessors - 1 ] , LocalContext - > NumberOfProcessors - 1 ) ;
return UNIT_TEST_PASSED ;
}
/**
Unit test of MP service StartupAllAPs .
When this service is called from an AP , the return status should be EFI_DEVICE_ERROR .
@ param [ in ] Context Context pointer for this test .
@ 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
TestStartupAllAPs3 (
IN UNIT_TEST_CONTEXT Context
)
{
EFI_STATUS Status ;
UINTN ApNumber ;
MP_SERVICE_UT_CONTEXT * LocalContext ;
LocalContext = ( MP_SERVICE_UT_CONTEXT * ) Context ;
for ( ApNumber = 0 ; ApNumber < LocalContext - > NumberOfProcessors ; ApNumber + + ) {
LocalContext - > ApNumber = ApNumber ;
Status = MpServicesUnitTestStartupThisAP (
LocalContext - > MpServices ,
( EFI_AP_PROCEDURE ) RunMpServiceStartupAllAPsOnAp ,
ApNumber ,
0 ,
( VOID * ) LocalContext
) ;
if ( ApNumber = = LocalContext - > BspNumber ) {
UT_ASSERT_STATUS_EQUAL ( Status , EFI_INVALID_PARAMETER ) ;
} else {
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
UT_ASSERT_STATUS_EQUAL ( LocalContext - > ApProcedureReturnStatus , EFI_DEVICE_ERROR ) ;
}
}
return UNIT_TEST_PASSED ;
}
/**
Unit test of MP service StartupAllAPs .
When called with all AP timeout , the return status should be EFI_TIMEOUT .
@ param [ in ] Context Context pointer for this test .
@ 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
TestStartupAllAPs4 (
IN UNIT_TEST_CONTEXT Context
)
{
EFI_STATUS Status ;
MP_SERVICE_UT_CONTEXT * LocalContext ;
LocalContext = ( MP_SERVICE_UT_CONTEXT * ) Context ;
Status = MpServicesUnitTestStartupAllAPs (
LocalContext - > MpServices ,
( EFI_AP_PROCEDURE ) InfiniteLoopProcedure ,
TRUE ,
RUN_PROCEDURE_TIMEOUT_VALUE ,
NULL
) ;
UT_ASSERT_STATUS_EQUAL ( Status , EFI_TIMEOUT ) ;
Status = MpServicesUnitTestStartupAllAPs (
LocalContext - > MpServices ,
( EFI_AP_PROCEDURE ) InfiniteLoopProcedure ,
FALSE ,
RUN_PROCEDURE_TIMEOUT_VALUE ,
NULL
) ;
UT_ASSERT_STATUS_EQUAL ( Status , EFI_TIMEOUT ) ;
return UNIT_TEST_PASSED ;
}
/**
Unit test of MP service StartupAllAPs .
When called with the empty Procedure on all disabled APs , the return status should be EFI_NOT_STARTED .
@ param [ in ] Context Context pointer for this test .
@ 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
TestStartupAllAPs5 (
IN UNIT_TEST_CONTEXT Context
)
{
EFI_STATUS Status ;
UINTN ApNumber ;
MP_SERVICE_UT_CONTEXT * LocalContext ;
LocalContext = ( MP_SERVICE_UT_CONTEXT * ) Context ;
for ( ApNumber = 0 ; ApNumber < LocalContext - > NumberOfProcessors ; ApNumber + + ) {
Status = MpServicesUnitTestEnableDisableAP (
LocalContext - > MpServices ,
ApNumber ,
FALSE ,
NULL
) ;
if ( ApNumber = = LocalContext - > BspNumber ) {
UT_ASSERT_STATUS_EQUAL ( Status , EFI_INVALID_PARAMETER ) ;
} else {
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
}
}
Status = MpServicesUnitTestStartupAllAPs (
LocalContext - > MpServices ,
( EFI_AP_PROCEDURE ) EmptyProcedure ,
FALSE ,
0 ,
NULL
) ;
UT_ASSERT_STATUS_EQUAL ( Status , EFI_NOT_STARTED ) ;
for ( ApNumber = 0 ; ApNumber < LocalContext - > NumberOfProcessors ; ApNumber + + ) {
Status = MpServicesUnitTestEnableDisableAP (
LocalContext - > MpServices ,
ApNumber ,
TRUE ,
NULL
) ;
if ( ApNumber = = LocalContext - > BspNumber ) {
UT_ASSERT_STATUS_EQUAL ( Status , EFI_INVALID_PARAMETER ) ;
} else {
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
}
}
return UNIT_TEST_PASSED ;
}
/**
Unit test of MP service SwitchBSP .
When switch current BSP to be BSP , the return status should be EFI_INVALID_PARAMETER .
When switch nonexistent processor to be BSP , the return status should be EFI_NOT_FOUND .
After switch BSP , all APs ( includes new AP ) should execute the Procedure when called by StartupAllAP .
@ param [ in ] Context Context pointer for this test .
@ 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
TestSwitchBSP1 (
IN UNIT_TEST_CONTEXT Context
)
{
EFI_STATUS Status ;
UINTN NewBspNumber ;
UINTN ProcessorIndex ;
MP_SERVICE_UT_CONTEXT * LocalContext ;
LocalContext = ( MP_SERVICE_UT_CONTEXT * ) Context ;
for ( NewBspNumber = 0 ; NewBspNumber < = LocalContext - > NumberOfProcessors ; NewBspNumber + + ) {
Status = MpServicesUnitTestSwitchBSP (
LocalContext - > MpServices ,
NewBspNumber ,
TRUE
) ;
if ( NewBspNumber = = LocalContext - > BspNumber ) {
UT_ASSERT_STATUS_EQUAL ( Status , EFI_INVALID_PARAMETER ) ;
} else if ( NewBspNumber = = LocalContext - > NumberOfProcessors ) {
UT_ASSERT_STATUS_EQUAL ( Status , EFI_NOT_FOUND ) ;
} else {
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
SetMem ( LocalContext - > CommonBuffer , LocalContext - > NumberOfProcessors * sizeof ( * LocalContext - > CommonBuffer ) , 0xFF ) ;
Status = MpServicesUnitTestStartupAllAPs (
LocalContext - > MpServices ,
( EFI_AP_PROCEDURE ) StoreCpuNumbers ,
FALSE ,
0 ,
( VOID * ) LocalContext
) ;
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
for ( ProcessorIndex = 0 ; ProcessorIndex < LocalContext - > NumberOfProcessors ; ProcessorIndex + + ) {
UT_ASSERT_TRUE (
( ( ProcessorIndex = = NewBspNumber ) & & ( LocalContext - > CommonBuffer [ ProcessorIndex ] = = ( UINTN ) ~ 0 ) ) | |
( ( ProcessorIndex ! = NewBspNumber ) & & ( LocalContext - > CommonBuffer [ ProcessorIndex ] = = ProcessorIndex ) )
) ;
}
Status = MpServicesUnitTestSwitchBSP (
LocalContext - > MpServices ,
LocalContext - > BspNumber ,
TRUE
) ;
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
}
}
return UNIT_TEST_PASSED ;
}
/**
Unit test of MP service SwitchBSP .
When run this procedure on AP , the return status should be EFI_DEVICE_ERROR .
@ param [ in ] Context Context pointer for this test .
@ 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
TestSwitchBSP2 (
IN UNIT_TEST_CONTEXT Context
)
{
EFI_STATUS Status ;
UINTN ApNumber ;
MP_SERVICE_UT_CONTEXT * LocalContext ;
LocalContext = ( MP_SERVICE_UT_CONTEXT * ) Context ;
for ( ApNumber = 0 ; ApNumber < LocalContext - > NumberOfProcessors ; ApNumber + + ) {
LocalContext - > ApNumber = ApNumber ;
Status = MpServicesUnitTestStartupThisAP (
LocalContext - > MpServices ,
( EFI_AP_PROCEDURE ) RunMpServiceSwitchBSPOnAp ,
ApNumber ,
0 ,
( VOID * ) LocalContext
) ;
if ( ApNumber = = LocalContext - > BspNumber ) {
UT_ASSERT_STATUS_EQUAL ( Status , EFI_INVALID_PARAMETER ) ;
} else {
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
UT_ASSERT_STATUS_EQUAL ( LocalContext - > ApProcedureReturnStatus , EFI_DEVICE_ERROR ) ;
}
}
return UNIT_TEST_PASSED ;
}
/**
Unit test of MP service SwitchBSP .
When switch a disabled AP to be BSP , the return status should be EFI_INVALID_PARAMETER .
@ param [ in ] Context Context pointer for this test .
@ 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
TestSwitchBSP3 (
IN UNIT_TEST_CONTEXT Context
)
{
EFI_STATUS Status ;
UINTN NewBspNumber ;
MP_SERVICE_UT_CONTEXT * LocalContext ;
LocalContext = ( MP_SERVICE_UT_CONTEXT * ) Context ;
for ( NewBspNumber = 0 ; NewBspNumber < LocalContext - > NumberOfProcessors ; NewBspNumber + + ) {
Status = MpServicesUnitTestEnableDisableAP (
LocalContext - > MpServices ,
NewBspNumber ,
FALSE ,
NULL
) ;
if ( NewBspNumber = = LocalContext - > BspNumber ) {
UT_ASSERT_STATUS_EQUAL ( Status , EFI_INVALID_PARAMETER ) ;
} else {
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
Status = MpServicesUnitTestSwitchBSP (
LocalContext - > MpServices ,
NewBspNumber ,
TRUE
) ;
UT_ASSERT_STATUS_EQUAL ( Status , EFI_INVALID_PARAMETER ) ;
Status = MpServicesUnitTestEnableDisableAP (
LocalContext - > MpServices ,
NewBspNumber ,
TRUE ,
NULL
) ;
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
}
}
return UNIT_TEST_PASSED ;
}
/**
Unit test of MP service SwitchBSP .
When SwitchBSP and EnableOldBSP is TRUE , the new BSP should be in the enabled state and the old BSP should
be in the enabled state .
When SwitchBSP and EnableOldBSP is False , the new BSP should be in the enabled state and the old BSP should
be in the disabled state .
@ param [ in ] Context Context pointer for this test .
@ 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
TestSwitchBSP4 (
IN UNIT_TEST_CONTEXT Context
)
{
EFI_STATUS Status ;
UINTN NewBspNumber ;
EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer ;
MP_SERVICE_UT_CONTEXT * LocalContext ;
LocalContext = ( MP_SERVICE_UT_CONTEXT * ) Context ;
for ( NewBspNumber = 0 ; NewBspNumber < LocalContext - > NumberOfProcessors ; NewBspNumber + + ) {
Status = MpServicesUnitTestSwitchBSP (
LocalContext - > MpServices ,
NewBspNumber ,
FALSE
) ;
if ( NewBspNumber = = LocalContext - > BspNumber ) {
UT_ASSERT_STATUS_EQUAL ( Status , EFI_INVALID_PARAMETER ) ;
} else {
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
Status = MpServicesUnitTestGetProcessorInfo (
LocalContext - > MpServices ,
NewBspNumber ,
& ProcessorInfoBuffer
) ;
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
UT_ASSERT_TRUE (
( ProcessorInfoBuffer . StatusFlag & PROCESSOR_AS_BSP_BIT ) & &
( ProcessorInfoBuffer . StatusFlag & PROCESSOR_ENABLED_BIT )
) ;
Status = MpServicesUnitTestGetProcessorInfo (
LocalContext - > MpServices ,
LocalContext - > BspNumber ,
& ProcessorInfoBuffer
) ;
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
UT_ASSERT_TRUE (
! ( ProcessorInfoBuffer . StatusFlag & PROCESSOR_AS_BSP_BIT ) & &
! ( ProcessorInfoBuffer . StatusFlag & PROCESSOR_ENABLED_BIT )
) ;
Status = MpServicesUnitTestEnableDisableAP (
LocalContext - > MpServices ,
LocalContext - > BspNumber ,
TRUE ,
NULL
) ;
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
Status = MpServicesUnitTestSwitchBSP (
LocalContext - > MpServices ,
LocalContext - > BspNumber ,
TRUE
) ;
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
Status = MpServicesUnitTestGetProcessorInfo (
LocalContext - > MpServices ,
LocalContext - > BspNumber ,
& ProcessorInfoBuffer
) ;
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
UT_ASSERT_TRUE (
( ProcessorInfoBuffer . StatusFlag & PROCESSOR_AS_BSP_BIT ) & &
( ProcessorInfoBuffer . StatusFlag & PROCESSOR_ENABLED_BIT )
) ;
Status = MpServicesUnitTestGetProcessorInfo (
LocalContext - > MpServices ,
NewBspNumber ,
& ProcessorInfoBuffer
) ;
UT_ASSERT_NOT_EFI_ERROR ( Status ) ;
UT_ASSERT_TRUE (
! ( ProcessorInfoBuffer . StatusFlag & PROCESSOR_AS_BSP_BIT ) & &
( ProcessorInfoBuffer . StatusFlag & PROCESSOR_ENABLED_BIT )
) ;
}
}
return UNIT_TEST_PASSED ;
}
/**
Create test suite and unit tests for both EdkiiPeiMpServices2Ppi and EfiMpServiceProtocol .
@ param [ in ] Framework A pointer to the framework that is being persisted .
@ param [ in ] Context A pointer to the private data buffer .
@ retval EFI_SUCCESS Create test suite and unit tests successfully .
@ retval Others Create test suite and unit tests unsuccessfully .
* */
EFI_STATUS
AddCommonTestCase (
IN UNIT_TEST_FRAMEWORK_HANDLE Framework ,
IN MP_SERVICE_UT_CONTEXT * Context
)
{
EFI_STATUS Status ;
UNIT_TEST_SUITE_HANDLE MpServiceWhoAmITestSuite ;
UNIT_TEST_SUITE_HANDLE MpServiceGetNumberOfProcessorsTestSuite ;
UNIT_TEST_SUITE_HANDLE MpServiceGetProcessorInfoTestSuite ;
UNIT_TEST_SUITE_HANDLE MpServiceEnableDisableAPTestSuite ;
UNIT_TEST_SUITE_HANDLE MpServiceStartupThisAPTestSuite ;
UNIT_TEST_SUITE_HANDLE MpServiceStartupAllAPsTestSuite ;
UNIT_TEST_SUITE_HANDLE MpServiceSwitchBSPTestSuite ;
MpServiceWhoAmITestSuite = NULL ;
MpServiceGetNumberOfProcessorsTestSuite = NULL ;
MpServiceGetProcessorInfoTestSuite = NULL ;
MpServiceEnableDisableAPTestSuite = NULL ;
MpServiceStartupThisAPTestSuite = NULL ;
MpServiceStartupAllAPsTestSuite = NULL ;
MpServiceSwitchBSPTestSuite = NULL ;
//
// Test WhoAmI function
//
Status = CreateUnitTestSuite ( & MpServiceWhoAmITestSuite , Framework , " Identify the currently executing processor " , " MpServices.WhoAmI " , NULL , NULL ) ;
if ( EFI_ERROR ( Status ) ) {
DEBUG ( ( DEBUG_ERROR , " Failed in CreateUnitTestSuite for MpServiceWhoAmI Test Suite \n " ) ) ;
return Status ;
}
AddTestCase ( MpServiceWhoAmITestSuite , " Test WhoAmI 1 " , " TestWhoAmI1 " , TestWhoAmI1 , InitUTContext , CheckUTContext , Context ) ;
//
// Test GetNumberOfProcessors function
//
Status = CreateUnitTestSuite ( & MpServiceGetNumberOfProcessorsTestSuite , Framework , " Retrieve the number of logical processor " , " MpServices.GetNumberOfProcessors " , NULL , NULL ) ;
if ( EFI_ERROR ( Status ) ) {
DEBUG ( ( DEBUG_ERROR , " Failed in CreateUnitTestSuite for MpServiceGetNumberOfProcessors Test Suite \n " ) ) ;
return Status ;
}
AddTestCase ( MpServiceGetNumberOfProcessorsTestSuite , " Test GetNumberOfProcessors 1 " , " TestGetNumberOfProcessors1 " , TestGetNumberOfProcessors1 , InitUTContext , CheckUTContext , Context ) ;
AddTestCase ( MpServiceGetNumberOfProcessorsTestSuite , " Test GetNumberOfProcessors 2 " , " TestGetNumberOfProcessors2 " , TestGetNumberOfProcessors2 , InitUTContext , CheckUTContext , Context ) ;
AddTestCase ( MpServiceGetNumberOfProcessorsTestSuite , " Test GetNumberOfProcessors 3 " , " TestGetNumberOfProcessors3 " , TestGetNumberOfProcessors3 , InitUTContext , CheckUTContext , Context ) ;
//
// Test GetProcessorInfo function
//
Status = CreateUnitTestSuite ( & MpServiceGetProcessorInfoTestSuite , Framework , " Get detailed information on the requested logical processor " , " MpServices.GetProcessorInfo " , NULL , NULL ) ;
if ( EFI_ERROR ( Status ) ) {
DEBUG ( ( DEBUG_ERROR , " Failed in CreateUnitTestSuite for MpServiceGetProcessorInfo Test Suite \n " ) ) ;
return Status ;
}
AddTestCase ( MpServiceGetProcessorInfoTestSuite , " Test GetProcessorInfo 1 " , " TestGetProcessorInfo1 " , TestGetProcessorInfo1 , InitUTContext , CheckUTContext , Context ) ;
AddTestCase ( MpServiceGetProcessorInfoTestSuite , " Test GetProcessorInfo 2 " , " TestGetProcessorInfo2 " , TestGetProcessorInfo2 , InitUTContext , CheckUTContext , Context ) ;
//
// Test EnableDisableAP function
//
Status = CreateUnitTestSuite ( & MpServiceEnableDisableAPTestSuite , Framework , " Caller enables or disables an AP from this point onward " , " MpServices.EnableDisableAP " , NULL , NULL ) ;
if ( EFI_ERROR ( Status ) ) {
DEBUG ( ( DEBUG_ERROR , " Failed in CreateUnitTestSuite for MpServiceEnableDisableAP Test Suite \n " ) ) ;
return Status ;
}
AddTestCase ( MpServiceEnableDisableAPTestSuite , " Test EnableDisableAP 1 " , " TestEnableDisableAP1 " , TestEnableDisableAP1 , InitUTContext , CheckUTContext , Context ) ;
AddTestCase ( MpServiceEnableDisableAPTestSuite , " Test EnableDisableAP 2 " , " TestEnableDisableAP2 " , TestEnableDisableAP2 , InitUTContext , CheckUTContext , Context ) ;
AddTestCase ( MpServiceEnableDisableAPTestSuite , " Test EnableDisableAP 3 " , " TestEnableDisableAP3 " , TestEnableDisableAP3 , InitUTContext , CheckUTContext , Context ) ;
//
// Test StartupThisAP function
//
Status = CreateUnitTestSuite ( & MpServiceStartupThisAPTestSuite , Framework , " Get the requested AP to execute a caller-provided function " , " MpServices.StartupThisAP " , NULL , NULL ) ;
if ( EFI_ERROR ( Status ) ) {
DEBUG ( ( DEBUG_ERROR , " Failed in CreateUnitTestSuite for MpServiceStartupThisAP Test Suite \n " ) ) ;
return Status ;
}
AddTestCase ( MpServiceStartupThisAPTestSuite , " Test StartupThisAP 1 " , " TestStartupThisAP1 " , TestStartupThisAP1 , InitUTContext , CheckUTContext , Context ) ;
AddTestCase ( MpServiceStartupThisAPTestSuite , " Test StartupThisAP 2 " , " TestStartupThisAP2 " , TestStartupThisAP2 , InitUTContext , CheckUTContext , Context ) ;
AddTestCase ( MpServiceStartupThisAPTestSuite , " Test StartupThisAP 3 " , " TestStartupThisAP3 " , TestStartupThisAP3 , InitUTContext , CheckUTContext , Context ) ;
AddTestCase ( MpServiceStartupThisAPTestSuite , " Test StartupThisAP 4 " , " TestStartupThisAP4 " , TestStartupThisAP4 , InitUTContext , CheckUTContext , Context ) ;
//
// Test StartupAllAPs function
//
Status = CreateUnitTestSuite ( & MpServiceStartupAllAPsTestSuite , Framework , " Execute a caller provided function on all enabled APs " , " MpServices.StartupAllAPs " , NULL , NULL ) ;
if ( EFI_ERROR ( Status ) ) {
DEBUG ( ( DEBUG_ERROR , " Failed in CreateUnitTestSuite for MpServiceStartupAllAPs Test Suite \n " ) ) ;
return Status ;
}
AddTestCase ( MpServiceStartupAllAPsTestSuite , " Test StartupAllAPs 1 " , " TestStartupAllAPs1 " , TestStartupAllAPs1 , InitUTContext , CheckUTContext , Context ) ;
AddTestCase ( MpServiceStartupAllAPsTestSuite , " Test StartupAllAPs 2 " , " TestStartupAllAPs2 " , TestStartupAllAPs2 , InitUTContext , CheckUTContext , Context ) ;
AddTestCase ( MpServiceStartupAllAPsTestSuite , " Test StartupAllAPs 3 " , " TestStartupAllAPs3 " , TestStartupAllAPs3 , InitUTContext , CheckUTContext , Context ) ;
AddTestCase ( MpServiceStartupAllAPsTestSuite , " Test StartupAllAPs 4 " , " TestStartupAllAPs4 " , TestStartupAllAPs4 , InitUTContext , CheckUTContext , Context ) ;
AddTestCase ( MpServiceStartupAllAPsTestSuite , " Test StartupAllAPs 5 " , " TestStartupAllAPs5 " , TestStartupAllAPs5 , InitUTContext , CheckUTContext , Context ) ;
//
// Test SwitchBSP function
//
Status = CreateUnitTestSuite ( & MpServiceSwitchBSPTestSuite , Framework , " Switch the requested AP to be the BSP from that point onward " , " MpServices.SwitchBSP " , NULL , NULL ) ;
if ( EFI_ERROR ( Status ) ) {
DEBUG ( ( DEBUG_ERROR , " Failed in CreateUnitTestSuite for MpServiceSwitchBSP Test Suite \n " ) ) ;
return Status ;
}
AddTestCase ( MpServiceSwitchBSPTestSuite , " Test SwitchBSP 1 " , " TestSwitchBSP1 " , TestSwitchBSP1 , InitUTContext , CheckUTContext , Context ) ;
AddTestCase ( MpServiceSwitchBSPTestSuite , " Test SwitchBSP 2 " , " TestSwitchBSP2 " , TestSwitchBSP2 , InitUTContext , CheckUTContext , Context ) ;
AddTestCase ( MpServiceSwitchBSPTestSuite , " Test SwitchBSP 3 " , " TestSwitchBSP3 " , TestSwitchBSP3 , InitUTContext , CheckUTContext , Context ) ;
AddTestCase ( MpServiceSwitchBSPTestSuite , " Test SwitchBSP 4 " , " TestSwitchBSP4 " , TestSwitchBSP4 , InitUTContext , FreeUTContext , Context ) ;
return EFI_SUCCESS ;
}