1181641Skmacy/*-
2181641Skmacy * Copyright (c) 1990 The Regents of the University of California.
3181641Skmacy * All rights reserved.
4181641Skmacy *
5181641Skmacy * This code is derived from software contributed to Berkeley by
6181641Skmacy * William Jolitz.
7181641Skmacy *
8181641Skmacy * Redistribution and use in source and binary forms, with or without
9181641Skmacy * modification, are permitted provided that the following conditions
10181641Skmacy * are met:
11181641Skmacy * 1. Redistributions of source code must retain the above copyright
12181641Skmacy *    notice, this list of conditions and the following disclaimer.
13181641Skmacy * 2. Redistributions in binary form must reproduce the above copyright
14181641Skmacy *    notice, this list of conditions and the following disclaimer in the
15181641Skmacy *    documentation and/or other materials provided with the distribution.
16181641Skmacy * 4. Neither the name of the University nor the names of its contributors
17181641Skmacy *    may be used to endorse or promote products derived from this software
18181641Skmacy *    without specific prior written permission.
19181641Skmacy *
20181641Skmacy * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21181641Skmacy * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22181641Skmacy * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23181641Skmacy * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24181641Skmacy * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25181641Skmacy * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26181641Skmacy * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27181641Skmacy * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28181641Skmacy * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29181641Skmacy * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30181641Skmacy * SUCH DAMAGE.
31181641Skmacy *
32181641Skmacy *	from: @(#)locore.s	7.3 (Berkeley) 5/13/91
33181641Skmacy * $FreeBSD$
34181641Skmacy *
35181641Skmacy *		originally from: locore.s, by William F. Jolitz
36181641Skmacy *
37181641Skmacy *		Substantially rewritten by David Greenman, Rod Grimes,
38181641Skmacy *			Bruce Evans, Wolfgang Solfrank, Poul-Henning Kamp
39181641Skmacy *			and many others.
40181641Skmacy */
41181641Skmacy
42181641Skmacy#include "opt_bootp.h"
43181641Skmacy#include "opt_compat.h"
44181641Skmacy#include "opt_nfsroot.h"
45181641Skmacy#include "opt_global.h"
46181641Skmacy#include "opt_pmap.h"
47181641Skmacy
48181641Skmacy#include <sys/syscall.h>
49181641Skmacy#include <sys/reboot.h>
50181641Skmacy
51181641Skmacy#include <machine/asmacros.h>
52181641Skmacy#include <machine/cputypes.h>
53181641Skmacy#include <machine/psl.h>
54181641Skmacy#include <machine/pmap.h>
55181641Skmacy#include <machine/specialreg.h>
56181641Skmacy
57181641Skmacy#define __ASSEMBLY__
58181641Skmacy#include <xen/interface/elfnote.h>
59181641Skmacy
60181641Skmacy/* The defines below have been lifted out of <machine/xen-public/arch-x86_32.h> */
61181641Skmacy#define FLAT_RING1_CS 0xe019    /* GDT index 259 */
62181641Skmacy#define FLAT_RING1_DS 0xe021    /* GDT index 260 */
63181641Skmacy#define KERNEL_CS FLAT_RING1_CS
64181641Skmacy#define KERNEL_DS FLAT_RING1_DS
65181641Skmacy
66181641Skmacy#include "assym.s"
67181641Skmacy
68181641Skmacy.section __xen_guest
69181641Skmacy	.ascii "LOADER=generic,GUEST_OS=freebsd,GUEST_VER=7.0,XEN_VER=xen-3.0,BSD_SYMTAB,VIRT_BASE=0xc0000000"
70181641Skmacy	.byte 0
71182697Skmacy
72181641Skmacy	ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS,       .asciz, "FreeBSD")
73181641Skmacy	ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION,  .asciz, "HEAD")
74181641Skmacy	ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION,    .asciz, "xen-3.0")
75181641Skmacy	ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE,      .long,  KERNBASE)
76181641Skmacy	ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET,   .long,  KERNBASE)
77181641Skmacy	ELFNOTE(Xen, XEN_ELFNOTE_ENTRY,          .long,  btext)
78181641Skmacy	ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .long,  hypercall_page)
79254671Sgibbs	ELFNOTE(Xen, XEN_ELFNOTE_HV_START_LOW,   .long,  XEN_HYPERVISOR_VIRT_START)
80181641Skmacy#if 0
81181641Skmacy	ELFNOTE(Xen, XEN_ELFNOTE_FEATURES,       .asciz, "writable_page_tables|writable_descriptor_tables|auto_translated_physmap|pae_pgdir_above_4gb|supervisor_mode_kernel")
82181641Skmacy#endif
83181641Skmacy	ELFNOTE(Xen, XEN_ELFNOTE_FEATURES,       .asciz, "writable_page_tables|supervisor_mode_kernel|writable_descriptor_tables")
84181641Skmacy
85181641Skmacy#ifdef PAE
86181641Skmacy	ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE,       .asciz, "yes")
87181641Skmacy	ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID,   .long,  PG_V, PG_V)
88181641Skmacy#else
89181641Skmacy	ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE,       .asciz, "no")
90181641Skmacy	ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID,   .long,  PG_V, PG_V)
91181641Skmacy#endif
92181641Skmacy	ELFNOTE(Xen, XEN_ELFNOTE_LOADER,         .asciz, "generic")
93181641Skmacy	ELFNOTE(Xen, XEN_ELFNOTE_SUSPEND_CANCEL, .long,  1)
94181641Skmacy
95181641Skmacy
96181641Skmacy
97181641Skmacy/*
98181641Skmacy *	XXX
99181641Skmacy *
100181641Skmacy * Note: This version greatly munged to avoid various assembler errors
101181641Skmacy * that may be fixed in newer versions of gas. Perhaps newer versions
102181641Skmacy * will have more pleasant appearance.
103181641Skmacy */
104181641Skmacy
105181641Skmacy/*
106181641Skmacy * PTmap is recursive pagemap at top of virtual address space.
107181641Skmacy * Within PTmap, the page directory can be found (third indirection).
108181641Skmacy */
109181641Skmacy	.globl	PTmap,PTD,PTDpde
110181641Skmacy	.set	PTmap,(PTDPTDI << PDRSHIFT)
111181641Skmacy	.set	PTD,PTmap + (PTDPTDI * PAGE_SIZE)
112181641Skmacy	.set	PTDpde,PTD + (PTDPTDI * PDESIZE)
113181641Skmacy
114181641Skmacy/*
115181641Skmacy * Compiled KERNBASE location and the kernel load address
116181641Skmacy */
117181641Skmacy	.globl	kernbase
118181641Skmacy	.set	kernbase,KERNBASE
119181641Skmacy	.globl	kernload
120181641Skmacy	.set	kernload,KERNLOAD
121181641Skmacy
122181641Skmacy/*
123181641Skmacy * Globals
124181641Skmacy */
125181641Skmacy	.data
126181641Skmacy	ALIGN_DATA			/* just to be sure */
127181641Skmacy
128181641Skmacy	.space	0x2000			/* space for tmpstk - temporary stack */
129181641Skmacytmpstk:
130181641Skmacy
131181641Skmacy		.globl	bootinfo
132181641Skmacybootinfo:	.space	BOOTINFO_SIZE	/* bootinfo that we can handle */
133181641Skmacy
134181641Skmacy		.globl KERNend
135181641SkmacyKERNend:	.long	0		/* phys addr end of kernel (just after bss) */
136181641Skmacy		.globl physfree
137181641Skmacyphysfree:	.long	0		/* phys addr of next free page */
138181641Skmacy
139181641Skmacy	.globl	IdlePTD
140181641SkmacyIdlePTD:	.long	0		/* phys addr of kernel PTD */
141181641Skmacy
142181641Skmacy#ifdef PAE
143181641Skmacy	.globl	IdlePDPT
144181641SkmacyIdlePDPT:	.long	0		/* phys addr of kernel PDPT */
145181641Skmacy#endif
146181641Skmacy
147181641Skmacy#ifdef SMP
148181641Skmacy	.globl	KPTphys
149181641Skmacy#endif
150181641SkmacyKPTphys:	.long	0		/* phys addr of kernel page tables */
151181747Skmacy	.globl	gdtset
152181747Skmacygdtset:		.long	0		/* GDT is valid */
153181641Skmacy
154181641Skmacy	.globl	proc0kstack
155181641Skmacyproc0kstack:	.long	0		/* address of proc 0 kstack space */
156181641Skmacyp0kpa:		.long	0		/* phys addr of proc0's STACK */
157181641Skmacy
158181641Skmacyvm86phystk:	.long	0		/* PA of vm86/bios stack */
159181641Skmacy
160181641Skmacy	.globl	vm86paddr, vm86pa
161181641Skmacyvm86paddr:	.long	0		/* address of vm86 region */
162181641Skmacyvm86pa:		.long	0		/* phys addr of vm86 region */
163181641Skmacy
164181641Skmacy#ifdef PC98
165181641Skmacy	.globl	pc98_system_parameter
166181641Skmacypc98_system_parameter:
167181641Skmacy	.space	0x240
168181641Skmacy#endif
169181641Skmacy
170181641Skmacy	.globl	avail_space
171181641Skmacyavail_space:	.long 0
172181641Skmacy
173181641Skmacy/**********************************************************************
174181641Skmacy *
175181641Skmacy * Some handy macros
176181641Skmacy *
177181641Skmacy */
178181641Skmacy
179181641Skmacy/*
180181641Skmacy * We're already in protected mode, so no remapping is needed.
181181641Skmacy */
182181641Skmacy#define R(foo) (foo)
183181641Skmacy
184181641Skmacy#define ALLOCPAGES(foo) \
185181641Skmacy	movl	R(physfree), %esi ; \
186181641Skmacy	movl	$((foo)*PAGE_SIZE), %eax ; \
187181641Skmacy	addl	%esi, %eax ; \
188181641Skmacy	movl	%eax, R(physfree) ; \
189181641Skmacy	movl	%esi, %edi ; \
190181641Skmacy	movl	$((foo)*PAGE_SIZE),%ecx ; \
191181641Skmacy	xorl	%eax,%eax ; \
192181641Skmacy	cld ; \
193181641Skmacy	rep ; \
194181641Skmacy	stosb
195181641Skmacy
196181641Skmacy/*
197181641Skmacy * fillkpt
198181641Skmacy *	eax = page frame address
199181641Skmacy *	ebx = index into page table
200181641Skmacy *	ecx = how many pages to map
201181641Skmacy * 	base = base address of page dir/table
202181641Skmacy *	prot = protection bits
203181641Skmacy */
204181641Skmacy#define	fillkpt(base, prot)		  \
205181641Skmacy	shll	$PTESHIFT,%ebx		; \
206181641Skmacy	addl	base,%ebx		; \
207181641Skmacy	orl	$PG_V,%eax		; \
208181641Skmacy	orl	prot,%eax		; \
209181641Skmacy1:	movl	%eax,(%ebx)		; \
210181641Skmacy	addl	$PAGE_SIZE,%eax		; /* increment physical address */ \
211181641Skmacy	addl	$PTESIZE,%ebx		; /* next pte */ \
212181641Skmacy	loop	1b
213181641Skmacy
214181641Skmacy/*
215181641Skmacy * fillkptphys(prot)
216181641Skmacy *	eax = physical address
217181641Skmacy *	ecx = how many pages to map
218181641Skmacy *	prot = protection bits
219181641Skmacy */
220181641Skmacy#define	fillkptphys(prot)		  \
221181641Skmacy	movl	%eax, %ebx		; \
222181641Skmacy	shrl	$PAGE_SHIFT, %ebx	; \
223181641Skmacy	fillkpt(R(KPTphys), prot)
224181641Skmacy
225181641Skmacy/* Temporary stack */
226181641Skmacy.space 	8192
227181641Skmacytmpstack:
228181641Skmacy	.long	tmpstack, KERNEL_DS
229181641Skmacy
230181641Skmacy	.text
231181641Skmacy
232181641Skmacy.p2align 12,	0x90
233181641Skmacy
234181641Skmacy#define HYPERCALL_PAGE_OFFSET 0x1000
235181641Skmacy.org HYPERCALL_PAGE_OFFSET
236181641SkmacyENTRY(hypercall_page)
237181641Skmacy	.cfi_startproc
238181641Skmacy	.skip	0x1000
239181641Skmacy	.cfi_endproc
240181641Skmacy
241181641Skmacy/**********************************************************************
242181641Skmacy *
243181641Skmacy * This is where the bootblocks start us, set the ball rolling...
244181641Skmacy *
245181641Skmacy */
246181641SkmacyNON_GPROF_ENTRY(btext)
247181641Skmacy	/* At the end of our stack, we shall have free space - so store it */
248181641Skmacy	movl	%esp,%ebx
249181641Skmacy	movl	%ebx,R(avail_space)
250181641Skmacy
251181641Skmacy	lss	tmpstack,%esp
252181641Skmacy
253181641Skmacy	pushl   %esi
254181641Skmacy	call	initvalues
255181641Skmacy	popl	%esi
256181641Skmacy
257181641Skmacy	/* Store the CPUID information */
258181641Skmacy	xorl	%eax,%eax
259181641Skmacy	cpuid					# cpuid 0
260181641Skmacy	movl	%eax,R(cpu_high)		# highest capability
261181641Skmacy	movl	%ebx,R(cpu_vendor)		# store vendor string
262181641Skmacy	movl	%edx,R(cpu_vendor+4)
263181641Skmacy	movl	%ecx,R(cpu_vendor+8)
264181641Skmacy	movb	$0,R(cpu_vendor+12)
265181641Skmacy
266181641Skmacy	movl	$1,%eax
267181641Skmacy	cpuid					# cpuid 1
268181641Skmacy	movl	%eax,R(cpu_id)			# store cpu_id
269181641Skmacy	movl	%ebx,R(cpu_procinfo)		# store cpu_procinfo
270181641Skmacy	movl	%edx,R(cpu_feature)		# store cpu_feature
271181641Skmacy	movl	%ecx,R(cpu_feature2)		# store cpu_feature2
272181641Skmacy	rorl	$8,%eax				# extract family type
273181641Skmacy	andl	$15,%eax
274181641Skmacy	cmpl	$5,%eax
275181641Skmacy	movl	$CPU_686,R(cpu)
276181641Skmacy
277181641Skmacy	movl	proc0kstack,%eax
278181641Skmacy	leal	(KSTACK_PAGES*PAGE_SIZE-PCB_SIZE)(%eax),%esp
279181641Skmacy	xorl    %ebp,%ebp               /* mark end of frames */
280181641Skmacy#ifdef PAE
281181641Skmacy	movl    IdlePDPT,%esi
282181641Skmacy#else
283181641Skmacy	movl    IdlePTD,%esi
284181641Skmacy#endif
285181641Skmacy	movl    %esi,(KSTACK_PAGES*PAGE_SIZE-PCB_SIZE+PCB_CR3)(%eax)
286181641Skmacy	pushl	physfree
287181641Skmacy	call	init386
288181641Skmacy	addl	$4, %esp
289181641Skmacy	call	mi_startup
290181641Skmacy	/* NOTREACHED */
291181641Skmacy	int	$3
292181641Skmacy
293181641Skmacy/*
294181641Skmacy * Signal trampoline, copied to top of user stack
295181641Skmacy */
296181641SkmacyNON_GPROF_ENTRY(sigcode)
297181641Skmacy	calll	*SIGF_HANDLER(%esp)
298181641Skmacy	leal	SIGF_UC(%esp),%eax	/* get ucontext */
299181641Skmacy	pushl	%eax
300181641Skmacy	testl	$PSL_VM,UC_EFLAGS(%eax)
301181641Skmacy	jne	1f
302181641Skmacy	mov	UC_GS(%eax), %gs	/* restore %gs */
303181641Skmacy1:
304181641Skmacy	movl	$SYS_sigreturn,%eax
305181641Skmacy	pushl	%eax			/* junk to fake return addr. */
306181641Skmacy	int	$0x80			/* enter kernel with args */
307181641Skmacy					/* on stack */
308181641Skmacy1:
309181641Skmacy	jmp	1b
310181641Skmacy
311181641Skmacy#ifdef COMPAT_FREEBSD4
312181641Skmacy	ALIGN_TEXT
313181641Skmacyfreebsd4_sigcode:
314181641Skmacy	calll	*SIGF_HANDLER(%esp)
315181641Skmacy	leal	SIGF_UC4(%esp),%eax	/* get ucontext */
316181641Skmacy	pushl	%eax
317181641Skmacy	testl	$PSL_VM,UC4_EFLAGS(%eax)
318181641Skmacy	jne	1f
319181641Skmacy	mov	UC4_GS(%eax),%gs	/* restore %gs */
320181641Skmacy1:
321181641Skmacy	movl	$344,%eax		/* 4.x SYS_sigreturn */
322181641Skmacy	pushl	%eax			/* junk to fake return addr. */
323181641Skmacy	int	$0x80			/* enter kernel with args */
324181641Skmacy					/* on stack */
325181641Skmacy1:
326181641Skmacy	jmp	1b
327181641Skmacy#endif
328181641Skmacy
329181641Skmacy#ifdef COMPAT_43
330181641Skmacy	ALIGN_TEXT
331181641Skmacyosigcode:
332181641Skmacy	call	*SIGF_HANDLER(%esp)	/* call signal handler */
333181641Skmacy	lea	SIGF_SC(%esp),%eax	/* get sigcontext */
334181641Skmacy	pushl	%eax
335181641Skmacy	testl	$PSL_VM,SC_PS(%eax)
336181641Skmacy	jne	9f
337181641Skmacy	movl	SC_GS(%eax),%gs		/* restore %gs */
338181641Skmacy9:
339181641Skmacy	movl	$103,%eax		/* 3.x SYS_sigreturn */
340181641Skmacy	pushl	%eax			/* junk to fake return addr. */
341181641Skmacy	int	$0x80			/* enter kernel with args */
342181641Skmacy0:	jmp	0b
343181641Skmacy#endif /* COMPAT_43 */
344181641Skmacy
345181641Skmacy	ALIGN_TEXT
346181641Skmacyesigcode:
347181641Skmacy
348181641Skmacy	.data
349181641Skmacy	.globl	szsigcode
350181641Skmacyszsigcode:
351181641Skmacy	.long	esigcode-sigcode
352181641Skmacy#ifdef COMPAT_FREEBSD4
353181641Skmacy	.globl	szfreebsd4_sigcode
354181641Skmacyszfreebsd4_sigcode:
355181641Skmacy	.long	esigcode-freebsd4_sigcode
356181641Skmacy#endif
357181641Skmacy#ifdef COMPAT_43
358181641Skmacy	.globl	szosigcode
359181641Skmacyszosigcode:
360181641Skmacy	.long	esigcode-osigcode
361181641Skmacy#endif
362