This slightly delays when we setup the idt.  But by doing it in C
things are noticeably simpler. 

Signed-off-by: Eric W. Biederman <[EMAIL PROTECTED]>
---
 arch/i386/kernel/head.S   |   68 +++-----------------------------------------
 arch/i386/kernel/head32.c |   26 +++++++++++++++++
 2 files changed, 31 insertions(+), 63 deletions(-)

diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S
index 22ddb3f..0ee615b 100644
--- a/arch/i386/kernel/head.S
+++ b/arch/i386/kernel/head.S
@@ -197,19 +197,6 @@ ENTRY(startup_32_smp)
        pushl $0
        popfl
 
-#ifdef CONFIG_SMP
-       cmpb $0, ready
-       jz  1f                          /* Initial CPU cleans BSS */
-       jmp checkCPUtype
-1:
-#endif /* CONFIG_SMP */
-
-/*
- * start system 32-bit setup. We need to re-do some of the things done
- * in 16-bit mode for the "real" operations.
- */
-       call setup_idt
-
 checkCPUtype:
 
        movl $-1,X86_CPUID              #  -1 for no CPUID initially
@@ -274,7 +261,6 @@ is386:      movl $2,%ecx            # set MP
 
        call check_x87
        lgdt early_gdt_descr
-       lidt idt_descr
        ljmp $(__KERNEL_CS),$1f
 1:     movl $(__KERNEL_DS),%eax        # reload all the segment registers
        movl %eax,%ss                   # after changing gdt.
@@ -321,65 +307,21 @@ check_x87:
        .byte 0xDB,0xE4         /* fsetpm for 287, ignored by 387 */
        ret
 
-/*
- *  setup_idt
- *
- *  sets up a idt with 256 entries pointing to
- *  ignore_int, interrupt gates. It doesn't actually load
- *  idt - that can be done only after paging has been enabled
- *  and the kernel moved to PAGE_OFFSET. Interrupts
- *  are enabled elsewhere, when we can be relatively
- *  sure everything is ok.
- *
- *  Warning: %esi is live across this function.
- */
-setup_idt:
-       lea ignore_int,%edx
-       movl $(__KERNEL_CS << 16),%eax
-       movw %dx,%ax            /* selector = 0x0010 = cs */
-       movw $0x8E00,%dx        /* interrupt gate - dpl=0, present */
-
-       lea idt_table,%edi
-       mov $256,%ecx
-rp_sidt:
-       movl %eax,(%edi)
-       movl %edx,4(%edi)
-       addl $8,%edi
-       dec %ecx
-       jne rp_sidt
-
-.macro set_early_handler handler,trapno
-       lea \handler,%edx
-       movl $(__KERNEL_CS << 16),%eax
-       movw %dx,%ax
-       movw $0x8E00,%dx        /* interrupt gate - dpl=0, present */
-       lea idt_table,%edi
-       movl %eax,8*\trapno(%edi)
-       movl %edx,8*\trapno+4(%edi)
-.endm
-
-       set_early_handler handler=early_divide_err,trapno=0
-       set_early_handler handler=early_illegal_opcode,trapno=6
-       set_early_handler handler=early_protection_fault,trapno=13
-       set_early_handler handler=early_page_fault,trapno=14
-
-       ret
-
-early_divide_err:
+ENTRY(early_divide_err)
        xor %edx,%edx
        pushl $0        /* fake errcode */
        jmp early_fault
 
-early_illegal_opcode:
+ENTRY(early_illegal_opcode)
        movl $6,%edx
        pushl $0        /* fake errcode */
        jmp early_fault
 
-early_protection_fault:
+ENTRY(early_protection_fault)
        movl $13,%edx
        jmp early_fault
 
-early_page_fault:
+ENTRY(early_page_fault)
        movl $14,%edx
        jmp early_fault
 
@@ -408,7 +350,7 @@ hlt_loop:
 
 /* This is the default interrupt "handler" :-) */
        ALIGN
-ignore_int:
+ENTRY(ignore_int)
        cld
 #ifdef CONFIG_PRINTK
        pushl %eax
diff --git a/arch/i386/kernel/head32.c b/arch/i386/kernel/head32.c
index 3db0590..d2f85d5 100644
--- a/arch/i386/kernel/head32.c
+++ b/arch/i386/kernel/head32.c
@@ -7,8 +7,34 @@
 
 #include <linux/init.h>
 #include <linux/start_kernel.h>
+#include <asm/desc.h>
+
+extern void ignore_int(void);
+extern void early_divide_err(void);
+extern void early_illegal_opcode(void);
+extern void early_protection_fault(void);
+extern void early_page_fault(void);
+
+/*
+ *  setup_idt
+ *
+ *  sets up a idt with 256 entries pointing to ignore_int.  Interrupts
+ *  are enabled elsewhere, when we can be relatively sure everything is ok.
+ */
+static void __init setup_idt(void)
+{
+       int i;
+       for (i = 0; i < IDT_ENTRIES; i++)
+               set_intr_gate(i, ignore_int);
+       set_intr_gate(0, early_divide_err);
+       set_intr_gate(6, early_illegal_opcode);
+       set_intr_gate(13, early_protection_fault);
+       set_intr_gate(14, early_page_fault);
+       load_idt(&idt_descr);
+}
 
 void __init i386_start_kernel(void)
 {
+       setup_idt();
        start_kernel();
 }
-- 
1.5.1.1.181.g2de0

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to