summaryrefslogtreecommitdiff
path: root/sys/arch/amd64/stand/libsa/pxe_call.S
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/amd64/stand/libsa/pxe_call.S')
-rw-r--r--sys/arch/amd64/stand/libsa/pxe_call.S202
1 files changed, 202 insertions, 0 deletions
diff --git a/sys/arch/amd64/stand/libsa/pxe_call.S b/sys/arch/amd64/stand/libsa/pxe_call.S
new file mode 100644
index 00000000000..81247ebe423
--- /dev/null
+++ b/sys/arch/amd64/stand/libsa/pxe_call.S
@@ -0,0 +1,202 @@
+/* $OpenBSD: pxe_call.S,v 1.1 2004/03/21 21:37:41 tom Exp $ */
+/* $NetBSD: pxe_call.S,v 1.2 2002/03/27 17:24:22 kanaoka Exp $ */
+
+/*
+ * Copyright 2001 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project by
+ * Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Low level PXE BIOS call glue.
+ */
+
+#include <machine/asm.h>
+#include <assym.h>
+
+#include "gidt.h"
+
+ENTRY(pxecall_bangpxe)
+ .code32
+ pushl %ebp
+ movl %esp, %ebp
+ pushl %ebx
+ pushl %ecx
+ pushl %edx
+
+ /* For simplicity, just move all 32 bits. */
+ movl 8(%ebp), %ebx
+
+ pushw _C_LABEL(pxe_command_buf_seg)
+ pushw _C_LABEL(pxe_command_buf_off)
+ pushw %bx
+
+ call prot_to_real /* Enter real mode */
+ .code16
+
+ sti
+ /* The encoding is: 0x9a offlo offhi seglo seghi */
+ lcall $0, $0xffff
+ .globl _C_LABEL(bangpxe_off)
+_C_LABEL(bangpxe_off) = . - 4
+ .globl _C_LABEL(bangpxe_seg)
+_C_LABEL(bangpxe_seg) = . - 2
+
+ cli
+ call real_to_prot /* Leave real mode */
+ .code32
+
+ add $6, %esp
+
+ popl %edx
+ popl %ecx
+ popl %ebx
+ popl %ebp
+ ret
+
+ENTRY(pxecall_pxenv)
+ .code32
+ pushl %ebp
+ movl %esp, %ebp
+ pushl %ebx
+ pushl %ecx
+ pushl %edx
+ pushl %edi
+
+ /* For simplicity, just move all 32 bits. */
+ movl 8(%ebp), %ebx
+
+ call prot_to_real /* Enter real mode */
+ .code16
+
+ /* prot_to_real() has already set %es to BOOTSEG */
+ lea _C_LABEL(pxe_command_buf), %di
+
+ /* The encoding is: 0x9a offlo offhi seglo seghi */
+ lcall $0, $0xffff
+ .globl _C_LABEL(pxenv_off)
+_C_LABEL(pxenv_off) = . - 4
+ .globl _C_LABEL(pxenv_seg)
+_C_LABEL(pxenv_seg) = . - 2
+
+ call real_to_prot /* Leave real mode */
+ .code32
+
+ popl %edi
+ popl %edx
+ popl %ecx
+ popl %ebx
+ popl %ebp
+ ret
+
+/*
+ * prot_to_real()
+ *
+ * Switch the processor back into real mode.
+ */
+ .globl prot_to_real
+prot_to_real:
+ .code32
+ ljmp $S16TEXT, $p2r16 - LINKADDR
+p2r16:
+ .code16
+
+ movw $S16DATA, %ax
+ movw %ax, %ds
+ movw %ax, %es
+
+ movl %cr0, %eax /* Disable protected mode */
+ andl $~CR0_PE, %eax
+ movl %eax, %cr0
+
+ /* reload real cs:ip */
+ data32 ljmp $(LINKADDR >> 4), $p2r16real - LINKADDR
+p2r16real:
+ xorw %ax, %ax /* Reset segment registers: */
+ movw %ax, %ds /* %ds: so we can get at Idtr_real */
+ movw %ax, %ss /* %ss: for our stack */
+
+ .extern Idtr_real
+ data32 addr32 lidt Idtr_real; /* Set up IDT for real mode */
+
+ movw %cs, %ax
+ movw %ax, %ds
+ movw %ax, %es /* Set %ds = %es = %cs */
+
+ /*
+ * We were called from 32-bit mode, so there's a 32-bit
+ * return address on the stack. No segment. This is within
+ * the flat memory model, so we need to adjust it back so
+ * that it's relative to our 16-bit %cs.
+ */
+ popl %eax
+ subl $LINKADDR, %eax
+ pushw %ax
+ ret
+
+/*
+ * real_to_prot()
+ *
+ * Switch the processor back into protected mode.
+ */
+ .globl real_to_prot
+real_to_prot:
+ .code16
+
+ xorw %ax, %ax
+ movw %ax, %ds /* Load %ds so we can get at Gdtr */
+ data32 addr32 lgdt Gdtr /* Load the GDT */
+
+ movl %cr0, %eax /* Enable protected mode */
+ orl $CR0_PE, %eax
+ movl %eax, %cr0
+
+ data32 ljmp $S32TEXT, $r2p32 /* Reload %cs, flush pipeline */
+r2p32:
+ .code32
+ /* Reload 32-bit %ds, %ss, %es */
+ movl $S32DATA, %eax
+ mov %ax, %ds
+ mov %ax, %ss
+ mov %ax, %es
+
+ /* Load IDT for debugger and DOS/BIOS interface */
+ .extern Idtr
+ lidt Idtr
+
+ xorl %eax, %eax
+ popw %ax /* 16-bit return addr on stack */
+ addl $LINKADDR, %eax
+ pushl %eax /* Now have correct 32-bit ret addr */
+ ret
+
+ .end