133965Sjdp/*	$NetBSD: startprog32.S,v 1.3 2023/04/20 00:42:24 manu Exp $	*/
233965Sjdp/*	NetBSD: startprog.S,v 1.4 2016/12/04 08:21:08 maxv Exp	*/
333965Sjdp
433965Sjdp/*
533965Sjdp * Ported to boot 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
633965Sjdp *
733965Sjdp * Mach Operating System
833965Sjdp * Copyright (c) 1992, 1991 Carnegie Mellon University
933965Sjdp * All Rights Reserved.
1033965Sjdp *
1133965Sjdp * Permission to use, copy, modify and distribute this software and its
1233965Sjdp * documentation is hereby granted, provided that both the copyright
1333965Sjdp * notice and this permission notice appear in all copies of the
1433965Sjdp * software, derivative works or modified versions, and any portions
1533965Sjdp * thereof, and that both notices appear in supporting documentation.
1633965Sjdp *
1733965Sjdp * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
1833965Sjdp * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
1933965Sjdp * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
2077298Sobrien *
2177298Sobrien * Carnegie Mellon requests users of this software to return to
2277298Sobrien *
2333965Sjdp *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
2433965Sjdp *  School of Computer Science
2533965Sjdp *  Carnegie Mellon University
2633965Sjdp *  Pittsburgh PA 15213-3890
2733965Sjdp *
2833965Sjdp * any improvements or extensions that they make and grant Carnegie Mellon
2933965Sjdp * the rights to redistribute these changes.
3033965Sjdp */
3133965Sjdp
3233965Sjdp/*
3333965Sjdp *   Copyright 1988, 1989, 1990, 1991, 1992
3433965Sjdp *    by Intel Corporation, Santa Clara, California.
3533965Sjdp *
3633965Sjdp *                 All Rights Reserved
3733965Sjdp *
3833965Sjdp * Permission to use, copy, modify, and distribute this software and
3933965Sjdp * its documentation for any purpose and without fee is hereby
4033965Sjdp * granted, provided that the above copyright notice appears in all
4133965Sjdp * copies and that both the copyright notice and this permission notice
4260484Sobrien * appear in supporting documentation, and that the name of Intel
4333965Sjdp * not be used in advertising or publicity pertaining to distribution
4433965Sjdp * of the software without specific, written prior permission.
4533965Sjdp *
4633965Sjdp * INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
4733965Sjdp * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
4833965Sjdp * IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
4960484Sobrien * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
5038889Sjdp * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
5138889Sjdp * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
5233965Sjdp * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
5360484Sobrien */
5433965Sjdp
5533965Sjdp#include <machine/asm.h>
5633965Sjdp#include <machine/specialreg.h>
5733965Sjdp
5833965Sjdp#define	CODE_SEGMENT	0x08
5933965Sjdp#define	DATA_SEGMENT	0x10
6060484Sobrien
6138889Sjdp	.align	16
6233965Sjdp	.globl _C_LABEL(startprog32)
6333965Sjdp_C_LABEL(startprog32):
6460484Sobrien	.quad 0
6533965Sjdp
6633965Sjdp	.globl _C_LABEL(startprog32_size)
6777298Sobrien_C_LABEL(startprog32_size):
6877298Sobrien	.long startprog32_end - _C_LABEL(startprog32_start)
6977298Sobrien
7077298Sobrien	.text
7177298Sobrien	.p2align 4,,15
7277298Sobrien
7377298Sobrien/*
7477298Sobrien * startprog32(entry,argc,argv,stack,kern_start,kern_load,kern_size,loadaddr)
7577298Sobrien */
7677298SobrienENTRY(startprog32_start)
7777298Sobrienstart:
7877298Sobrien	pushl	%ebp
7977298Sobrien	movl	%esp, %ebp
8077298Sobrien
8177298Sobrien	/*
8277298Sobrien	 * 8(%ebp): kernel entry address
8377298Sobrien	 * 12(%ebp): argc
8477298Sobrien	 * 16(%ebp): argv
8577298Sobrien	 * 20(%ebp): stack address
8677298Sobrien	 * 24(%ebp): kernel start address
8777298Sobrien	 * 28(%ebp): loaded kernel address
8877298Sobrien	 * 32(%ebp): loaded kernel size
8977298Sobrien	 * 36(%ebp): loaded start address
9077298Sobrien	 */
9177298Sobrien
9233965Sjdp	cli
9333965Sjdp
9433965Sjdp	movl	8(%ebp), %ebx	/* %ebx: entry address */
9533965Sjdp	movl	36(%ebp), %edx	/* %edx: loaded start address */
9633965Sjdp
9733965Sjdp	/* Prepare a new stack */
9833965Sjdp	movl	20(%ebp), %eax	/* stack */
9933965Sjdp	subl	$4, %eax
10033965Sjdp	movl	%eax, %edi
10133965Sjdp
10277298Sobrien	/* Push some number of args onto the stack */
10333965Sjdp	movl	12(%ebp), %ecx	/* argc */
10433965Sjdp	movl	%ecx, %eax
10533965Sjdp	decl	%eax
10633965Sjdp	shl	$2, %eax
10733965Sjdp	addl	16(%ebp), %eax	/* ptr to last arg */
10860484Sobrien	movl	%eax, %esi
10960484Sobrien
11060484Sobrien	std			/* backwards */
11160484Sobrien	rep
11260484Sobrien	movsl			/* copy %ds:(%esi) -> %es:(%edi) */
11360484Sobrien	cld
11460484Sobrien	mov	%edi, %esp	/* set new stack pointer */
11560484Sobrien
11660484Sobrien	/* Copy kernel */
11760484Sobrien	movl	24(%ebp), %edi	/* dest */
11877298Sobrien	movl	28(%ebp), %esi	/* src */
11960484Sobrien	movl	32(%ebp), %ecx	/* size */
12060484Sobrien
12160484Sobrien	/* skip copy if same source and destination */
12260484Sobrien	cmpl    %edi,%esi
12360484Sobrien	jz      .Lcopy_done
12433965Sjdp
12533965Sjdp#if defined(NO_OVERLAP)
12633965Sjdp	movl	%ecx, %eax
12733965Sjdp#else
12833965Sjdp	movl	%edi, %eax
12933965Sjdp	subl	%esi, %eax
13033965Sjdp	cmpl	%ecx, %eax	/* overlapping? */
13133965Sjdp	movl	%ecx, %eax
13233965Sjdp	jb	.Lbackwards
13333965Sjdp#endif
13433965Sjdp	/* nope, copy forwards. */
13533965Sjdp	shrl	$2, %ecx	/* copy by words */
13633965Sjdp	rep
13777298Sobrien	movsl
13833965Sjdp	and	$3, %eax	/* any bytes left? */
13933965Sjdp	jnz	.Ltrailing
14033965Sjdp	jmp	.Lcopy_done
141
142.Ltrailing:
143	cmp	$2, %eax
144	jb	1f
145	movw	(%esi), %ax
146	movw	%ax, (%edi)
147	je	.Lcopy_done
148	movb	2(%esi), %al
149	movb	%al, 2(%edi)
150	jmp	.Lcopy_done
1511:	movb	(%esi), %al
152	movb	%al, (%edi)
153	jmp	.Lcopy_done
154
155#if !defined(NO_OVERLAP)
156.Lbackwards:
157	addl	%ecx, %edi	/* copy backwards. */
158	addl	%ecx, %esi
159	and	$3, %eax	/* any fractional bytes? */
160	jnz	.Lback_align
161.Lback_aligned:
162	shrl	$2, %ecx
163	subl	$4, %esi
164	subl	$4, %edi
165	std
166	rep
167	movsl
168	cld
169	jmp	.Lcopy_done
170
171.Lback_align:
172	sub	%eax, %esi
173	sub	%eax, %edi
174	cmp	$2, %eax
175	jb	1f
176	je	2f
177	movb	2(%esi), %al
178	movb	%al, 2(%edi)
1792:	movw	(%esi), %ax
180	movw	%ax, (%edi)
181	jmp	.Lback_aligned
1821:	movb	(%esi), %al
183	movb	%al, (%edi)
184	jmp	.Lback_aligned
185#endif
186	/* End of copy kernel */
187.Lcopy_done:
188	cld			/* LynxOS depends on it */
189
190	/* Prepare jump address */
191	lea	(start32a - start)(%edx), %eax
192	movl	%eax, (start32r - start)(%edx)
193
194	/* Setup GDT */
195	lea	(gdt - start)(%edx), %eax
196	movl	%eax, (gdtrr - start)(%edx)
197	lgdt	(gdtr - start)(%edx)
198
199	/* Jump to set %cs */
200	ljmp	*(start32r - start)(%edx)
201
202	.align	4
203start32a:
204	movl	$DATA_SEGMENT, %eax
205	movw	%ax, %ds
206	movw	%ax, %es
207	movw	%ax, %fs
208	movw	%ax, %gs
209	movw	%ax, %ss
210
211	/* Already set new stack pointer */
212	movl	%esp, %ebp
213
214	/* Disable Paging in CR0 */
215	movl	%cr0, %eax
216	andl	$(~CR0_PG), %eax
217	movl	%eax, %cr0
218
219	/* Disable PAE in CR4 */
220	movl	%cr4, %eax
221	andl	$(~CR4_PAE), %eax
222	movl	%eax, %cr4
223
224	jmp	start32b
225
226	.align	4
227start32b:
228	xor	%eax, %eax
229	movl	%ebx, (start32r - start)(%edx)
230	ljmp	*(start32r - start)(%edx)
231
232	.align	16
233start32r:
234	.long	0
235	.long	CODE_SEGMENT
236	.align	16
237gdt:
238	.long	0, 0
239	.byte	0xff, 0xff, 0x00, 0x00, 0x00, 0x9f, 0xcf, 0x00
240	.byte	0xff, 0xff, 0x00, 0x00, 0x00, 0x93, 0xcf, 0x00
241gdtr:
242	.word	gdtr - gdt
243gdtrr:
244	.quad
245start32end:
246	/* Space for the stack */
247	.align	16
248	.space	8192
249startprog32_end:
250