]>
git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c
2 SMM CPU misc functions for x64 arch specific.
4 Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "PiSmmCpuDxeSmm.h"
18 Initialize Gdt for all processors.
20 @param[in] Cr3 CR3 value.
21 @param[out] GdtStepSize The step size for GDT table.
23 @return GdtBase for processor 0.
24 GdtBase for processor X is: GdtBase + (GdtStepSize * X)
29 OUT UINTN
*GdtStepSize
33 IA32_SEGMENT_DESCRIPTOR
*GdtDescriptor
;
35 UINTN GdtTssTableSize
;
37 UINTN GdtTableStepSize
;
40 // For X64 SMM, we allocate separate GDT/TSS for each CPUs to avoid TSS load contention
43 GdtTssTableSize
= (gcSmiGdtr
.Limit
+ 1 + TSS_SIZE
+ 7) & ~7; // 8 bytes aligned
44 GdtTssTables
= (UINT8
*)AllocatePages (EFI_SIZE_TO_PAGES (GdtTssTableSize
* gSmmCpuPrivate
->SmmCoreEntryContext
.NumberOfCpus
));
45 ASSERT (GdtTssTables
!= NULL
);
46 GdtTableStepSize
= GdtTssTableSize
;
48 for (Index
= 0; Index
< gSmmCpuPrivate
->SmmCoreEntryContext
.NumberOfCpus
; Index
++) {
49 CopyMem (GdtTssTables
+ GdtTableStepSize
* Index
, (VOID
*)(UINTN
)gcSmiGdtr
.Base
, gcSmiGdtr
.Limit
+ 1 + TSS_SIZE
);
52 // Fixup TSS descriptors
54 TssBase
= (UINTN
)(GdtTssTables
+ GdtTableStepSize
* Index
+ gcSmiGdtr
.Limit
+ 1);
55 GdtDescriptor
= (IA32_SEGMENT_DESCRIPTOR
*)(TssBase
) - 2;
56 GdtDescriptor
->Bits
.BaseLow
= (UINT16
)(UINTN
)TssBase
;
57 GdtDescriptor
->Bits
.BaseMid
= (UINT8
)((UINTN
)TssBase
>> 16);
58 GdtDescriptor
->Bits
.BaseHigh
= (UINT8
)((UINTN
)TssBase
>> 24);
60 if (FeaturePcdGet (PcdCpuSmmStackGuard
)) {
62 // Setup top of known good stack as IST1 for each processor.
64 *(UINTN
*)(TssBase
+ TSS_X64_IST1_OFFSET
) = (mSmmStackArrayBase
+ EFI_PAGE_SIZE
+ Index
* mSmmStackSize
);
68 *GdtStepSize
= GdtTableStepSize
;