1 /** @file 2 3 Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR> 4 This program and the accompanying materials 5 are licensed and made available under the terms and conditions of the BSD License 6 which accompanies this distribution. The full text of the license may be found at 7 http://opensource.org/licenses/bsd-license.php. 8 9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11 12 **/ 13 14 #include <Uefi.h> 15 #include <Library/BaseLib.h> 16 #include <Library/CacheLib.h> 17 #include <Library/CacheAsRamLib.h> 18 #include "CacheLibInternal.h" 19 20 /** 21 Search the memory cache type for specific memory from MTRR. 22 23 @param[in] MemoryAddress the address of target memory 24 @param[in] MemoryLength the length of target memory 25 @param[in] ValidMtrrAddressMask the MTRR address mask 26 @param[out] UsedMsrNum the used MSR number 27 @param[out] UsedMemoryCacheType the cache type for the target memory 28 29 @retval EFI_SUCCESS The memory is found in MTRR and cache type is returned 30 @retval EFI_NOT_FOUND The memory is not found in MTRR 31 32 **/ 33 EFI_STATUS 34 SearchForExactMtrr ( 35 IN EFI_PHYSICAL_ADDRESS MemoryAddress, 36 IN UINT64 MemoryLength, 37 IN UINT64 ValidMtrrAddressMask, 38 OUT UINT32 *UsedMsrNum, 39 OUT EFI_MEMORY_CACHE_TYPE *MemoryCacheType 40 ); 41 42 /** 43 Check if CacheType match current default setting. 44 45 @param[in] MemoryCacheType input cache type to be checked. 46 47 @retval TRUE MemoryCacheType is default MTRR setting. 48 @retval FALSE MemoryCacheType is NOT default MTRR setting. 49 **/ 50 BOOLEAN 51 IsDefaultType ( 52 IN EFI_MEMORY_CACHE_TYPE MemoryCacheType 53 ); 54 55 /** 56 Return MTRR alignment requirement for base address and size. 57 58 @param[in] BaseAddress Base address. 59 @param[in] Size Size. 60 61 @retval Zero Alligned. 62 @retval Non-Zero Not alligned. 63 64 **/ 65 UINT32 66 CheckMtrrAlignment ( 67 IN UINT64 BaseAddress, 68 IN UINT64 Size 69 ); 70 71 typedef struct { 72 UINT32 Msr; 73 UINT32 BaseAddress; 74 UINT32 Length; 75 } EFI_FIXED_MTRR; 76 77 EFI_FIXED_MTRR mFixedMtrrTable[] = { 78 { EFI_MSR_IA32_MTRR_FIX64K_00000, 0, 0x10000}, 79 { EFI_MSR_IA32_MTRR_FIX16K_80000, 0x80000, 0x4000}, 80 { EFI_MSR_IA32_MTRR_FIX16K_A0000, 0xA0000, 0x4000}, 81 { EFI_MSR_IA32_MTRR_FIX4K_C0000, 0xC0000, 0x1000}, 82 { EFI_MSR_IA32_MTRR_FIX4K_C8000, 0xC8000, 0x1000}, 83 { EFI_MSR_IA32_MTRR_FIX4K_D0000, 0xD0000, 0x1000}, 84 { EFI_MSR_IA32_MTRR_FIX4K_D8000, 0xD8000, 0x1000}, 85 { EFI_MSR_IA32_MTRR_FIX4K_E0000, 0xE0000, 0x1000}, 86 { EFI_MSR_IA32_MTRR_FIX4K_E8000, 0xE8000, 0x1000}, 87 { EFI_MSR_IA32_MTRR_FIX4K_F0000, 0xF0000, 0x1000}, 88 { EFI_MSR_IA32_MTRR_FIX4K_F8000, 0xF8000, 0x1000} 89 }; 90 91 /** 92 Given the input, check if the number of MTRR is lesser. 93 if positive or subtractive. 94 95 @param[in] Input Length of Memory to program MTRR. 96 97 @retval Zero do positive. 98 @retval Non-Zero do subtractive. 99 100 **/ 101 INT8 102 CheckDirection ( 103 IN UINT64 Input 104 ) 105 { 106 return 0; 107 } 108 109 /** 110 Disable cache and its mtrr. 111 112 @param[out] OldMtrr To return the Old MTRR value 113 114 **/ 115 VOID 116 EfiDisableCacheMtrr ( 117 OUT UINT64 *OldMtrr 118 ) 119 { 120 UINT64 TempQword; 121 122 // 123 // Disable Cache MTRR 124 // 125 *OldMtrr = AsmReadMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE); 126 TempQword = (*OldMtrr) & ~B_EFI_MSR_GLOBAL_MTRR_ENABLE & ~B_EFI_MSR_FIXED_MTRR_ENABLE; 127 AsmWriteMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE, TempQword); 128 AsmDisableCache (); 129 } 130 131 /** 132 Recover cache MTRR. 133 134 @param[in] EnableMtrr Whether to enable the MTRR 135 @param[in] OldMtrr The saved old MTRR value to restore when not to enable the MTRR 136 137 **/ 138 VOID 139 EfiRecoverCacheMtrr ( 140 IN BOOLEAN EnableMtrr, 141 IN UINT64 OldMtrr 142 ) 143 { 144 UINT64 TempQword; 145 146 // 147 // Enable Cache MTRR 148 // 149 if (EnableMtrr) { 150 TempQword = AsmReadMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE); 151 TempQword |= (UINT64)(B_EFI_MSR_GLOBAL_MTRR_ENABLE | B_EFI_MSR_FIXED_MTRR_ENABLE); 152 } else { 153 TempQword = OldMtrr; 154 } 155 156 AsmWriteMsr64 (EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE, TempQword); 157 158 AsmEnableCache (); 159 } 160 161 /** 162 Programming MTRR according to Memory address, length, and type. 163 164 @param[in] MtrrNumber the variable MTRR index number 165 @param[in] MemoryAddress the address of target memory 166 @param[in] MemoryLength the length of target memory 167 @param[in] MemoryCacheType the cache type of target memory 168 @param[in] ValidMtrrAddressMask the MTRR address mask 169 170 **/ 171 VOID 172 EfiProgramMtrr ( 173 IN UINTN MtrrNumber, 174 IN EFI_PHYSICAL_ADDRESS MemoryAddress, 175 IN UINT64 MemoryLength, 176 IN EFI_MEMORY_CACHE_TYPE MemoryCacheType, 177 IN UINT64 ValidMtrrAddressMask 178 ) 179 { 180 UINT64 TempQword; 181 UINT64 OldMtrr; 182 183 if (MemoryLength == 0) { 184 return; 185 } 186 187 EfiDisableCacheMtrr (&OldMtrr); 188 189 // 190 // MTRR Physical Base 191 // 192 TempQword = (MemoryAddress & ValidMtrrAddressMask) | MemoryCacheType; 193 AsmWriteMsr64 (MtrrNumber, TempQword); 194 195 // 196 // MTRR Physical Mask 197 // 198 TempQword = ~(MemoryLength - 1); 199 AsmWriteMsr64 (MtrrNumber + 1, (TempQword & ValidMtrrAddressMask) | B_EFI_MSR_CACHE_MTRR_VALID); 200 201 EfiRecoverCacheMtrr (TRUE, OldMtrr); 202 } 203 204 /** 205 Calculate the maximum value which is a power of 2, but less the MemoryLength. 206 207 @param[in] MemoryAddress Memory address. 208 @param[in] MemoryLength The number to pass in. 209 210 @return The maximum value which is align to power of 2 and less the MemoryLength 211 212 **/ 213 UINT64 214 Power2MaxMemory ( 215 IN UINT64 MemoryAddress, 216 IN UINT64 MemoryLength 217 ) 218 { 219 UINT64 Result; 220 221 if (MemoryLength == 0) { 222 return EFI_INVALID_PARAMETER; 223 } 224 225 // 226 // Compute inital power of 2 size to return 227 // 228 Result = GetPowerOfTwo64(MemoryLength); 229 230 // 231 // Special case base of 0 as all ranges are valid 232 // 233 if (MemoryAddress == 0) { 234 return Result; 235 } 236 237 // 238 // Loop till a value that can be mapped to this base address is found 239 // 240 while (CheckMtrrAlignment (MemoryAddress, Result) != 0) { 241 // 242 // Need to try the next smaller power of 2 243 // 244 Result = RShiftU64 (Result, 1); 245 } 246 247 return Result; 248 } 249 250 /** 251 Return MTRR alignment requirement for base address and size. 252 253 @param[in] BaseAddress Base address. 254 @param[in] Size Size. 255 256 @retval Zero Alligned. 257 @retval Non-Zero Not alligned. 258 259 **/ 260 UINT32 261 CheckMtrrAlignment ( 262 IN UINT64 BaseAddress, 263 IN UINT64 Size 264 ) 265 { 266 UINT32 ShiftedBase; 267 UINT32 ShiftedSize; 268 269 // 270 // Shift base and size right 12 bits to allow for larger memory sizes. The 271 // MTRRs do not use the first 12 bits so this is safe for now. Only supports 272 // up to 52 bits of physical address space. 273 // 274 ShiftedBase = (UINT32) RShiftU64 (BaseAddress, 12); 275 ShiftedSize = (UINT32) RShiftU64 (Size, 12); 276 277 // 278 // Return the results to the caller of the MOD 279 // 280 return ShiftedBase % ShiftedSize; 281 } 282 283 /** 284 Programs fixed MTRRs registers. 285 286 @param[in] MemoryCacheType The memory type to set. 287 @param[in] Base The base address of memory range. 288 @param[in] Length The length of memory range. 289 290 @retval RETURN_SUCCESS The cache type was updated successfully 291 @retval RETURN_UNSUPPORTED The requested range or cache type was invalid 292 for the fixed MTRRs. 293 294 **/ 295 EFI_STATUS 296 ProgramFixedMtrr ( 297 IN EFI_MEMORY_CACHE_TYPE MemoryCacheType, 298 IN UINT64 *Base, 299 IN UINT64 *Len 300 ) 301 { 302 UINT32 MsrNum; 303 UINT32 ByteShift; 304 UINT64 TempQword; 305 UINT64 OrMask; 306 UINT64 ClearMask; 307 308 TempQword = 0; 309 OrMask = 0; 310 ClearMask = 0; 311 312 for (MsrNum = 0; MsrNum < V_EFI_FIXED_MTRR_NUMBER; MsrNum++) { 313 if ((*Base >= mFixedMtrrTable[MsrNum].BaseAddress) && 314 (*Base < (mFixedMtrrTable[MsrNum].BaseAddress + 8 * mFixedMtrrTable[MsrNum].Length))) { 315 break; 316 } 317 } 318 if (MsrNum == V_EFI_FIXED_MTRR_NUMBER ) { 319 return EFI_DEVICE_ERROR; 320 } 321 // 322 // We found the fixed MTRR to be programmed 323 // 324 for (ByteShift=0; ByteShift < 8; ByteShift++) { 325 if ( *Base == (mFixedMtrrTable[MsrNum].BaseAddress + ByteShift * mFixedMtrrTable[MsrNum].Length)) { 326 break; 327 } 328 } 329 if (ByteShift == 8 ) { 330 return EFI_DEVICE_ERROR; 331 } 332 for (; ((ByteShift<8) && (*Len >= mFixedMtrrTable[MsrNum].Length));ByteShift++) { 333 OrMask |= LShiftU64((UINT64) MemoryCacheType, (UINT32) (ByteShift* 8)); 334 ClearMask |= LShiftU64((UINT64) 0xFF, (UINT32) (ByteShift * 8)); 335 *Len -= mFixedMtrrTable[MsrNum].Length; 336 *Base += mFixedMtrrTable[MsrNum].Length; 337 } 338 TempQword = (AsmReadMsr64 (mFixedMtrrTable[MsrNum].Msr) & (~ClearMask)) | OrMask; 339 AsmWriteMsr64 (mFixedMtrrTable[MsrNum].Msr, TempQword); 340 341 return EFI_SUCCESS; 342 } 343 344 /** 345 Check if there is a valid variable MTRR that overlaps the given range. 346 347 @param[in] Start Base Address of the range to check. 348 @param[in] End End address of the range to check. 349 350 @retval TRUE Mtrr overlap. 351 @retval FALSE Mtrr not overlap. 352 **/ 353 BOOLEAN 354 CheckMtrrOverlap ( 355 IN EFI_PHYSICAL_ADDRESS Start, 356 IN EFI_PHYSICAL_ADDRESS End 357 ) 358 { 359 return FALSE; 360 } 361 362 /** 363 Given the memory range and cache type, programs the MTRRs. 364 365 @param[in] MemoryAddress Base Address of Memory to program MTRR. 366 @param[in] MemoryLength Length of Memory to program MTRR. 367 @param[in] MemoryCacheType Cache Type. 368 369 @retval EFI_SUCCESS Mtrr are set successfully. 370 @retval EFI_LOAD_ERROR No empty MTRRs to use. 371 @retval EFI_INVALID_PARAMETER The input parameter is not valid. 372 @retval others An error occurs when setting MTTR. 373 374 **/ 375 EFI_STATUS 376 EFIAPI 377 SetCacheAttributes ( 378 IN EFI_PHYSICAL_ADDRESS MemoryAddress, 379 IN UINT64 MemoryLength, 380 IN EFI_MEMORY_CACHE_TYPE MemoryCacheType 381 ) 382 { 383 EFI_STATUS Status; 384 UINT32 MsrNum, MsrNumEnd; 385 UINT64 TempQword; 386 UINT32 LastVariableMtrrForBios; 387 UINT64 OldMtrr; 388 UINT32 UsedMsrNum; 389 EFI_MEMORY_CACHE_TYPE UsedMemoryCacheType; 390 UINT64 ValidMtrrAddressMask; 391 UINT32 Cpuid_RegEax; 392 393 AsmCpuid (CPUID_EXTENDED_FUNCTION, &Cpuid_RegEax, NULL, NULL, NULL); 394 if (Cpuid_RegEax >= CPUID_VIR_PHY_ADDRESS_SIZE) { 395 AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &Cpuid_RegEax, NULL, NULL, NULL); 396 ValidMtrrAddressMask = (LShiftU64((UINT64) 1, (Cpuid_RegEax & 0xFF)) - 1) & (~(UINT64)0x0FFF); 397 } else { 398 ValidMtrrAddressMask = (LShiftU64((UINT64) 1, 36) - 1) & (~(UINT64)0x0FFF); 399 } 400 401 // 402 // Check for invalid parameter 403 // 404 if ((MemoryAddress & ~ValidMtrrAddressMask) != 0 || (MemoryLength & ~ValidMtrrAddressMask) != 0) { 405 return EFI_INVALID_PARAMETER; 406 } 407 408 if (MemoryLength == 0) { 409 return EFI_INVALID_PARAMETER; 410 } 411 412 switch (MemoryCacheType) { 413 case EFI_CACHE_UNCACHEABLE: 414 case EFI_CACHE_WRITECOMBINING: 415 case EFI_CACHE_WRITETHROUGH: 416 case EFI_CACHE_WRITEPROTECTED: 417 case EFI_CACHE_WRITEBACK: 418 break; 419 420 default: 421 return EFI_INVALID_PARAMETER; 422 } 423 424 // 425 // Check if Fixed MTRR 426 // 427 if ((MemoryAddress + MemoryLength) <= (1 << 20)) { 428 Status = EFI_SUCCESS; 429 EfiDisableCacheMtrr (&OldMtrr); 430 while ((MemoryLength > 0) && (Status == EFI_SUCCESS)) { 431 Status = ProgramFixedMtrr (MemoryCacheType, &MemoryAddress, &MemoryLength); 432 } 433 EfiRecoverCacheMtrr (TRUE, OldMtrr); 434 return Status; 435 } 436 437 // 438 // Search if the range attribute has been set before 439 // 440 Status = SearchForExactMtrr( 441 MemoryAddress, 442 MemoryLength, 443 ValidMtrrAddressMask, 444 &UsedMsrNum, 445 &UsedMemoryCacheType 446 ); 447 448 if (!EFI_ERROR(Status)) { 449 // 450 // Compare if it has the same type as current setting 451 // 452 if (UsedMemoryCacheType == MemoryCacheType) { 453 return EFI_SUCCESS; 454 } else { 455 // 456 // Different type 457 // 458 459 // 460 // Check if the set type is the same as Default Type 461 // 462 if (IsDefaultType(MemoryCacheType)) { 463 // 464 // Clear the MTRR 465 // 466 AsmWriteMsr64(UsedMsrNum, 0); 467 AsmWriteMsr64(UsedMsrNum + 1, 0); 468 469 return EFI_SUCCESS; 470 } else { 471 // 472 // Modify the MTRR type 473 // 474 EfiProgramMtrr(UsedMsrNum, 475 MemoryAddress, 476 MemoryLength, 477 MemoryCacheType, 478 ValidMtrrAddressMask 479 ); 480 return EFI_SUCCESS; 481 } 482 } 483 } 484 485 #if 0 486 // 487 // @bug - Need to create memory map so that when checking for overlap we 488 // can determine if an overlap exists based on all caching requests. 489 // 490 // Don't waste a variable MTRR if the caching attrib is same as default in MTRR_DEF_TYPE 491 // 492 if (MemoryCacheType == (AsmReadMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE) & B_EFI_MSR_CACHE_MEMORY_TYPE)) { 493 if (!CheckMtrrOverlap (MemoryAddress, MemoryAddress+MemoryLength-1)) { 494 return EFI_SUCCESS; 495 } 496 } 497 #endif 498 499 // 500 // Find first unused MTRR 501 // 502 MsrNumEnd = EFI_MSR_CACHE_VARIABLE_MTRR_BASE + (2 * (UINT32)(AsmReadMsr64(EFI_MSR_IA32_MTRR_CAP) & B_EFI_MSR_IA32_MTRR_CAP_VARIABLE_SUPPORT)); 503 for (MsrNum = EFI_MSR_CACHE_VARIABLE_MTRR_BASE; MsrNum < MsrNumEnd; MsrNum +=2) { 504 if ((AsmReadMsr64(MsrNum+1) & B_EFI_MSR_CACHE_MTRR_VALID) == 0 ) { 505 break; 506 } 507 } 508 509 // 510 // Reserve 1 MTRR pair for OS. 511 // 512 LastVariableMtrrForBios = MsrNumEnd - 1 - (EFI_CACHE_NUM_VAR_MTRR_PAIRS_FOR_OS * 2); 513 if (MsrNum > LastVariableMtrrForBios) { 514 return EFI_LOAD_ERROR; 515 } 516 517 // 518 // Special case for 1 MB base address 519 // 520 if (MemoryAddress == BASE_1MB) { 521 MemoryAddress = 0; 522 } 523 524 // 525 // Program MTRRs 526 // 527 TempQword = MemoryLength; 528 529 if (TempQword == Power2MaxMemory(MemoryAddress, TempQword)) { 530 EfiProgramMtrr(MsrNum, 531 MemoryAddress, 532 MemoryLength, 533 MemoryCacheType, 534 ValidMtrrAddressMask 535 ); 536 537 } else { 538 // 539 // Fill in MTRRs with values. Direction can not be checked for this method 540 // as we are using WB as the default cache type and only setting areas to UC. 541 // 542 do { 543 // 544 // Do boundary check so we don't go past last MTRR register 545 // for BIOS use. Leave one MTRR pair for OS use. 546 // 547 if (MsrNum > LastVariableMtrrForBios) { 548 return EFI_LOAD_ERROR; 549 } 550 551 // 552 // Set next power of 2 region 553 // 554 MemoryLength = Power2MaxMemory(MemoryAddress, TempQword); 555 EfiProgramMtrr(MsrNum, 556 MemoryAddress, 557 MemoryLength, 558 MemoryCacheType, 559 ValidMtrrAddressMask 560 ); 561 MemoryAddress += MemoryLength; 562 TempQword -= MemoryLength; 563 MsrNum += 2; 564 } while (TempQword != 0); 565 } 566 567 return EFI_SUCCESS; 568 } 569 570 /** 571 Reset all the MTRRs to a known state. 572 573 @retval EFI_SUCCESS All MTRRs have been reset successfully. 574 575 **/ 576 EFI_STATUS 577 EFIAPI 578 ResetCacheAttributes ( 579 VOID 580 ) 581 { 582 UINT32 MsrNum, MsrNumEnd; 583 UINT16 Index; 584 UINT64 OldMtrr; 585 UINT64 CacheType; 586 BOOLEAN DisableCar; 587 Index = 0; 588 DisableCar = TRUE; 589 590 // 591 // Determine default cache type 592 // 593 CacheType = EFI_CACHE_UNCACHEABLE; 594 595 // 596 // Set default cache type 597 // 598 AsmWriteMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE, CacheType); 599 600 // 601 // Disable CAR 602 // 603 DisableCacheAsRam (DisableCar); 604 605 EfiDisableCacheMtrr (&OldMtrr); 606 607 // 608 // Reset Fixed MTRRs 609 // 610 for (Index = 0; Index < V_EFI_FIXED_MTRR_NUMBER; Index++) { 611 AsmWriteMsr64 (mFixedMtrrTable[Index].Msr, 0); 612 } 613 614 // 615 // Reset Variable MTRRs 616 // 617 MsrNumEnd = EFI_MSR_CACHE_VARIABLE_MTRR_BASE + (2 * (UINT32)(AsmReadMsr64(EFI_MSR_IA32_MTRR_CAP) & B_EFI_MSR_IA32_MTRR_CAP_VARIABLE_SUPPORT)); 618 for (MsrNum = EFI_MSR_CACHE_VARIABLE_MTRR_BASE; MsrNum < MsrNumEnd; MsrNum++) { 619 AsmWriteMsr64 (MsrNum, 0); 620 } 621 622 // 623 // Enable Fixed and Variable MTRRs 624 // 625 EfiRecoverCacheMtrr (TRUE, OldMtrr); 626 627 return EFI_SUCCESS; 628 } 629 630 /** 631 Search the memory cache type for specific memory from MTRR. 632 633 @param[in] MemoryAddress the address of target memory 634 @param[in] MemoryLength the length of target memory 635 @param[in] ValidMtrrAddressMask the MTRR address mask 636 @param[out] UsedMsrNum the used MSR number 637 @param[out] UsedMemoryCacheType the cache type for the target memory 638 639 @retval EFI_SUCCESS The memory is found in MTRR and cache type is returned 640 @retval EFI_NOT_FOUND The memory is not found in MTRR 641 642 **/ 643 EFI_STATUS 644 SearchForExactMtrr ( 645 IN EFI_PHYSICAL_ADDRESS MemoryAddress, 646 IN UINT64 MemoryLength, 647 IN UINT64 ValidMtrrAddressMask, 648 OUT UINT32 *UsedMsrNum, 649 OUT EFI_MEMORY_CACHE_TYPE *UsedMemoryCacheType 650 ) 651 { 652 UINT32 MsrNum, MsrNumEnd; 653 UINT64 TempQword; 654 655 if (MemoryLength == 0) { 656 return EFI_INVALID_PARAMETER; 657 } 658 659 MsrNumEnd = EFI_MSR_CACHE_VARIABLE_MTRR_BASE + (2 * (UINT32)(AsmReadMsr64(EFI_MSR_IA32_MTRR_CAP) & B_EFI_MSR_IA32_MTRR_CAP_VARIABLE_SUPPORT)); 660 for (MsrNum = EFI_MSR_CACHE_VARIABLE_MTRR_BASE; MsrNum < MsrNumEnd; MsrNum +=2) { 661 TempQword = AsmReadMsr64(MsrNum+1); 662 if ((TempQword & B_EFI_MSR_CACHE_MTRR_VALID) == 0) { 663 continue; 664 } 665 666 if ((TempQword & ValidMtrrAddressMask) != ((~(MemoryLength - 1)) & ValidMtrrAddressMask)) { 667 continue; 668 } 669 670 TempQword = AsmReadMsr64 (MsrNum); 671 if ((TempQword & ValidMtrrAddressMask) != (MemoryAddress & ValidMtrrAddressMask)) { 672 continue; 673 } 674 675 *UsedMemoryCacheType = (EFI_MEMORY_CACHE_TYPE)(TempQword & B_EFI_MSR_CACHE_MEMORY_TYPE); 676 *UsedMsrNum = MsrNum; 677 678 return EFI_SUCCESS; 679 } 680 681 return EFI_NOT_FOUND; 682 } 683 684 /** 685 Check if CacheType match current default setting. 686 687 @param[in] MemoryCacheType input cache type to be checked. 688 689 @retval TRUE MemoryCacheType is default MTRR setting. 690 @retval TRUE MemoryCacheType is NOT default MTRR setting. 691 **/ 692 BOOLEAN 693 IsDefaultType ( 694 IN EFI_MEMORY_CACHE_TYPE MemoryCacheType 695 ) 696 { 697 if ((AsmReadMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE) & B_EFI_MSR_CACHE_MEMORY_TYPE) != MemoryCacheType) { 698 return FALSE; 699 } 700 701 return TRUE; 702 } 703 704