summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Sing <jsing@cvs.openbsd.org>2012-10-09 11:39:58 +0000
committerJoel Sing <jsing@cvs.openbsd.org>2012-10-09 11:39:58 +0000
commit6d8d4e7980d70c2d122e261bbadd500b6ab2e8b6 (patch)
treef2dcdd575f89754a92773cc0111e10fefedcce1c
parent4ca1805b95143c219be93f45e8194ff7adcfea8f (diff)
Dynamically build the Interrupt Descriptor Table (IDT), instead of using
a static table. This allows the IDT to be placed in .bss and avoids the "relocation truncated" errors that result from the linker trying to put a 32-bit address into a 16-bit hole. With input from Marco Peereboom. ok weingart@
-rw-r--r--sys/arch/amd64/stand/boot/srt0.S5
-rw-r--r--sys/arch/amd64/stand/libsa/gidt.S83
-rw-r--r--sys/arch/i386/stand/boot/srt0.S5
-rw-r--r--sys/arch/i386/stand/libsa/gidt.S82
4 files changed, 104 insertions, 71 deletions
diff --git a/sys/arch/amd64/stand/boot/srt0.S b/sys/arch/amd64/stand/boot/srt0.S
index ccd3eff0ed2..b0780b36ade 100644
--- a/sys/arch/amd64/stand/boot/srt0.S
+++ b/sys/arch/amd64/stand/boot/srt0.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: srt0.S,v 1.1 2004/02/03 12:09:47 mickey Exp $ */
+/* $OpenBSD: srt0.S,v 1.2 2012/10/09 11:39:57 jsing Exp $ */
/*
* Copyright (c) 1997 Michael Shalayeff
@@ -73,7 +73,6 @@ _start:
movl %edx, _C_LABEL(bios_bootdev)
/* Now do it all */
- call _ASM_LABEL(pmm_init)
#ifdef DEBUG
movl $0xb80a4, %ebx
movl $0x07520752, (%ebx)
@@ -86,7 +85,7 @@ _start:
cld
rep; stosb
+ call _ASM_LABEL(pmm_init)
call _C_LABEL(boot)
jmp _C_LABEL(_rtt)
-
diff --git a/sys/arch/amd64/stand/libsa/gidt.S b/sys/arch/amd64/stand/libsa/gidt.S
index 325433b45dc..df5ab7cf1ec 100644
--- a/sys/arch/amd64/stand/libsa/gidt.S
+++ b/sys/arch/amd64/stand/libsa/gidt.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: gidt.S,v 1.7 2012/10/08 12:46:37 jsing Exp $ */
+/* $OpenBSD: gidt.S,v 1.8 2012/10/09 11:39:57 jsing Exp $ */
/*
* Copyright (c) 1997 Michael Shalayeff
@@ -147,7 +147,7 @@ ENTRY(_rtt)
#endif
/* Try to cause a triple fault... */
- lidt Idtr_reset
+ lidt Idtr_reset
xorl %eax, %eax
divl %eax, %eax
@@ -158,26 +158,33 @@ ENTRY(_rtt)
movl $0, %esp /* segment violation */
ret
- .align 8, 0x90
-pmm_init:
- /* load idtr for interrupts */
- lidt Idtr
+#define IPROC(n) X##n
+#define IEMU(n) IPROC(emu##n)
+
+create_idt_entry:
+ movw %ax, (%ebx)
+ movw $S32TEXT, 2(%ebx)
+ movw $((0x80|SDT_SYS386TGT) << 8), 4(%ebx)
+ shr $16, %eax
+ movw %ax, 6(%ebx)
+ addl $8, %ebx
ret
+ .align 8, 0x90
+pmm_init:
-#ifdef __STDC__
-#define IPROC(n) X##n
-#define IEMU(n) IPROC(emu##n)
-#else
-#define IPROC(n) X/**/n
-#define IEMU(n) IPROC(emu/**/n)
-#endif
- .align 8, 0x90
-idt:
#define idte(e) \
- .short IPROC(e); .short (S32TEXT); \
- .short ((0x80|SDT_SYS386TGT) << 8); .short (LINKADDR >> 16)
-/* internal (0-31) */
+ movl $IPROC(e), %eax; call create_idt_entry
+#define idtb(b) idte(emu##b)
+
+ /* Build interrupt descriptor table. */
+ /* Maskable interrupts (32-255) */
+ movl $idt, %ebx
+ movl $Idtr, %eax
+ movw $(640 - 1), (%eax)
+ movl %ebx, 2(%eax)
+
+ /* Internal (0-31) */
idte(de); idte(db); idte(nmi); idte(bp); idte(of); idte(br)
idte(ud); idte(nm); idte(df); idte(fo); idte(ts); idte(np)
idte(ss); idte(gp); idte(pf); idte(xx); idte(mf); idte(ac)
@@ -185,14 +192,7 @@ idt:
idte(xx); idte(xx); idte(xx); idte(xx); idte(xx); idte(xx)
idte(xx); idte(xx); idte(xx); idte(xx); idte(xx); idte(xx)
idte(xx)
- /* Maskable interrupts (32-255) */
- /* BIOS entry points (32-63) */
- /* DOS entry points (64-80) */
-#ifdef __STDC__
-#define idtb(b) idte(emu##b)
-#else
-#define idtb(b) idte(emu/**/b)
-#endif
+ /* BIOS entry points (32-63) */
idtb(0); idtb(1); idtb(2); idtb(3); idtb(4); idtb(5)
idtb(6); idtb(7); idtb(8); idtb(9); idtb(10); idtb(11)
idtb(12); idtb(13); idtb(14); idtb(15); idtb(16); idtb(17)
@@ -201,20 +201,37 @@ idt:
idtb(30); idtb(31); idtb(32); idtb(33); idtb(34); idtb(35)
idtb(36); idtb(37); idtb(38); idtb(39); idtb(40); idtb(41)
idtb(42); idtb(43); idtb(44); idtb(45); idtb(46); idtb(47)
+ /* DOS entry points (64-80) */
+
+#undef idtb
#undef idte
+
+ /* load idtr for interrupts */
+ lidt Idtr
+ ret
+
+ .bss
+ .align 8, 0x90
+idt:
+ /* IDT has 80 entries at 8 bytes each. */
+ .space 640
+
.globl Idtr
-Idtr: .word . - idt - 1
- .long idt
+Idtr: .word 0 // 640 - 1
+ .long 0 // idt
.word 0
+ .data
.align 8
.globl Idtr_real
-Idtr_real: .word 1023
- .long 0
- .word 0
+Idtr_real:
+ .word 1023
+ .long 0
+ .word 0
.align 8
-Idtr_reset: .long 0, 0
+Idtr_reset:
+ .long 0, 0
.align 8
gdt:
@@ -254,6 +271,7 @@ Gdtr: .word . - gdt - 1
.long gdt
.word 0
+ .text
#define IENTRY(name,type) \
IPROC(name): \
pushl $type ; \
@@ -286,7 +304,6 @@ IENTRY(gp,T_PROTFLT) /* #GP general protection */
IENTRY(pf,T_PAGEFLT) /* #PF page fault */
IENTRY_ERR(mf,0,T_ARITHTRAP) /* #MF floating point error */
IENTRY(ac,T_ALIGNFLT) /* #AC alignment check */
-
1:
cli
hlt
diff --git a/sys/arch/i386/stand/boot/srt0.S b/sys/arch/i386/stand/boot/srt0.S
index 9a1d6264df3..81e3d7b4f7d 100644
--- a/sys/arch/i386/stand/boot/srt0.S
+++ b/sys/arch/i386/stand/boot/srt0.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: srt0.S,v 1.14 2003/11/22 09:18:25 grange Exp $ */
+/* $OpenBSD: srt0.S,v 1.15 2012/10/09 11:39:57 jsing Exp $ */
/*
* Copyright (c) 1997 Michael Shalayeff
@@ -73,7 +73,6 @@ _start:
movl %edx, _C_LABEL(bios_bootdev)
/* Now do it all */
- call _ASM_LABEL(pmm_init)
#ifdef DEBUG
movl $0xb80a4, %ebx
movl $0x07520752, (%ebx)
@@ -86,7 +85,7 @@ _start:
cld
rep; stosb
+ call _ASM_LABEL(pmm_init)
call _C_LABEL(boot)
jmp _C_LABEL(_rtt)
-
diff --git a/sys/arch/i386/stand/libsa/gidt.S b/sys/arch/i386/stand/libsa/gidt.S
index 6ea7e8323d4..0dd8922618d 100644
--- a/sys/arch/i386/stand/libsa/gidt.S
+++ b/sys/arch/i386/stand/libsa/gidt.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: gidt.S,v 1.33 2012/10/08 12:46:37 jsing Exp $ */
+/* $OpenBSD: gidt.S,v 1.34 2012/10/09 11:39:57 jsing Exp $ */
/*
* Copyright (c) 1997 Michael Shalayeff
@@ -148,7 +148,7 @@ ENTRY(_rtt)
#endif
/* Try to cause a triple fault... */
- lidt Idtr_reset
+ lidt Idtr_reset
xorl %eax, %eax
divl %eax, %eax
@@ -159,26 +159,33 @@ ENTRY(_rtt)
movl $0, %esp /* segment violation */
ret
- .align 8, 0x90
-pmm_init:
- /* load idtr for interrupts */
- lidt Idtr
+#define IPROC(n) X##n
+#define IEMU(n) IPROC(emu##n)
+
+create_idt_entry:
+ movw %ax, (%ebx)
+ movw $S32TEXT, 2(%ebx)
+ movw $((0x80|SDT_SYS386TGT) << 8), 4(%ebx)
+ shr $16, %eax
+ movw %ax, 6(%ebx)
+ addl $8, %ebx
ret
+ .align 8, 0x90
+pmm_init:
-#ifdef __STDC__
-#define IPROC(n) X##n
-#define IEMU(n) IPROC(emu##n)
-#else
-#define IPROC(n) X/**/n
-#define IEMU(n) IPROC(emu/**/n)
-#endif
- .align 8, 0x90
-idt:
#define idte(e) \
- .short IPROC(e); .short (S32TEXT); \
- .short ((0x80|SDT_SYS386TGT) << 8); .short (LINKADDR >> 16)
-/* internal (0-31) */
+ movl $IPROC(e), %eax; call create_idt_entry
+#define idtb(b) idte(emu##b)
+
+ /* Build interrupt descriptor table. */
+ /* Maskable interrupts (32-255) */
+ movl $idt, %ebx
+ movl $Idtr, %eax
+ movw $(640 - 1), (%eax)
+ movl %ebx, 2(%eax)
+
+ /* Internal (0-31) */
idte(de); idte(db); idte(nmi); idte(bp); idte(of); idte(br)
idte(ud); idte(nm); idte(df); idte(fo); idte(ts); idte(np)
idte(ss); idte(gp); idte(pf); idte(xx); idte(mf); idte(ac)
@@ -186,14 +193,7 @@ idt:
idte(xx); idte(xx); idte(xx); idte(xx); idte(xx); idte(xx)
idte(xx); idte(xx); idte(xx); idte(xx); idte(xx); idte(xx)
idte(xx)
- /* Maskable interrupts (32-255) */
- /* BIOS entry points (32-63) */
- /* DOS entry points (64-80) */
-#ifdef __STDC__
-#define idtb(b) idte(emu##b)
-#else
-#define idtb(b) idte(emu/**/b)
-#endif
+ /* BIOS entry points (32-63) */
idtb(0); idtb(1); idtb(2); idtb(3); idtb(4); idtb(5)
idtb(6); idtb(7); idtb(8); idtb(9); idtb(10); idtb(11)
idtb(12); idtb(13); idtb(14); idtb(15); idtb(16); idtb(17)
@@ -202,20 +202,37 @@ idt:
idtb(30); idtb(31); idtb(32); idtb(33); idtb(34); idtb(35)
idtb(36); idtb(37); idtb(38); idtb(39); idtb(40); idtb(41)
idtb(42); idtb(43); idtb(44); idtb(45); idtb(46); idtb(47)
+ /* DOS entry points (64-80) */
+
+#undef idtb
#undef idte
+
+ /* load idtr for interrupts */
+ lidt Idtr
+ ret
+
+ .bss
+ .align 8, 0x90
+idt:
+ /* IDT has 80 entries at 8 bytes each. */
+ .space 640
+
.globl Idtr
-Idtr: .word . - idt - 1
- .long idt
+Idtr: .word 0 // 640 - 1
+ .long 0 // idt
.word 0
+ .data
.align 8
.globl Idtr_real
-Idtr_real: .word 1023
- .long 0
- .word 0
+Idtr_real:
+ .word 1023
+ .long 0
+ .word 0
.align 8
-Idtr_reset: .long 0, 0
+Idtr_reset:
+ .long 0, 0
.align 8
gdt:
@@ -255,6 +272,7 @@ Gdtr: .word . - gdt - 1
.long gdt
.word 0
+ .text
#define IENTRY(name,type) \
IPROC(name): \
pushl $type ; \