]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdePkg/Library/BaseCacheMaintenanceLib/X86Cache.c
MdePkg UefiLib: Check Table against NULL in ScanTableInSDT
[mirror_edk2.git] / MdePkg / Library / BaseCacheMaintenanceLib / X86Cache.c
index 060a146ab0516777d4f8194d9eacfa5eb72938a1..42049144a4c782fbd0b47c98c9a514553da54df6 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Cache Maintenance Functions.\r
 \r
-  Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\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
 #include <Library/BaseLib.h>\r
 #include <Library/DebugLib.h>\r
 \r
-//\r
-// This size must be at or below the smallest cache size possible among all\r
-// supported processors\r
-//\r
-#define CACHE_LINE_SIZE             0x20\r
-\r
 /**\r
   Invalidates the entire instruction cache in cache coherency domain of the\r
   calling CPU.\r
@@ -128,6 +122,9 @@ WriteBackInvalidateDataCacheRange (
   IN      UINTN                     Length\r
   )\r
 {\r
+  UINT32                            RegEbx;\r
+  UINT32                            RegEdx;\r
+  UINTN                             CacheLineSize;\r
   UINTN                             Start;\r
   UINTN                             End;\r
 \r
@@ -137,15 +134,30 @@ WriteBackInvalidateDataCacheRange (
 \r
   ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Address));\r
 \r
+  //\r
+  // If the CPU does not support CLFLUSH instruction,\r
+  // then promote flush range to flush entire cache.\r
+  //\r
+  AsmCpuid (0x01, NULL, &RegEbx, NULL, &RegEdx);\r
+  if ((RegEdx & BIT19) == 0) {\r
+    AsmWbinvd ();\r
+    return Address;\r
+  }\r
+\r
+  //\r
+  // Cache line size is 8 * Bits 15-08 of EBX returned from CPUID 01H\r
+  //\r
+  CacheLineSize = (RegEbx & 0xff00) >> 5;\r
+\r
   Start = (UINTN)Address;\r
   //\r
   // Calculate the cache line alignment\r
-  // \r
-  End = (Start + Length + (CACHE_LINE_SIZE - 1)) & ~(CACHE_LINE_SIZE - 1);\r
-  Start &= ~(CACHE_LINE_SIZE - 1);\r
+  //\r
+  End = (Start + Length + (CacheLineSize - 1)) & ~(CacheLineSize - 1);\r
+  Start &= ~((UINTN)CacheLineSize - 1);\r
 \r
   do {\r
-    Start = (UINTN)AsmFlushCacheLine ((VOID*)Start) + CACHE_LINE_SIZE;\r
+    Start = (UINTN)AsmFlushCacheLine ((VOID*)Start) + CacheLineSize;\r
   } while (Start != End);\r
   return Address;\r
 }\r