diff options
author | Joel Sing <jsing@cvs.openbsd.org> | 2012-10-09 11:39:58 +0000 |
---|---|---|
committer | Joel Sing <jsing@cvs.openbsd.org> | 2012-10-09 11:39:58 +0000 |
commit | 6d8d4e7980d70c2d122e261bbadd500b6ab2e8b6 (patch) | |
tree | f2dcdd575f89754a92773cc0111e10fefedcce1c | |
parent | 4ca1805b95143c219be93f45e8194ff7adcfea8f (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.S | 5 | ||||
-rw-r--r-- | sys/arch/amd64/stand/libsa/gidt.S | 83 | ||||
-rw-r--r-- | sys/arch/i386/stand/boot/srt0.S | 5 | ||||
-rw-r--r-- | sys/arch/i386/stand/libsa/gidt.S | 82 |
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 ; \ |