Newer
Older
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
* Note, this is not accurate accounting, but at least good enough to
* prevent that the actual interrupt move will run out of vectors.
*/
int lapic_can_unplug_cpu(void)
{
unsigned int rsvd, avl, tomove, cpu = smp_processor_id();
int ret = 0;
raw_spin_lock(&vector_lock);
tomove = irq_matrix_allocated(vector_matrix);
avl = irq_matrix_available(vector_matrix, true);
if (avl < tomove) {
pr_warn("CPU %u has %u vectors, %u available. Cannot disable CPU\n",
cpu, tomove, avl);
ret = -ENOSPC;
goto out;
}
rsvd = irq_matrix_reserved(vector_matrix);
if (avl < rsvd) {
pr_warn("Reserved vectors %u > available %u. IRQ request may fail\n",
rsvd, avl);
}
out:
raw_spin_unlock(&vector_lock);
return ret;
}
#endif /* HOTPLUG_CPU */
#endif /* SMP */
static void __init print_APIC_field(int base)
{
int i;
printk(KERN_DEBUG);
for (i = 0; i < 8; i++)
pr_cont("%08x", apic_read(base + i*0x10));
pr_cont("\n");
}
static void __init print_local_APIC(void *dummy)
{
unsigned int i, v, ver, maxlvt;
u64 icr;
pr_debug("printing local APIC contents on CPU#%d/%d:\n",
smp_processor_id(), hard_smp_processor_id());
v = apic_read(APIC_ID);
pr_info("... APIC ID: %08x (%01x)\n", v, read_apic_id());
v = apic_read(APIC_LVR);
pr_info("... APIC VERSION: %08x\n", v);
ver = GET_APIC_VERSION(v);
maxlvt = lapic_get_maxlvt();
v = apic_read(APIC_TASKPRI);
pr_debug("... APIC TASKPRI: %08x (%02x)\n", v, v & APIC_TPRI_MASK);
/* !82489DX */
if (APIC_INTEGRATED(ver)) {
if (!APIC_XAPIC(ver)) {
v = apic_read(APIC_ARBPRI);
pr_debug("... APIC ARBPRI: %08x (%02x)\n",
v, v & APIC_ARBPRI_MASK);
}
v = apic_read(APIC_PROCPRI);
pr_debug("... APIC PROCPRI: %08x\n", v);
}
/*
* Remote read supported only in the 82489DX and local APIC for
* Pentium processors.
*/
if (!APIC_INTEGRATED(ver) || maxlvt == 3) {
v = apic_read(APIC_RRR);
pr_debug("... APIC RRR: %08x\n", v);
}
v = apic_read(APIC_LDR);
pr_debug("... APIC LDR: %08x\n", v);
if (!x2apic_enabled()) {
v = apic_read(APIC_DFR);
pr_debug("... APIC DFR: %08x\n", v);
}
v = apic_read(APIC_SPIV);
pr_debug("... APIC SPIV: %08x\n", v);
pr_debug("... APIC ISR field:\n");
print_APIC_field(APIC_ISR);
pr_debug("... APIC TMR field:\n");
print_APIC_field(APIC_TMR);
pr_debug("... APIC IRR field:\n");
print_APIC_field(APIC_IRR);
/* !82489DX */
if (APIC_INTEGRATED(ver)) {
/* Due to the Pentium erratum 3AP. */
if (maxlvt > 3)
apic_write(APIC_ESR, 0);
v = apic_read(APIC_ESR);
pr_debug("... APIC ESR: %08x\n", v);
}
icr = apic_icr_read();
pr_debug("... APIC ICR: %08x\n", (u32)icr);
pr_debug("... APIC ICR2: %08x\n", (u32)(icr >> 32));
v = apic_read(APIC_LVTT);
pr_debug("... APIC LVTT: %08x\n", v);
if (maxlvt > 3) {
/* PC is LVT#4. */
v = apic_read(APIC_LVTPC);
pr_debug("... APIC LVTPC: %08x\n", v);
}
v = apic_read(APIC_LVT0);
pr_debug("... APIC LVT0: %08x\n", v);
v = apic_read(APIC_LVT1);
pr_debug("... APIC LVT1: %08x\n", v);
if (maxlvt > 2) {
/* ERR is LVT#3. */
v = apic_read(APIC_LVTERR);
pr_debug("... APIC LVTERR: %08x\n", v);
}
v = apic_read(APIC_TMICT);
pr_debug("... APIC TMICT: %08x\n", v);
v = apic_read(APIC_TMCCT);
pr_debug("... APIC TMCCT: %08x\n", v);
v = apic_read(APIC_TDCR);
pr_debug("... APIC TDCR: %08x\n", v);
if (boot_cpu_has(X86_FEATURE_EXTAPIC)) {
v = apic_read(APIC_EFEAT);
maxlvt = (v >> 16) & 0xff;
pr_debug("... APIC EFEAT: %08x\n", v);
v = apic_read(APIC_ECTRL);
pr_debug("... APIC ECTRL: %08x\n", v);
for (i = 0; i < maxlvt; i++) {
v = apic_read(APIC_EILVTn(i));
pr_debug("... APIC EILVT%d: %08x\n", i, v);
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
}
}
pr_cont("\n");
}
static void __init print_local_APICs(int maxcpu)
{
int cpu;
if (!maxcpu)
return;
preempt_disable();
for_each_online_cpu(cpu) {
if (cpu >= maxcpu)
break;
smp_call_function_single(cpu, print_local_APIC, NULL, 1);
}
preempt_enable();
}
static void __init print_PIC(void)
{
unsigned int v;
unsigned long flags;
if (!nr_legacy_irqs())
return;
pr_debug("\nprinting PIC contents\n");
raw_spin_lock_irqsave(&i8259A_lock, flags);
v = inb(0xa1) << 8 | inb(0x21);
pr_debug("... PIC IMR: %04x\n", v);
v = inb(0xa0) << 8 | inb(0x20);
pr_debug("... PIC IRR: %04x\n", v);
outb(0x0b, 0xa0);
outb(0x0b, 0x20);
v = inb(0xa0) << 8 | inb(0x20);
outb(0x0a, 0xa0);
outb(0x0a, 0x20);
raw_spin_unlock_irqrestore(&i8259A_lock, flags);
pr_debug("... PIC ISR: %04x\n", v);
v = inb(0x4d1) << 8 | inb(0x4d0);
pr_debug("... PIC ELCR: %04x\n", v);
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
}
static int show_lapic __initdata = 1;
static __init int setup_show_lapic(char *arg)
{
int num = -1;
if (strcmp(arg, "all") == 0) {
show_lapic = CONFIG_NR_CPUS;
} else {
get_option(&arg, &num);
if (num >= 0)
show_lapic = num;
}
return 1;
}
__setup("show_lapic=", setup_show_lapic);
static int __init print_ICs(void)
{
if (apic_verbosity == APIC_QUIET)
return 0;
print_PIC();
/* don't print out if apic is not there */
if (!boot_cpu_has(X86_FEATURE_APIC) && !apic_from_smp_config())