+\r
+ //\r
+ // Find a 32-bit code segment\r
+ //\r
+ Selector = (IA32_SEGMENT_DESCRIPTOR *)ExchangeInfo->GdtrProfile.Base;\r
+ Size = ExchangeInfo->GdtrProfile.Limit + 1;\r
+ while (Size > 0) {\r
+ if (Selector->Bits.L == 0 && Selector->Bits.Type >= 8) {\r
+ ExchangeInfo->ModeTransitionSegment =\r
+ (UINT16)((UINTN)Selector - ExchangeInfo->GdtrProfile.Base);\r
+ break;\r
+ }\r
+ Selector += 1;\r
+ Size -= sizeof (IA32_SEGMENT_DESCRIPTOR);\r
+ }\r
+\r
+ //\r
+ // Copy all 32-bit code and 64-bit code into memory with type of\r
+ // EfiBootServicesCode to avoid page fault if NX memory protection is enabled.\r
+ //\r
+ if (CpuMpData->WakeupBufferHigh != 0) {\r
+ Size = CpuMpData->AddressMap.RendezvousFunnelSize -\r
+ CpuMpData->AddressMap.ModeTransitionOffset;\r
+ CopyMem (\r
+ (VOID *)CpuMpData->WakeupBufferHigh,\r
+ CpuMpData->AddressMap.RendezvousFunnelAddress +\r
+ CpuMpData->AddressMap.ModeTransitionOffset,\r
+ Size\r
+ );\r
+\r
+ ExchangeInfo->ModeTransitionMemory = (UINT32)CpuMpData->WakeupBufferHigh;\r
+ } else {\r
+ ExchangeInfo->ModeTransitionMemory = (UINT32)\r
+ (ExchangeInfo->BufferStart + CpuMpData->AddressMap.ModeTransitionOffset);\r
+ }\r
+\r
+ ExchangeInfo->ModeHighMemory = ExchangeInfo->ModeTransitionMemory +\r
+ (UINT32)ExchangeInfo->ModeOffset -\r
+ (UINT32)CpuMpData->AddressMap.ModeTransitionOffset;\r
+ ExchangeInfo->ModeHighSegment = (UINT16)ExchangeInfo->CodeSegment;\r