Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit afcc8a40 authored by Joerg Roedel's avatar Joerg Roedel
Browse files

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: default avatarJoerg Roedel <joro@8bytes.org>
Acked-by: default avatarSebastian Andrzej Siewior <sebastian@breakpoint.cc>
Reviewed-by: default avatarKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
parent 1c4248ca
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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_modify(unsigned int apic, unsigned int reg, unsigned int val);
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)
{
@@ -225,6 +227,7 @@ static inline void disable_ioapic_support(void) { }
#define native_io_apic_write		NULL
#define native_io_apic_modify		NULL
#define native_disable_io_apic		NULL
#define native_io_apic_print_entries	NULL
#endif

#endif /* _ASM_X86_IO_APIC_H */
+1 −0
Original line number Diff line number Diff line
@@ -195,6 +195,7 @@ struct x86_io_apic_ops {
	void		(*write)  (unsigned int apic, unsigned int reg, unsigned int value);
	void		(*modify) (unsigned int apic, unsigned int reg, unsigned int value);
	void		(*disable)(void);
	void		(*print_entries)(unsigned int apic, unsigned int nr_entries);
};

extern struct x86_init_ops x86_init;
+56 −53
Original line number Diff line number Diff line
@@ -1513,9 +1513,63 @@ static void __init setup_timer_IRQ0_pin(unsigned int ioapic_idx,
	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;

	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_01 reg_01;
	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");

	if (irq_remapping_enabled) {
		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
			);
		}
	}
	x86_io_apic_ops.print_entries(ioapic_idx, reg_01.bits.entries);
}

__apicdebuginit(void) print_IO_APICs(void)
+1 −0
Original line number Diff line number Diff line
@@ -123,4 +123,5 @@ struct x86_io_apic_ops x86_io_apic_ops = {
	.write			= native_io_apic_write,
	.modify			= native_io_apic_modify,
	.disable		= native_disable_io_apic,
	.print_entries		= native_io_apic_print_entries,
};
+8 −0
Original line number Diff line number Diff line
@@ -617,6 +617,14 @@ static int __init intel_enable_irq_remapping(void)
		goto error;

	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");

	return eim ? IRQ_REMAP_X2APIC_MODE : IRQ_REMAP_XAPIC_MODE;