* See if we should monitor CMCI for this bank. If CMCI_EN is already * set in MC_CTL2, then another CPU is responsible for this bank, so * ignore it. If CMCI_EN returns zero after being set, then this bank * does not support CMCI_EN. If this CPU sets CMCI_EN, then it should * now monitor this bank. */
| 1063 | * now monitor this bank. |
| 1064 | */ |
| 1065 | static void |
| 1066 | cmci_monitor(int i) |
| 1067 | { |
| 1068 | struct cmc_state *cc; |
| 1069 | uint64_t ctl; |
| 1070 | |
| 1071 | KASSERT(i < mca_banks, ("CPU %d has more MC banks", PCPU_GET(cpuid))); |
| 1072 | |
| 1073 | /* |
| 1074 | * It is possible for some APs to report CMCI support even if the BSP |
| 1075 | * does not, apparently due to a BIOS bug. |
| 1076 | */ |
| 1077 | if (cmc_state == NULL) { |
| 1078 | if (bootverbose) { |
| 1079 | printf( |
| 1080 | "AP %d (%d,%d) reports CMCI support but the BSP does not\n", |
| 1081 | PCPU_GET(cpuid), PCPU_GET(apic_id), |
| 1082 | PCPU_GET(acpi_id)); |
| 1083 | } |
| 1084 | return; |
| 1085 | } |
| 1086 | |
| 1087 | ctl = rdmsr(MSR_MC_CTL2(i)); |
| 1088 | if (ctl & MC_CTL2_CMCI_EN) |
| 1089 | /* Already monitored by another CPU. */ |
| 1090 | return; |
| 1091 | |
| 1092 | /* Set the threshold to one event for now. */ |
| 1093 | ctl &= ~MC_CTL2_THRESHOLD; |
| 1094 | ctl |= MC_CTL2_CMCI_EN | 1; |
| 1095 | wrmsr(MSR_MC_CTL2(i), ctl); |
| 1096 | ctl = rdmsr(MSR_MC_CTL2(i)); |
| 1097 | if (!(ctl & MC_CTL2_CMCI_EN)) |
| 1098 | /* This bank does not support CMCI. */ |
| 1099 | return; |
| 1100 | |
| 1101 | cc = &cmc_state[PCPU_GET(cpuid)][i]; |
| 1102 | |
| 1103 | /* Determine maximum threshold. */ |
| 1104 | ctl &= ~MC_CTL2_THRESHOLD; |
| 1105 | ctl |= 0x7fff; |
| 1106 | wrmsr(MSR_MC_CTL2(i), ctl); |
| 1107 | ctl = rdmsr(MSR_MC_CTL2(i)); |
| 1108 | cc->max_threshold = ctl & MC_CTL2_THRESHOLD; |
| 1109 | |
| 1110 | /* Start off with a threshold of 1. */ |
| 1111 | ctl &= ~MC_CTL2_THRESHOLD; |
| 1112 | ctl |= 1; |
| 1113 | wrmsr(MSR_MC_CTL2(i), ctl); |
| 1114 | |
| 1115 | /* Mark this bank as monitored. */ |
| 1116 | PCPU_SET(cmci_mask, PCPU_GET(cmci_mask) | 1 << i); |
| 1117 | } |
| 1118 | |
| 1119 | /* |
| 1120 | * For resume, reset the threshold for any banks we monitor back to |