locore.S revision 85656
1/*-
2 * Copyright (c) 1998 Doug Rabson
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD: head/sys/ia64/ia64/locore.S 85656 2001-10-29 02:16:02Z marcel $
27 */
28/*
29 * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
30 * All rights reserved.
31 *
32 * Author: Chris G. Demetriou
33 *
34 * Permission to use, copy, modify and distribute this software and
35 * its documentation is hereby granted, provided that both the copyright
36 * notice and this permission notice appear in all copies of the
37 * software, derivative works or modified versions, and any portions
38 * thereof, and that both notices appear in supporting documentation.
39 *
40 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
41 * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
42 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
43 *
44 * Carnegie Mellon requests users of this software to return to
45 *
46 *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
47 *  School of Computer Science
48 *  Carnegie Mellon University
49 *  Pittsburgh PA 15213-3890
50 *
51 * any improvements or extensions that they make and grant Carnegie the
52 * rights to redistribute these changes.
53 */
54
55#include <sys/cdefs.h>
56#include <machine/asm.h>
57#include <machine/ia64_cpu.h>
58#include <machine/fpu.h>
59#include <sys/syscall.h>
60#include <assym.s>
61
62#ifndef EVCNT_COUNTERS
63#define _LOCORE
64#include <machine/intrcnt.h>
65#endif
66
67	.section .data.proc0,"aw"
68	.global	kstack
69	.align	PAGE_SIZE
70kstack:	.space KSTACK_PAGES * PAGE_SIZE
71
72	.text
73
74/*
75 * Not really a leaf but we can't return.
76 */
77ENTRY(__start, 1)
78	movl	r8=ia64_vector_table	// set up IVT early
79	movl	r9=ia64_vhpt+(1<<8)+(15<<2)+1 // and VHPT
80	;;
81	mov	cr.iva=r8
82	mov	cr.pta=r9
83	;;
84	movl	r11=kstack
85	;;
86	srlz.i
87	;;
88	srlz.d
89	mov	r9=KSTACK_PAGES*PAGE_SIZE-SIZEOF_PCB-SIZEOF_TRAPFRAME-16
90	;;
91	movl	gp=__gp			// find kernel globals
92	add	sp=r9,r11		// proc0's stack
93	mov	ar.rsc=0		// turn off rse
94	;;
95	mov	ar.bspstore=r11		// switch backing store
96	;;
97	loadrs				// invalidate regs
98	;;
99	mov	ar.rsc=3		// turn rse back on
100	;;
101	alloc	r16=ar.pfs,0,0,1,0
102	;;
103	movl	out0=0			// we are linked at the right address
104	;;				// we just need to process fptrs
105	br.call.sptk.many rp=_reloc
106	;;
107	br.call.sptk.many rp=ia64_init
108
109	/*
110	 * switch to thread0 and then initialise the rest of the kernel.
111	 */
112	alloc	r16=ar.pfs,0,0,1,0
113	;;
114	movl	out0=thread0
115	;;
116	ld8	out0=[out0]
117	;;
118	add	out0=TD_PCB,out0
119	;;
120	ld8	out0=[out0]
121	;;
122	add	r16=PCB_B0,out0		// return to mi_startup
123	movl	r17=mi_startup
124	;;
125	st8	[r16]=r17
126	;;
127	br.call.sptk.many rp=restorectx
128
129	/* NOTREACHED */
130
131END(__start)
132
133/*
134 * AP wake-up entry point. The handoff state is similar as for the BSP,
135 * as described on page 3-9 of the IPF SAL Specification. The difference
136 * lies in the contents of register b0. For APs this register holds the
137 * return address into the SAL rendezvous routine.
138 */
139	.align	32
140ENTRY(os_boot_rendez,0)
1411:	mov	r16 = ip
142	movl	r17 = (IA64_PSR_AC|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_IT|IA64_PSR_BN)
143	mov	r18 = 7
144	;;
145	add	r16 = 2f-1b, r16
146	mov	cr.ipsr = r17
147	;;
148	dep	r16 = r18, r16, 61, 3
149	;;
150	mov	cr.iip = r16
151	;;
152	rfi
153
154	.align	32
1552:	movl	r16 = ia64_vector_table			// set up IVT early
156	movl	r17 = ia64_vhpt+(1<<8)+(15<<2)+1		// and VHPT
157	;;
158	mov	cr.iva = r16
159	mov	cr.pta = r17
160	;;
161	srlz.i
162	;;
163	srlz.d
164	movl	gp = __gp
165	;;
166	br.call.sptk.many rp = ia64_ap_get_stack
167	;;
168	mov	r9 = KSTACK_PAGES*PAGE_SIZE-SIZEOF_PCB-SIZEOF_TRAPFRAME-16
169	;;
170	add	sp = r9, r8
171	mov	ar.bspstore = r8
172	;;
173	loadrs
174	;;
175	mov	ar.rsc = 3
176	;;
177	alloc	r16=ar.pfs,0,0,0,0
178	;;
179	br.call.sptk.many rp=ia64_ap_startup
180	/* NOT REACHED */
181END(os_boot_rendez)
182
183/**************************************************************************/
184
185/*
186 * Signal "trampoline" code. Invoked from RTE setup by sendsig().
187 *
188 * On entry, registers look like:
189 *
190 *      r14	signal number
191 *      r15	pointer to siginfo_t
192 *	r16	pointer to signal context frame (scp)
193 *      r17	address of handler function descriptor
194 *	r18	address of new backing store (if any)
195 *      sp+16	pointer to sigframe
196 */
197
198ENTRY(sigcode,0)
199	ld8	r8=[r17],8		// function address
200	;;
201	ld8	gp=[r17]		// function's gp value
202	mov	b6=r8			// transfer to a branch register
203	cover
204	;;
205	add	r8=UC_MCONTEXT_MC_AR_BSP,r16 // address or mc_ar_bsp
206	mov	r9=ar.bsp		// save ar.bsp
207	;;
208	st8	[r8]=r9
209	cmp.eq	p1,p2=r0,r18		// check for new bs
210(p1)	br.cond.sptk.few 1f		// branch if not switching
211	flushrs				// flush out to old bs
212	mov	ar.rsc=0		// switch off RSE
213	add	r8=UC_MCONTEXT_MC_AR_RNAT,r16 // address of mc_ar_rnat
214	;;
215	mov	r9=ar.rnat		// value of ar.rnat after flush
216	mov	ar.bspstore=r18		// point at new bs
217	;;
218	st8	[r8]=r9			// remember ar.rnat
219	mov	ar.rsc=15		// XXX bogus value - check
220	invala
221	;;
2221:	alloc	r5=ar.pfs,0,0,3,0	// register frame for call
223	;;
224	mov	out0=r14		// signal number
225	mov	out1=r15		// siginfo
226	mov	out2=r16		// ucontext
227	mov	r4=r16			// save from call
228	br.call.sptk.few rp=b6		// call the signal handler
229	;;
230	alloc	r14=ar.pfs,0,0,0,0	// discard call frame
231	;;
232	flushrs
233	;;
234(p1)	br.cond.sptk.few 2f		// note: p1 is preserved
235	mov	ar.rsc=0
236	add	r8=UC_MCONTEXT_MC_AR_RNAT,r4 // address of mc_ar_rnat
237	;;
238	ld8	r9=[r8]
239	;;
240	add	r8=UC_MCONTEXT_MC_AR_BSP,r4 // address of mc_ar_bsp
241	;;
242	ld8	r10=[r8]
243	;;
244	mov	ar.bspstore=r10
245	;;
246	mov	ar.rnat=r9
247	mov	ar.rsc=15
248	;;
2492:	CALLSYS_NOERROR(sigreturn)	// call sigreturn()
250	alloc	r14=ar.pfs,0,0,1,0 ;;
251	mov	out0=ret0		// if that failed, get error code
252	CALLSYS_NOERROR(exit)		// and call exit() with it.
253XENTRY(esigcode)
254	END(sigcode)
255
256	.data
257	EXPORT(szsigcode)
258	.quad	esigcode-sigcode
259	.text
260
261/* XXX: make systat/vmstat happy */
262	.data
263EXPORT(intrnames)
264	.asciz	"clock"
265intr_n = 0
266.rept INTRCNT_COUNT
267	.ascii "intr "
268	.byte intr_n / 10 + '0, intr_n % 10 + '0
269	.asciz "     "		/* space for platform-specific rewrite */
270	intr_n = intr_n + 1
271.endr
272EXPORT(eintrnames)
273	.align 8
274EXPORT(intrcnt)
275	.fill INTRCNT_COUNT + 1, 8, 0
276EXPORT(eintrcnt)
277	.text
278
279	// in0:	image base
280STATIC_ENTRY(_reloc, 1)
281	alloc	loc0=ar.pfs,1,2,0,0
282	mov	loc1=rp
283	;;
284	movl	r15=@gprel(_DYNAMIC)	// find _DYNAMIC etc.
285	movl	r2=@gprel(fptr_storage)
286	movl	r3=@gprel(fptr_storage_end)
287	;;
288	add	r15=r15,gp		// relocate _DYNAMIC etc.
289	add	r2=r2,gp
290	add	r3=r3,gp
291	;;
2921:	ld8	r16=[r15],8		// read r15->d_tag
293	;;
294	ld8	r17=[r15],8		// and r15->d_val
295	;;
296	cmp.eq	p6,p0=DT_NULL,r16	// done?
297(p6)	br.cond.dpnt.few 2f
298	;;
299	cmp.eq	p6,p0=DT_RELA,r16
300	;;
301(p6)	add	r18=r17,in0		// found rela section
302	;;
303	cmp.eq	p6,p0=DT_RELASZ,r16
304	;;
305(p6)	mov	r19=r17			// found rela size
306	;;
307	cmp.eq	p6,p0=DT_SYMTAB,r16
308	;;
309(p6)	add	r20=r17,in0		// found symbol table
310	;;
311(p6)	setf.sig f8=r20
312	;;
313	cmp.eq	p6,p0=DT_SYMENT,r16
314	;;
315(p6)	setf.sig f9=r17			// found symbol entry size
316	;;
317	cmp.eq	p6,p0=DT_RELAENT,r16
318	;;
319(p6)	mov	r22=r17			// found rela entry size
320	;;
321	br.sptk.few 1b
322
3232:
324	ld8	r15=[r18],8		// read r_offset
325	;;
326	ld8	r16=[r18],8		// read r_info
327	add	r15=r15,in0		// relocate r_offset
328	;;
329	ld8	r17=[r18],8		// read r_addend
330	sub	r19=r19,r22		// update relasz
331
332	extr.u	r23=r16,0,32		// ELF64_R_TYPE(r16)
333	;;
334	cmp.eq	p6,p0=R_IA64_NONE,r23
335(p6)	br.cond.dpnt.few 3f
336	;;
337	cmp.eq	p6,p0=R_IA64_DIR64LSB,r23
338	;;
339(p6)	br.cond.dptk.few 4f
340	;;
341	cmp.eq	p6,p0=R_IA64_FPTR64LSB,r23
342	;;
343(p6)	br.cond.dptk.few 5f
344	;;
345	cmp.eq	p6,p0=R_IA64_REL64LSB,r23
346	;;
347(p6)	br.cond.dptk.few 4f
348	;;
349
3503:	cmp.ltu	p6,p0=0,r19		// more?
351(p6)	br.cond.dptk.few 2b		// loop
352
353	mov	r8=0			// success return value
354	;;
355	br.cond.sptk.few 9f		// done
356
3574:
358	ld8	r16=[r15]		// read value
359	;;
360	add	r16=r16,in0		// relocate it
361	;;
362	st8	[r15]=r16		// and store it back
363	br.cond.sptk.few 3b
364
3655:
366	extr.u	r23=r16,32,32		// ELF64_R_SYM(r16)
367	;;
368	setf.sig f10=r23		// so we can multiply
369	;;
370	xma.lu	f10=f10,f9,f8		// f10=symtab + r_sym*syment
371	;;
372	getf.sig r16=f10
373	;;
374	add	r16=8,r16		// address of st_value
375	;;
376	ld8	r16=[r16]		// read symbol value
377	;;
378	add	r16=r16,in0		// relocate symbol value
379	;;
380	movl	r17=@gprel(fptr_storage)
381	;;
382	add	r17=r17,gp		// start of fptrs
383	;;
3846:	cmp.geu	p6,p0=r17,r2		// end of fptrs?
385(p6)	br.cond.dpnt.few 7f		// can't find existing fptr
386	ld8	r20=[r17]		// read function from fptr
387	;;
388	cmp.eq	p6,p0=r16,r20		// same function?
389	;;
390(p6)	st8	[r15]=r17		// reuse fptr
391(p6)	br.cond.sptk.few 3b		// done
392	add	r17=16,r17		// next fptr
393	br.cond.sptk.few 6b
394
3957:					// allocate new fptr
396	mov	r8=1			// failure return value
397	;;
398	cmp.geu	p6,p0=r2,r3		// space left?
399(p6)	br.cond.dpnt.few 9f		// bail out
400
401	st8	[r15]=r2		// install fptr
402	st8	[r2]=r16,8		// write fptr address
403	;;
404	st8	[r2]=gp,8		// write fptr gp
405	br.cond.sptk.few 3b
406
4079:
408	mov	ar.pfs=loc0
409	mov	rp=loc1
410	;;
411	br.ret.sptk.few rp
412
413END(_reloc)
414
415	.data
416	.align	16
417
418fptr_storage:
419	.space	4096*16			// XXX
420fptr_storage_end:
421