diff options
Diffstat (limited to 'sys/i386/bios/apm_setup.s')
-rw-r--r-- | sys/i386/bios/apm_setup.s | 134 |
1 files changed, 129 insertions, 5 deletions
diff --git a/sys/i386/bios/apm_setup.s b/sys/i386/bios/apm_setup.s index d354679..b3ae77d 100644 --- a/sys/i386/bios/apm_setup.s +++ b/sys/i386/bios/apm_setup.s @@ -12,14 +12,29 @@ * * Sep., 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD) * - * $Id: apm_setup.s,v 1.3 1994/10/02 01:45:42 phk Exp $ + * $Id: apm_setup.s,v 1.4 1994/10/10 01:14:03 phk Exp $ */ -#define ASM +#include "apm.h" + +#if NAPM > 0 -#include <machine/asmacros.h> -#include "assym.s" +#ifdef __FreeBSD__ +#define ASSEMBLER +#include "assym.s" /* system definitions */ +#include <machine/asmacros.h> /* miscellaneous asm macros */ #include <machine/apm_bios.h> +#include <machine/apm_segments.h> +#define PADDR(addr) addr-KERNBASE +#endif /* __FreeBSD__ */ + +#ifdef MACH_KERNEL +#define ASSEMBLER +#include "assym.s" +#include "i386at/apm_bios.h" +#include "i386at/apm_segments.h" +#define PADDR(addr) addr-KERNELBASE +#endif /* MACH_KERNEL */ .file "apm_setup.s" @@ -28,7 +43,12 @@ _apm_init_image: .globl _apm_init_image 1: -#include "apm_init/apm_init.inc" +#ifdef __FreeBSD__ +#include "i386/apm/apm_init/apm_init.inc" +#endif /* __FreeBSD__ */ +#ifdef MACH_KERNEL +#include "i386at/apm_init/apm_init.inc" +#endif /* MACH_KERNEL */ 2: _apm_init_image_size: @@ -66,4 +86,108 @@ _apm_ds_limit: _apm_flags: .globl _apm_flags .word 0 + .globl _apm_current_gdt_pdesc /* current GDT pseudo desc. */ +_apm_current_gdt_pdesc: + .word 0, 0, 0 + + .globl _bootstrap_gdt +_bootstrap_gdt: + .space SIZEOF_GDT*BOOTSTRAP_GDT_NUM + + .text +_apm_setup: + .globl _apm_setup + + /* + * Setup APM BIOS: + * + * APM BIOS initialization should be done from real mode or V86 mode. + * + * (by HOSOKAWA, Tatsumi <hosokawa@mt.cs.keio.ac.jp>) + */ + + /* + * Don't trust the value of %fs and %gs (some AT-compatible BIOS + * implementations leave junk values in these segment registers + * on bootstrap) + */ + xorl %eax, %eax /* null selector */ + movw %ax, %fs + movw %ax, %gs + + /* + * Copy APM initializer under 1MB boundary: + * + * APM initializer program must switch the CPU to real mode. + * But FreeBSD kernel runs above 1MB boundary. So we must + * copy the initializer code to conventional memory. + */ + movl PADDR(_apm_init_image_size), %ecx /* size */ + lea PADDR(_apm_init_image), %esi /* source */ + movl $ APM_OURADDR, %edi /* destination */ + cld + rep + movsb + + /* get GDT base */ + sgdt PADDR(_apm_current_gdt_pdesc) + + /* copy GDT to _bootstrap_gdt */ + xorl %ecx, %ecx + movw PADDR(_apm_current_gdt_pdesc), %cx + movl PADDR(_apm_current_gdt_pdesc + 2), %esi + lea PADDR(_bootstrap_gdt), %edi + cld + rep + movsb + + /* setup GDT pseudo descriptor */ + movw $(SIZEOF_GDT*BOOTSTRAP_GDT_NUM), %ax + movw %ax, PADDR(_apm_current_gdt_pdesc) + leal PADDR(_bootstrap_gdt), %eax + movl %eax, PADDR(_apm_current_gdt_pdesc + 2) + + /* load new GDTR */ + lgdt PADDR(_apm_current_gdt_pdesc) + + /* setup GDT for APM initializer */ + lea PADDR(_bootstrap_gdt), %ecx + movl $(APM_OURADDR), %eax /* use %ax for 15..0 */ + movl %eax, %ebx + shrl $16, %ebx /* use %bl for 23..16 */ + /* use %bh for 31..24 */ +#define APM_SETUP_GDT(index, attrib) \ + movl $(index), %si ; \ + lea 0(%ecx,%esi,8), %edx ; \ + movw $0xffff, (%edx) ; \ + movw %ax, 2(%edx) ; \ + movb %bl, 4(%edx) ; \ + movw $(attrib), 5(%edx) ; \ + movb %bh, 7(%edx) + + APM_SETUP_GDT(APM_INIT_CS_INDEX , CS32_ATTRIB) + APM_SETUP_GDT(APM_INIT_DS_INDEX , DS32_ATTRIB) + APM_SETUP_GDT(APM_INIT_CS16_INDEX, CS16_ATTRIB) + + /* + * Call the initializer: + * + * direct intersegment call to conventional memory code + */ + .byte 0x9a /* actually, lcall $APM_INIT_CS_SEL, $0 */ + .long 0 + .word APM_INIT_CS_SEL + + movl %eax, PADDR(_apm_version) + movl %ebx, PADDR(_apm_cs_entry) + movw %cx, PADDR(_apm_cs32_base) + shrl $16, %ecx + movw %cx, PADDR(_apm_cs16_base) + movw %dx, PADDR(_apm_ds_base) + movw %si, PADDR(_apm_cs_limit) + shrl $16, %esi + movw %si, PADDR(_apm_ds_limit) + movw %di, PADDR(_apm_flags) + ret +#endif NAPM > 0 |