MdePkg/BaseCacheMaintenanceLib: Support IA32 processors without CLFLUSH

Use CPUID Leaf 01 to detect support for CLFLUSH instruction.  
If CLFLUSH is supported, use CPUID to determine the cache line size to use with CLFLUSH.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Michael Kinney <michael.d.kinney@intel.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>



git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17211 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Michael Kinney 2015-04-27 19:35:32 +00:00 committed by mdkinney
parent ff6955afb5
commit d2660fe32d
2 changed files with 25 additions and 13 deletions

View File

@ -4,7 +4,7 @@
# Cache Maintenance Library that uses Base Library services to maintain caches. # Cache Maintenance Library that uses Base Library services to maintain caches.
# This library assumes there are no chipset dependencies required to maintain caches. # This library assumes there are no chipset dependencies required to maintain caches.
# #
# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR> # Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>
# Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR> # Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
# #
# This program and the accompanying materials # This program and the accompanying materials
@ -23,7 +23,7 @@
MODULE_UNI_FILE = BaseCacheMaintenanceLib.uni MODULE_UNI_FILE = BaseCacheMaintenanceLib.uni
FILE_GUID = 123dd843-57c9-4158-8418-ce68b3944ce7 FILE_GUID = 123dd843-57c9-4158-8418-ce68b3944ce7
MODULE_TYPE = BASE MODULE_TYPE = BASE
VERSION_STRING = 1.0 VERSION_STRING = 1.1
LIBRARY_CLASS = CacheMaintenanceLib LIBRARY_CLASS = CacheMaintenanceLib

View File

@ -1,7 +1,7 @@
/** @file /** @file
Cache Maintenance Functions. Cache Maintenance Functions.
Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR> Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License 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 which accompanies this distribution. The full text of the license may be found at
@ -17,12 +17,6 @@
#include <Library/BaseLib.h> #include <Library/BaseLib.h>
#include <Library/DebugLib.h> #include <Library/DebugLib.h>
//
// This size must be at or below the smallest cache size possible among all
// supported processors
//
#define CACHE_LINE_SIZE 0x20
/** /**
Invalidates the entire instruction cache in cache coherency domain of the Invalidates the entire instruction cache in cache coherency domain of the
calling CPU. calling CPU.
@ -128,6 +122,9 @@ WriteBackInvalidateDataCacheRange (
IN UINTN Length IN UINTN Length
) )
{ {
UINT32 RegEbx;
UINT32 RegEdx;
UINTN CacheLineSize;
UINTN Start; UINTN Start;
UINTN End; UINTN End;
@ -137,15 +134,30 @@ WriteBackInvalidateDataCacheRange (
ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Address)); ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Address));
//
// If the CPU does not support CLFLUSH instruction,
// then promote flush range to flush entire cache.
//
AsmCpuid (0x01, NULL, &RegEbx, NULL, &RegEdx);
if ((RegEdx & BIT19) == 0) {
AsmWbinvd ();
return Address;
}
//
// Cache line size is 8 * Bits 15-08 of EBX returned from CPUID 01H
//
CacheLineSize = (RegEbx & 0xff00) >> 5;
Start = (UINTN)Address; Start = (UINTN)Address;
// //
// Calculate the cache line alignment // Calculate the cache line alignment
// //
End = (Start + Length + (CACHE_LINE_SIZE - 1)) & ~(CACHE_LINE_SIZE - 1); End = (Start + Length + (CacheLineSize - 1)) & ~(CacheLineSize - 1);
Start &= ~((UINTN) CACHE_LINE_SIZE - 1); Start &= ~((UINTN)CacheLineSize - 1);
do { do {
Start = (UINTN)AsmFlushCacheLine ((VOID*)Start) + CACHE_LINE_SIZE; Start = (UINTN)AsmFlushCacheLine ((VOID*)Start) + CacheLineSize;
} while (Start != End); } while (Start != End);
return Address; return Address;
} }