]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/alpha/alpha/locore.s
This commit was generated by cvs2svn to compensate for changes in r58653,
[FreeBSD/FreeBSD.git] / sys / alpha / alpha / locore.s
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$
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 <machine/asm.h>
56 #include <sys/syscall.h>
57 #include <assym.s>
58
59 #ifndef EVCNT_COUNTERS
60 #define _LOCORE
61 #include <machine/intrcnt.h>
62 #endif
63
64 /*
65  * PTmap is recursive pagemap at top of virtual address space.
66  * Within PTmap, the lev1 and lev0 page tables can be found.
67  */
68         .globl  PTmap,PTlev2,PTlev1,PTlev1pte
69         .equ    PTmap,VPTBASE
70         .equ    PTlev2,PTmap + (PTLEV1I << ALPHA_L2SHIFT)
71         .equ    PTlev1,PTlev2 + (PTLEV1I << ALPHA_L3SHIFT)
72         .equ    PTlev1pte,PTlev1 + (PTLEV1I * PTESIZE)
73         
74 /*
75  * Perform actions necessary to switch to a new context.  The
76  * hwpcb should be in a0.
77  */
78 #define SWITCH_CONTEXT                                                  \
79         /* Make a note of the context we're running on. */              \
80         stq     a0, curpcb                                      ;       \
81                                                                         \
82         /* Swap in the new context. */                                  \
83         call_pal PAL_OSF1_swpctx
84         
85         .text
86
87         NESTED(locorestart, 1, 0, ra, 0, 0)
88
89         br      pv,1f
90 1:      LDGP(pv)
91         
92         /* Load KGP with current GP. */
93         or      a0,zero,s0              /* save pfn */
94         or      gp,zero,a0
95         call_pal PAL_OSF1_wrkgp         /* clobbers a0, t0, t8-t11 */
96         or      s0,zero,a0              /* restore pfn */
97
98         /*
99          * Call alpha_init() to do pre-main initialization.
100          * alpha_init() gets the arguments we were called with,
101          * which are already in a0, a1, a2, a3, and a4.
102          */
103         CALL(alpha_init)
104
105         /* Set up the virtual page table pointer. */
106         ldiq    a0, VPTBASE
107         call_pal PAL_OSF1_wrvptptr      /* clobbers a0, t0, t8-t11 */
108
109         /*
110          * Switch to proc0's PCB, which is at U_PCB off of proc0paddr.
111          */
112         lda     t0,proc0                        /* get phys addr of pcb */
113         ldq     a0,P_MD_PCBPADDR(t0)
114         SWITCH_CONTEXT
115
116         /*
117          * We've switched to a new page table base, so invalidate the TLB
118          * and I-stream.  This happens automatically everywhere but here.
119          */
120         ldiq    a0, -2                          /* TBIA */
121         call_pal PAL_OSF1_tbi
122         call_pal PAL_imb
123
124         /*
125          * Construct a fake trap frame, so execve() can work normally.
126          * Note that setregs() is responsible for setting its contents
127          * to 'reasonable' values.
128          */
129         lda     sp,-(FRAME_SIZE * 8)(sp)        /* space for struct trapframe */
130         mov     sp, a0                          /* arg is frame ptr */
131         CALL(mi_startup)                        /* go to mi_startup()! */
132
133         /*
134          * Call exception_return, to simulate return from (fake)
135          * exception to user-land, running process 1, init!
136          */
137         jmp     zero, exception_return          /* "And that's all she wrote." */
138         END(locorestart)
139
140         
141 /**************************************************************************/
142
143 /*
144  * Signal "trampoline" code. Invoked from RTE setup by sendsig().
145  *
146  * On entry, stack & registers look like:
147  *
148  *      a0      signal number
149  *      a1      pointer to siginfo_t
150  *      a2      pointer to signal context frame (scp)
151  *      a3      address of handler
152  *      sp+0    saved hardware state
153  *                      .
154  *                      .
155  *      scp+0   beginning of signal context frame
156  */
157
158 NESTED(sigcode,0,0,ra,0,0)
159         lda     sp, -16(sp)             /* save the sigcontext pointer */
160         stq     a2, 0(sp)
161         jsr     ra, (t12)               /* call the signal handler (t12==pv) */
162         ldq     a0, 0(sp)               /* get the sigcontext pointer */
163         lda     sp, 16(sp)
164         CALLSYS_NOERROR(sigreturn)      /* and call sigreturn() with it. */
165         mov     v0, a0                  /* if that failed, get error code */
166         CALLSYS_NOERROR(exit)           /* and call exit() with it. */
167 XNESTED(esigcode,0)
168         END(sigcode)
169
170         .data
171         EXPORT(szsigcode)
172         .quad   esigcode-sigcode
173         .text
174         
175 /**************************************************************************/
176
177 /*
178  * savefpstate: Save a process's floating point state.
179  *
180  * Arguments:
181  *      a0      'struct fpstate *' to save into
182  */
183
184 LEAF(savefpstate, 1)
185         LDGP(pv)
186         /* save all of the FP registers */
187         lda     t1, FPREG_FPR_REGS(a0)  /* get address of FP reg. save area */
188         stt     $f0,   (0 * 8)(t1)      /* save first register, using hw name */
189         stt     $f1,   (1 * 8)(t1)      /* etc. */
190         stt     $f2,   (2 * 8)(t1)
191         stt     $f3,   (3 * 8)(t1)
192         stt     $f4,   (4 * 8)(t1)
193         stt     $f5,   (5 * 8)(t1)
194         stt     $f6,   (6 * 8)(t1)
195         stt     $f7,   (7 * 8)(t1)
196         stt     $f8,   (8 * 8)(t1)
197         stt     $f9,   (9 * 8)(t1)
198         stt     $f10, (10 * 8)(t1)
199         stt     $f11, (11 * 8)(t1)
200         stt     $f12, (12 * 8)(t1)
201         stt     $f13, (13 * 8)(t1)
202         stt     $f14, (14 * 8)(t1)
203         stt     $f15, (15 * 8)(t1)
204         stt     $f16, (16 * 8)(t1)
205         stt     $f17, (17 * 8)(t1)
206         stt     $f18, (18 * 8)(t1)
207         stt     $f19, (19 * 8)(t1)
208         stt     $f20, (20 * 8)(t1)
209         stt     $f21, (21 * 8)(t1)
210         stt     $f22, (22 * 8)(t1)
211         stt     $f23, (23 * 8)(t1)
212         stt     $f24, (24 * 8)(t1)
213         stt     $f25, (25 * 8)(t1)
214         stt     $f26, (26 * 8)(t1)
215         stt     $f27, (27 * 8)(t1)
216         .set noat
217         stt     $f28, (28 * 8)(t1)
218         .set at
219         stt     $f29, (29 * 8)(t1)
220         stt     $f30, (30 * 8)(t1)
221
222         /*
223          * Then save the FPCR; note that the necessary 'trapb's are taken
224          * care of on kernel entry and exit.
225          */
226         mf_fpcr ft0
227         stt     ft0, FPREG_FPR_CR(a0)   /* store to FPCR save area */
228
229         RET
230         END(savefpstate)
231
232 /**************************************************************************/
233
234 /*
235  * restorefpstate: Restore a process's floating point state.
236  *
237  * Arguments:
238  *      a0      'struct fpstate *' to restore from
239  */
240
241 LEAF(restorefpstate, 1)
242         LDGP(pv)
243         /*
244          * Restore the FPCR; note that the necessary 'trapb's are taken care of
245          * on kernel entry and exit.
246          */
247         ldt     ft0, FPREG_FPR_CR(a0)   /* load from FPCR save area */
248         mt_fpcr ft0
249
250         /* Restore all of the FP registers. */
251         lda     t1, FPREG_FPR_REGS(a0)  /* get address of FP reg. save area */
252         ldt     $f0,   (0 * 8)(t1)      /* restore first reg., using hw name */
253         ldt     $f1,   (1 * 8)(t1)      /* etc. */
254         ldt     $f2,   (2 * 8)(t1)
255         ldt     $f3,   (3 * 8)(t1)
256         ldt     $f4,   (4 * 8)(t1)
257         ldt     $f5,   (5 * 8)(t1)
258         ldt     $f6,   (6 * 8)(t1)
259         ldt     $f7,   (7 * 8)(t1)
260         ldt     $f8,   (8 * 8)(t1)
261         ldt     $f9,   (9 * 8)(t1)
262         ldt     $f10, (10 * 8)(t1)
263         ldt     $f11, (11 * 8)(t1)
264         ldt     $f12, (12 * 8)(t1)
265         ldt     $f13, (13 * 8)(t1)
266         ldt     $f14, (14 * 8)(t1)
267         ldt     $f15, (15 * 8)(t1)
268         ldt     $f16, (16 * 8)(t1)
269         ldt     $f17, (17 * 8)(t1)
270         ldt     $f18, (18 * 8)(t1)
271         ldt     $f19, (19 * 8)(t1)
272         ldt     $f20, (20 * 8)(t1)
273         ldt     $f21, (21 * 8)(t1)
274         ldt     $f22, (22 * 8)(t1)
275         ldt     $f23, (23 * 8)(t1)
276         ldt     $f24, (24 * 8)(t1)
277         ldt     $f25, (25 * 8)(t1)
278         ldt     $f26, (26 * 8)(t1)
279         ldt     $f27, (27 * 8)(t1)
280         ldt     $f28, (28 * 8)(t1)
281         ldt     $f29, (29 * 8)(t1)
282         ldt     $f30, (30 * 8)(t1)
283
284         RET
285         END(restorefpstate)
286
287 /*
288  * When starting init, call this to configure the process for user
289  * mode.  This will be inherited by other processes.
290  */
291         LEAF_NOPROFILE(prepare_usermode, 0)
292         RET
293         END(prepare_usermode)
294
295         .data
296         EXPORT(proc0paddr)
297         .quad   0
298         
299         .text
300         
301 /* XXX: make systat/vmstat happy */
302         .data
303 EXPORT(intrnames)
304         .asciz  "clock"
305 intr_n = 0
306 .rept INTRCNT_COUNT
307         .ascii "intr "
308         .byte intr_n / 10 + '0, intr_n % 10 + '0
309         .asciz "     "          # space for platform-specific rewrite
310         intr_n = intr_n + 1
311 .endr
312 EXPORT(eintrnames)
313         .align 3
314 EXPORT(intrcnt)
315         .fill INTRCNT_COUNT + 1, 8, 0
316 EXPORT(eintrcnt)
317         .text