]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
UefiCpuPkg/PiSmmCpuDxeSmm: Refine casting result to bigger size
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / MpService.c
index 9b8db90ff6edb465787c972b250a0133aafc6dfe..a1d16b45705259eda1fdb12d31d534049adcd8ee 100644 (file)
@@ -1,7 +1,9 @@
 /** @file\r
 SMM MP service implementation\r
 \r
-Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>\r
+\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -17,13 +19,14 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 //\r
 // Slots for all MTRR( FIXED MTRR + VARIABLE MTRR + MTRR_LIB_IA32_MTRR_DEF_TYPE)\r
 //\r
-UINT64                                      gSmiMtrrs[MTRR_NUMBER_OF_FIXED_MTRR + 2 * MTRR_NUMBER_OF_VARIABLE_MTRR + 1];\r
+MTRR_SETTINGS                               gSmiMtrrs;\r
 UINT64                                      gPhyMask;\r
 SMM_DISPATCHER_MP_SYNC_DATA                 *mSmmMpSyncData = NULL;\r
 UINTN                                       mSmmMpSyncDataSize;\r
 SMM_CPU_SEMAPHORES                          mSmmCpuSemaphores;\r
 UINTN                                       mSemaphoreSize;\r
 SPIN_LOCK                                   *mPFLock = NULL;\r
+SMM_CPU_SYNC_MODE                           mCpuSmmSyncMode;\r
 \r
 /**\r
   Performs an atomic compare exchange operation to get semaphore.\r
@@ -282,20 +285,12 @@ ReplaceOSMtrrs (
   IN      UINTN                     CpuIndex\r
   )\r
 {\r
-  PROCESSOR_SMM_DESCRIPTOR       *Psd;\r
-  UINT64                         *SmiMtrrs;\r
-  MTRR_SETTINGS                  *BiosMtrr;\r
-\r
-  Psd = (PROCESSOR_SMM_DESCRIPTOR*)(mCpuHotPlugData.SmBase[CpuIndex] + SMM_PSD_OFFSET);\r
-  SmiMtrrs = (UINT64*)(UINTN)Psd->MtrrBaseMaskPtr;\r
-\r
   SmmCpuFeaturesDisableSmrr ();\r
 \r
   //\r
   // Replace all MTRRs registers\r
   //\r
-  BiosMtrr  = (MTRR_SETTINGS*)SmiMtrrs;\r
-  MtrrSetAllMtrrs(BiosMtrr);\r
+  MtrrSetAllMtrrs (&gSmiMtrrs);\r
 }\r
 \r
 /**\r
@@ -788,7 +783,8 @@ Gen4GPageTable (
   // Set Page Directory Pointers\r
   //\r
   for (Index = 0; Index < 4; Index++) {\r
-    Pte[Index] = (UINTN)PageTable + EFI_PAGE_SIZE * (Index + 1) + (Is32BitPageTable ? IA32_PAE_PDPTE_ATTRIBUTE_BITS : PAGE_ATTRIBUTE_BITS);\r
+    Pte[Index] = ((UINTN)PageTable + EFI_PAGE_SIZE * (Index + 1)) | mAddressEncMask |\r
+                   (Is32BitPageTable ? IA32_PAE_PDPTE_ATTRIBUTE_BITS : PAGE_ATTRIBUTE_BITS);\r
   }\r
   Pte += EFI_PAGE_SIZE / sizeof (*Pte);\r
 \r
@@ -796,7 +792,7 @@ Gen4GPageTable (
   // Fill in Page Directory Entries\r
   //\r
   for (Index = 0; Index < EFI_PAGE_SIZE * 4 / sizeof (*Pte); Index++) {\r
-    Pte[Index] = (Index << 21) | IA32_PG_PS | PAGE_ATTRIBUTE_BITS;\r
+    Pte[Index] = (Index << 21) | mAddressEncMask | IA32_PG_PS | PAGE_ATTRIBUTE_BITS;\r
   }\r
 \r
   if (FeaturePcdGet (PcdCpuSmmStackGuard)) {\r
@@ -804,8 +800,8 @@ Gen4GPageTable (
     GuardPage = mSmmStackArrayBase + EFI_PAGE_SIZE;\r
     Pdpte = (UINT64*)PageTable;\r
     for (PageIndex = Low2MBoundary; PageIndex <= High2MBoundary; PageIndex += SIZE_2MB) {\r
-      Pte = (UINT64*)(UINTN)(Pdpte[BitFieldRead32 ((UINT32)PageIndex, 30, 31)] & ~(EFI_PAGE_SIZE - 1));\r
-      Pte[BitFieldRead32 ((UINT32)PageIndex, 21, 29)] = (UINT64)Pages | PAGE_ATTRIBUTE_BITS;\r
+      Pte = (UINT64*)(UINTN)(Pdpte[BitFieldRead32 ((UINT32)PageIndex, 30, 31)] & ~mAddressEncMask & ~(EFI_PAGE_SIZE - 1));\r
+      Pte[BitFieldRead32 ((UINT32)PageIndex, 21, 29)] = (UINT64)Pages | mAddressEncMask | PAGE_ATTRIBUTE_BITS;\r
       //\r
       // Fill in Page Table Entries\r
       //\r
@@ -816,13 +812,13 @@ Gen4GPageTable (
           //\r
           // Mark the guard page as non-present\r
           //\r
-          Pte[Index] = PageAddress;\r
+          Pte[Index] = PageAddress | mAddressEncMask;\r
           GuardPage += mSmmStackSize;\r
           if (GuardPage > mSmmStackArrayEnd) {\r
             GuardPage = 0;\r
           }\r
         } else {\r
-          Pte[Index] = PageAddress | PAGE_ATTRIBUTE_BITS;\r
+          Pte[Index] = PageAddress | mAddressEncMask | PAGE_ATTRIBUTE_BITS;\r
         }\r
         PageAddress+= EFI_PAGE_SIZE;\r
       }\r
@@ -833,80 +829,12 @@ Gen4GPageTable (
   return (UINT32)(UINTN)PageTable;\r
 }\r
 \r
-/**\r
-  Set memory cache ability.\r
-\r
-  @param    PageTable              PageTable Address\r
-  @param    Address                Memory Address to change cache ability\r
-  @param    Cacheability           Cache ability to set\r
-\r
-**/\r
-VOID\r
-SetCacheability (\r
-  IN      UINT64                    *PageTable,\r
-  IN      UINTN                     Address,\r
-  IN      UINT8                     Cacheability\r
-  )\r
-{\r
-  UINTN   PTIndex;\r
-  VOID    *NewPageTableAddress;\r
-  UINT64  *NewPageTable;\r
-  UINTN   Index;\r
-\r
-  ASSERT ((Address & EFI_PAGE_MASK) == 0);\r
-\r
-  if (sizeof (UINTN) == sizeof (UINT64)) {\r
-    PTIndex = (UINTN)RShiftU64 (Address, 39) & 0x1ff;\r
-    ASSERT (PageTable[PTIndex] & IA32_PG_P);\r
-    PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & gPhyMask);\r
-  }\r
-\r
-  PTIndex = (UINTN)RShiftU64 (Address, 30) & 0x1ff;\r
-  ASSERT (PageTable[PTIndex] & IA32_PG_P);\r
-  PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & gPhyMask);\r
-\r
-  //\r
-  // A perfect implementation should check the original cacheability with the\r
-  // one being set, and break a 2M page entry into pieces only when they\r
-  // disagreed.\r
-  //\r
-  PTIndex = (UINTN)RShiftU64 (Address, 21) & 0x1ff;\r
-  if ((PageTable[PTIndex] & IA32_PG_PS) != 0) {\r
-    //\r
-    // Allocate a page from SMRAM\r
-    //\r
-    NewPageTableAddress = AllocatePageTableMemory (1);\r
-    ASSERT (NewPageTableAddress != NULL);\r
-\r
-    NewPageTable = (UINT64 *)NewPageTableAddress;\r
-\r
-    for (Index = 0; Index < 0x200; Index++) {\r
-      NewPageTable[Index] = PageTable[PTIndex];\r
-      if ((NewPageTable[Index] & IA32_PG_PAT_2M) != 0) {\r
-        NewPageTable[Index] &= ~((UINT64)IA32_PG_PAT_2M);\r
-        NewPageTable[Index] |= (UINT64)IA32_PG_PAT_4K;\r
-      }\r
-      NewPageTable[Index] |= (UINT64)(Index << EFI_PAGE_SHIFT);\r
-    }\r
-\r
-    PageTable[PTIndex] = ((UINTN)NewPageTableAddress & gPhyMask) | PAGE_ATTRIBUTE_BITS;\r
-  }\r
-\r
-  ASSERT (PageTable[PTIndex] & IA32_PG_P);\r
-  PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & gPhyMask);\r
-\r
-  PTIndex = (UINTN)RShiftU64 (Address, 12) & 0x1ff;\r
-  ASSERT (PageTable[PTIndex] & IA32_PG_P);\r
-  PageTable[PTIndex] &= ~((UINT64)((IA32_PG_PAT_4K | IA32_PG_CD | IA32_PG_WT)));\r
-  PageTable[PTIndex] |= (UINT64)Cacheability;\r
-}\r
-\r
 /**\r
   Schedule a procedure to run on the specified CPU.\r
 \r
   @param[in]       Procedure                The address of the procedure to run\r
   @param[in]       CpuIndex                 Target CPU Index\r
-  @param[in, OUT]  ProcArguments            The parameter to pass to the procedure\r
+  @param[in, out]  ProcArguments            The parameter to pass to the procedure\r
   @param[in]       BlockingMode             Startup AP in blocking mode or not\r
 \r
   @retval EFI_INVALID_PARAMETER    CpuNumber not valid\r
@@ -1338,7 +1266,7 @@ InitializeMpSyncData (
       //\r
       mSmmMpSyncData->BspIndex = (UINT32)-1;\r
     }\r
-    mSmmMpSyncData->EffectiveSyncMode = (SMM_CPU_SYNC_MODE) PcdGet8 (PcdCpuSmmSyncMode);\r
+    mSmmMpSyncData->EffectiveSyncMode = mCpuSmmSyncMode;\r
 \r
     mSmmMpSyncData->Counter       = mSmmCpuSemaphores.SemaphoreGlobal.Counter;\r
     mSmmMpSyncData->InsideSmm     = mSmmCpuSemaphores.SemaphoreGlobal.InsideSmm;\r
@@ -1356,6 +1284,9 @@ InitializeMpSyncData (
         (UINT32 *)((UINTN)mSmmCpuSemaphores.SemaphoreCpu.Run + mSemaphoreSize * CpuIndex);\r
       mSmmMpSyncData->CpuData[CpuIndex].Present =\r
         (BOOLEAN *)((UINTN)mSmmCpuSemaphores.SemaphoreCpu.Present + mSemaphoreSize * CpuIndex);\r
+      *(mSmmMpSyncData->CpuData[CpuIndex].Busy)    = 0;\r
+      *(mSmmMpSyncData->CpuData[CpuIndex].Run)     = 0;\r
+      *(mSmmMpSyncData->CpuData[CpuIndex].Present) = FALSE;\r
     }\r
   }\r
 }\r
@@ -1375,8 +1306,6 @@ InitializeMpServiceData (
 {\r
   UINT32                    Cr3;\r
   UINTN                     Index;\r
-  MTRR_SETTINGS             *Mtrr;\r
-  PROCESSOR_SMM_DESCRIPTOR  *Psd;\r
   UINT8                     *GdtTssTables;\r
   UINTN                     GdtTableStepSize;\r
 \r
@@ -1392,6 +1321,7 @@ InitializeMpServiceData (
                        (sizeof (SMM_CPU_DATA_BLOCK) + sizeof (BOOLEAN)) * gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus;\r
   mSmmMpSyncData = (SMM_DISPATCHER_MP_SYNC_DATA*) AllocatePages (EFI_SIZE_TO_PAGES (mSmmMpSyncDataSize));\r
   ASSERT (mSmmMpSyncData != NULL);\r
+  mCpuSmmSyncMode = (SMM_CPU_SYNC_MODE)PcdGet8 (PcdCpuSmmSyncMode);\r
   InitializeMpSyncData ();\r
 \r
   //\r
@@ -1410,24 +1340,16 @@ InitializeMpServiceData (
   GdtTssTables = InitGdt (Cr3, &GdtTableStepSize);\r
 \r
   //\r
-  // Initialize PROCESSOR_SMM_DESCRIPTOR for each CPU\r
+  // Install SMI handler for each CPU\r
   //\r
   for (Index = 0; Index < mMaxNumberOfCpus; Index++) {\r
-    Psd = (PROCESSOR_SMM_DESCRIPTOR *)(VOID *)(UINTN)(mCpuHotPlugData.SmBase[Index] + SMM_PSD_OFFSET);\r
-    CopyMem (Psd, &gcPsd, sizeof (gcPsd));\r
-    Psd->SmmGdtPtr = (UINT64)(UINTN)(GdtTssTables + GdtTableStepSize * Index);\r
-    Psd->SmmGdtSize = gcSmiGdtr.Limit + 1;\r
-\r
-    //\r
-    // Install SMI handler\r
-    //\r
     InstallSmiHandler (\r
       Index,\r
       (UINT32)mCpuHotPlugData.SmBase[Index],\r
       (VOID*)((UINTN)Stacks + (StackSize * Index)),\r
       StackSize,\r
-      (UINTN)Psd->SmmGdtPtr,\r
-      Psd->SmmGdtSize,\r
+      (UINTN)(GdtTssTables + GdtTableStepSize * Index),\r
+      gcSmiGdtr.Limit + 1,\r
       gcSmiIdtr.Base,\r
       gcSmiIdtr.Limit + 1,\r
       Cr3\r
@@ -1437,9 +1359,8 @@ InitializeMpServiceData (
   //\r
   // Record current MTRR settings\r
   //\r
-  ZeroMem(gSmiMtrrs, sizeof (gSmiMtrrs));\r
-  Mtrr =  (MTRR_SETTINGS*)gSmiMtrrs;\r
-  MtrrGetAllMtrrs (Mtrr);\r
+  ZeroMem (&gSmiMtrrs, sizeof (gSmiMtrrs));\r
+  MtrrGetAllMtrrs (&gSmiMtrrs);\r
 \r
   return Cr3;\r
 }\r