summaryrefslogtreecommitdiff
path: root/gpxe/src/arch/i386/interface/pxe/pxe_entry.S
blob: 0d3a57cd3c3707ec513124b0076a297659c34d00 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
/*
 * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

FILE_LICENCE ( GPL2_OR_LATER )

	.arch i386

/****************************************************************************
 * !PXE structure
 ****************************************************************************
 */
	.section ".text16.data", "aw", @progbits
	.globl ppxe
	.align 16
ppxe:
	.ascii "!PXE"			/* Signature */
	.byte pxe_length		/* StructLength */
	.byte 0				/* StructCksum */
	.byte 0				/* StructRev */
	.byte 0				/* reserved_1 */
	.word undiheader, 0		/* UNDIROMID */
	.word 0, 0			/* BaseROMID */
	.word pxe_entry_sp, 0		/* EntryPointSP */
	.word pxe_entry_esp, 0		/* EntryPointESP */
	.word -1, -1			/* StatusCallout */
	.byte 0				/* reserved_2 */
	.byte SegDescCnt		/* SegDescCnt */
	.word 0				/* FirstSelector */
pxe_segments:
	.word 0, 0, 0, _data16_memsz	/* Stack */
	.word 0, 0, 0, _data16_memsz	/* UNDIData */
	.word 0, 0, 0, _text16_memsz	/* UNDICode */
	.word 0, 0, 0, _text16_memsz	/* UNDICodeWrite */
	.word 0, 0, 0, 0		/* BC_Data */
	.word 0, 0, 0, 0		/* BC_Code */
	.word 0, 0, 0, 0		/* BC_CodeWrite */
	.equ	SegDescCnt, ( ( . - pxe_segments ) / 8 )
	.equ	pxe_length, . - ppxe
	.size	ppxe, . - ppxe

	/* Define undiheader=0 as a weak symbol for non-ROM builds */
	.section ".weak", "a", @nobits
	.weak	undiheader
undiheader:

/****************************************************************************
 * PXENV+ structure
 ****************************************************************************
 */
	.section ".text16.data", "aw", @progbits
	.globl pxenv
	.align 16
pxenv:
	.ascii "PXENV+"			/* Signature */
	.word 0x0201			/* Version */
	.byte pxenv_length		/* Length */
	.byte 0				/* Checksum */
	.word pxenv_entry, 0		/* RMEntry */
	.long 0				/* PMEntry */
	.word 0				/* PMSelector */
	.word 0				/* StackSeg */
	.word _data16_memsz		/* StackSize */
	.word 0				/* BC_CodeSeg */
	.word 0				/* BC_CodeSize */
	.word 0				/* BC_DataSeg */
	.word 0				/* BC_DataSize */
	.word 0				/* UNDIDataSeg */
	.word _data16_memsz		/* UNDIDataSize */
	.word 0				/* UNDICodeSeg */
	.word _text16_memsz		/* UNDICodeSize */
	.word ppxe, 0			/* PXEPtr */
	.equ	pxenv_length, . - pxenv
	.size	pxenv, . - pxenv
 
/****************************************************************************
 * pxenv_entry (16-bit far call)
 *
 * PXE API call PXENV+ entry point
 *
 * Parameters:
 *   %es:di : Far pointer to PXE parameter structure
 *   %bx : PXE API call
 * Returns:
 *   %ax : PXE exit status
 * Corrupts:
 *   none
 ****************************************************************************
 */
	/* Wyse Streaming Manager server (WLDRM13.BIN) assumes that
	 * the PXENV+ entry point is at UNDI_CS:0000; apparently,
	 * somebody at Wyse has difficulty distinguishing between the
	 * words "may" and "must"...
	 */
	.section ".text16.null", "ax", @progbits
	.code16
pxenv_null_entry:
	jmp	pxenv_entry

	.section ".text16", "ax", @progbits
	.code16
pxenv_entry:
	pushl	$pxe_api_call
	pushw	%cs
	call	prot_call
	addl	$4, %esp
	lret
	.size	pxenv_entry, . - pxenv_entry

/****************************************************************************
 * pxe_entry
 *
 * PXE API call !PXE entry point
 *
 * Parameters:
 *   stack : Far pointer to PXE parameter structure
 *   stack : PXE API call
 * Returns:
 *   %ax : PXE exit status
 * Corrupts:
 *   none
 ****************************************************************************
 */
	.section ".text16", "ax", @progbits
	.code16
pxe_entry:
pxe_entry_sp:
	/* Preserve original %esp */
	pushl	%esp
	/* Zero high word of %esp to allow use of common code */
	movzwl	%sp, %esp
	jmp	pxe_entry_common
pxe_entry_esp:
	/* Preserve %esp to match behaviour of pxe_entry_sp */
	pushl	%esp
pxe_entry_common:
	/* Save PXENV+ API call registers */
	pushw	%es
	pushw	%di
	pushw	%bx
	/* Load !PXE parameters from stack into PXENV+ registers */
	addr32 movw	18(%esp), %bx
	movw	%bx, %es
	addr32 movw	16(%esp), %di
	addr32 movw	14(%esp), %bx
	/* Make call as for PXENV+ */
	pushw	%cs
	call	pxenv_entry
	/* Restore PXENV+ registers */
	popw	%bx
	popw	%di
	popw	%es
	/* Restore original %esp and return */
	popl	%esp
	lret
	.size	pxe_entry, . - pxe_entry

/****************************************************************************
 * pxe_int_1a
 *
 * PXE INT 1A handler
 *
 * Parameters:
 *   %ax : 0x5650
 * Returns:
 *   %ax : 0x564e
 *   %es:bx : Far pointer to the PXENV+ structure
 *   %edx : Physical address of the PXENV+ structure
 *   CF cleared
 * Corrupts:
 *   none
 ****************************************************************************
 */
	.section ".text16", "ax", @progbits
	.code16
	.globl	pxe_int_1a
pxe_int_1a:
	pushfw
	cmpw	$0x5650, %ax
	jne	1f
	/* INT 1A,5650 - PXE installation check */
	xorl	%edx, %edx
	movw	%cs, %dx
	movw	%dx, %es
	movw	$pxenv, %bx
	shll	$4, %edx
	addl	$pxenv, %edx
	movw	$0x564e, %ax
	pushw	%bp
	movw	%sp, %bp
	andb	$~0x01, 8(%bp)	/* Clear CF on return */
	popw	%bp
	popfw
	iret
1:	/* INT 1A,other - pass through */
	popfw
	ljmp	*%cs:pxe_int_1a_vector

	.section ".text16.data", "aw", @progbits
	.globl	pxe_int_1a_vector
pxe_int_1a_vector:	.long 0