1 /** 2 * @file op_apic.c 3 * 4 * APIC setup etc. routines 5 * 6 * @remark Copyright 2002 OProfile authors 7 * @remark Read the file COPYING 8 * 9 * @author John Levon 10 * @author Philippe Elie 11 * @author Dave Jones 12 * @author Graydon Hoare 13 */ 14 15 #include <linux/mm.h> 16 #include <linux/init.h> 17 #include <linux/config.h> 18 #include <asm/io.h> 19 20 #include "oprofile.h" 21 #include "op_msr.h" 22 #include "op_apic.h" 23 24 /* used to save/restore original kernel nmi */ 25 static struct gate_struct kernel_nmi; 26 static ulong lvtpc_masked; 27 28 /* this masking code is unsafe and nasty but might deal with the small 29 * race when installing the NMI entry into the IDT. 30 */ 31 static void mask_lvtpc(void * e) 32 { 33 u32 v = apic_read(APIC_LVTPC); 34 lvtpc_masked = v & APIC_LVT_MASKED; 35 apic_write(APIC_LVTPC, v | APIC_LVT_MASKED); 36 } 37 38 static void unmask_lvtpc(void * e) 39 { 40 if (!lvtpc_masked) 41 apic_write(APIC_LVTPC, apic_read(APIC_LVTPC) & ~APIC_LVT_MASKED); 42 } 43 44 45 void install_nmi(void) 46 { 47 struct _descr descr; 48 49 /* NMI handler is at idt_table[IDT_VECTOR_NUMBER] */ 50 /* see Intel Vol.3 Figure 5-2, interrupt gate */ 51 52 smp_call_function(mask_lvtpc, NULL, 0, 1); 53 mask_lvtpc(NULL); 54 55 store_idt(descr); 56 kernel_nmi = descr.base[NMI_VECTOR_NUM]; 57 SET_NMI_GATE; 58 59 smp_call_function(unmask_lvtpc, NULL, 0, 1); 60 unmask_lvtpc(NULL); 61 } 62 63 void restore_nmi(void) 64 { 65 struct _descr descr; 66 67 smp_call_function(mask_lvtpc, NULL, 0, 1); 68 mask_lvtpc(NULL); 69 70 store_idt(descr); 71 descr.base[NMI_VECTOR_NUM] = kernel_nmi; 72 73 smp_call_function(unmask_lvtpc, NULL, 0, 1); 74 unmask_lvtpc(NULL); 75 } 76 77 78 /* ---------------- APIC setup ------------------ */ 79 static uint saved_lvtpc[NR_CPUS]; 80 81 void __init lvtpc_apic_setup(void * dummy) 82 { 83 uint val; 84 85 /* set up LVTPC as we need it */ 86 /* IA32 V3, Figure 7.8 */ 87 val = apic_read(APIC_LVTPC); 88 saved_lvtpc[op_cpu_id()] = val; 89 /* allow PC overflow interrupts */ 90 val &= ~APIC_LVT_MASKED; 91 /* set delivery to NMI */ 92 val = SET_APIC_DELIVERY_MODE(val, APIC_MODE_NMI); 93 apic_write(APIC_LVTPC, val); 94 } 95 96 /* not safe to mark as __exit since used from __init code */ 97 void lvtpc_apic_restore(void * dummy) 98 { 99 /* restoring APIC_LVTPC can trigger an apic error because the delivery 100 * mode and vector nr combination can be illegal. That's by design: on 101 * power on apic lvt contain a zero vector nr which are legal only for 102 * NMI delivrey mode. So inhibit apic err before restoring lvtpc 103 */ 104 uint v = apic_read(APIC_LVTERR); 105 apic_write(APIC_LVTERR, v | APIC_LVT_MASKED); 106 apic_write(APIC_LVTPC, saved_lvtpc[op_cpu_id()]); 107 apic_write(APIC_LVTERR, v); 108 } 109 110 static int __init enable_apic(void) 111 { 112 uint msr_low, msr_high; 113 uint val; 114 115 /* enable local APIC via MSR. Forgetting this is a fun way to 116 * lock the box. But we have to hope this is allowed if the APIC 117 * has already been enabled. 118 * 119 * IA32 V3, 7.4.2 */ 120 rdmsr(MSR_IA32_APICBASE, msr_low, msr_high); 121 if ((msr_low & (1 << 11)) == 0) 122 wrmsr(MSR_IA32_APICBASE, msr_low | (1 << 11), msr_high); 123 124 /* even if the apic is up we must check for a good APIC */ 125 126 /* IA32 V3, 7.4.15 */ 127 val = apic_read(APIC_LVR); 128 if (!APIC_INTEGRATED(GET_APIC_VERSION(val))) 129 goto not_local_apic; 130 131 /* LVT0,LVT1,LVTT,LVTPC */ 132 if (GET_APIC_MAXLVT(apic_read(APIC_LVR)) < 4) 133 goto not_local_apic; 134 135 /* IA32 V3, 7.4.14.1 */ 136 val = apic_read(APIC_SPIV); 137 if (!(val & APIC_SPIV_APIC_ENABLED)) 138 apic_write(APIC_SPIV, val | APIC_SPIV_APIC_ENABLED); 139 140 return !!(val & APIC_SPIV_APIC_ENABLED); 141 142 not_local_apic: 143 /* disable the apic only if it was disabled */ 144 if ((msr_low & (1 << 11)) == 0) 145 wrmsr(MSR_IA32_APICBASE, msr_low & ~(1 << 11), msr_high); 146 147 printk(KERN_ERR "oprofile: no suitable local APIC. Falling back to RTC mode.\n"); 148 return -ENODEV; 149 } 150 151 static void __init do_apic_setup(void) 152 { 153 uint val; 154 155 local_irq_disable(); 156 157 val = APIC_LVT_LEVEL_TRIGGER; 158 val = SET_APIC_DELIVERY_MODE(val, APIC_MODE_EXINT); 159 apic_write(APIC_LVT0, val); 160 161 /* edge triggered, IA 7.4.11 */ 162 val = SET_APIC_DELIVERY_MODE(0, APIC_MODE_NMI); 163 apic_write(APIC_LVT1, val); 164 165 /* clear error register */ 166 /* IA32 V3, 7.4.17 */ 167 /* PHE must be cleared after unmasking by a back-to-back write, 168 * but it is probably ok because we mask only, the ESR is not 169 * updated is this a real problem ? */ 170 apic_write(APIC_ESR, 0); 171 172 /* mask error interrupt */ 173 /* IA32 V3, Figure 7.8 */ 174 val = apic_read(APIC_LVTERR); 175 val |= APIC_LVT_MASKED; 176 apic_write(APIC_LVTERR, val); 177 178 /* setup timer vector */ 179 /* IA32 V3, 7.4.8 */ 180 apic_write(APIC_LVTT, APIC_SEND_PENDING | 0x31); 181 182 /* Divide configuration register */ 183 /* PHE the apic clock is based on the FSB. This should only 184 * changed with a calibration method. */ 185 val = APIC_TDR_DIV_1; 186 apic_write(APIC_TDCR, val); 187 188 local_irq_enable(); 189 } 190 191 /* does the CPU have a local APIC ? */ 192 static int __init check_cpu_ok(void) 193 { 194 if (sysctl.cpu_type != CPU_PPRO && 195 sysctl.cpu_type != CPU_PII && 196 sysctl.cpu_type != CPU_PIII && 197 sysctl.cpu_type != CPU_ATHLON && 198 sysctl.cpu_type != CPU_HAMMER && 199 sysctl.cpu_type != CPU_P4 && 200 sysctl.cpu_type != CPU_P4_HT2) 201 return 0; 202 203 return 1; 204 } 205 206 int __init apic_setup(void) 207 { 208 u32 val; 209 210 if (!check_cpu_ok()) 211 goto nodev; 212 213 fixmap_setup(); 214 215 switch (enable_apic()) { 216 case 0: 217 do_apic_setup(); 218 val = apic_read(APIC_ESR); 219 printk(KERN_INFO "oprofile: enabled local APIC. Err code %.08x\n", val); 220 break; 221 case 1: 222 printk(KERN_INFO "oprofile: APIC was already enabled\n"); 223 break; 224 default: 225 goto nodev; 226 } 227 228 lvtpc_apic_setup(NULL); 229 return 0; 230 nodev: 231 printk(KERN_WARNING "Your CPU does not have a local APIC, e.g. " 232 "mobile P6. Falling back to RTC mode.\n"); 233 return -ENODEV; 234 } 235 236 void apic_restore(void) 237 { 238 fixmap_restore(); 239 } 240