-/* $OpenBSD: gidt.S,v 1.3 1997/04/09 08:39:37 mickey Exp $ */
+/* $OpenBSD: gidt.S,v 1.4 1997/04/18 01:28:02 mickey Exp $ */
/*
* Copyright (c) 1997 Michael Shalayeff
* SUCH DAMAGE.
*
*/
+
+ .file "gidt.S"
+
#include <machine/asm.h>
#include <machine/psl.h>
#define _LOCORE
.data
.globl _Gdtr
- .globl _codeseg
.align 3
gdt:
.byte 0 # hibase
/* 0x18 : 16 bit code */
.word 0xFFFF # lolimit
- .word 0 # lobase
- .byte 0 # midbase
+ .word (START & 0xffff) # lobase
+ .byte (START >> 16) & 0xff # midbase
.byte SDT_MEMERA | 0 | 0x80 # RXAC, dpl = 0, present
- .byte 0x0 | 0 | 0 | 0 # hilimit, xx, 16bit, byte granularity
- .byte 0 # hibase
+ .byte 0xf | 0 | 0 | 0 # hilimit, xx, 16bit, byte granularity
+ .byte (START >> 20) & 0xff # hibase
+ /* 0x20 : 16 bit data */
+ .word 0xFFFF # lolimit
+ .word (START & 0xffff) # lobase
+ .byte (START >> 16) & 0xff # midbase
+ .byte SDT_MEMRWA | 0 | 0x80 # RXAC, dpl = 0, present
+ .byte 0xf | 0 | 0 | 0 # hilimit, xx, 16bit, byte granularity
+ .byte (START >> 20) & 0xff # hibase
+
_Gdtr: .word . - gdt - 1
.long gdt
.word 0
-_codeseg: .long 0
-
.globl _Idtr_real
.align 3
_Idtr_real:
.globl _Idtr_prot
.align 3
-idt: /*
- * We beleive that all the boot code fits into
- * 64k, so no need for high 16 bit of procedure address (;
- *
- */
-#define IPROC(n) X/**/n
-#define IDTENTRY(proc) \
- .word IPROC(proc) /* lo offset handler */ ; \
- .word 0x8 /* handler %cs */ ; \
- .byte 0 /* reserved */ ; \
- .byte 0x80 | SDT_SYS386TGT /* present, dpl=0, 32bit trap gate */ ; \
- .word 0 /* hi offset handler */
-
- IDTENTRY(de) /* #DE divide by zero */
- IDTENTRY(db) /* #DB debug */
- IDTENTRY(nmi) /* NMI */
- IDTENTRY(bp) /* #BP breakpoint */
- IDTENTRY(of) /* #OF overflow */
- IDTENTRY(br) /* #BR BOUND range exceeded */
- IDTENTRY(ud) /* #UD invalid opcode */
- IDTENTRY(nm) /* #NM device not available */
- IDTENTRY(df) /* #DF double fault */
- IDTENTRY(fo) /* #FO coprocessor segment overrun */
- IDTENTRY(ts) /* #TS innvalid TSS */
- IDTENTRY(np) /* #NP segmant not present */
- IDTENTRY(ss) /* #SS stack fault */
- IDTENTRY(gp) /* #GP general protection */
- IDTENTRY(pf) /* #PF page fault */
- IDTENTRY(xx) /* Intel reserved */
- IDTENTRY(mf) /* #MF floating point error */
- IDTENTRY(ac) /* #AC alignment check */
- IDTENTRY(mc) /* #MC machine check */
- /* Intel reserved (19-31) */
- IDTENTRY(xx); IDTENTRY(xx); IDTENTRY(xx); IDTENTRY(xx)
- IDTENTRY(xx); IDTENTRY(xx); IDTENTRY(xx); IDTENTRY(xx)
- IDTENTRY(xx); IDTENTRY(xx); IDTENTRY(xx); IDTENTRY(xx)
- IDTENTRY(xx)
- /* Maskable interrupts(32-255) */
- /* BIOS entry points (32-63) */
-#define IBIOS(n) IPROC(bios/**/n)
-#define IDTBIOS(n) IDTENTRY(bios/**/n)
- IDTBIOS(0); IDTBIOS(1); IDTBIOS(2); IDTBIOS(3); IDTBIOS(4)
- IDTBIOS(5); IDTBIOS(6); IDTBIOS(7); IDTBIOS(8); IDTBIOS(9)
- IDTBIOS(10); IDTBIOS(11); IDTBIOS(12); IDTBIOS(13); IDTBIOS(14)
- IDTBIOS(15); IDTBIOS(16); IDTBIOS(17); IDTBIOS(18); IDTBIOS(19)
- IDTBIOS(20); IDTBIOS(21); IDTBIOS(22); IDTBIOS(23)
- /* DOS entry points */
+idt:
+ .space 32*8, 0 /* internal (0-31) */
+ /* Maskable interrupts (32-255) */
+ .space 32*8, 0 /* BIOS entry points (32-63) */
+ .space 16*8, 0 /* DOS entry points (64-80) */
_Idtr_prot:
.word . - idt - 1
.long idt
.text
+#define IPROC(n) X/**/n
+#define IBIOS(n) IPROC(bios/**/n)
+#define IDOS(n) IPROC(dos/**/n)
+
+ .globl idt_init
+idt_init:
+ pushl %edi
+
+ movl $idt, %edi
+
+#define fixe(p) \
+ movl $ IPROC(p), %eax; \
+ stosw; /* lo offset handler */ \
+ movw $0x8, (%edi); /* handler %cs */ \
+ incl %edi; incl %edi; \
+ incl %edi; /* reserved */ \
+ movb $(0x80|SDT_SYS386TGT), (%edi); /* 32bit trap gate */ \
+ incl %edi; \
+ shrl $16, %eax; \
+ stosw; /* hi offset handler */
+
+ fixe(de); fixe(db); fixe(nmi); fixe(bp); fixe(of); fixe(br)
+ fixe(ud); fixe(nm); fixe(df); fixe(fo); fixe(ts); fixe(np)
+ fixe(ss); fixe(gp); fixe(pf); fixe(xx); fixe(mf); fixe(ac)
+ fixe(mc)
+ fixe(xx); fixe(xx); fixe(xx); fixe(xx); fixe(xx); fixe(xx)
+ fixe(xx); fixe(xx); fixe(xx); fixe(xx); fixe(xx); fixe(xx)
+ fixe(xx)
+
+#define fixb(b) fixe(bios/**/b)
+ fixb(0); fixb(1); fixb(2); fixb(3); fixb(4); fixb(5)
+ fixb(6); fixb(7); fixb(8); fixb(9); fixb(10); fixb(11)
+ fixb(12); fixb(13); fixb(14); fixb(15); fixb(16); fixb(17)
+ fixb(18); fixb(19); fixb(20); fixb(21); fixb(22); fixb(23)
+ fixb(24); fixb(25); fixb(26); fixb(27); fixb(28); fixb(29)
+ fixb(30); fixb(31)
+
+#define fixd(d) fixe(dos/**/b)
+
+ popl %edi
+ ret
#define IENTRY(name,type) \
IPROC(name): \
IPROC(xx):
pushl $1
- pushl $256
+ pushl $T_RESERVED
jmp 1f
-IENTRY_ERR(de,0,T_DIVIDE)
-IENTRY_ERR(db,0,T_TRCTRAP)
-IENTRY_ERR(nmi,0,T_NMI)
-IENTRY_ERR(bp,0,T_BPTFLT)
-IENTRY_ERR(of,0,T_OFLOW)
-IENTRY_ERR(br,0,T_BOUND)
-IENTRY_ERR(ud,0,T_PRIVINFLT)
-IENTRY_ERR(nm,0,T_DNA)
-IENTRY(df,T_DOUBLEFLT)
-IENTRY_ERR(fo,0,T_FPOPFLT)
-IENTRY(ts,T_TSSFLT)
-IENTRY(np,T_SEGNPFLT)
-IENTRY(ss,T_STKFLT)
-IENTRY(gp,T_PROTFLT)
-IENTRY(pf,T_PAGEFLT)
-IENTRY_ERR(mf,0,T_ARITHTRAP)
-IENTRY(ac,T_ALIGNFLT)
-IENTRY(mc,T_MACHK)
+IENTRY_ERR(de,0,T_DIVIDE) /* #DE divide by zero */
+IENTRY_ERR(db,0,T_TRCTRAP) /* #DB debug */
+IENTRY_ERR(nmi,0,T_NMI) /* NMI */
+IENTRY_ERR(bp,0,T_BPTFLT) /* #BP breakpoint */
+IENTRY_ERR(of,0,T_OFLOW) /* #OF overflow */
+IENTRY_ERR(br,0,T_BOUND) /* #BR BOUND range exceeded */
+IENTRY_ERR(ud,0,T_PRIVINFLT) /* #UD invalid opcode */
+IENTRY_ERR(nm,0,T_DNA) /* #NM device not available */
+IENTRY(df,T_DOUBLEFLT) /* #DF double fault */
+IENTRY_ERR(fo,0,T_FPOPFLT) /* #FO coprocessor segment overrun */
+IENTRY(ts,T_TSSFLT) /* #TS innvalid TSS */
+IENTRY(np,T_SEGNPFLT) /* #NP segmant not present */
+IENTRY(ss,T_STKFLT) /* #SS stack fault */
+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 */
+IENTRY(mc,T_MACHK) /* #MC machine check */
.globl alltraps
1: /* save on jumps */
jmp alltraps
-#define IBIOSENT(n) IBIOS(n): pushl %eax; movb $n, %al ; jmp 1f
+#define IBIOSENT(n) IBIOS(n): pushl $n; jmp BIOSh
IBIOSENT(0); IBIOSENT(1); IBIOSENT(2); IBIOSENT(3)
IBIOSENT(4); IBIOSENT(5); IBIOSENT(6); IBIOSENT(7)
IBIOSENT(12); IBIOSENT(13); IBIOSENT(14); IBIOSENT(15)
IBIOSENT(16); IBIOSENT(17); IBIOSENT(18); IBIOSENT(19)
IBIOSENT(20); IBIOSENT(21); IBIOSENT(22); IBIOSENT(23)
+IBIOSENT(24); IBIOSENT(25); IBIOSENT(26); IBIOSENT(27)
+IBIOSENT(28); IBIOSENT(29); IBIOSENT(30); IBIOSENT(31)
- .text
- .globl _real_to_prot, _prot_to_real
-1:
- movb %al, intno
- popl %eax
+/*
+ * entry point for BIOS real-mode interface
+ * all the magic for real-prot mode switching is here
+ *
+ * Call: %eax, %ecx, %edx, %ebx, %ebp, %esi, %ds, %di==real mode %es
+ * Return: %eax, %edx, %ecx, %eflags (as returned from BIOS)
+ *
+ */
+ .globl BIOSh
+BIOSh:
pushal
pushl %ds
pushl %es
- call _prot_to_real
+ /* save %eax */
+ movl %eax, 2f
+
+ /* save BIOS int vector */
+ movb 10*4(%esp), %al
+ movb %al, intno
+
+ /* setup 16bit labels in ljmps */
+#ifdef GIDT_DEBUG
+ movl $0xb8000, %eax
+ movl $0x47314730, (%eax)
+#endif
+ movl $0x20, %eax
+
+ # ljmp $0x18, $2f
+ .byte 0xea /* Change to 16bit mode */
+ .long 1f - START
+ .word 0x18
+1:
+ movl %ax, %ds
+#ifdef GIDT_DEBUG
+ data32
+ movl $(0xb8000 - START), %eax
+ data32
+ addr32
+ movl $0x4f314f30, (%eax)
+#endif
+ movl %cr0, %eax /* disable prot mode memory management */
+ data32
+ andl $~CR0_PE, %eax
+ movl %eax, %cr0
+
+ # ljmp (START >> 16), $4f
+ .byte 0xea /* load real mode cs:ip */
+ .word 1f
+ .word (START >> 4)
+1:
+ xorl %eax, %eax /* setup: %ds, %es, %ss */
+ movl %ax, %ds
+ movl %ax, %ss
movl %di, %es
+#ifdef GIDT_DEBUG
+ data32
+ movl $0xb8004, %eax
+ data32
+ addr32
+ movl $0x47334732, (%eax)
+#endif
+
+ addr32
+ data32
+ lidt _Idtr_real /* load idtr for DOS/BIOS operations */
+
+ data32
+ # movl Leax, %eax
+ .byte 0xb8
+2: .long 0x90909090 /* restore %eax */
+
+ sti
int $0
-intno = . - 1
+intno = . - 1
- movb %ah, %bh
+ movb %ah, %bh /* save flags to return to caller */
lahf
xchgb %ah, %bh
+ cli /* no maskable interrupts in prot mode */
+
+ addr32
+ data32
+ movl %eax, 2f /* save %eax */
+
+#ifdef GIDT_DEBUG
+ data32
+ movl $0xb8004, %eax
+ data32
+ addr32
+ movl $0x4f334f32, (%eax)
+#endif
+
+ addr32
+ data32
+ lgdt _C_LABEL(Gdtr) /* load the gdtr */
+
+ movl %cr0, %eax /* enable prot mode memory management */
+ data32
+ orl $CR0_PE, %eax
+ movl %eax, %cr0
+
data32
- call _real_to_prot
+ ljmp $0x08, $1f /* reload %cs, and flush pipeline */
+1:
+ /* reload 32bit %ds, %ss, %es */
+ movl $0x10, %eax
+ movl %ax, %ds
+ movl %ax, %ss
+
+#ifdef GIDT_DEBUG
+ movl $0xb8008, %eax
+ movl $0x47344733, (%eax)
+#endif
+
+ /* load idtr for debugger and DOS/BIOS iface */
+ lidt _Idtr_prot
+
+ # movl Leax, %eax
+ .byte 0xb8
+2: .long 0x90909090 /* eax */
/* pass BIOS return values back to caller */
movl %eax, 0x9*4(%esp)
movl %ecx, 0x8*4(%esp)
movl %edx, 0x7*4(%esp)
- movb %bh , 0xc*4(%esp)
+ movb %bh , 0xd*4(%esp)
popl %es
popl %ds
popal
+ incl %esp; incl %esp; incl %esp; incl %esp
iret
+++ /dev/null
-/* $OpenBSD: real_prot.S,v 1.5 1997/04/09 08:39:42 mickey Exp $ */
-
-/*
- * Mach Operating System
- * Copyright (c) 1992, 1991 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- *
- * from: Mach, Revision 2.2 92/04/04 11:34:13 rpd
- */
-
-
-/*
- Copyright 1988, 1989, 1990, 1991, 1992
- by Intel Corporation, Santa Clara, California.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and
-its documentation for any purpose and without fee is hereby
-granted, provided that the above copyright notice appears in all
-copies and that both the copyright notice and this permission notice
-appear in supporting documentation, and that the name of Intel
-not be used in advertising or publicity pertaining to distribution
-of the software without specific, written prior permission.
-
-INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
-IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
-CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
-NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
-WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
- .file "real_prot.S"
-
-#include <machine/asm.h>
-#include <machine/specialreg.h>
-
-#define addr32 .byte 0x67
-#define data32 .byte 0x66
-
- .data
-
- .globl _codeseg
- .globl _Gdtr
- .globl _Idtr_prot
- .globl _Idtr_real
-
- .text
-
-/*
- *
- * real_to_prot()
- * transfer from real mode to protected mode.
- */
-
-ENTRY(real_to_prot)
- /* guarantee that interrupts are disabled when in prot mode */
- cli
- addr32
- data32
- movl %eax, 2f
-
- /* load the gdtr */
- addr32
- data32
- lgdt _C_LABEL(Gdtr)
-
- /* set the PE bit of CR0 */
- movl %cr0, %eax
- data32
- orl $CR0_PE, %eax
- movl %eax, %cr0
-
- /*
- * make intrasegment jump to flush the processor pipeline and
- * reload CS register
- */
- data32
- ljmp $0x08, $1f
-
-1: /*
- * we are in USE32 mode now
- * set up the protected mode segment registers : DS, SS, ES
- */
- movl $0x10, %eax
- movl %ax, %ds
- movl %ax, %ss
- movl %ax, %es
-
- /* load idtr for debugger and BIOS iface */
- lidt _Idtr_prot
- # movl Leax, %eax
- .byte 0xb8
-2: .long 0 /* eax */
- ret
-
-/*
- *
- * prot_to_real()
- * transfer from protected mode to real mode
- *
- */
-
-ENTRY(prot_to_real)
-
- movl %eax, 4f
- movl _codeseg, %eax
- movw %ax, 2f
-
- /* Change to use16 mode. */
- ljmp $0x18, $1f
-1:
- /* clear the PE bit of CR0 */
- movl %cr0, %eax
- data32
- andl $~CR0_PE, %eax
- movl %eax, %cr0
-
- data32
- # ljmp _codeseg, $2f
- .byte 0xea
- .long 3f
-2: .word 0
-3:
- /* setup: %ds, %es, %ss */
- movl %cs, %ax
- movl %ax, %ds
- movl %ax, %ss
- movl %ax, %es
-
- /* load idtr for BIOS operations */
- addr32
- data32
- lidt _Idtr_real
-
- addr32
- data32
- # movl Leax, %eax
- .byte 0xb8
-4: .long 0 /* %eax */
-
- sti
- data32
- ret
-