IN UINT32 TimeLimit\r
);\r
\r
+/**\r
+ Get available system memory below 1MB by specified size.\r
+\r
+ @param[in] CpuMpData The pointer to CPU MP Data structure.\r
+**/\r
+VOID\r
+BackupAndPrepareWakeupBuffer(\r
+ IN CPU_MP_DATA *CpuMpData\r
+ )\r
+{\r
+ CopyMem (\r
+ (VOID *) CpuMpData->BackupBuffer,\r
+ (VOID *) CpuMpData->WakeupBuffer,\r
+ CpuMpData->BackupBufferSize\r
+ );\r
+ CopyMem (\r
+ (VOID *) CpuMpData->WakeupBuffer,\r
+ (VOID *) CpuMpData->AddressMap.RendezvousFunnelAddress,\r
+ CpuMpData->AddressMap.RendezvousFunnelSize\r
+ );\r
+}\r
+\r
+/**\r
+ Restore wakeup buffer data.\r
+\r
+ @param[in] CpuMpData The pointer to CPU MP Data structure.\r
+**/\r
+VOID\r
+RestoreWakeupBuffer(\r
+ IN CPU_MP_DATA *CpuMpData\r
+ )\r
+{\r
+ CopyMem (\r
+ (VOID *) CpuMpData->WakeupBuffer,\r
+ (VOID *) CpuMpData->BackupBuffer,\r
+ CpuMpData->BackupBufferSize\r
+ );\r
+}\r
+\r
+/**\r
+ Allocate reset vector buffer.\r
+\r
+ @param[in, out] CpuMpData The pointer to CPU MP Data structure.\r
+**/\r
+VOID\r
+AllocateResetVector (\r
+ IN OUT CPU_MP_DATA *CpuMpData\r
+ )\r
+{\r
+ UINTN ApResetVectorSize;\r
+\r
+ if (CpuMpData->WakeupBuffer == (UINTN) -1) {\r
+ ApResetVectorSize = CpuMpData->AddressMap.RendezvousFunnelSize +\r
+ sizeof (MP_CPU_EXCHANGE_INFO);\r
+\r
+ CpuMpData->WakeupBuffer = GetWakeupBuffer (ApResetVectorSize);\r
+ CpuMpData->MpCpuExchangeInfo = (MP_CPU_EXCHANGE_INFO *) (UINTN)\r
+ (CpuMpData->WakeupBuffer + CpuMpData->AddressMap.RendezvousFunnelSize);\r
+ }\r
+ BackupAndPrepareWakeupBuffer (CpuMpData);\r
+}\r
+\r
+/**\r
+ Free AP reset vector buffer.\r
+\r
+ @param[in] CpuMpData The pointer to CPU MP Data structure.\r
+**/\r
+VOID\r
+FreeResetVector (\r
+ IN CPU_MP_DATA *CpuMpData\r
+ )\r
+{\r
+ RestoreWakeupBuffer (CpuMpData);\r
+}\r
+\r
/**\r
This function will be called by BSP to wakeup AP.\r
\r
OUT UINT64 *CurrentTime\r
)\r
{\r
+ UINT64 TimeoutInSeconds;\r
+ UINT64 TimestampCounterFreq;\r
+\r
//\r
// Read the current value of the performance counter\r
//\r
\r
//\r
// GetPerformanceCounterProperties () returns the timestamp counter's frequency\r
- // in Hz. So multiply the return value with TimeoutInMicroseconds and then divide\r
- // it by 1,000,000, to get the number of ticks for the timeout value.\r
- //\r
- return DivU64x32 (\r
- MultU64x64 (\r
- GetPerformanceCounterProperties (NULL, NULL),\r
- TimeoutInMicroseconds\r
- ),\r
- 1000000\r
- );\r
+ // in Hz. \r
+ //\r
+ TimestampCounterFreq = GetPerformanceCounterProperties (NULL, NULL);\r
+\r
+ //\r
+ // Check the potential overflow before calculate the number of ticks for the timeout value.\r
+ //\r
+ if (DivU64x64Remainder (MAX_UINT64, TimeoutInMicroseconds, NULL) < TimestampCounterFreq) {\r
+ //\r
+ // Convert microseconds into seconds if direct multiplication overflows\r
+ //\r
+ TimeoutInSeconds = DivU64x32 (TimeoutInMicroseconds, 1000000);\r
+ //\r
+ // Assertion if the final tick count exceeds MAX_UINT64\r
+ //\r
+ ASSERT (DivU64x64Remainder (MAX_UINT64, TimeoutInSeconds, NULL) >= TimestampCounterFreq);\r
+ return MultU64x64 (TimestampCounterFreq, TimeoutInSeconds);\r
+ } else {\r
+ //\r
+ // No overflow case, multiply the return value with TimeoutInMicroseconds and then divide\r
+ // it by 1,000,000, to get the number of ticks for the timeout value.\r
+ //\r
+ return DivU64x32 (\r
+ MultU64x64 (\r
+ TimestampCounterFreq,\r
+ TimeoutInMicroseconds\r
+ ),\r
+ 1000000\r
+ );\r
+ }\r
}\r
\r
/**\r
CpuMpData->CpuApStackSize = ApStackSize;\r
CpuMpData->BackupBuffer = BackupBufferAddr;\r
CpuMpData->BackupBufferSize = ApResetVectorSize;\r
- CpuMpData->SaveRestoreFlag = FALSE;\r
CpuMpData->WakeupBuffer = (UINTN) -1;\r
CpuMpData->CpuCount = 1;\r
CpuMpData->BspNumber = 0;\r
//\r
MpInitLibWhoAmI (&CallerNumber);\r
if (CallerNumber != CpuMpData->BspNumber) {\r
- return EFI_SUCCESS;\r
+ return EFI_DEVICE_ERROR;\r
}\r
\r
if (ProcessorNumber >= CpuMpData->CpuCount) {\r
if (!EnableAP) {\r
SetApState (&CpuMpData->CpuData[ProcessorNumber], CpuStateDisabled);\r
} else {\r
- SetApState (&CpuMpData->CpuData[ProcessorNumber], CpuStateIdle);\r
+ ResetProcessorToIdleState (ProcessorNumber);\r
}\r
\r
if (HealthFlag != NULL) {\r
return CpuMpData;\r
}\r
\r
-/**\r
- Get available system memory below 1MB by specified size.\r
-\r
- @param[in] CpuMpData The pointer to CPU MP Data structure.\r
-**/\r
-VOID\r
-BackupAndPrepareWakeupBuffer(\r
- IN CPU_MP_DATA *CpuMpData\r
- )\r
-{\r
- CopyMem (\r
- (VOID *) CpuMpData->BackupBuffer,\r
- (VOID *) CpuMpData->WakeupBuffer,\r
- CpuMpData->BackupBufferSize\r
- );\r
- CopyMem (\r
- (VOID *) CpuMpData->WakeupBuffer,\r
- (VOID *) CpuMpData->AddressMap.RendezvousFunnelAddress,\r
- CpuMpData->AddressMap.RendezvousFunnelSize\r
- );\r
-}\r
-\r
-/**\r
- Restore wakeup buffer data.\r
-\r
- @param[in] CpuMpData The pointer to CPU MP Data structure.\r
-**/\r
-VOID\r
-RestoreWakeupBuffer(\r
- IN CPU_MP_DATA *CpuMpData\r
- )\r
-{\r
- CopyMem (\r
- (VOID *) CpuMpData->WakeupBuffer,\r
- (VOID *) CpuMpData->BackupBuffer,\r
- CpuMpData->BackupBufferSize\r
- );\r
-}\r