diff options
Diffstat (limited to 'sys/arch/amd64/stand/libsa/pxe_call.S')
-rw-r--r-- | sys/arch/amd64/stand/libsa/pxe_call.S | 202 |
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 |