From a0ed800376b0db57428f9bf6401db36789ff1aa6 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 4 Nov 2020 09:57:28 -0700 Subject: [PATCH] x86: Show the interrupt pointer with 'irqinfo' It is useful for this command to show the address of the interrupt table. Add support for this. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- arch/x86/cpu/i386/interrupt.c | 14 +++++++------- arch/x86/include/asm/interrupt.h | 17 +++++++++++++++++ arch/x86/lib/interrupts.c | 3 +++ 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/arch/x86/cpu/i386/interrupt.c b/arch/x86/cpu/i386/interrupt.c index c0c4bc9..d85f84b 100644 --- a/arch/x86/cpu/i386/interrupt.c +++ b/arch/x86/cpu/i386/interrupt.c @@ -180,16 +180,11 @@ struct idt_entry { u16 base_high; } __packed; -struct desc_ptr { - unsigned short size; - unsigned long address; -} __packed; - struct idt_entry idt[256] __aligned(16); -struct desc_ptr idt_ptr; +struct idt_ptr idt_ptr; -static inline void load_idt(const struct desc_ptr *dtr) +static inline void load_idt(const struct idt_ptr *dtr) { asm volatile("cs lidt %0" : : "m" (*dtr)); } @@ -232,6 +227,11 @@ int cpu_init_interrupts(void) return 0; } +void interrupt_read_idt(struct idt_ptr *ptr) +{ + asm volatile("sidt %0" : : "m" (*ptr)); +} + void *x86_get_idt(void) { return &idt_ptr; diff --git a/arch/x86/include/asm/interrupt.h b/arch/x86/include/asm/interrupt.h index fdeb857..e23fb2c 100644 --- a/arch/x86/include/asm/interrupt.h +++ b/arch/x86/include/asm/interrupt.h @@ -38,6 +38,16 @@ enum x86_exception { EXC_VE }; +/** + * struct idt_ptr - Holds the IDT (Interrupt Descriptor Table) + * + * @size: Size of IDT in bytes + */ +struct idt_ptr { + unsigned short size; + unsigned long address; +} __packed; + /* arch/x86/cpu/interrupts.c */ void set_vector(u8 intnum, void *routine); @@ -61,4 +71,11 @@ void configure_irq_trigger(int int_num, bool is_level_triggered); void *x86_get_idt(void); +/** + * interrupt_read_idt() - Read the IDT + * + * @ptr: Place to put IDT contents + */ +void interrupt_read_idt(struct idt_ptr *ptr); + #endif diff --git a/arch/x86/lib/interrupts.c b/arch/x86/lib/interrupts.c index a81e429..ff52959 100644 --- a/arch/x86/lib/interrupts.c +++ b/arch/x86/lib/interrupts.c @@ -131,8 +131,11 @@ void do_irq(int hw_irq) int do_irqinfo(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { #if !CONFIG_IS_ENABLED(X86_64) + struct idt_ptr ptr; int irq; + interrupt_read_idt(&ptr); + printf("IDT at %lx, size %x\n", ptr.address, ptr.size); printf("Spurious IRQ: %u, last unknown IRQ: %d\n", spurious_irq_cnt, spurious_irq); -- 2.7.4