Changeset 108794 in vbox for trunk/src/VBox/Devices/EFI/FirmwareNew/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
- Timestamp:
- Mar 31, 2025 11:31:09 AM (2 weeks ago)
- svn:sync-xref-src-repo-rev:
- 168237
- Location:
- trunk/src/VBox/Devices/EFI/FirmwareNew
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/EFI/FirmwareNew
-
Property svn:mergeinfo
changed from (toggle deleted branches)
to (toggle deleted branches)/vendor/edk2/current 103735-103757,103769-103776,129194-164365 /vendor/edk2/current 103735-103757,103769-103776,129194-168232
-
Property svn:mergeinfo
changed from (toggle deleted branches)
-
trunk/src/VBox/Devices/EFI/FirmwareNew/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
r101291 r108794 2 2 MP initialize support functions for DXE phase. 3 3 4 Copyright (c) 2016 - 2023, Intel Corporation. All rights reserved.<BR> 4 Copyright (c) 2016 - 2024, Intel Corporation. All rights reserved.<BR> 5 Copyright (c) 2024, AMD Inc. All rights reserved.<BR> 5 6 SPDX-License-Identifier: BSD-2-Clause-Patent 6 7 … … 14 15 #include <Library/DxeServicesTableLib.h> 15 16 #include <Library/CcExitLib.h> 16 #include <Register/Amd/ Fam17Msr.h>17 #include <Register/Amd/SevSnpMsr.h> 17 18 #include <Register/Amd/Ghcb.h> 18 19 … … 21 22 #define AP_SAFE_STACK_SIZE 128 22 23 23 CPU_MP_DATA *mCpuMpData = NULL; 24 EFI_EVENT mCheckAllApsEvent = NULL; 25 EFI_EVENT mMpInitExitBootServicesEvent = NULL; 26 EFI_EVENT mLegacyBootEvent = NULL; 27 volatile BOOLEAN mStopCheckAllApsStatus = TRUE; 28 RELOCATE_AP_LOOP_ENTRY mReservedApLoop; 29 UINTN mReservedTopOfApStack; 30 volatile UINT32 mNumberToFinish = 0; 31 UINTN mApPageTable; 24 CPU_MP_DATA *mCpuMpData = NULL; 25 EFI_EVENT mCheckAllApsEvent = NULL; 26 EFI_EVENT mMpInitExitBootServicesEvent = NULL; 27 EFI_EVENT mLegacyBootEvent = NULL; 28 volatile BOOLEAN mStopCheckAllApsStatus = TRUE; 32 29 33 30 // … … 317 314 IA32_SEGMENT_DESCRIPTOR *GdtEntry; 318 315 UINTN GdtEntryCount; 319 UINT16 Index; 316 UINTN Index; 317 UINT16 CodeSegmentValue; 318 EFI_STATUS Status; 320 319 321 320 Index = (UINT16)-1; … … 333 332 } 334 333 335 ASSERT (Index != GdtEntryCount); 336 return Index * 8; 334 Status = SafeUintnToUint16 (Index, &CodeSegmentValue); 335 if (EFI_ERROR (Status)) { 336 ASSERT_EFI_ERROR (Status); 337 return 0; 338 } 339 340 Status = SafeUint16Mult (CodeSegmentValue, 8, &CodeSegmentValue); 341 if (EFI_ERROR (Status)) { 342 ASSERT_EFI_ERROR (Status); 343 return 0; 344 } 345 346 return CodeSegmentValue; 337 347 } 338 348 … … 350 360 IA32_SEGMENT_DESCRIPTOR *GdtEntry; 351 361 UINTN GdtEntryCount; 352 UINT16 Index; 362 UINTN Index; 363 UINT16 CodeSegmentValue; 364 EFI_STATUS Status; 353 365 354 366 AsmReadGdtr (&GdtrDesc); … … 365 377 } 366 378 367 ASSERT (Index != GdtEntryCount); 368 return Index * 8; 369 } 370 371 /** 372 Do sync on APs. 373 374 @param[in, out] Buffer Pointer to private data buffer. 379 Status = SafeUintnToUint16 (Index, &CodeSegmentValue); 380 if (EFI_ERROR (Status)) { 381 ASSERT_EFI_ERROR (Status); 382 return 0; 383 } 384 385 Status = SafeUint16Mult (CodeSegmentValue, 8, &CodeSegmentValue); 386 if (EFI_ERROR (Status)) { 387 ASSERT_EFI_ERROR (Status); 388 return 0; 389 } 390 391 return CodeSegmentValue; 392 } 393 394 /** 395 Allocate buffer for ApLoopCode. 396 397 @param[in] Pages Number of pages to allocate. 398 @param[in, out] Address Pointer to the allocated buffer. 375 399 **/ 376 400 VOID 377 EFIAPI 378 RelocateApLoop ( 379 IN OUT VOID *Buffer380 ) 381 { 382 CPU_MP_DATA *CpuMpData;383 BOOLEAN MwaitSupport; 384 UINTN ProcessorNumber;385 UINTN StackStart;386 387 MpInitLibWhoAmI (&ProcessorNumber);388 CpuMpData = GetCpuMpData ();389 MwaitSupport = IsMwaitSupport ();390 if (CpuMpData->UseSevEsAPMethod) {391 // 392 // 64-bit AMD processors with SEV-ES 393 // 394 StackStart = CpuMpData->SevEsAPResetStackStart;395 mReservedApLoop.AmdSevEntry ( 396 MwaitSupport,397 CpuMpData->ApTargetCState,398 CpuMpData->PmCodeSegment, 399 StackStart - ProcessorNumber * AP_SAFE_STACK_SIZE,400 (UINTN)&mNumberToFinish,401 CpuMpData->Pm16CodeSegment, 402 CpuMpData->SevEsAPBuffer, 403 CpuMpData->WakeupBuffer 404 );405 } else {406 //407 // Intel processors (32-bit or 64-bit), 32-bit AMD processors, or 64-bit AMD processors without SEV-ES 408 //409 StackStart = mReservedTopOfApStack;410 mReservedApLoop.GenericEntry ( 411 MwaitSupport,412 CpuMpData->ApTargetCState,413 StackStart - ProcessorNumber * AP_SAFE_STACK_SIZE,414 (UINTN)&mNumberToFinish,415 mApPageTable416 );417 }418 419 //420 // It should never reach here421 //422 ASSERT (FALSE);401 AllocateApLoopCodeBuffer ( 402 IN UINTN Pages, 403 IN OUT EFI_PHYSICAL_ADDRESS *Address 404 ) 405 { 406 EFI_STATUS Status; 407 408 Status = gBS->AllocatePages ( 409 AllocateMaxAddress, 410 EfiReservedMemoryType, 411 Pages, 412 Address 413 ); 414 ASSERT_EFI_ERROR (Status); 415 } 416 417 /** 418 Remove Nx protection for the range specific by BaseAddress and Length. 419 420 The PEI implementation uses CpuPageTableLib to change the attribute. 421 The DXE implementation uses gDS to change the attribute. 422 423 @param[in] BaseAddress BaseAddress of the range. 424 @param[in] Length Length of the range. 425 **/ 426 VOID 427 RemoveNxprotection ( 428 IN EFI_PHYSICAL_ADDRESS BaseAddress, 429 IN UINTN Length 430 ) 431 { 432 EFI_STATUS Status; 433 EFI_GCD_MEMORY_SPACE_DESCRIPTOR MemDesc; 434 435 // 436 // TODO: Check EFI_MEMORY_XP bit set or not once it's available in DXE GCD 437 // service. 438 // 439 Status = gDS->GetMemorySpaceDescriptor (BaseAddress, &MemDesc); 440 if (!EFI_ERROR (Status)) { 441 gDS->SetMemorySpaceAttributes ( 442 BaseAddress, 443 Length, 444 MemDesc.Attributes & (~EFI_MEMORY_XP) 445 ); 446 } 423 447 } 424 448 … … 478 502 { 479 503 EFI_STATUS Status; 480 EFI_PHYSICAL_ADDRESS Address;481 504 UINTN Index; 482 505 EFI_GCD_MEMORY_SPACE_DESCRIPTOR MemDesc; 483 506 UINTN StackBase; 484 507 CPU_INFO_IN_HOB *CpuInfoInHob; 485 MP_ASSEMBLY_ADDRESS_MAP *AddressMap;486 UINT8 *ApLoopFunc;487 UINTN ApLoopFuncSize;488 UINTN StackPages;489 UINTN FuncPages;490 508 491 509 SaveCpuMpData (CpuMpData); … … 542 560 } 543 561 544 AddressMap = &CpuMpData->AddressMap; 545 if (CpuMpData->UseSevEsAPMethod) { 546 // 547 // 64-bit AMD processors with SEV-ES 548 // 549 Address = BASE_4GB - 1; 550 ApLoopFunc = AddressMap->RelocateApLoopFuncAddressAmdSev; 551 ApLoopFuncSize = AddressMap->RelocateApLoopFuncSizeAmdSev; 552 } else { 553 // 554 // Intel processors (32-bit or 64-bit), 32-bit AMD processors, or 64-bit AMD processors without SEV-ES 555 // 556 Address = MAX_ADDRESS; 557 ApLoopFunc = AddressMap->RelocateApLoopFuncAddressGeneric; 558 ApLoopFuncSize = AddressMap->RelocateApLoopFuncSizeGeneric; 559 } 560 561 // 562 // Avoid APs access invalid buffer data which allocated by BootServices, 563 // so we will allocate reserved data for AP loop code. We also need to 564 // allocate this buffer below 4GB due to APs may be transferred to 32bit 565 // protected mode on long mode DXE. 566 // Allocating it in advance since memory services are not available in 567 // Exit Boot Services callback function. 568 // 569 // +------------+ (TopOfApStack) 570 // | Stack * N | 571 // +------------+ (stack base, 4k aligned) 572 // | Padding | 573 // +------------+ 574 // | Ap Loop | 575 // +------------+ ((low address, 4k-aligned) 576 // 577 578 StackPages = EFI_SIZE_TO_PAGES (CpuMpData->CpuCount * AP_SAFE_STACK_SIZE); 579 FuncPages = EFI_SIZE_TO_PAGES (ApLoopFuncSize); 580 581 Status = gBS->AllocatePages ( 582 AllocateMaxAddress, 583 EfiReservedMemoryType, 584 StackPages + FuncPages, 585 &Address 586 ); 587 ASSERT_EFI_ERROR (Status); 588 589 // 590 // Make sure that the buffer memory is executable if NX protection is enabled 591 // for EfiReservedMemoryType. 592 // 593 // TODO: Check EFI_MEMORY_XP bit set or not once it's available in DXE GCD 594 // service. 595 // 596 Status = gDS->GetMemorySpaceDescriptor (Address, &MemDesc); 597 if (!EFI_ERROR (Status)) { 598 gDS->SetMemorySpaceAttributes ( 599 Address, 600 EFI_PAGES_TO_SIZE (FuncPages), 601 MemDesc.Attributes & (~EFI_MEMORY_XP) 602 ); 603 } 604 605 mReservedTopOfApStack = (UINTN)Address + EFI_PAGES_TO_SIZE (StackPages+FuncPages); 606 ASSERT ((mReservedTopOfApStack & (UINTN)(CPU_STACK_ALIGNMENT - 1)) == 0); 607 mReservedApLoop.Data = (VOID *)(UINTN)Address; 608 ASSERT (mReservedApLoop.Data != NULL); 609 CopyMem (mReservedApLoop.Data, ApLoopFunc, ApLoopFuncSize); 610 if (!CpuMpData->UseSevEsAPMethod) { 611 // 612 // processors without SEV-ES 613 // 614 mApPageTable = CreatePageTable ( 615 (UINTN)Address, 616 EFI_PAGES_TO_SIZE (StackPages+FuncPages) 617 ); 618 } 562 PrepareApLoopCode (CpuMpData); 619 563 620 564 Status = gBS->CreateEvent (
Note:
See TracChangeset
for help on using the changeset viewer.