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/
[Index of Archives]
[Kernel Newbies]
[Netfilter]
[Bugtraq]
[Photo]
[Stuff]
[Gimp]
[Yosemite News]
[MIPS Linux]
[ARM Linux]
[Linux Security]
[Linux RAID]
[Video 4 Linux]
[Linux for the blind]
[Linux Resources]