X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=UefiCpuPkg%2FPiSmmCpuDxeSmm%2FPiSmmCpuDxeSmm.h;h=a01d0d76d6ff2010638b83335158278155243dcf;hp=9b119c8412c529a08844025787acaf5bd58e8564;hb=6b0841c166f079c7f5c21196dd239e26172bfd97;hpb=b10d5ddc0385f39d2c2c62843710b7609a4ca169 diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h index 9b119c8412..a01d0d76d6 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h @@ -1,7 +1,9 @@ /** @file Agent Module to load other modules to deploy SMM Entry Vector for X86 CPU. -Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.
+Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+Copyright (c) 2017, AMD Incorporated. All rights reserved.
+ This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -23,8 +25,10 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include #include +#include #include +#include #include #include @@ -83,13 +87,40 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #define IA32_PG_PMNT BIT62 #define IA32_PG_NX BIT63 -#define PAGE_ATTRIBUTE_BITS (IA32_PG_RW | IA32_PG_P) +#define PAGE_ATTRIBUTE_BITS (IA32_PG_D | IA32_PG_A | IA32_PG_U | IA32_PG_RW | IA32_PG_P) // // Bits 1, 2, 5, 6 are reserved in the IA32 PAE PDPTE // X64 PAE PDPTE does not have such restriction // #define IA32_PAE_PDPTE_ATTRIBUTE_BITS (IA32_PG_P) +#define PAGE_PROGATE_BITS (IA32_PG_NX | PAGE_ATTRIBUTE_BITS) + +#define PAGING_4K_MASK 0xFFF +#define PAGING_2M_MASK 0x1FFFFF +#define PAGING_1G_MASK 0x3FFFFFFF + +#define PAGING_PAE_INDEX_MASK 0x1FF + +#define PAGING_4K_ADDRESS_MASK_64 0x000FFFFFFFFFF000ull +#define PAGING_2M_ADDRESS_MASK_64 0x000FFFFFFFE00000ull +#define PAGING_1G_ADDRESS_MASK_64 0x000FFFFFC0000000ull + +#define SMRR_MAX_ADDRESS BASE_4GB + +typedef enum { + PageNone, + Page4K, + Page2M, + Page1G, +} PAGE_ATTRIBUTE; + +typedef struct { + PAGE_ATTRIBUTE Attribute; + UINT64 Length; + UINT64 AddressMask; +} PAGE_ATTRIBUTE_TABLE; + // // Size of Task-State Segment defined in IA32 Manual // @@ -98,6 +129,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #define TSS_IA32_CR3_OFFSET 28 #define TSS_IA32_ESP_OFFSET 56 +#define CR0_WP BIT16 + // // Code select value // @@ -156,7 +189,6 @@ extern EFI_SMM_CPU_PROTOCOL mSmmCpu; /// extern UINT8 mSmmSaveStateRegisterLma; - // // SMM CPU Protocol function prototypes. // @@ -277,7 +309,7 @@ extern IA32_FAR_ADDRESS gSmmJmpAddr; extern CONST UINT8 gcSmmInitTemplate[]; extern CONST UINT16 gcSmmInitSize; extern UINT32 gSmmCr0; -extern UINT32 gSmmCr3; +X86_ASSEMBLY_PATCH_LABEL gPatchSmmCr3; extern UINT32 gSmmCr4; extern UINTN gSmmInitStack; @@ -331,31 +363,6 @@ typedef struct { #define SMM_PSD_OFFSET 0xfb00 -typedef struct { - UINT64 Signature; // Offset 0x00 - UINT16 Reserved1; // Offset 0x08 - UINT16 Reserved2; // Offset 0x0A - UINT16 Reserved3; // Offset 0x0C - UINT16 SmmCs; // Offset 0x0E - UINT16 SmmDs; // Offset 0x10 - UINT16 SmmSs; // Offset 0x12 - UINT16 SmmOtherSegment; // Offset 0x14 - UINT16 Reserved4; // Offset 0x16 - UINT64 Reserved5; // Offset 0x18 - UINT64 Reserved6; // Offset 0x20 - UINT64 Reserved7; // Offset 0x28 - UINT64 SmmGdtPtr; // Offset 0x30 - UINT32 SmmGdtSize; // Offset 0x38 - UINT32 Reserved8; // Offset 0x3C - UINT64 Reserved9; // Offset 0x40 - UINT64 Reserved10; // Offset 0x48 - UINT16 Reserved11; // Offset 0x50 - UINT16 Reserved12; // Offset 0x52 - UINT32 Reserved13; // Offset 0x54 - UINT64 MtrrBaseMaskPtr; // Offset 0x58 -} PROCESSOR_SMM_DESCRIPTOR; - - /// /// All global semaphores' pointer /// @@ -395,9 +402,10 @@ typedef struct { } SMM_CPU_SEMAPHORES; extern IA32_DESCRIPTOR gcSmiGdtr; +extern EFI_PHYSICAL_ADDRESS mGdtBuffer; +extern UINTN mGdtBufferSize; extern IA32_DESCRIPTOR gcSmiIdtr; extern VOID *gcSmiIdtrPtr; -extern CONST PROCESSOR_SMM_DESCRIPTOR gcPsd; extern UINT64 gPhyMask; extern SMM_DISPATCHER_MP_SYNC_DATA *mSmmMpSyncData; extern UINTN mSmmStackArrayBase; @@ -410,18 +418,24 @@ extern UINTN mSemaphoreSize; extern SPIN_LOCK *mPFLock; extern SPIN_LOCK *mConfigSmmCodeAccessCheckLock; extern SPIN_LOCK *mMemoryMappedLock; +extern EFI_SMRAM_DESCRIPTOR *mSmmCpuSmramRanges; +extern UINTN mSmmCpuSmramRangeCount; +extern UINT8 mPhysicalAddressBits; + +// +// Copy of the PcdPteMemoryEncryptionAddressOrMask +// +extern UINT64 mAddressEncMask; /** Create 4G PageTable in SMRAM. - @param ExtraPages Additional page numbers besides for 4G memory - @param Is32BitPageTable Whether the page table is 32-bit PAE + @param[in] Is32BitPageTable Whether the page table is 32-bit PAE @return PageTable Address **/ UINT32 Gen4GPageTable ( - IN UINTN ExtraPages, IN BOOLEAN Is32BitPageTable ); @@ -482,7 +496,7 @@ InitializeIDTSmmStackGuard ( /** Initialize Gdt for all processors. - + @param[in] Cr3 CR3 value. @param[out] GdtStepSize The step size for GDT table. @@ -567,6 +581,66 @@ SmmBlockingStartupThisAp ( IN OUT VOID *ProcArguments OPTIONAL ); +/** + This function sets the attributes for the memory region specified by BaseAddress and + Length from their current attributes to the attributes specified by Attributes. + + @param[in] BaseAddress The physical address that is the start address of a memory region. + @param[in] Length The size in bytes of the memory region. + @param[in] Attributes The bit mask of attributes to set for the memory region. + + @retval EFI_SUCCESS The attributes were set for the memory region. + @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by + BaseAddress and Length cannot be modified. + @retval EFI_INVALID_PARAMETER Length is zero. + Attributes specified an illegal combination of attributes that + cannot be set together. + @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of + the memory resource range. + @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory + resource range specified by BaseAddress and Length. + The bit mask of attributes is not support for the memory resource + range specified by BaseAddress and Length. + +**/ +EFI_STATUS +EFIAPI +SmmSetMemoryAttributes ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes + ); + +/** + This function clears the attributes for the memory region specified by BaseAddress and + Length from their current attributes to the attributes specified by Attributes. + + @param[in] BaseAddress The physical address that is the start address of a memory region. + @param[in] Length The size in bytes of the memory region. + @param[in] Attributes The bit mask of attributes to clear for the memory region. + + @retval EFI_SUCCESS The attributes were cleared for the memory region. + @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by + BaseAddress and Length cannot be modified. + @retval EFI_INVALID_PARAMETER Length is zero. + Attributes specified an illegal combination of attributes that + cannot be set together. + @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of + the memory resource range. + @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory + resource range specified by BaseAddress and Length. + The bit mask of attributes is not support for the memory resource + range specified by BaseAddress and Length. + +**/ +EFI_STATUS +EFIAPI +SmmClearMemoryAttributes ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes + ); + /** Initialize MP synchronization data. @@ -614,8 +688,8 @@ SmmRelocateBases ( VOID EFIAPI SmiPFHandler ( - IN EFI_EXCEPTION_TYPE InterruptType, - IN EFI_SYSTEM_CONTEXT SystemContext + IN EFI_EXCEPTION_TYPE InterruptType, + IN EFI_SYSTEM_CONTEXT SystemContext ); /** @@ -760,6 +834,125 @@ DumpModuleInfoByIp ( IN UINTN CallerIpAddress ); +/** + This function sets memory attribute according to MemoryAttributesTable. +**/ +VOID +SetMemMapAttributes ( + VOID + ); + +/** + This function sets UEFI memory attribute according to UEFI memory map. +**/ +VOID +SetUefiMemMapAttributes ( + VOID + ); + +/** + Return if the Address is forbidden as SMM communication buffer. + + @param[in] Address the address to be checked + + @return TRUE The address is forbidden as SMM communication buffer. + @return FALSE The address is allowed as SMM communication buffer. +**/ +BOOLEAN +IsSmmCommBufferForbiddenAddress ( + IN UINT64 Address + ); + +/** + This function caches the UEFI memory map information. +**/ +VOID +GetUefiMemoryMap ( + VOID + ); + +/** + This function sets memory attribute for page table. +**/ +VOID +SetPageTableAttributes ( + VOID + ); + +/** + Return page table base. + + @return page table base. +**/ +UINTN +GetPageTableBase ( + VOID + ); + +/** + This function sets the attributes for the memory region specified by BaseAddress and + Length from their current attributes to the attributes specified by Attributes. + + @param[in] BaseAddress The physical address that is the start address of a memory region. + @param[in] Length The size in bytes of the memory region. + @param[in] Attributes The bit mask of attributes to set for the memory region. + @param[out] IsSplitted TRUE means page table splitted. FALSE means page table not splitted. + + @retval EFI_SUCCESS The attributes were set for the memory region. + @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by + BaseAddress and Length cannot be modified. + @retval EFI_INVALID_PARAMETER Length is zero. + Attributes specified an illegal combination of attributes that + cannot be set together. + @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of + the memory resource range. + @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory + resource range specified by BaseAddress and Length. + The bit mask of attributes is not support for the memory resource + range specified by BaseAddress and Length. + +**/ +EFI_STATUS +EFIAPI +SmmSetMemoryAttributesEx ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes, + OUT BOOLEAN *IsSplitted OPTIONAL + ); + +/** + This function clears the attributes for the memory region specified by BaseAddress and + Length from their current attributes to the attributes specified by Attributes. + + @param[in] BaseAddress The physical address that is the start address of a memory region. + @param[in] Length The size in bytes of the memory region. + @param[in] Attributes The bit mask of attributes to clear for the memory region. + @param[out] IsSplitted TRUE means page table splitted. FALSE means page table not splitted. + + @retval EFI_SUCCESS The attributes were cleared for the memory region. + @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by + BaseAddress and Length cannot be modified. + @retval EFI_INVALID_PARAMETER Length is zero. + Attributes specified an illegal combination of attributes that + cannot be set together. + @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of + the memory resource range. + @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory + resource range specified by BaseAddress and Length. + The bit mask of attributes is not support for the memory resource + range specified by BaseAddress and Length. + +**/ +EFI_STATUS +EFIAPI +SmmClearMemoryAttributesEx ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes, + OUT BOOLEAN *IsSplitted OPTIONAL + ); + /** This API provides a way to allocate memory for page table. @@ -780,6 +973,34 @@ AllocatePageTableMemory ( IN UINTN Pages ); +/** + Allocate pages for code. + + @param[in] Pages Number of pages to be allocated. + + @return Allocated memory. +**/ +VOID * +AllocateCodePages ( + IN UINTN Pages + ); + +/** + Allocate aligned pages for code. + + @param[in] Pages Number of pages to be allocated. + @param[in] Alignment The requested alignment of the allocation. + Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return Allocated memory. +**/ +VOID * +AllocateAlignedCodePages ( + IN UINTN Pages, + IN UINTN Alignment + ); + // // S3 related global variable and function prototype. @@ -825,4 +1046,131 @@ GetAcpiS3EnableFlag ( VOID ); +/** + Transfer AP to safe hlt-loop after it finished restore CPU features on S3 patch. + + @param[in] ApHltLoopCode The address of the safe hlt-loop function. + @param[in] TopOfStack A pointer to the new stack to use for the ApHltLoopCode. + @param[in] NumberToFinishAddress Address of Semaphore of APs finish count. + +**/ +VOID +TransferApToSafeState ( + IN UINTN ApHltLoopCode, + IN UINTN TopOfStack, + IN UINTN NumberToFinishAddress + ); + +/** + This function set given attributes of the memory region specified by + BaseAddress and Length. + + @param This The EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL instance. + @param BaseAddress The physical address that is the start address of + a memory region. + @param Length The size in bytes of the memory region. + @param Attributes The bit mask of attributes to set for the memory + region. + + @retval EFI_SUCCESS The attributes were set for the memory region. + @retval EFI_INVALID_PARAMETER Length is zero. + Attributes specified an illegal combination of + attributes that cannot be set together. + @retval EFI_UNSUPPORTED The processor does not support one or more + bytes of the memory resource range specified + by BaseAddress and Length. + The bit mask of attributes is not supported for + the memory resource range specified by + BaseAddress and Length. + +**/ +EFI_STATUS +EFIAPI +EdkiiSmmSetMemoryAttributes ( + IN EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This, + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes + ); + +/** + This function clears given attributes of the memory region specified by + BaseAddress and Length. + + @param This The EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL instance. + @param BaseAddress The physical address that is the start address of + a memory region. + @param Length The size in bytes of the memory region. + @param Attributes The bit mask of attributes to clear for the memory + region. + + @retval EFI_SUCCESS The attributes were cleared for the memory region. + @retval EFI_INVALID_PARAMETER Length is zero. + Attributes specified an illegal combination of + attributes that cannot be cleared together. + @retval EFI_UNSUPPORTED The processor does not support one or more + bytes of the memory resource range specified + by BaseAddress and Length. + The bit mask of attributes is not supported for + the memory resource range specified by + BaseAddress and Length. + +**/ +EFI_STATUS +EFIAPI +EdkiiSmmClearMemoryAttributes ( + IN EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This, + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes + ); + +/** + This function retrieves the attributes of the memory region specified by + BaseAddress and Length. If different attributes are got from different part + of the memory region, EFI_NO_MAPPING will be returned. + + @param This The EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL instance. + @param BaseAddress The physical address that is the start address of + a memory region. + @param Length The size in bytes of the memory region. + @param Attributes Pointer to attributes returned. + + @retval EFI_SUCCESS The attributes got for the memory region. + @retval EFI_INVALID_PARAMETER Length is zero. + Attributes is NULL. + @retval EFI_NO_MAPPING Attributes are not consistent cross the memory + region. + @retval EFI_UNSUPPORTED The processor does not support one or more + bytes of the memory resource range specified + by BaseAddress and Length. + +**/ +EFI_STATUS +EFIAPI +EdkiiSmmGetMemoryAttributes ( + IN EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This, + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 *Attributes + ); + +/** + This function fixes up the address of the global variable or function + referred in SmmInit assembly files to be the absoute address. +**/ +VOID +EFIAPI +PiSmmCpuSmmInitFixupAddress ( + ); + +/** + This function fixes up the address of the global variable or function + referred in SmiEntry assembly files to be the absoute address. +**/ +VOID +EFIAPI +PiSmmCpuSmiEntryFixupAddress ( + ); + #endif