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