1/*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28/*
29 * @OSF_COPYRIGHT@
30 */
31
32/*
33 * Mach Operating System
34 * Copyright (c) 1991,1990 Carnegie Mellon University
35 * All Rights Reserved.
36 *
37 * Permission to use, copy, modify and distribute this software and its
38 * documentation is hereby granted, provided that both the copyright
39 * notice and this permission notice appear in all copies of the
40 * software, derivative works or modified versions, and any portions
41 * thereof, and that both notices appear in supporting documentation.
42 *
43 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
44 * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
45 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
46 *
47 * Carnegie Mellon requests users of this software to return to
48 *
49 *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
50 *  School of Computer Science
51 *  Carnegie Mellon University
52 *  Pittsburgh PA 15213-3890
53 *
54 * any improvements or extensions that they make and grant Carnegie Mellon
55 * the rights to redistribute these changes.
56 */
57
58#include <i386/asm.h>
59#include <i386/mp_slave_boot.h>
60#include <i386/postcode.h>
61
62#define CR0_PE_ON	0x1
63#define CR0_PE_OFF	0xfffffffe
64
65	.file	"slave_boot.s"
66
67	.text
68	.align	12		// Page align for single bcopy_phys()
69
70#define	operand_size_prefix	.byte 0x66
71#define	address_size_prefix	.byte 0x67
72
73#define	LJMP(segment,address)			\
74	operand_size_prefix			;\
75	.byte	0xea				;\
76	.long	address-EXT(slave_boot_base)	;\
77	.word	segment
78
79#define	LGDT(address)				\
80	address_size_prefix			;\
81	operand_size_prefix			;\
82	.word	0x010f				;\
83	.byte	0x15				;\
84	.long	address-EXT(slave_boot_base)
85
86Entry(slave_boot_base)
87	/* code is loaded at 0x0:0x1000 */
88	/* ljmp to the next instruction to set up %cs */
89	LJMP(MP_BOOTSEG, EXT(slave_rstart))
90
91Entry(slave_rstart)
92	/* set up %ds */
93	mov	%cs, %ax
94	mov	%ax, %ds
95
96	POSTCODE(SLAVE_RSTART_ENTRY);
97
98	/* set up %ss and %esp */
99	mov	%cs, %ax
100	mov	%ax, %ss
101	mov	$(MP_BOOTSTACK), %esp
102
103	/*set up %es */
104	mov	%ax, %es
105
106	/* change to protected mode */
107	operand_size_prefix
108	call	EXT(slave_real_to_prot)
109
110	push	MP_MACH_START
111	call	EXT(slave_startprog)
112
113/*
114 slave_real_to_prot()
115 	transfer from real mode to protected mode.
116*/
117
118Entry(slave_real_to_prot)
119	/* guarantee that interrupt is disabled when in prot mode */
120	cli
121
122	POSTCODE(SLAVE_REAL_TO_PROT_ENTRY);
123
124	/* load the gdtr */
125	LGDT(EXT(gdtr))
126
127	/* load the gdtr */
128	/* set the PE bit of CR0 */
129	mov	%cr0, %eax
130	or	$(CR0_PE_ON), %eax
131	mov	%eax, %cr0
132
133	/* make intrasegment jump to flush the processor pipeline and */
134	/* reload CS register */
135	LJMP(0x08, xprot)
136xprot:
137
138	/* we are in USE32 mode now */
139	/* set up the protective mode segment registers : DS, SS, ES */
140	mov	$0x10, %eax
141	movw	%ax, %ds
142	movw	%ax, %ss
143	movw	%ax, %es
144
145	POSTCODE(SLAVE_REAL_TO_PROT_EXIT);
146
147	ret
148
149/*
150 slave_startprog(phyaddr)
151	start the program on protected mode where phyaddr is the entry point
152*/
153
154Entry(slave_startprog)
155	push	%ebp
156	movl	%esp, %ebp
157
158	POSTCODE(SLAVE_STARTPROG_ENTRY);
159
160	movl	0x8(%ebp), %ecx		/* entry offset  */
161	movl	$0x28, %ebx		/* segment */
162	push	%ebx
163	push	%ecx
164
165	/* set up %ds and %es */
166	movl	$0x20, %ebx
167	movw	%bx, %ds
168	movw	%bx, %es
169
170	POSTCODE(SLAVE_STARTPROG_EXIT);
171
172	lret
173
174
175	. = MP_BOOTGDT-MP_BOOT	/* GDT location */
176Entry(Gdt)
177
178/*  Segment Descriptor
179 *
180 * 31          24         19   16                 7           0
181 * ------------------------------------------------------------
182 * |             | |B| |A|       | |   |1|0|E|W|A|            |
183 * | BASE 31..24 |G|/|0|V| LIMIT |P|DPL|  TYPE   | BASE 23:16 |
184 * |             | |D| |L| 19..16| |   |1|1|C|R|A|            |
185 * ------------------------------------------------------------
186 * |                             |                            |
187 * |        BASE 15..0           |       LIMIT 15..0          |
188 * |                             |                            |
189 * ------------------------------------------------------------
190 */
191	.word	0,0		/* 0x0 : null */
192	.byte	0,0,0,0
193
194	.word	0xffff,MP_BOOT	/* 0x8 : boot code */
195	.byte	0,0x9e,0xcf,0
196
197	.word	0xffff,MP_BOOT	/* 0x10 : boot data */
198	.byte	0,0x92,0xcf,0
199
200	.word	0xffff,MP_BOOT	/* 0x18 : boot code, 16 bits */
201	.byte	0,0x9e,0x0,0
202
203	.word	0xffff,0	/* 0x20 : init data */
204	.byte	0,0x9f,0xcf,0
205
206	.word	0xffff,0	/* 0x28 : init code */
207	.byte	0,0x9f,0xcf,0
208
209Entry(gdtr)
210	.short	48		/* limit (8*6 segs) */
211	.short	MP_BOOTGDT	/* base low */
212	.short	0		/* base high */
213
214Entry(slave_boot_end)
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229