1 /**@file
2   Initialize Secure Encrypted Virtualization (SEV) support
3 
4   Copyright (c) 2017, Advanced Micro Devices. All rights reserved.<BR>
5 
6   SPDX-License-Identifier: BSD-2-Clause-Patent
7 
8 **/
9 //
10 // The package level header files this module uses
11 //
12 #include <Library/DebugLib.h>
13 #include <Library/HobLib.h>
14 #include <Library/MemEncryptSevLib.h>
15 #include <Library/PcdLib.h>
16 #include <PiPei.h>
17 #include <Register/Amd/Cpuid.h>
18 #include <Register/Cpuid.h>
19 
20 #include "Platform.h"
21 
22 /**
23 
24   Function checks if SEV support is available, if present then it sets
25   the dynamic PcdPteMemoryEncryptionAddressOrMask with memory encryption mask.
26 
27   **/
28 VOID
AmdSevInitialize(VOID)29 AmdSevInitialize (
30   VOID
31   )
32 {
33   CPUID_MEMORY_ENCRYPTION_INFO_EBX  Ebx;
34   UINT64                            EncryptionMask;
35   RETURN_STATUS                     PcdStatus;
36 
37   //
38   // Check if SEV is enabled
39   //
40   if (!MemEncryptSevIsEnabled ()) {
41     return;
42   }
43 
44   //
45   // CPUID Fn8000_001F[EBX] Bit 0:5 (memory encryption bit position)
46   //
47   AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, NULL, &Ebx.Uint32, NULL, NULL);
48   EncryptionMask = LShiftU64 (1, Ebx.Bits.PtePosBits);
49 
50   //
51   // Set Memory Encryption Mask PCD
52   //
53   PcdStatus = PcdSet64S (PcdPteMemoryEncryptionAddressOrMask, EncryptionMask);
54   ASSERT_RETURN_ERROR (PcdStatus);
55 
56   DEBUG ((DEBUG_INFO, "SEV is enabled (mask 0x%lx)\n", EncryptionMask));
57 
58   //
59   // Set Pcd to Deny the execution of option ROM when security
60   // violation.
61   //
62   PcdStatus = PcdSet32S (PcdOptionRomImageVerificationPolicy, 0x4);
63   ASSERT_RETURN_ERROR (PcdStatus);
64 
65   //
66   // When SMM is required, cover the pages containing the initial SMRAM Save
67   // State Map with a memory allocation HOB:
68   //
69   // There's going to be a time interval between our decrypting those pages for
70   // SMBASE relocation and re-encrypting the same pages after SMBASE
71   // relocation. We shall ensure that the DXE phase stay away from those pages
72   // until after re-encryption, in order to prevent an information leak to the
73   // hypervisor.
74   //
75   if (FeaturePcdGet (PcdSmmSmramRequire) && (mBootMode != BOOT_ON_S3_RESUME)) {
76     RETURN_STATUS LocateMapStatus;
77     UINTN         MapPagesBase;
78     UINTN         MapPagesCount;
79 
80     LocateMapStatus = MemEncryptSevLocateInitialSmramSaveStateMapPages (
81                         &MapPagesBase,
82                         &MapPagesCount
83                         );
84     ASSERT_RETURN_ERROR (LocateMapStatus);
85 
86     BuildMemoryAllocationHob (
87       MapPagesBase,                      // BaseAddress
88       EFI_PAGES_TO_SIZE (MapPagesCount), // Length
89       EfiBootServicesData                // MemoryType
90       );
91   }
92 }
93