x86: Show the interrupt pointer with 'irqinfo'
authorSimon Glass <sjg@chromium.org>
Wed, 4 Nov 2020 16:57:28 +0000 (09:57 -0700)
committerBin Meng <bmeng.cn@gmail.com>
Fri, 6 Nov 2020 01:51:29 +0000 (09:51 +0800)
It is useful for this command to show the address of the interrupt table.
Add support for this.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
arch/x86/cpu/i386/interrupt.c
arch/x86/include/asm/interrupt.h
arch/x86/lib/interrupts.c

index c0c4bc9..d85f84b 100644 (file)
@@ -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;
index fdeb857..e23fb2c 100644 (file)
@@ -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
index a81e429..ff52959 100644 (file)
@@ -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);