1221271Smarcel/*-
2221271Smarcel * Copyright (c) 2011 Marcel Moolenaar
3221271Smarcel * All rights reserved.
4221271Smarcel *
5221271Smarcel * Redistribution and use in source and binary forms, with or without
6221271Smarcel * modification, are permitted provided that the following conditions
7221271Smarcel * are met:
8221271Smarcel * 1. Redistributions of source code must retain the above copyright
9221271Smarcel *    notice, this list of conditions and the following disclaimer.
10221271Smarcel * 2. Redistributions in binary form must reproduce the above copyright
11221271Smarcel *    notice, this list of conditions and the following disclaimer in the
12221271Smarcel *    documentation and/or other materials provided with the distribution.
13221271Smarcel *
14221271Smarcel * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15221271Smarcel * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16221271Smarcel * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17221271Smarcel * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18221271Smarcel * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19221271Smarcel * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20221271Smarcel * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21221271Smarcel * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22221271Smarcel * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23221271Smarcel * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24221271Smarcel * SUCH DAMAGE.
25221271Smarcel *
26221271Smarcel * $FreeBSD$
27221271Smarcel */
28221271Smarcel
29221271Smarcel#include <machine/asm.h>
30221271Smarcel#include <machine/ia64_cpu.h>
31221271Smarcel#include <machine/pte.h>
32221271Smarcel#include <assym.s>
33221271Smarcel
34221271Smarcel/*
35221271Smarcel * AP wake-up entry point. The handoff state is similar as for the BSP,
36221271Smarcel * as described on page 3-9 of the IPF SAL Specification. The difference
37221271Smarcel * lies in the contents of register b0. For APs this register holds the
38221271Smarcel * return address into the SAL rendezvous routine.
39221271Smarcel *
40221271Smarcel * Note that we're responsible for clearing the IRR bit by reading cr.ivr
41221271Smarcel * and issuing the EOI to the local SAPIC.
42221271Smarcel */
43221271Smarcel	.align	32
44221271SmarcelENTRY_NOPROFILE(os_boot_rendez,0)
45221271Smarcel{	.mmi
46221271Smarcel	st8	[gp] = gp		// trace = 0x00
47221271Smarcel	mov	r8 = cr.ivr		// clear IRR bit
48221271Smarcel	add	r2 = 8, gp
49221271Smarcel	;;
50221271Smarcel}
51221271Smarcel{	.mmi
52221271Smarcel	srlz.d
53221271Smarcel	mov	cr.eoi = r0		// ACK the wake-up
54221271Smarcel	add	r3 = 16, gp
55221271Smarcel	;;
56221271Smarcel}
57221271Smarcel{	.mmi
58221271Smarcel	srlz.d
59221271Smarcel	rsm	IA64_PSR_IC | IA64_PSR_I
60221271Smarcel	mov	r16 = (IA64_PBVM_RR << 8) | (IA64_PBVM_PAGE_SHIFT << 2)
61221271Smarcel	;;
62221271Smarcel}
63221271Smarcel{	.mmi
64221271Smarcel	srlz.d
65221271Smarcel	st8	[gp] = r2		// trace = 0x08
66221271Smarcel	dep.z	r17 = IA64_PBVM_RR, 61, 3
67221271Smarcel	;;
68221271Smarcel}
69221271Smarcel{	.mlx
70221271Smarcel	mov     rr[r17] = r16
71221271Smarcel	movl	r18 = IA64_PBVM_PGTBL
72221271Smarcel	;;
73221271Smarcel}
74221271Smarcel{	.mmi
75221271Smarcel	srlz.i
76221271Smarcel	;;
77221271Smarcel	st8	[gp] = r3		// trace = 0x10
78221271Smarcel	nop	0
79221271Smarcel	;;
80221271Smarcel}
81221271Smarcel{	.mmi
82221271Smarcel	ld8	r16 = [r2], 16		// as_pgtbl_pte
83221271Smarcel	ld8	r17 = [r3], 16		// as_pgtbl_itir
84221271Smarcel	nop	0
85221271Smarcel	;;
86221271Smarcel}
87221271Smarcel{	.mmi
88221271Smarcel	mov	cr.itir = r17
89221271Smarcel	mov	cr.ifa = r18
90221271Smarcel	nop	0
91221271Smarcel	;;
92221271Smarcel}
93221271Smarcel{	.mmi
94221271Smarcel	srlz.d
95221271Smarcel	ptr.d	r18, r17
96221271Smarcel	nop	0
97221271Smarcel	;;
98221271Smarcel}
99221271Smarcel{	.mmi
100221271Smarcel	srlz.d
101221271Smarcel	st8	[gp] = r2		// trace = 0x18
102221271Smarcel	mov	r8 = r0
103221271Smarcel	;;
104221271Smarcel}
105221271Smarcel{	.mmi
106221271Smarcel	itr.d	dtr[r8] = r16
107221271Smarcel	;;
108221271Smarcel	srlz.d
109221271Smarcel	mov	r9 = r0
110221271Smarcel	;;
111221271Smarcel}
112221271Smarcel{	.mmi
113221271Smarcel	ld8	r16 = [r2], 16		// as_text_va
114221271Smarcel	st8	[gp] = r3		// trace = 0x20
115221271Smarcel	add	r8 = 1, r8
116221271Smarcel	;;
117221271Smarcel}
118221271Smarcel{	.mmi
119221271Smarcel	ld8	r17 = [r3], 16		// as_text_pte
120221271Smarcel	ld8	r18 = [r2], 16		// as_text_itir
121221271Smarcel	nop	0
122221271Smarcel	;;
123221271Smarcel}
124221271Smarcel{	.mmi
125221271Smarcel	mov	cr.ifa = r16
126221271Smarcel	mov	cr.itir = r18
127221271Smarcel	nop	0
128221271Smarcel	;;
129221271Smarcel}
130221271Smarcel{	.mmi
131221271Smarcel	srlz.d
132221271Smarcel	ptr.d	r16, r18
133221271Smarcel	nop	0
134221271Smarcel	;;
135221271Smarcel}
136221271Smarcel{	.mmi
137221271Smarcel	srlz.d
138221271Smarcel	st8	[gp] = r3		// trace = 0x30
139221271Smarcel	nop	0
140221271Smarcel	;;
141221271Smarcel}
142221271Smarcel{	.mmi
143221271Smarcel	itr.d	dtr[r8] = r17
144221271Smarcel	;;
145221271Smarcel	srlz.d
146221271Smarcel	nop	0
147221271Smarcel}
148221271Smarcel{	.mmi
149221271Smarcel	st8	[gp] = r2		// trace = 0x38
150221271Smarcel	ptr.i	r16, r18
151221271Smarcel	add	r8 = 1, r8
152221271Smarcel	;;
153221271Smarcel}
154221271Smarcel{	.mmi
155221271Smarcel	srlz.i
156221271Smarcel	;;
157221271Smarcel	itr.i	itr[r9] = r17
158221271Smarcel	nop	0
159221271Smarcel	;;
160221271Smarcel}
161221271Smarcel{	.mmi
162221271Smarcel	srlz.i
163221271Smarcel	;;
164221271Smarcel	ld8	r16 = [r3], 16          // as_data_va
165221271Smarcel	add	r9 = 1, r9
166221271Smarcel	;;
167221271Smarcel}
168221271Smarcel{	.mmi
169221271Smarcel	st8	[gp] = r3		// trace = 0x40
170221271Smarcel	ld8	r17 = [r2], 16		// as_data_pte
171221271Smarcel	nop	0
172221271Smarcel	;;
173221271Smarcel}
174221271Smarcel{	.mmi
175221271Smarcel	mov	cr.ifa = r16
176221271Smarcel	ld8	r18 = [r3], 16		// as_data_itir
177221271Smarcel	nop	0
178221271Smarcel	;;
179221271Smarcel}
180221271Smarcel{	.mmi
181221271Smarcel	mov	cr.itir = r18
182221271Smarcel	;;
183221271Smarcel	srlz.d
184221271Smarcel	nop	0
185221271Smarcel	;;
186221271Smarcel}
187221271Smarcel{	.mmi
188221271Smarcel	ptr.d	r16, r18
189221271Smarcel	;;
190221271Smarcel	srlz.d
191221271Smarcel	mov	r19 = IA64_DCR_DEFAULT
192221271Smarcel	;;
193221271Smarcel}
194221271Smarcel{	.mmi
195221271Smarcel	itr.d	dtr[r8] = r17
196221271Smarcel	;;
197221271Smarcel	srlz.d
198221271Smarcel	add	r8 = 1, r8
199221271Smarcel	;;
200221271Smarcel}
201221271Smarcel{	.mmi
202221271Smarcel	st8	[gp] = r2		// trace = 0x48
203221271Smarcel	;;
204221271Smarcel	ld8	r16 = [r2], 16		// as_kstack
205221271Smarcel	nop	0
206221271Smarcel}
207221271Smarcel{	.mmi
208221271Smarcel	ld8	r17 = [r3], 16		// as_kstack_top
209221271Smarcel	mov	cr.dcr = r19
210221271Smarcel	nop	0
211221271Smarcel	;;
212221271Smarcel}
213221271Smarcel{	.mlx
214221271Smarcel	srlz.i
215221271Smarcel	movl	r18 = IA64_PSR_BN | IA64_PSR_IT | IA64_PSR_DT | IA64_PSR_IC | \
216221271Smarcel			IA64_PSR_RT | IA64_PSR_DFH
217221271Smarcel	;;
218221271Smarcel}
219221271Smarcel{	.mlx
220221271Smarcel	mov	cr.ipsr = r18
221221271Smarcel	movl	r19 = ia64_vector_table		// set up IVT early
222221271Smarcel	;;
223221271Smarcel}
224221271Smarcel{	.mlx
225221271Smarcel	mov	cr.iva = r19
226221271Smarcel	movl	r18 = 1f
227221271Smarcel	;;
228221271Smarcel}
229221271Smarcel{	.mmi
230221271Smarcel	mov	cr.iip = r18
231221271Smarcel	mov	cr.ifs = r0
232221271Smarcel	nop	0
233221271Smarcel	;;
234221271Smarcel}
235221271Smarcel{	.mmb
236221271Smarcel	srlz.d
237221271Smarcel	st8	[gp] = r2		// trace = 0x58
238221271Smarcel	rfi
239221271Smarcel	;;
240221271Smarcel}
241221271Smarcel
242221271Smarcel	.align	32
243221271Smarcel1:
244221271Smarcel{	.mlx
245221271Smarcel	mov	ar.bspstore = r16
246221271Smarcel	movl	gp = __gp
247221271Smarcel	;;
248221271Smarcel}
249221271Smarcel{	.mmi
250221271Smarcel	loadrs
251221271Smarcel	add	sp = -16, r17
252221271Smarcel	nop	0
253221271Smarcel	;;
254221271Smarcel}
255221271Smarcel{	.mmi
256221271Smarcel	mov	ar.rsc = 3
257221271Smarcel	;;
258221271Smarcel	alloc	r18 = ar.pfs, 0, 0, 0, 0
259221271Smarcel	;;
260221271Smarcel}
261221271Smarcel{	.mib
262221271Smarcel	nop	0
263221271Smarcel	nop	0
264221271Smarcel	br.call.sptk.few rp = ia64_ap_startup
265221271Smarcel	;;
266221271Smarcel}
267221271Smarcel	/* NOT REACHED */
268221271Smarcel9:
269221271Smarcel{	.mib
270221271Smarcel	nop	0
271221271Smarcel	nop	0
272221271Smarcel	br.sptk	9b
273221271Smarcel	;;
274221271Smarcel}
275221271SmarcelEND(os_boot_rendez)
276