1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * William Jolitz.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 4. Neither the name of the University nor the names of its contributors
17 *    may be used to endorse or promote products derived from this software
18 *    without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 *	from: @(#)locore.s	7.3 (Berkeley) 5/13/91
33 * $FreeBSD$
34 *
35 *		originally from: locore.s, by William F. Jolitz
36 *
37 *		Substantially rewritten by David Greenman, Rod Grimes,
38 *			Bruce Evans, Wolfgang Solfrank, Poul-Henning Kamp
39 *			and many others.
40 */
41
42#include "opt_bootp.h"
43#include "opt_compat.h"
44#include "opt_nfsroot.h"
45#include "opt_global.h"
46#include "opt_pmap.h"
47
48#include <sys/syscall.h>
49#include <sys/reboot.h>
50
51#include <machine/asmacros.h>
52#include <machine/cputypes.h>
53#include <machine/psl.h>
54#include <machine/pmap.h>
55#include <machine/specialreg.h>
56
57#define __ASSEMBLY__
58#include <xen/interface/elfnote.h>
59
60/* The defines below have been lifted out of <machine/xen-public/arch-x86_32.h> */
61#define FLAT_RING1_CS 0xe019    /* GDT index 259 */
62#define FLAT_RING1_DS 0xe021    /* GDT index 260 */
63#define KERNEL_CS FLAT_RING1_CS
64#define KERNEL_DS FLAT_RING1_DS
65
66#include "assym.s"
67
68.section __xen_guest
69	.ascii "LOADER=generic,GUEST_OS=freebsd,GUEST_VER=7.0,XEN_VER=xen-3.0,BSD_SYMTAB,VIRT_BASE=0xc0000000"
70	.byte 0
71
72	ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS,       .asciz, "FreeBSD")
73	ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION,  .asciz, "HEAD")
74	ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION,    .asciz, "xen-3.0")
75	ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE,      .long,  KERNBASE)
76	ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET,   .long,  KERNBASE)
77	ELFNOTE(Xen, XEN_ELFNOTE_ENTRY,          .long,  btext)
78	ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .long,  hypercall_page)
79	ELFNOTE(Xen, XEN_ELFNOTE_HV_START_LOW,   .long,  XEN_HYPERVISOR_VIRT_START)
80#if 0
81	ELFNOTE(Xen, XEN_ELFNOTE_FEATURES,       .asciz, "writable_page_tables|writable_descriptor_tables|auto_translated_physmap|pae_pgdir_above_4gb|supervisor_mode_kernel")
82#endif
83	ELFNOTE(Xen, XEN_ELFNOTE_FEATURES,       .asciz, "writable_page_tables|supervisor_mode_kernel|writable_descriptor_tables")
84
85#ifdef PAE
86	ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE,       .asciz, "yes")
87	ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID,   .long,  PG_V, PG_V)
88#else
89	ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE,       .asciz, "no")
90	ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID,   .long,  PG_V, PG_V)
91#endif
92	ELFNOTE(Xen, XEN_ELFNOTE_LOADER,         .asciz, "generic")
93	ELFNOTE(Xen, XEN_ELFNOTE_SUSPEND_CANCEL, .long,  1)
94
95
96
97/*
98 *	XXX
99 *
100 * Note: This version greatly munged to avoid various assembler errors
101 * that may be fixed in newer versions of gas. Perhaps newer versions
102 * will have more pleasant appearance.
103 */
104
105/*
106 * PTmap is recursive pagemap at top of virtual address space.
107 * Within PTmap, the page directory can be found (third indirection).
108 */
109	.globl	PTmap,PTD,PTDpde
110	.set	PTmap,(PTDPTDI << PDRSHIFT)
111	.set	PTD,PTmap + (PTDPTDI * PAGE_SIZE)
112	.set	PTDpde,PTD + (PTDPTDI * PDESIZE)
113
114/*
115 * Compiled KERNBASE location and the kernel load address
116 */
117	.globl	kernbase
118	.set	kernbase,KERNBASE
119	.globl	kernload
120	.set	kernload,KERNLOAD
121
122/*
123 * Globals
124 */
125	.data
126	ALIGN_DATA			/* just to be sure */
127
128	.space	0x2000			/* space for tmpstk - temporary stack */
129tmpstk:
130
131		.globl	bootinfo
132bootinfo:	.space	BOOTINFO_SIZE	/* bootinfo that we can handle */
133
134		.globl KERNend
135KERNend:	.long	0		/* phys addr end of kernel (just after bss) */
136		.globl physfree
137physfree:	.long	0		/* phys addr of next free page */
138
139	.globl	IdlePTD
140IdlePTD:	.long	0		/* phys addr of kernel PTD */
141
142#ifdef PAE
143	.globl	IdlePDPT
144IdlePDPT:	.long	0		/* phys addr of kernel PDPT */
145#endif
146
147#ifdef SMP
148	.globl	KPTphys
149#endif
150KPTphys:	.long	0		/* phys addr of kernel page tables */
151	.globl	gdtset
152gdtset:		.long	0		/* GDT is valid */
153
154	.globl	proc0kstack
155proc0kstack:	.long	0		/* address of proc 0 kstack space */
156p0kpa:		.long	0		/* phys addr of proc0's STACK */
157
158vm86phystk:	.long	0		/* PA of vm86/bios stack */
159
160	.globl	vm86paddr, vm86pa
161vm86paddr:	.long	0		/* address of vm86 region */
162vm86pa:		.long	0		/* phys addr of vm86 region */
163
164#ifdef PC98
165	.globl	pc98_system_parameter
166pc98_system_parameter:
167	.space	0x240
168#endif
169
170	.globl	avail_space
171avail_space:	.long 0
172
173/**********************************************************************
174 *
175 * Some handy macros
176 *
177 */
178
179/*
180 * We're already in protected mode, so no remapping is needed.
181 */
182#define R(foo) (foo)
183
184#define ALLOCPAGES(foo) \
185	movl	R(physfree), %esi ; \
186	movl	$((foo)*PAGE_SIZE), %eax ; \
187	addl	%esi, %eax ; \
188	movl	%eax, R(physfree) ; \
189	movl	%esi, %edi ; \
190	movl	$((foo)*PAGE_SIZE),%ecx ; \
191	xorl	%eax,%eax ; \
192	cld ; \
193	rep ; \
194	stosb
195
196/*
197 * fillkpt
198 *	eax = page frame address
199 *	ebx = index into page table
200 *	ecx = how many pages to map
201 * 	base = base address of page dir/table
202 *	prot = protection bits
203 */
204#define	fillkpt(base, prot)		  \
205	shll	$PTESHIFT,%ebx		; \
206	addl	base,%ebx		; \
207	orl	$PG_V,%eax		; \
208	orl	prot,%eax		; \
2091:	movl	%eax,(%ebx)		; \
210	addl	$PAGE_SIZE,%eax		; /* increment physical address */ \
211	addl	$PTESIZE,%ebx		; /* next pte */ \
212	loop	1b
213
214/*
215 * fillkptphys(prot)
216 *	eax = physical address
217 *	ecx = how many pages to map
218 *	prot = protection bits
219 */
220#define	fillkptphys(prot)		  \
221	movl	%eax, %ebx		; \
222	shrl	$PAGE_SHIFT, %ebx	; \
223	fillkpt(R(KPTphys), prot)
224
225/* Temporary stack */
226.space 	8192
227tmpstack:
228	.long	tmpstack, KERNEL_DS
229
230	.text
231
232.p2align 12,	0x90
233
234#define HYPERCALL_PAGE_OFFSET 0x1000
235.org HYPERCALL_PAGE_OFFSET
236ENTRY(hypercall_page)
237	.cfi_startproc
238	.skip	0x1000
239	.cfi_endproc
240
241/**********************************************************************
242 *
243 * This is where the bootblocks start us, set the ball rolling...
244 *
245 */
246NON_GPROF_ENTRY(btext)
247	/* At the end of our stack, we shall have free space - so store it */
248	movl	%esp,%ebx
249	movl	%ebx,R(avail_space)
250
251	lss	tmpstack,%esp
252
253	pushl   %esi
254	call	initvalues
255	popl	%esi
256
257	/* Store the CPUID information */
258	xorl	%eax,%eax
259	cpuid					# cpuid 0
260	movl	%eax,R(cpu_high)		# highest capability
261	movl	%ebx,R(cpu_vendor)		# store vendor string
262	movl	%edx,R(cpu_vendor+4)
263	movl	%ecx,R(cpu_vendor+8)
264	movb	$0,R(cpu_vendor+12)
265
266	movl	$1,%eax
267	cpuid					# cpuid 1
268	movl	%eax,R(cpu_id)			# store cpu_id
269	movl	%ebx,R(cpu_procinfo)		# store cpu_procinfo
270	movl	%edx,R(cpu_feature)		# store cpu_feature
271	movl	%ecx,R(cpu_feature2)		# store cpu_feature2
272	rorl	$8,%eax				# extract family type
273	andl	$15,%eax
274	cmpl	$5,%eax
275	movl	$CPU_686,R(cpu)
276
277	movl	proc0kstack,%eax
278	leal	(KSTACK_PAGES*PAGE_SIZE-PCB_SIZE)(%eax),%esp
279	xorl    %ebp,%ebp               /* mark end of frames */
280#ifdef PAE
281	movl    IdlePDPT,%esi
282#else
283	movl    IdlePTD,%esi
284#endif
285	movl    %esi,(KSTACK_PAGES*PAGE_SIZE-PCB_SIZE+PCB_CR3)(%eax)
286	pushl	physfree
287	call	init386
288	addl	$4, %esp
289	call	mi_startup
290	/* NOTREACHED */
291	int	$3
292
293/*
294 * Signal trampoline, copied to top of user stack
295 */
296NON_GPROF_ENTRY(sigcode)
297	calll	*SIGF_HANDLER(%esp)
298	leal	SIGF_UC(%esp),%eax	/* get ucontext */
299	pushl	%eax
300	testl	$PSL_VM,UC_EFLAGS(%eax)
301	jne	1f
302	mov	UC_GS(%eax), %gs	/* restore %gs */
3031:
304	movl	$SYS_sigreturn,%eax
305	pushl	%eax			/* junk to fake return addr. */
306	int	$0x80			/* enter kernel with args */
307					/* on stack */
3081:
309	jmp	1b
310
311#ifdef COMPAT_FREEBSD4
312	ALIGN_TEXT
313freebsd4_sigcode:
314	calll	*SIGF_HANDLER(%esp)
315	leal	SIGF_UC4(%esp),%eax	/* get ucontext */
316	pushl	%eax
317	testl	$PSL_VM,UC4_EFLAGS(%eax)
318	jne	1f
319	mov	UC4_GS(%eax),%gs	/* restore %gs */
3201:
321	movl	$344,%eax		/* 4.x SYS_sigreturn */
322	pushl	%eax			/* junk to fake return addr. */
323	int	$0x80			/* enter kernel with args */
324					/* on stack */
3251:
326	jmp	1b
327#endif
328
329#ifdef COMPAT_43
330	ALIGN_TEXT
331osigcode:
332	call	*SIGF_HANDLER(%esp)	/* call signal handler */
333	lea	SIGF_SC(%esp),%eax	/* get sigcontext */
334	pushl	%eax
335	testl	$PSL_VM,SC_PS(%eax)
336	jne	9f
337	movl	SC_GS(%eax),%gs		/* restore %gs */
3389:
339	movl	$103,%eax		/* 3.x SYS_sigreturn */
340	pushl	%eax			/* junk to fake return addr. */
341	int	$0x80			/* enter kernel with args */
3420:	jmp	0b
343#endif /* COMPAT_43 */
344
345	ALIGN_TEXT
346esigcode:
347
348	.data
349	.globl	szsigcode
350szsigcode:
351	.long	esigcode-sigcode
352#ifdef COMPAT_FREEBSD4
353	.globl	szfreebsd4_sigcode
354szfreebsd4_sigcode:
355	.long	esigcode-freebsd4_sigcode
356#endif
357#ifdef COMPAT_43
358	.globl	szosigcode
359szosigcode:
360	.long	esigcode-osigcode
361#endif
362