1/*	$NetBSD: startprog32.S,v 1.3 2023/04/20 00:42:24 manu Exp $	*/
2/*	NetBSD: startprog.S,v 1.4 2016/12/04 08:21:08 maxv Exp	*/
3
4/*
5 * Ported to boot 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
6 *
7 * Mach Operating System
8 * Copyright (c) 1992, 1991 Carnegie Mellon University
9 * All Rights Reserved.
10 *
11 * Permission to use, copy, modify and distribute this software and its
12 * documentation is hereby granted, provided that both the copyright
13 * notice and this permission notice appear in all copies of the
14 * software, derivative works or modified versions, and any portions
15 * thereof, and that both notices appear in supporting documentation.
16 *
17 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
18 * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
19 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
20 *
21 * Carnegie Mellon requests users of this software to return to
22 *
23 *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
24 *  School of Computer Science
25 *  Carnegie Mellon University
26 *  Pittsburgh PA 15213-3890
27 *
28 * any improvements or extensions that they make and grant Carnegie Mellon
29 * the rights to redistribute these changes.
30 */
31
32/*
33 *   Copyright 1988, 1989, 1990, 1991, 1992
34 *    by Intel Corporation, Santa Clara, California.
35 *
36 *                 All Rights Reserved
37 *
38 * Permission to use, copy, modify, and distribute this software and
39 * its documentation for any purpose and without fee is hereby
40 * granted, provided that the above copyright notice appears in all
41 * copies and that both the copyright notice and this permission notice
42 * appear in supporting documentation, and that the name of Intel
43 * not be used in advertising or publicity pertaining to distribution
44 * of the software without specific, written prior permission.
45 *
46 * INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
47 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
48 * IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
49 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
50 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
51 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
52 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
53 */
54
55#include <machine/asm.h>
56#include <machine/specialreg.h>
57
58#define	CODE_SEGMENT	0x08
59#define	DATA_SEGMENT	0x10
60
61	.align	16
62	.globl _C_LABEL(startprog32)
63_C_LABEL(startprog32):
64	.quad 0
65
66	.globl _C_LABEL(startprog32_size)
67_C_LABEL(startprog32_size):
68	.long startprog32_end - _C_LABEL(startprog32_start)
69
70	.text
71	.p2align 4,,15
72
73/*
74 * startprog32(entry,argc,argv,stack,kern_start,kern_load,kern_size,loadaddr)
75 */
76ENTRY(startprog32_start)
77start:
78	pushl	%ebp
79	movl	%esp, %ebp
80
81	/*
82	 * 8(%ebp): kernel entry address
83	 * 12(%ebp): argc
84	 * 16(%ebp): argv
85	 * 20(%ebp): stack address
86	 * 24(%ebp): kernel start address
87	 * 28(%ebp): loaded kernel address
88	 * 32(%ebp): loaded kernel size
89	 * 36(%ebp): loaded start address
90	 */
91
92	cli
93
94	movl	8(%ebp), %ebx	/* %ebx: entry address */
95	movl	36(%ebp), %edx	/* %edx: loaded start address */
96
97	/* Prepare a new stack */
98	movl	20(%ebp), %eax	/* stack */
99	subl	$4, %eax
100	movl	%eax, %edi
101
102	/* Push some number of args onto the stack */
103	movl	12(%ebp), %ecx	/* argc */
104	movl	%ecx, %eax
105	decl	%eax
106	shl	$2, %eax
107	addl	16(%ebp), %eax	/* ptr to last arg */
108	movl	%eax, %esi
109
110	std			/* backwards */
111	rep
112	movsl			/* copy %ds:(%esi) -> %es:(%edi) */
113	cld
114	mov	%edi, %esp	/* set new stack pointer */
115
116	/* Copy kernel */
117	movl	24(%ebp), %edi	/* dest */
118	movl	28(%ebp), %esi	/* src */
119	movl	32(%ebp), %ecx	/* size */
120
121	/* skip copy if same source and destination */
122	cmpl    %edi,%esi
123	jz      .Lcopy_done
124
125#if defined(NO_OVERLAP)
126	movl	%ecx, %eax
127#else
128	movl	%edi, %eax
129	subl	%esi, %eax
130	cmpl	%ecx, %eax	/* overlapping? */
131	movl	%ecx, %eax
132	jb	.Lbackwards
133#endif
134	/* nope, copy forwards. */
135	shrl	$2, %ecx	/* copy by words */
136	rep
137	movsl
138	and	$3, %eax	/* any bytes left? */
139	jnz	.Ltrailing
140	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