| 64 | static int hw_clflush_disable = -1; |
| 65 | |
| 66 | static void |
| 67 | init_amd(void) |
| 68 | { |
| 69 | uint64_t msr; |
| 70 | |
| 71 | /* |
| 72 | * C1E renders the local APIC timer dead, so we disable it by |
| 73 | * reading the Interrupt Pending Message register and clearing |
| 74 | * both C1eOnCmpHalt (bit 28) and SmiOnCmpHalt (bit 27). |
| 75 | * |
| 76 | * Reference: |
| 77 | * "BIOS and Kernel Developer's Guide for AMD NPT Family 0Fh Processors" |
| 78 | * #32559 revision 3.00+ |
| 79 | * |
| 80 | * Detect the presence of C1E capability mostly on latest |
| 81 | * dual-cores (or future) k8 family. Affected models range is |
| 82 | * taken from Linux sources. |
| 83 | */ |
| 84 | if ((CPUID_TO_FAMILY(cpu_id) == 0xf || |
| 85 | CPUID_TO_FAMILY(cpu_id) == 0x10) && (cpu_feature2 & CPUID2_HV) == 0) |
| 86 | cpu_amdc1e_bug = 1; |
| 87 | |
| 88 | /* |
| 89 | * Work around Erratum 721 for Family 10h and 12h processors. |
| 90 | * These processors may incorrectly update the stack pointer |
| 91 | * after a long series of push and/or near-call instructions, |
| 92 | * or a long series of pop and/or near-return instructions. |
| 93 | * |
| 94 | * http://support.amd.com/us/Processor_TechDocs/41322_10h_Rev_Gd.pdf |
| 95 | * http://support.amd.com/us/Processor_TechDocs/44739_12h_Rev_Gd.pdf |
| 96 | * |
| 97 | * Hypervisors do not provide access to the errata MSR, |
| 98 | * causing #GP exception on attempt to apply the errata. The |
| 99 | * MSR write shall be done on host and persist globally |
| 100 | * anyway, so do not try to do it when under virtualization. |
| 101 | */ |
| 102 | switch (CPUID_TO_FAMILY(cpu_id)) { |
| 103 | case 0x10: |
| 104 | case 0x12: |
| 105 | if ((cpu_feature2 & CPUID2_HV) == 0) |
| 106 | wrmsr(MSR_DE_CFG, rdmsr(MSR_DE_CFG) | 1); |
| 107 | break; |
| 108 | } |
| 109 | |
| 110 | /* |
| 111 | * BIOS may fail to set InitApicIdCpuIdLo to 1 as it should per BKDG. |
| 112 | * So, do it here or otherwise some tools could be confused by |
| 113 | * Initial Local APIC ID reported with CPUID Function 1 in EBX. |
| 114 | */ |
| 115 | if (CPUID_TO_FAMILY(cpu_id) == 0x10) { |
| 116 | if ((cpu_feature2 & CPUID2_HV) == 0) { |
| 117 | msr = rdmsr(MSR_NB_CFG1); |
| 118 | msr |= (uint64_t)1 << 54; |
| 119 | wrmsr(MSR_NB_CFG1, msr); |
| 120 | } |
| 121 | } |
| 122 | |
| 123 | /* |
no test coverage detected