x86, io_apic: Introduce x86_io_apic_ops.print_entries for debugging
This call-back is used to dump IO-APIC entries for debugging purposes into the kernel log. VT-d needs a special routine for this and will overwrite the default. Signed-off-by: Joerg Roedel <joro@8bytes.org> Acked-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc> Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
This commit is contained in:
parent
1c4248ca4e
commit
afcc8a40a0
|
@ -180,6 +180,8 @@ extern unsigned int native_io_apic_read(unsigned int apic, unsigned int reg);
|
||||||
extern void native_io_apic_write(unsigned int apic, unsigned int reg, unsigned int val);
|
extern void native_io_apic_write(unsigned int apic, unsigned int reg, unsigned int val);
|
||||||
extern void native_io_apic_modify(unsigned int apic, unsigned int reg, unsigned int val);
|
extern void native_io_apic_modify(unsigned int apic, unsigned int reg, unsigned int val);
|
||||||
extern void native_disable_io_apic(void);
|
extern void native_disable_io_apic(void);
|
||||||
|
extern void native_io_apic_print_entries(unsigned int apic, unsigned int nr_entries);
|
||||||
|
extern void intel_ir_io_apic_print_entries(unsigned int apic, unsigned int nr_entries);
|
||||||
|
|
||||||
static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg)
|
static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg)
|
||||||
{
|
{
|
||||||
|
@ -225,6 +227,7 @@ static inline void disable_ioapic_support(void) { }
|
||||||
#define native_io_apic_write NULL
|
#define native_io_apic_write NULL
|
||||||
#define native_io_apic_modify NULL
|
#define native_io_apic_modify NULL
|
||||||
#define native_disable_io_apic NULL
|
#define native_disable_io_apic NULL
|
||||||
|
#define native_io_apic_print_entries NULL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _ASM_X86_IO_APIC_H */
|
#endif /* _ASM_X86_IO_APIC_H */
|
||||||
|
|
|
@ -195,6 +195,7 @@ struct x86_io_apic_ops {
|
||||||
void (*write) (unsigned int apic, unsigned int reg, unsigned int value);
|
void (*write) (unsigned int apic, unsigned int reg, unsigned int value);
|
||||||
void (*modify) (unsigned int apic, unsigned int reg, unsigned int value);
|
void (*modify) (unsigned int apic, unsigned int reg, unsigned int value);
|
||||||
void (*disable)(void);
|
void (*disable)(void);
|
||||||
|
void (*print_entries)(unsigned int apic, unsigned int nr_entries);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct x86_init_ops x86_init;
|
extern struct x86_init_ops x86_init;
|
||||||
|
|
|
@ -1513,9 +1513,63 @@ static void __init setup_timer_IRQ0_pin(unsigned int ioapic_idx,
|
||||||
ioapic_write_entry(ioapic_idx, pin, entry);
|
ioapic_write_entry(ioapic_idx, pin, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
__apicdebuginit(void) print_IO_APIC(int ioapic_idx)
|
void native_io_apic_print_entries(unsigned int apic, unsigned int nr_entries)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
pr_debug(" NR Dst Mask Trig IRR Pol Stat Dmod Deli Vect:\n");
|
||||||
|
|
||||||
|
for (i = 0; i <= nr_entries; i++) {
|
||||||
|
struct IO_APIC_route_entry entry;
|
||||||
|
|
||||||
|
entry = ioapic_read_entry(apic, i);
|
||||||
|
|
||||||
|
pr_debug(" %02x %02X ", i, entry.dest);
|
||||||
|
pr_cont("%1d %1d %1d %1d %1d "
|
||||||
|
"%1d %1d %02X\n",
|
||||||
|
entry.mask,
|
||||||
|
entry.trigger,
|
||||||
|
entry.irr,
|
||||||
|
entry.polarity,
|
||||||
|
entry.delivery_status,
|
||||||
|
entry.dest_mode,
|
||||||
|
entry.delivery_mode,
|
||||||
|
entry.vector);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void intel_ir_io_apic_print_entries(unsigned int apic,
|
||||||
|
unsigned int nr_entries)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
pr_debug(" NR Indx Fmt Mask Trig IRR Pol Stat Indx2 Zero Vect:\n");
|
||||||
|
|
||||||
|
for (i = 0; i <= nr_entries; i++) {
|
||||||
|
struct IR_IO_APIC_route_entry *ir_entry;
|
||||||
|
struct IO_APIC_route_entry entry;
|
||||||
|
|
||||||
|
entry = ioapic_read_entry(apic, i);
|
||||||
|
|
||||||
|
ir_entry = (struct IR_IO_APIC_route_entry *)&entry;
|
||||||
|
|
||||||
|
pr_debug(" %02x %04X ", i, ir_entry->index);
|
||||||
|
pr_cont("%1d %1d %1d %1d %1d "
|
||||||
|
"%1d %1d %X %02X\n",
|
||||||
|
ir_entry->format,
|
||||||
|
ir_entry->mask,
|
||||||
|
ir_entry->trigger,
|
||||||
|
ir_entry->irr,
|
||||||
|
ir_entry->polarity,
|
||||||
|
ir_entry->delivery_status,
|
||||||
|
ir_entry->index2,
|
||||||
|
ir_entry->zero,
|
||||||
|
ir_entry->vector);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__apicdebuginit(void) print_IO_APIC(int ioapic_idx)
|
||||||
|
{
|
||||||
union IO_APIC_reg_00 reg_00;
|
union IO_APIC_reg_00 reg_00;
|
||||||
union IO_APIC_reg_01 reg_01;
|
union IO_APIC_reg_01 reg_01;
|
||||||
union IO_APIC_reg_02 reg_02;
|
union IO_APIC_reg_02 reg_02;
|
||||||
|
@ -1568,58 +1622,7 @@ __apicdebuginit(void) print_IO_APIC(int ioapic_idx)
|
||||||
|
|
||||||
printk(KERN_DEBUG ".... IRQ redirection table:\n");
|
printk(KERN_DEBUG ".... IRQ redirection table:\n");
|
||||||
|
|
||||||
if (irq_remapping_enabled) {
|
x86_io_apic_ops.print_entries(ioapic_idx, reg_01.bits.entries);
|
||||||
printk(KERN_DEBUG " NR Indx Fmt Mask Trig IRR"
|
|
||||||
" Pol Stat Indx2 Zero Vect:\n");
|
|
||||||
} else {
|
|
||||||
printk(KERN_DEBUG " NR Dst Mask Trig IRR Pol"
|
|
||||||
" Stat Dmod Deli Vect:\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i <= reg_01.bits.entries; i++) {
|
|
||||||
if (irq_remapping_enabled) {
|
|
||||||
struct IO_APIC_route_entry entry;
|
|
||||||
struct IR_IO_APIC_route_entry *ir_entry;
|
|
||||||
|
|
||||||
entry = ioapic_read_entry(ioapic_idx, i);
|
|
||||||
ir_entry = (struct IR_IO_APIC_route_entry *) &entry;
|
|
||||||
printk(KERN_DEBUG " %02x %04X ",
|
|
||||||
i,
|
|
||||||
ir_entry->index
|
|
||||||
);
|
|
||||||
pr_cont("%1d %1d %1d %1d %1d "
|
|
||||||
"%1d %1d %X %02X\n",
|
|
||||||
ir_entry->format,
|
|
||||||
ir_entry->mask,
|
|
||||||
ir_entry->trigger,
|
|
||||||
ir_entry->irr,
|
|
||||||
ir_entry->polarity,
|
|
||||||
ir_entry->delivery_status,
|
|
||||||
ir_entry->index2,
|
|
||||||
ir_entry->zero,
|
|
||||||
ir_entry->vector
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
struct IO_APIC_route_entry entry;
|
|
||||||
|
|
||||||
entry = ioapic_read_entry(ioapic_idx, i);
|
|
||||||
printk(KERN_DEBUG " %02x %02X ",
|
|
||||||
i,
|
|
||||||
entry.dest
|
|
||||||
);
|
|
||||||
pr_cont("%1d %1d %1d %1d %1d "
|
|
||||||
"%1d %1d %02X\n",
|
|
||||||
entry.mask,
|
|
||||||
entry.trigger,
|
|
||||||
entry.irr,
|
|
||||||
entry.polarity,
|
|
||||||
entry.delivery_status,
|
|
||||||
entry.dest_mode,
|
|
||||||
entry.delivery_mode,
|
|
||||||
entry.vector
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
__apicdebuginit(void) print_IO_APICs(void)
|
__apicdebuginit(void) print_IO_APICs(void)
|
||||||
|
|
|
@ -123,4 +123,5 @@ struct x86_io_apic_ops x86_io_apic_ops = {
|
||||||
.write = native_io_apic_write,
|
.write = native_io_apic_write,
|
||||||
.modify = native_io_apic_modify,
|
.modify = native_io_apic_modify,
|
||||||
.disable = native_disable_io_apic,
|
.disable = native_disable_io_apic,
|
||||||
|
.print_entries = native_io_apic_print_entries,
|
||||||
};
|
};
|
||||||
|
|
|
@ -617,6 +617,14 @@ static int __init intel_enable_irq_remapping(void)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
irq_remapping_enabled = 1;
|
irq_remapping_enabled = 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* VT-d has a different layout for IO-APIC entries when
|
||||||
|
* interrupt remapping is enabled. So it needs a special routine
|
||||||
|
* to print IO-APIC entries for debugging purposes too.
|
||||||
|
*/
|
||||||
|
x86_io_apic_ops.print_entries = intel_ir_io_apic_print_entries;
|
||||||
|
|
||||||
pr_info("Enabled IRQ remapping in %s mode\n", eim ? "x2apic" : "xapic");
|
pr_info("Enabled IRQ remapping in %s mode\n", eim ? "x2apic" : "xapic");
|
||||||
|
|
||||||
return eim ? IRQ_REMAP_X2APIC_MODE : IRQ_REMAP_XAPIC_MODE;
|
return eim ? IRQ_REMAP_X2APIC_MODE : IRQ_REMAP_XAPIC_MODE;
|
||||||
|
|
Loading…
Reference in New Issue