xref: /openbsd/sys/arch/amd64/stand/libsa/pxe_call.S (revision 81621933)
1*81621933Sguenther/*	$OpenBSD: pxe_call.S,v 1.5 2022/12/08 01:25:44 guenther Exp $ */
28641b11fStom/*	$NetBSD: pxe_call.S,v 1.2 2002/03/27 17:24:22 kanaoka Exp $	*/
38641b11fStom
48641b11fStom/*
58641b11fStom * Copyright 2001 Wasabi Systems, Inc.
68641b11fStom * All rights reserved.
78641b11fStom *
88641b11fStom * Written by Jason R. Thorpe for Wasabi Systems, Inc.
98641b11fStom *
108641b11fStom * Redistribution and use in source and binary forms, with or without
118641b11fStom * modification, are permitted provided that the following conditions
128641b11fStom * are met:
138641b11fStom * 1. Redistributions of source code must retain the above copyright
148641b11fStom *    notice, this list of conditions and the following disclaimer.
158641b11fStom * 2. Redistributions in binary form must reproduce the above copyright
168641b11fStom *    notice, this list of conditions and the following disclaimer in the
178641b11fStom *    documentation and/or other materials provided with the distribution.
188641b11fStom * 3. All advertising materials mentioning features or use of this software
198641b11fStom *    must display the following acknowledgement:
208641b11fStom *	This product includes software developed for the NetBSD Project by
218641b11fStom *	Wasabi Systems, Inc.
228641b11fStom * 4. The name of Wasabi Systems, Inc. may not be used to endorse
238641b11fStom *    or promote products derived from this software without specific prior
248641b11fStom *    written permission.
258641b11fStom *
268641b11fStom * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
278641b11fStom * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
288641b11fStom * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
298641b11fStom * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
308641b11fStom * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
318641b11fStom * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
328641b11fStom * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
338641b11fStom * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
348641b11fStom * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
358641b11fStom * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
368641b11fStom * POSSIBILITY OF SUCH DAMAGE.
378641b11fStom */
388641b11fStom
398641b11fStom/*
408641b11fStom * Low level PXE BIOS call glue.
418641b11fStom */
428641b11fStom
438641b11fStom#include <machine/asm.h>
448641b11fStom#include <assym.h>
458641b11fStom
468641b11fStom#include "gidt.h"
478641b11fStom
488641b11fStomENTRY(pxecall_bangpxe)
498641b11fStom	.code32
508641b11fStom	pushl	%ebp
518641b11fStom	movl	%esp, %ebp
528641b11fStom	pushl	%ebx
538641b11fStom	pushl	%ecx
548641b11fStom	pushl	%edx
558641b11fStom
568641b11fStom	/* For simplicity, just move all 32 bits. */
578641b11fStom	movl	8(%ebp), %ebx
588641b11fStom
59*81621933Sguenther	pushw	pxe_command_buf_seg
60*81621933Sguenther	pushw	pxe_command_buf_off
618641b11fStom	pushw	%bx
628641b11fStom
638641b11fStom	call	prot_to_real			/* Enter real mode */
648641b11fStom	.code16
658641b11fStom
668641b11fStom	sti
678641b11fStom	/* The encoding is: 0x9a offlo offhi seglo seghi */
688641b11fStom	lcall	$0, $0xffff
69*81621933Sguenther	.globl	bangpxe_off
70*81621933Sguentherbangpxe_off = . - 4
71*81621933Sguenther	.globl	bangpxe_seg
72*81621933Sguentherbangpxe_seg = . - 2
738641b11fStom
748641b11fStom	cli
758641b11fStom	call	real_to_prot			/* Leave real mode */
768641b11fStom	.code32
778641b11fStom
788641b11fStom	add	$6, %esp
798641b11fStom
808641b11fStom	popl	%edx
818641b11fStom	popl	%ecx
828641b11fStom	popl	%ebx
838641b11fStom	popl	%ebp
848641b11fStom	ret
858641b11fStom
868641b11fStomENTRY(pxecall_pxenv)
878641b11fStom	.code32
888641b11fStom	pushl	%ebp
898641b11fStom	movl	%esp, %ebp
908641b11fStom	pushl	%ebx
918641b11fStom	pushl	%ecx
928641b11fStom	pushl	%edx
938641b11fStom	pushl	%edi
948641b11fStom
954019367fStom	/*
964019367fStom         * Using the PXENV+ calling convention, the (16 bit) function
974019367fStom         * number is passed in %bx, with the address of the command
984019367fStom         * buffer in %es:%di.
994019367fStom	 */
1004019367fStom	movl	8(%ebp), %ebx	/* For simplicity, just move all 32 bits. */
1014019367fStom
1024019367fStom	/*
1034019367fStom	 * prot_to_real() will set %es to BOOTSEG, so we just need to set
1044019367fStom	 * %(e)di up here.  Remember to relocate it!
1054019367fStom	 */
106*81621933Sguenther	movl	$pxe_command_buf, %edi
1074019367fStom	subl	$LINKADDR, %edi
1088641b11fStom
1098641b11fStom	call	prot_to_real			/* Enter real mode */
1108641b11fStom	.code16
1118641b11fStom
1128641b11fStom	/* The encoding is: 0x9a offlo offhi seglo seghi */
1138641b11fStom	lcall	$0, $0xffff
114*81621933Sguenther	.globl	pxenv_off
115*81621933Sguentherpxenv_off = . - 4
116*81621933Sguenther	.globl	pxenv_seg
117*81621933Sguentherpxenv_seg = . - 2
1188641b11fStom
1198641b11fStom	call	real_to_prot			/* Leave real mode */
1208641b11fStom	.code32
1218641b11fStom
1228641b11fStom	popl	%edi
1238641b11fStom	popl	%edx
1248641b11fStom	popl	%ecx
1258641b11fStom	popl	%ebx
1268641b11fStom	popl	%ebp
1278641b11fStom	ret
1288641b11fStom
1298641b11fStom/*
1308641b11fStom * prot_to_real()
1318641b11fStom *
1328641b11fStom * Switch the processor back into real mode.
1338641b11fStom */
1348641b11fStom	.globl	prot_to_real
1358641b11fStomprot_to_real:
1368641b11fStom	.code32
1378641b11fStom	ljmp	$S16TEXT, $p2r16 - LINKADDR
1388641b11fStomp2r16:
1398641b11fStom	.code16
1408641b11fStom
1418641b11fStom	movw	$S16DATA, %ax
1428641b11fStom	movw	%ax, %ds
1438641b11fStom	movw	%ax, %es
1448641b11fStom
1458641b11fStom	movl	%cr0, %eax		/* Disable protected mode */
1468641b11fStom	andl 	$~CR0_PE, %eax
1478641b11fStom	movl	%eax, %cr0
1488641b11fStom
1498641b11fStom	/* reload real cs:ip */
1508641b11fStom	data32 ljmp	$(LINKADDR >> 4), $p2r16real - LINKADDR
1518641b11fStomp2r16real:
1528641b11fStom	xorw	%ax, %ax		/* Reset segment registers: */
1538641b11fStom	movw	%ax, %ss		/* %ss: for our stack */
1548641b11fStom
1551bf98718Stom	movw	$LINKADDR >> 4, %ax	/* We're linked to LINKADDR/16:0000 */
1561bf98718Stom	movw	%ax, %ds		/* %ds: so we can get at Idtr_real */
1571bf98718Stom
1588641b11fStom	.extern	Idtr_real
1591bf98718Stom	data32 addr32 lidt (Idtr_real - LINKADDR);	/* Set up IDT for real mode */
1608641b11fStom
1618641b11fStom	movw	%cs, %ax
1628641b11fStom	movw	%ax, %ds
1638641b11fStom	movw	%ax, %es		/* Set %ds = %es = %cs */
1648641b11fStom
1658641b11fStom	/*
1668641b11fStom	 * We were called from 32-bit mode, so there's a 32-bit
1678641b11fStom	 * return address on the stack.  No segment.  This is within
1688641b11fStom	 * the flat memory model, so we need to adjust it back so
1698641b11fStom	 * that it's relative to our 16-bit %cs.
1708641b11fStom	 */
1718641b11fStom	popl	%eax
1728641b11fStom	subl	$LINKADDR, %eax
1738641b11fStom	pushw	%ax
1748641b11fStom	ret
1758641b11fStom
1768641b11fStom/*
1778641b11fStom * real_to_prot()
1788641b11fStom *
1798641b11fStom * Switch the processor back into protected mode.
1808641b11fStom */
1818641b11fStom	.globl	real_to_prot
1828641b11fStomreal_to_prot:
1838641b11fStom	.code16
1848641b11fStom
1858f770448Stom	movw	$LINKADDR >> 4, %ax	/* We're linked to LINKADDR/16:0000 */
1868f770448Stom	movw	%ax, %ds
1871bf98718Stom	data32 addr32 lgdt (Gdtr - LINKADDR)	/* Reload the GDT */
1888641b11fStom
1898641b11fStom	movl	%cr0, %eax		/* Enable protected mode */
1908641b11fStom	orl	$CR0_PE, %eax
1918641b11fStom	movl	%eax, %cr0
1928641b11fStom
1938641b11fStom	data32 ljmp	$S32TEXT, $r2p32 /* Reload %cs, flush pipeline */
1948641b11fStomr2p32:
1958641b11fStom	.code32
1968641b11fStom	/* Reload 32-bit %ds, %ss, %es */
1978641b11fStom	movl	$S32DATA, %eax
1988641b11fStom	mov	%ax, %ds
1998641b11fStom	mov	%ax, %ss
2008641b11fStom	mov	%ax, %es
2018641b11fStom
2028641b11fStom	/* Load IDT for debugger and DOS/BIOS interface */
2038641b11fStom	.extern	Idtr
2048641b11fStom	lidt	Idtr
2058641b11fStom
2068641b11fStom	xorl	%eax, %eax
2078641b11fStom	popw	%ax			/* 16-bit return addr on stack */
2088641b11fStom	addl	$LINKADDR, %eax
2098641b11fStom	pushl	%eax			/* Now have correct 32-bit ret addr */
2108641b11fStom	ret
2118641b11fStom
2128641b11fStom	.end
213