223 UINT8 *BlockClearFunc;
229 UINT8 *LocationSnow32;
230 UINT8 *LocationTigerTsc;
231 UINT8 *LocationTigerTscEnd;
234 BOOLEAN IsTigerTscInit;
235 BOOLEAN IsTigerTscInitOld;
255 LocationSnow32 = NULL;
256 LocationTigerTsc = NULL;
257 LocationTigerTscEnd = NULL;
263 Status =
PatcherGetSymbolAddress (Patcher, IsTiger ?
"_cpuid_get_info" :
"_cpuid_set_info", (UINT8 **)&Record);
264 if (EFI_ERROR (Status) || (Record >= Last)) {
265 DEBUG ((DEBUG_WARN,
"OCAK: [FAIL] Failed to locate _cpuid_%a_info (%p) - %r\n", IsTiger ?
"get" :
"set", Record, Status));
266 return EFI_NOT_FOUND;
285 STATIC CONST UINT8 mKernelCpuidFindPatchTigerStart[4] = {
290 STATIC CONST UINT8 mKernelCpuidFindPatchLeoSnowLionStruct32[2] = {
295 STATIC CONST UINT8 mKernelCpuidFindPatchLeoSnowLionStart32[5] = {
296 0x04, 0x00, 0x00, 0x00,
300 STATIC CONST UINT8 mKernelCpuidFindPatchSnowStart64[8] = {
301 0xBA, 0x04, 0x00, 0x00, 0x00,
305 if (Patcher->Is32Bit) {
307 for (Index = 0; Index < EFI_PAGE_SIZE; Index++, Record++) {
308 if ( (Record[0] == mKernelCpuidFindPatchTigerStart[0])
309 && (Record[1] == mKernelCpuidFindPatchTigerStart[1])
310 && (Record[2] == mKernelCpuidFindPatchTigerStart[2])
311 && (Record[3] == mKernelCpuidFindPatchTigerStart[3]))
321 if (EFI_ERROR (Status) || (Record >= Last)) {
322 DEBUG ((DEBUG_WARN,
"OCAK: [FAIL] Failed to locate %a (%p) - %r\n", IsLion ?
"_bzero" :
"_blkclr", Record, Status));
323 return EFI_NOT_FOUND;
329 for (Index = 0; Index < EFI_PAGE_SIZE; Index++, Record++) {
330 if ( (Record[0] == mKernelCpuidFindPatchLeoSnowLionStruct32[0])
331 && (Record[1] == mKernelCpuidFindPatchLeoSnowLionStruct32[1])
332 && (*((INT32 *)&Record[2]) == (INT32)(BlockClearFunc - (Record +
sizeof (mKernelCpuidFindPatchLeoSnowLionStruct32) +
sizeof (UINT32)))))
338 if (Index >= EFI_PAGE_SIZE) {
339 return EFI_NOT_FOUND;
342 StructAddr = *((UINT32 *)(Record - 3));
344 for (Index = 0; Index < EFI_PAGE_SIZE; Index++, Record++) {
345 if ( (Record[0] == mKernelCpuidFindPatchLeoSnowLionStart32[0])
346 && (Record[1] == mKernelCpuidFindPatchLeoSnowLionStart32[1])
347 && (Record[2] == mKernelCpuidFindPatchLeoSnowLionStart32[2])
348 && (Record[3] == mKernelCpuidFindPatchLeoSnowLionStart32[3])
349 && (Record[4] == mKernelCpuidFindPatchLeoSnowLionStart32[4]))
356 for (Index = 0; Index < EFI_PAGE_SIZE; Index++, Record++) {
357 if ( (Record[0] == mKernelCpuidFindPatchSnowStart64[0])
358 && (Record[1] == mKernelCpuidFindPatchSnowStart64[1])
359 && (Record[2] == mKernelCpuidFindPatchSnowStart64[2])
360 && (Record[3] == mKernelCpuidFindPatchSnowStart64[3])
361 && (Record[4] == mKernelCpuidFindPatchSnowStart64[4])
362 && (Record[5] == mKernelCpuidFindPatchSnowStart64[5])
363 && (Record[6] == mKernelCpuidFindPatchSnowStart64[6])
364 && (Record[7] == mKernelCpuidFindPatchSnowStart64[7]))
371 if (Index >= EFI_PAGE_SIZE) {
372 return EFI_NOT_FOUND;
375 if (Patcher->Is32Bit) {
376 StartPointer = IsTiger ? Record : Record - 4;
378 StartPointer = Record +
sizeof (mKernelCpuidFindPatchSnowStart64) +
sizeof (UINT32);
384 STATIC CONST UINT8 mKernelCpuidFindPatchTigerEnd[4] = {
390 STATIC UINT8 mKernelCpuidFindPatchSnowLionEnd32[7] = {
391 0xC6, 0x05, 0xFF, 0xFF, 0xFF, 0xFF, 0x00
393 STATIC UINT32 *mKernelCpuidFindPatchSnowLionEndPtr32 = (UINT32 *)&mKernelCpuidFindPatchSnowLionEnd32[2];
395 *mKernelCpuidFindPatchSnowLionEndPtr32 = StructAddr +
sizeof (
Signature[0]) * 3;
397 STATIC CONST UINT8 mKernelCpuidFindPatchLeoEnd1[5] = {
398 0xB8, 0x00, 0x00, 0x00, 0x80
400 STATIC CONST UINT8 mKernelCpuidFindPatchLeoEnd1Mask = 0xFD;
403 for (Index = 0; Index < EFI_PAGE_SIZE; Index++, Record++) {
404 if ( (Record[0] == mKernelCpuidFindPatchTigerEnd[0])
405 && (Record[1] == mKernelCpuidFindPatchTigerEnd[1])
406 && (Record[2] == mKernelCpuidFindPatchTigerEnd[2])
407 && (Record[3] == mKernelCpuidFindPatchTigerEnd[3]))
412 }
else if ((IsSnow || IsLion) && Patcher->Is32Bit) {
413 for (Index = 0; Index < EFI_PAGE_SIZE; Index++, Record++) {
414 if ( (Record[0] == mKernelCpuidFindPatchSnowLionEnd32[0])
415 && (Record[1] == mKernelCpuidFindPatchSnowLionEnd32[1])
416 && (Record[2] == mKernelCpuidFindPatchSnowLionEnd32[2])
417 && (Record[3] == mKernelCpuidFindPatchSnowLionEnd32[3])
418 && (Record[4] == mKernelCpuidFindPatchSnowLionEnd32[4])
419 && (Record[5] == mKernelCpuidFindPatchSnowLionEnd32[5])
420 && (Record[6] == mKernelCpuidFindPatchSnowLionEnd32[6]))
426 for (Index = 0; Index < EFI_PAGE_SIZE; Index++, Record++) {
427 if ( ((Record[0] & mKernelCpuidFindPatchLeoEnd1Mask) == mKernelCpuidFindPatchLeoEnd1[0])
428 && (Record[1] == mKernelCpuidFindPatchLeoEnd1[1])
429 && (Record[2] == mKernelCpuidFindPatchLeoEnd1[2])
430 && (Record[3] == mKernelCpuidFindPatchLeoEnd1[3])
431 && (Record[4] == mKernelCpuidFindPatchLeoEnd1[4]))
438 if (Index >= EFI_PAGE_SIZE) {
439 return EFI_NOT_FOUND;
442 if (IsSnow && !Patcher->Is32Bit) {
443 STATIC CONST UINT8 mKernelCpuidFindPatchLeoEnd2[3] = {
448 for ( ; Index < EFI_PAGE_SIZE; Index++, Record++) {
449 if ( (Record[0] == mKernelCpuidFindPatchLeoEnd2[0])
450 && (Record[1] == mKernelCpuidFindPatchLeoEnd2[1])
451 && (Record[2] == mKernelCpuidFindPatchLeoEnd2[2]))
457 if (Index >= EFI_PAGE_SIZE) {
458 return EFI_NOT_FOUND;
462 EndPointer = IsTiger ? Record - 3 : Record;
476 STATIC CONST UINT8 mKernelCpuidFindLocLeoTigerStart[7] = {
477 0xB9, 0x01, 0x00, 0x00, 0x00,
481 STATIC CONST UINT8 mKernelCpuidFindLocSnowStart[5] = {
482 0xB8, 0x01, 0x00, 0x00, 0x00
485 STATIC CONST UINT8 mKernelCpuidFindLocSnowStart32[6] = {
486 0xE8, 0xFF, 0xFF, 0xFF, 0xFF,
490 STATIC CONST UINT8 mKernelCpuidFindLocLionStart32[8] = {
491 0xB9, 0x01, 0x00, 0x00, 0x00,
495 if (IsTiger || IsLeopard) {
496 for ( ; Index < EFI_PAGE_SIZE; Index++, Record++) {
497 if ( (Record[0] == mKernelCpuidFindLocLeoTigerStart[0])
498 && (Record[1] == mKernelCpuidFindLocLeoTigerStart[1])
499 && (Record[2] == mKernelCpuidFindLocLeoTigerStart[2])
500 && (Record[3] == mKernelCpuidFindLocLeoTigerStart[3])
501 && (Record[4] == mKernelCpuidFindLocLeoTigerStart[4])
502 && (Record[5] == mKernelCpuidFindLocLeoTigerStart[5])
503 && (Record[6] == mKernelCpuidFindLocLeoTigerStart[6]))
509 for ( ; Index < EFI_PAGE_SIZE; Index++, Record++) {
510 if ( (Record[0] == mKernelCpuidFindLocSnowStart[0])
511 && (Record[1] == mKernelCpuidFindLocSnowStart[1])
512 && (Record[2] == mKernelCpuidFindLocSnowStart[2])
513 && (Record[3] == mKernelCpuidFindLocSnowStart[3])
514 && (Record[4] == mKernelCpuidFindLocSnowStart[4]))
520 if (Index >= EFI_PAGE_SIZE) {
521 return EFI_NOT_FOUND;
528 if (Patcher->Is32Bit) {
529 for ( ; Index < EFI_PAGE_SIZE; Index++, Record++) {
530 if ( (Record[0] == mKernelCpuidFindLocSnowStart32[0])
531 && (Record[5] == mKernelCpuidFindLocSnowStart32[5]))
537 if (Index >= EFI_PAGE_SIZE) {
538 return EFI_NOT_FOUND;
541 LocationSnow32 = Record;
543 for ( ; Index < EFI_PAGE_SIZE; Index++, Record++) {
544 if ( (Record[0] == mKernelCpuidFindLocSnowStart[0])
545 && (Record[1] == mKernelCpuidFindLocSnowStart[1])
546 && (Record[2] == mKernelCpuidFindLocSnowStart[2])
547 && (Record[3] == mKernelCpuidFindLocSnowStart[3])
548 && (Record[4] == mKernelCpuidFindLocSnowStart[4]))
555 for ( ; Index < EFI_PAGE_SIZE; Index++, Record++) {
556 if ( (Record[0] == mKernelCpuidFindLocLionStart32[0])
557 && (Record[1] == mKernelCpuidFindLocLionStart32[1])
558 && (Record[2] == mKernelCpuidFindLocLionStart32[2])
559 && (Record[3] == mKernelCpuidFindLocLionStart32[3])
560 && (Record[4] == mKernelCpuidFindLocLionStart32[4])
561 && (Record[5] == mKernelCpuidFindLocLionStart32[5])
562 && (Record[6] == mKernelCpuidFindLocLionStart32[6])
563 && (Record[7] == mKernelCpuidFindLocLionStart32[7]))
570 if (Index >= EFI_PAGE_SIZE) {
571 return EFI_NOT_FOUND;
574 Location = IsLion ? Record +
sizeof (mKernelCpuidFindLocLionStart32) : Record;
579 STATIC CONST UINT8 mKernelCpuidFindLegacyLocEnd[3] = {
585 for ( ; Index < EFI_PAGE_SIZE; Index++, Record++) {
586 if ( (Record[0] == mKernelCpuidFindLegacyLocEnd[0])
587 && (Record[1] == mKernelCpuidFindLegacyLocEnd[1])
588 && (Record[2] == mKernelCpuidFindLegacyLocEnd[2]))
594 if (Index >= EFI_PAGE_SIZE) {
595 return EFI_NOT_FOUND;
598 LocationEnd = Record + 2;
600 LocationEnd = Location;
611 if (IsTigerTscInit || IsTigerTscInitOld) {
613 if (EFI_ERROR (Status) || (Record >= Last)) {
614 DEBUG ((DEBUG_WARN,
"OCAK: [FAIL] Failed to locate _tsc_init (%p) - %r\n", Record, Status));
615 return EFI_NOT_FOUND;
618 if (IsTigerTscInit) {
625 STATIC CONST UINT8 mKernelCpuidFindTscLocTigerStart[7] = {
626 0xBA, 0x01, 0x00, 0x00, 0x00,
630 for (Index = 0; Index < EFI_PAGE_SIZE; Index++, Record++) {
631 if ( (Record[0] == mKernelCpuidFindTscLocTigerStart[0])
632 && (Record[1] == mKernelCpuidFindTscLocTigerStart[1])
633 && (Record[2] == mKernelCpuidFindTscLocTigerStart[2])
634 && (Record[3] == mKernelCpuidFindTscLocTigerStart[3])
635 && (Record[4] == mKernelCpuidFindTscLocTigerStart[4])
636 && (Record[5] == mKernelCpuidFindTscLocTigerStart[5])
637 && (Record[6] == mKernelCpuidFindTscLocTigerStart[6]))
649 STATIC CONST UINT8 mKernelCpuidFindTscLocTigerOldStart[7] = {
650 0xB8, 0x01, 0x00, 0x00, 0x00,
654 for (Index = 0; Index < EFI_PAGE_SIZE; Index++, Record++) {
655 if ( (Record[0] == mKernelCpuidFindTscLocTigerOldStart[0])
656 && (Record[1] == mKernelCpuidFindTscLocTigerOldStart[1])
657 && (Record[2] == mKernelCpuidFindTscLocTigerOldStart[2])
658 && (Record[3] == mKernelCpuidFindTscLocTigerOldStart[3])
659 && (Record[4] == mKernelCpuidFindTscLocTigerOldStart[4])
660 && (Record[5] == mKernelCpuidFindTscLocTigerOldStart[5])
661 && (Record[6] == mKernelCpuidFindTscLocTigerOldStart[6]))
668 if (Index >= EFI_PAGE_SIZE) {
669 return EFI_NOT_FOUND;
672 LocationTigerTsc = Record;
677 for ( ; Index < EFI_PAGE_SIZE; Index++, Record++) {
678 if ( (Record[0] == mKernelCpuidFindLegacyLocEnd[0])
679 && (Record[1] == mKernelCpuidFindLegacyLocEnd[1])
680 && (Record[2] == mKernelCpuidFindLegacyLocEnd[2]))
686 if (Index >= EFI_PAGE_SIZE) {
687 return EFI_NOT_FOUND;
690 LocationTigerTscEnd = Record + 2;
695 "OCAK: Legacy CPUID patch %p:%p, loc %p:%p, tsc loc %p:%p, struct @ 0x%X\n",
696 StartPointer -
Start,
700 (IsTigerTscInit || IsTigerTscInitOld) ? LocationTigerTsc -
Start : 0,
701 (IsTigerTscInit || IsTigerTscInitOld) ? LocationTigerTscEnd -
Start : 0,
708 if (IsSnow && !Patcher->Is32Bit) {
709 AsmCpuid (0x80000000, &MaxExt, NULL, NULL, NULL);
710 EndPointer[0] = 0xB8;
711 CopyMem (&EndPointer[1], &MaxExt,
sizeof (MaxExt));
720 for (Index = 0; Index < 3; ++Index) {
724 *StartPointer++ = 0xB8;
728 if (IsLeopard || ((IsSnow || IsLion) && Patcher->Is32Bit)) {
732 *StartPointer++ = 0xA3;
733 CopyMem (StartPointer, &StructAddr,
sizeof (StructAddr));
734 StartPointer +=
sizeof (StructAddr);
736 }
else if (IsTiger) {
740 *StartPointer++ = 0x89;
741 *StartPointer++ = 0x46;
742 *StartPointer++ = (UINT8)(Index *
sizeof (
Signature[0]));
747 *StartPointer++ = 0x89;
748 *StartPointer++ = 0x06;
754 *StartPointer++ = 0x48;
755 *StartPointer++ = 0x83;
756 *StartPointer++ = 0xC6;
757 *StartPointer++ = 0x04;
766 if ( (StartPointer >= EndPointer)
767 || (EndPointer - StartPointer > 128)
770 return EFI_OUT_OF_RESOURCES;
776 StartPointer[0] = 0xEB;
777 StartPointer[1] = (UINT8)(EndPointer - StartPointer - 2);
783 if ( (CpuInfo->CpuidVerEcx.Bits.XSAVE != 0)
784 && (CpuInfo->CpuidVerEcx.Bits.OSXSAVE == 0)
785 && (CpuInfo->CpuidVerEcx.Bits.AVX != 0))
787 CpuInfo->CpuidVerEcx.Bits.OSXSAVE = 1;
793 if (IsSnow && Patcher->Is32Bit) {
794 while (LocationSnow32 < LocationEnd) {
795 *LocationSnow32++ = 0x90;
802 Delta = (INT32)(StartPointer - (Location + 5));
804 CopyMem (Location, &Delta,
sizeof (Delta));
805 Location +=
sizeof (Delta);
806 while (Location < LocationEnd) {
814 if (IsTigerTscInit || IsTigerTscInitOld) {
815 Delta = (INT32)(StartPointer - (LocationTigerTsc + 5));
816 *LocationTigerTsc++ = 0xE8;
817 CopyMem (LocationTigerTsc, &Delta,
sizeof (Delta));
818 LocationTigerTsc +=
sizeof (Delta);
819 while (LocationTigerTsc < LocationTigerTscEnd) {
820 *LocationTigerTsc++ = 0x90;
830 Patch.
EaxVal = (Data[0] & DataMask[0]) | (CpuInfo->CpuidVerEax.Uint32 & ~DataMask[0]);
832 Patch.
EbxVal = (Data[1] & DataMask[1]) | (CpuInfo->CpuidVerEbx.Uint32 & ~DataMask[1]);
834 Patch.
EcxVal = (Data[2] & DataMask[2]) | (CpuInfo->CpuidVerEcx.Uint32 & ~DataMask[2]);
835 Patch.
EdxCmd = IsLion ? 0xBE : 0xBA;
836 Patch.
EdxVal = (Data[3] & DataMask[3]) | (CpuInfo->CpuidVerEdx.Uint32 & ~DataMask[3]);
837 CopyMem (StartPointer, &Patch,
sizeof (Patch));
838 StartPointer +=
sizeof (Patch);
847 *StartPointer++ = 0x89;
848 *StartPointer++ = 0x02;
852 *StartPointer++ = 0x89;
853 *StartPointer++ = 0x5A;
854 *StartPointer++ = 0x04;
858 *StartPointer++ = 0x89;
859 *StartPointer++ = 0x4A;
860 *StartPointer++ = 0x08;
864 *StartPointer++ = 0x89;
865 *StartPointer++ = 0x72;
866 *StartPointer++ = 0x0C;
872 *StartPointer++ = 0xC3;
874 DEBUG ((DEBUG_INFO,
"OCAK: [OK] Legacy CPUID patch completed @ %p\n", StartPointer -
Start));
1578 UINT64 TscInitFuncSymAddr;
1579 UINT64 BusFreqSymAddr;
1580 UINT64 BusFCvtt2nSymAddr;
1581 UINT64 BusFCvtn2tSymAddr;
1582 UINT64 TscFreqSymAddr;
1583 UINT64 TscFCvtt2nSymAddr;
1584 UINT64 TscFCvtn2tSymAddr;
1585 UINT64 TscGranularitySymAddr;
1586 UINT64 Bus2TscSymAddr;
1590 UINT64 busFreqValue;
1591 UINT64 busFCvtt2nValue;
1592 UINT64 busFCvtn2tValue;
1593 UINT64 tscFreqValue;
1594 UINT64 tscFCvtt2nValue;
1595 UINT64 tscFCvtn2tValue;
1596 UINT64 tscGranularityValue;
1598 BOOLEAN IsLeaf4CacheSupported;
1603 BOOLEAN IsSnowLeopard;
1604 BOOLEAN IsTigerCacheUnsupported;
1605 UINT8 *LocationTigerCache;
1606 UINT8 *LocationTigerCacheEnd;
1609 CPUID_CACHE_PARAMS_EAX CpuidCacheParamsEax;
1610 CPUID_CACHE_PARAMS_EBX CpuidCacheParamsEbx;
1611 CPUID_CACHE_INFO_CACHE_TLB CpuidCacheInfo[4];
1612 UINT8 CpuidCacheDescriptors[64];
1617 UINT32 CacheLineSize;
1619 BOOLEAN CacheDescriptorFound;
1621 UINT32 CacheDescriptorSize;
1623 UINT32 msrCoreThreadCount;
1625 ASSERT (Patcher != NULL);
1627 LocationTigerCache = NULL;
1628 LocationTigerCacheEnd = NULL;
1633 IsLeaf4CacheSupported = CpuInfo->MaxId >= CPUID_CACHE_PARAMS;
1644 IsTigerCacheUnsupported = (IsTigerOld || IsTigerNew) && IsLeaf4CacheSupported;
1646 Status = EFI_SUCCESS;
1677 if (EFI_ERROR (Status)) {
1678 DEBUG ((DEBUG_WARN,
"OCAK: [FAIL] Failed to locate one or more TSC symbols - %r\n", Status));
1679 return EFI_NOT_FOUND;
1686 if ((CpuInfo->Family == 0xF) && ((CpuInfo->ExtFamily == 0x8) || (CpuInfo->ExtFamily == 0xA) || (CpuInfo->ExtFamily == 0xB))) {
1687 DEBUG ((DEBUG_INFO,
"OCAK: Setting FSB and TSC for Family 0x%x and ExtFamily 0x%x\n", (UINT16)CpuInfo->Family, (UINT16)CpuInfo->ExtFamily));
1688 busFreqValue = CpuInfo->FSBFrequency;
1691 if (busFreqValue == 0) {
1692 busFreqValue = 100000000;
1693 DEBUG ((DEBUG_WARN,
"OCAK: FSBFrequency is zero, using fallback value: 100 MHz\n"));
1699 tscFreqValue = CpuInfo->CPUFrequency;
1705 busFreqValue = CpuInfo->FSBFrequency;
1709 tscFreqValue = CpuInfo->CPUFrequency;
1716 DEBUG ((DEBUG_INFO,
"OCAK: BusFreq = %LuHz, BusFCvtt2n = %Lu, BusFCvtn2t = %Lu\n", busFreqValue, busFCvtt2nValue, busFCvtn2tValue));
1717 DEBUG ((DEBUG_INFO,
"OCAK: TscFreq = %LuHz, TscFCvtt2n = %Lu, TscFCvtn2t = %Lu\n", tscFreqValue, tscFCvtt2nValue, tscFCvtn2tValue));
1722 TscLocation = TscInitFunc;
1725 TscLocation =
PatchMovVar (TscLocation, Patcher->Is32Bit, &TscInitFuncSymAddr, BusFreqSymAddr, busFreqValue);
1728 TscLocation =
PatchMovVar (TscLocation, Patcher->Is32Bit, &TscInitFuncSymAddr, BusFCvtt2nSymAddr, busFCvtt2nValue);
1729 TscLocation =
PatchMovVar (TscLocation, Patcher->Is32Bit, &TscInitFuncSymAddr, BusFCvtn2tSymAddr, busFCvtn2tValue);
1730 TscLocation =
PatchMovVar (TscLocation, Patcher->Is32Bit, &TscInitFuncSymAddr, TscFreqSymAddr, tscFreqValue);
1731 TscLocation =
PatchMovVar (TscLocation, Patcher->Is32Bit, &TscInitFuncSymAddr, TscFCvtt2nSymAddr, tscFCvtt2nValue);
1732 TscLocation =
PatchMovVar (TscLocation, Patcher->Is32Bit, &TscInitFuncSymAddr, TscFCvtn2tSymAddr, tscFCvtn2tValue);
1733 TscLocation =
PatchMovVar (TscLocation, Patcher->Is32Bit, &TscInitFuncSymAddr, TscGranularitySymAddr, tscGranularityValue);
1735 if (Patcher->Is32Bit) {
1740 *TscLocation++ = 0x55;
1741 *TscLocation++ = 0x89;
1742 *TscLocation++ = 0xE5;
1744 ValueLower = (UINT32)busFreqValue;
1745 ValueUpper = (UINT32)(busFreqValue >> 32);
1750 *TscLocation++ = 0xB8;
1751 CopyMem (TscLocation, &ValueLower,
sizeof (ValueLower));
1752 TscLocation +=
sizeof (ValueLower);
1757 *TscLocation++ = 0x50;
1762 *TscLocation++ = 0xB8;
1763 CopyMem (TscLocation, &ValueUpper,
sizeof (ValueUpper));
1764 TscLocation +=
sizeof (ValueUpper);
1769 *TscLocation++ = 0x50;
1771 ValueLower = (UINT32)tscFreqValue;
1772 ValueUpper = (UINT32)(tscFreqValue >> 32);
1777 *TscLocation++ = 0xB8;
1778 CopyMem (TscLocation, &ValueLower,
sizeof (ValueLower));
1779 TscLocation +=
sizeof (ValueLower);
1784 *TscLocation++ = 0x50;
1789 *TscLocation++ = 0xB8;
1790 CopyMem (TscLocation, &ValueUpper,
sizeof (ValueUpper));
1791 TscLocation +=
sizeof (ValueUpper);
1796 *TscLocation++ = 0x50;
1801 Delta = (INT32)(TmrCvtFunc - (TscLocation + 5));
1802 *TscLocation++ = 0xE8;
1803 CopyMem (TscLocation, &Delta,
sizeof (Delta));
1804 TscLocation +=
sizeof (Delta);
1809 VarAddr32 = (UINT32)(Bus2TscSymAddr);
1810 *TscLocation++ = 0xA3;
1811 CopyMem (TscLocation, &VarAddr32,
sizeof (VarAddr32));
1812 TscLocation +=
sizeof (VarAddr32);
1817 VarAddr32 +=
sizeof (UINT32);
1818 *TscLocation++ = 0x89;
1819 *TscLocation++ = 0x15;
1820 CopyMem (TscLocation, &VarAddr32,
sizeof (VarAddr32));
1821 TscLocation +=
sizeof (VarAddr32);
1827 *TscLocation++ = 0x58;
1828 *TscLocation++ = 0x58;
1829 *TscLocation++ = 0x58;
1830 *TscLocation++ = 0x58;
1831 *TscLocation++ = 0xC9;
1836 *TscLocation++ = 0x48;
1837 *TscLocation++ = 0xBF;
1838 CopyMem (TscLocation, &busFreqValue,
sizeof (busFreqValue));
1839 TscLocation +=
sizeof (busFreqValue);
1840 TscInitFuncSymAddr +=
sizeof (busFreqValue) + 2;
1845 *TscLocation++ = 0x48;
1846 *TscLocation++ = 0xBE;
1847 CopyMem (TscLocation, &tscFreqValue,
sizeof (tscFreqValue));
1848 TscLocation +=
sizeof (tscFreqValue);
1849 TscInitFuncSymAddr +=
sizeof (tscFreqValue) + 2;
1854 Delta = (INT32)(TmrCvtFunc - (TscLocation + 5));
1855 *TscLocation++ = 0xE8;
1856 CopyMem (TscLocation, &Delta,
sizeof (Delta));
1857 TscLocation +=
sizeof (Delta);
1858 TscInitFuncSymAddr +=
sizeof (Delta) + 1;
1863 Delta = (INT32)(Bus2TscSymAddr - (TscInitFuncSymAddr + 7));
1865 *TscLocation++ = 0x48;
1866 *TscLocation++ = 0x89;
1867 *TscLocation++ = 0x05;
1868 CopyMem (TscLocation, &Delta,
sizeof (Delta));
1869 TscLocation +=
sizeof (Delta);
1875 *TscLocation++ = 0xC3;
1881 if (IsTigerCacheUnsupported) {
1883 if (EFI_ERROR (Status) || (Record >= Last)) {
1884 DEBUG ((DEBUG_WARN,
"OCAK: [FAIL] Failed to locate _cpuid_info (%p) - %r\n", Record, Status));
1885 return EFI_NOT_FOUND;
1892 STATIC CONST UINT8 mKernelCpuidFindCacheLocTigerStart[9] = {
1902 STATIC CONST UINT8 mKernelCpuidFindCacheLocTigerEnd[5] = {
1908 for (Index = 0; Index < EFI_PAGE_SIZE; Index++, Record++) {
1909 if ( (Record[0] == mKernelCpuidFindCacheLocTigerStart[0])
1910 && (Record[1] == mKernelCpuidFindCacheLocTigerStart[1])
1911 && (Record[2] == mKernelCpuidFindCacheLocTigerStart[2])
1912 && (Record[3] == mKernelCpuidFindCacheLocTigerStart[3])
1913 && (Record[4] == mKernelCpuidFindCacheLocTigerStart[4])
1914 && (Record[5] == mKernelCpuidFindCacheLocTigerStart[5])
1915 && (Record[6] == mKernelCpuidFindCacheLocTigerStart[6])
1916 && (Record[7] == mKernelCpuidFindCacheLocTigerStart[7])
1917 && (Record[8] == mKernelCpuidFindCacheLocTigerStart[8]))
1923 if (Index >= EFI_PAGE_SIZE) {
1924 return EFI_NOT_FOUND;
1927 LocationTigerCache = Record + 3;
1929 for ( ; Index < EFI_PAGE_SIZE; Index++, Record++) {
1930 if ( (Record[0] == mKernelCpuidFindCacheLocTigerEnd[0])
1931 && (Record[1] == mKernelCpuidFindCacheLocTigerEnd[1])
1932 && (Record[2] == mKernelCpuidFindCacheLocTigerEnd[2])
1933 && (Record[3] == mKernelCpuidFindCacheLocTigerEnd[3])
1934 && (Record[4] == mKernelCpuidFindCacheLocTigerEnd[4]))
1940 if (Index >= EFI_PAGE_SIZE) {
1941 return EFI_NOT_FOUND;
1944 LocationTigerCacheEnd = Record;
1948 "OCAK: CPU info cache loc %p:%p\n",
1949 LocationTigerCache -
Start,
1950 LocationTigerCacheEnd -
Start
1953 ZeroMem (CacheLineSizes,
sizeof (CacheLineSizes));
1960 AsmCpuidEx (CPUID_CACHE_PARAMS, Index, &CpuidCacheParamsEax.Uint32, &CpuidCacheParamsEbx.Uint32, &CacheSets, NULL);
1961 if (CpuidCacheParamsEax.Bits.CacheType == 0) {
1965 switch (CpuidCacheParamsEax.Bits.CacheLevel) {
1967 CacheType = (CpuidCacheParamsEax.Bits.CacheType == 1) ?
L1D :
1968 (CpuidCacheParamsEax.Bits.CacheType == 2) ?
L1I :
1973 CacheType = (CpuidCacheParamsEax.Bits.CacheType == 3) ?
L2U :
1978 CacheType = (CpuidCacheParamsEax.Bits.CacheType == 3) ?
L3U :
1986 if (CacheType !=
Lnone) {
1987 CacheSizes[CacheType] = (CpuidCacheParamsEbx.Bits.LineSize + 1) * (CacheSets + 1) * (CpuidCacheParamsEbx.Bits.Ways + 1);
1988 CacheLineSizes[CacheType] = CpuidCacheParamsEbx.Bits.LineSize + 1;
1994 if (CacheLineSizes[
L2U]) {
1995 CacheLineSize = CacheLineSizes[
L2U];
1996 }
else if (CacheLineSizes[
L1D]) {
1997 CacheLineSize = CacheLineSizes[
L1D];
2002 DEBUG ((DEBUG_WARN,
"OCAK: [FAIL] Unable to determine CPU cache line size\n"));
2003 return EFI_UNSUPPORTED;
2011 *LocationTigerCache++ = 0xC7;
2012 *LocationTigerCache++ = 0x40;
2013 *LocationTigerCache++ = 0x68 + ((UINT8)(
sizeof (UINT32) * Index));
2014 CopyMem (LocationTigerCache, &CacheSizes[Index],
sizeof (CacheSizes[Index]));
2015 LocationTigerCache +=
sizeof (CacheSizes[Index]);
2016 DEBUG ((DEBUG_INFO,
"OCAK: Cache size (L%u): %u bytes\n", (Index >= 3) ? (Index - 1) : 1, CacheSizes[Index]));
2023 *LocationTigerCache++ = 0xC7;
2024 *LocationTigerCache++ = 0x40;
2025 *LocationTigerCache++ = 0x7C;
2026 CopyMem (LocationTigerCache, &CacheLineSize,
sizeof (CacheLineSize));
2027 LocationTigerCache +=
sizeof (CacheLineSize);
2028 DEBUG ((DEBUG_INFO,
"OCAK: Cache line size: %u bytes\n", CacheLineSize));
2030 while (LocationTigerCache < LocationTigerCacheEnd) {
2031 *LocationTigerCache++ = 0x90;
2039 if (Patcher->Is32Bit && !IsLeaf4CacheSupported && (IsLeopard || IsSnowLeopard)) {
2040 ZeroMem (CpuidCacheDescriptors,
sizeof (CpuidCacheDescriptors));
2041 ZeroMem (CacheSizes,
sizeof (CacheSizes));
2042 ZeroMem (CacheSharings,
sizeof (CacheSharings));
2043 AsmCpuid (CPUID_CACHE_INFO, &CpuidCacheInfo[0].Uint32, &CpuidCacheInfo[1].Uint32, &CpuidCacheInfo[2].Uint32, &CpuidCacheInfo[3].Uint32);
2045 for (Index = 0; Index < 4; Index++) {
2046 if (CpuidCacheInfo[Index].Bits.NotValid) {
2050 ((UINT32 *)CpuidCacheDescriptors)[Index] = CpuidCacheInfo[Index].Uint32;
2053 for (Index = 1; Index < CpuidCacheDescriptors[0]; Index++) {
2054 if ((Index * 16) >
sizeof (CpuidCacheDescriptors)) {
2058 AsmCpuid (CPUID_CACHE_INFO, &CpuidCacheInfo[0].Uint32, &CpuidCacheInfo[1].Uint32, &CpuidCacheInfo[2].Uint32, &CpuidCacheInfo[3].Uint32);
2060 for (Index2 = 0; Index2 < 4; Index2++) {
2061 if (CpuidCacheInfo[Index2].Bits.NotValid) {
2065 ((UINT32 *)CpuidCacheDescriptors)[
sizeof (UINT32) * Index * Index2] = CpuidCacheInfo[Index2].Uint32;
2072 for (Index = 0; Index <
sizeof (CpuidCacheDescriptors); Index++) {
2073 CacheDescriptorFound = FALSE;
2078 CacheDescriptorFound = TRUE;
2083 if (!CacheDescriptorFound) {
2087 CacheSizes[CacheDescriptorType] = CacheDescriptorSize;
2088 CacheSharings[CacheDescriptorType] = 1;
2091 DEBUG ((DEBUG_INFO,
"OCAK: Caches L1I: %u, L1D: %u, L2: %u, L3: %u\n", CacheSizes[
L1I], CacheSizes[
L1D], CacheSizes[
L2U], CacheSizes[
L3U]));
2097 CacheSize =
MAX (CacheSharings[
L1I], CacheSharings[
L1D]);
2113 &CacheSharings[
L2U],
2126 &CacheSharings[
L3U],
2137 CacheSize =
MAX (CacheSizes[
L1I], CacheSizes[
L1D]);
2177 CacheSize =
MAX (CacheSharings[
L1I], CacheSharings[
L1D]);
2193 &CacheSharings[
L2U],
2206 &CacheSharings[
L3U],
2217 CacheSize =
MAX (CacheSizes[
L1I], CacheSizes[
L1D]);
2255 if (EFI_ERROR (Status)) {
2256 DEBUG ((DEBUG_WARN,
"OCAK: [FAIL] Failed to patch or more areas in _sysctl_mib_init - %r\n", Status));
2257 return EFI_NOT_FOUND;
2274 msrCoreThreadCount = (CpuInfo->CoreCount << 16) | CpuInfo->ThreadCount;
2278 &msrCoreThreadCount,
2279 sizeof (msrCoreThreadCount)
2286 if (EFI_ERROR (Status)) {
2287 DEBUG ((DEBUG_INFO,
"OCAK: [FAIL] Failed to find CPU MSR 0x35 default value patch - %r\n", Status));
2290 DEBUG ((DEBUG_INFO,
"OCAK: [OK] Skipping CPU MSR 0x35 default value patch on %u\n",
KernelVersion));
2301 if (EFI_ERROR (Status)) {
2302 DEBUG ((DEBUG_INFO,
"OCAK: [FAIL] Failed to find CPU topology validation patch - %r\n", Status));
2305 DEBUG ((DEBUG_INFO,
"OCAK: [OK] Skipping CPU topology validation patch on %u\n",
KernelVersion));