xref: /openbsd-src/sys/arch/m88k/m88k/eh_common.S (revision b2db68b468d761b954a669ab4defe6963903aae7)
1/*   $OpenBSD: eh_common.S,v 1.66 2024/06/05 19:22:04 miod Exp $	*/
2/*
3 * Mach Operating System
4 * Copyright (c) 1993-1991 Carnegie Mellon University
5 * Copyright (c) 1991 OMRON Corporation
6 * Copyright (c) 1996 Nivas Madhur
7 * Copyright (c) 1998 Steve Murphree, Jr.
8 * All Rights Reserved.
9 *
10 * Permission to use, copy, modify and distribute this software and its
11 * documentation is hereby granted, provided that both the copyright
12 * notice and this permission notice appear in all copies of the
13 * software, derivative works or modified versions, and any portions
14 * thereof, and that both notices appear in supporting documentation.
15 *
16 * CARNEGIE MELLON AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
17 * CONDITION.  CARNEGIE MELLON AND OMRON DISCLAIM ANY LIABILITY OF ANY KIND
18 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
19 *
20 * Carnegie Mellon requests users of this software to return to
21 *
22 *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
23 *  School of Computer Science
24 *  Carnegie Mellon University
25 *  Pittsburgh PA 15213-3890
26 *
27 * any improvements or extensions that they make and grant Carnegie the
28 * rights to redistribute these changes.
29 */
30
31/*
32 * NOTICE: This is not a standalone file.  To use it, define the PFSR_SAVE
33 * macro (if supporting 88100 processors) and #include this file in your
34 * port's eh.S:
35 * #include <m88k/m88k/eh_common.S>
36 */
37
38/*
39 * In the following discussion, references are made to:
40 *    MC88100 - RISC MICROPROCESSOR USER'S MANUAL
41 * (second edition). Reference in []s refer to section numbers.
42 *
43 * This discussion assumes that you are at least vaguely familiar with 88100
44 * exception handling (chapter 6), the BSD kernel, and that you have a brain
45 * (and use it while reading this).
46 *
47 * I also assume (and hope) that you're not offended by frequent misspellings.
48 *
49 * Jeffrey Friedl
50 * jfriedl@rna.ncl.omron.co.jp
51 * December, 1989
52 *  -------------------------------------------------------------------
53 *
54 * EXCEPTIONS, INTERRUPTS, and TRAPS
55 * ---------------------------------
56 * This is the machine exception handler.
57 * In the MC88100, various "conditions" cause an exception, where
58 * processing momentarily jumps here to "service" the exception,
59 * and then continues where it left off.
60 *
61 * There are a number of different types of exceptions.
62 * For example, exception #6 is the privilege violation exception which
63 * is raised when the user tries to execute a supervisor-only instruction.
64 *
65 * Exception #1 is the interrupt exception, and is raised when an
66 * outside device raises the INT line on the CPU.  This happens,
67 * for example, when the clock signals that it is time for a context
68 * switch, or perhaps the disk drive signaling that some operation
69 * is complete.
70 *
71 * Traps are also exceptions.  Traps are ways for user programs to request
72 * kernel operations.  For example, "tcnd eq0, r0, 450" will raise
73 * exception 450, the system call exception.
74 *
75 *
76 * SERVICING AN EXCEPTION
77 * -----------------------
78 * When an exception occurs, each control register is saved in its
79 * respective shadow register and execution continues from the
80 * appropriate exception handler.  The exception handler must
81 *      - save the context from the time of the exception
82 *      - service the exception
83 *      - restore the context (registers, etc)
84 *      - pick up from where the exception occurred.
85 *
86 * The context is saved on a stack. Actually, in the user_state area
87 * in the PCB if the exception happens in user mode.
88 *
89 * Servicing the exception is usually straightforward and in fact not dealt
90 * with very much here.  Usually a C routine is called to handle it.
91 * For example, when a privilege exception is raised, the routine that sends
92 * an "illegal instruction" signal to the offending process is called.
93 *
94 * When the exception has been serviced, the context is restored from the
95 * stack and execution resumes from where it left off.
96 *
97 * In more detail:
98 *
99 * Saving the exception-time context.
100 * ---------------------------------
101 *     In saving the exception-time context, we copy the shadow and general
102 * purpose registers to memory.  Since one exception may occur while
103 * servicing another, the memory used to save the exception-time context may
104 * not be static (i.e. the same every time).  Thus, memory on a stack is set
105 * aside for the exception frame (area where the exception-time context is
106 * saved). The same stack is also used when C routines are called (to
107 * service the exception).
108 *
109 *    Each process has a stack in kernel space (called the "kernel stack",
110 * short for "process's kernel stack) as well as the user space stack.  When
111 * entering the kernel from user space, the kernel stack is unused.  On this
112 * stack we save the exception state and (most likely call a C routine to)
113 * service the exception.
114 *
115 * Before servicing an exception, several issues must be addressed.
116 *
117 * 1) When an interrupt is recognized by the hardware, the data pipeline is
118 *    allowed to clear.  However, if one of these data accesses faults (bad
119 *    reference, or a reference to a page which needs to be swapped in), that
120 *    reference, as well as any others in the pipeline at the time (at most
121 *    three total) are left there, to be taken care of by the exception
122 *    handler [6.4.1].  This involves swapping in the proper page and
123 *    manually doing the appropriate load or store.
124 *
125 *    The other (at most, two other) data accesses that might have been in
126 *    the pipeline must also be manually completed (even though they may not
127 *    be at fault [yes, that's a bad pun, thank you]).
128 *
129 * 2) If any of the (at most three) uncompleted data access in the pipeline
130 *    are loads (from memory to a register), then the bit for the destination
131 *    register is set in the SSBR.  Since the hardware will never complete
132 *    that load (since we do it manually), the hardware will never clear that
133 *    SSBR bit.  Thus, we must clear it manually.  If this isn't done, the
134 *    system will hang waiting for a bit to clear that will never.
135 *
136 * 3) If the exception is the privilege violation exception, the bounds
137 *    check exception, or the misaligned access exception, the
138 *    destination register bit in the SSBR may need to be cleared.
139 *
140 * 4) If the exception is one of the floating exceptions, then the
141 *    destination register for that floating process won't be written,
142 *    and the SSBR must be cleared explicitly.
143 *
144 * 5) The FPU must be enabled (as it is disabled by the exception processing
145 *    hardware) and allowed to complete actions in progress. This is
146 *    so that it may be used in the servicing of any instruction.
147 *    When the FPU is being restarted, operations attempting to complete
148 *    may themselves fault (raising another exception).
149 *
150 * More on Restarting the FPU
151 * --------------------------
152 *   The manual [section 6.4.3.4] gives only minor mention to this
153 * rather complex task.  Before the FPU is restarted all SSBR bits are
154 * cleared for actions that the exception handler completes (as mentioned
155 * above) so that the SSBR is clear unless there are FPU operations that
156 * have not actually been completed (and hence not written to the registers).
157 * Also, all control registers (at least all those that we care about) are
158 * saved to the stack exception frame before the FPU is restarted (this
159 * is important... the reason comes later).
160 *
161 * The FPU is restarted by doing an rte to a trap-not-taken (the rte
162 * actually enables the fpu because we ensure that the EPSR has the
163 * FPU-enable bit on; the trap-not-taken ensures anything in the FPU
164 * completes by waiting until scoreboard register is clear).
165 *
166 * At the time the FPU is restarted (the rte to the trap-not-taken) the FPU
167 * can write to ANY of the general registers.  Thus, we must make sure that
168 * all general registers (r1..r31) are in their pre-exception state so that
169 * when saved to the exception frame after the FPU is enabled, they properly
170 * reflect any changes made by the FPU in being restarted.
171 *
172 * Because we can't save the pointer to the exception frame in a general
173 * register during the FPU restart (it could get overwritten by the FPU!),
174 * we save it in a control register, SR3, during the restart.
175 *
176 * HOWEVER .....
177 *
178 * Because other uncompleted actions in the FPU may fault when the FPU is
179 * restarted, a new exception may be raised during the restart. This may
180 * happen recursively a number of times. Thus, during a restart, ANY register
181 * whatsoever may be modified, including control registers.  Because of this
182 * we must make sure that the exception handler preserves SR3 throughout
183 * servicing an exception so that, if the exception had been raised during
184 * an FPU restart, it is returned unmolested when control returns to the FPU
185 * restart.
186 *
187 * Thus: if an exception is from kernel space, we MUST preserve SR3.
188 * (if it from user space, no FPU-enable can be in progress and SR3 is
189 *  unimportant).
190 *
191 * Now is a good time to recap SR1..SR3 usage:
192 *   SR1 - CPU flags (exception handler flags)
193 *   SR2 - generally free
194 *   SR3 - free only if the exception is from user mode
195 *
196 * Once the FPU has been restarted, the general registers are saved to the
197 * exception frame.  If the exception is not the interrupt exception,
198 * interrupts are enabled and any faulted data accesses (see above) are
199 * serviced.  In either case, the exception is then serviced (usually by
200 * calling a C routine).  After servicing, any faulted data accesses are
201 * serviced (if it had been the interrupt exception).  The context is then
202 * restored and control returns to where the exception occurred.
203 *
204 */
205
206#include "assym.h"
207
208#include <machine/param.h>
209#include <machine/asm.h>
210#include <machine/trap.h>
211
212/*
213 * SR1 - CPU FLAGS REGISTER
214 *
215 * SR1 contains flags about the current CPU status.
216 *
217 * The bit FLAG_IGNORE_DATA_EXCEPTION indicates that any data exceptions
218 * 	should be ignored (well, at least treated in a special way).
219 * The bit FLAG_ENABLING_FPU indicates that the exception handler is
220 * 	in the process of enabling the FPU (so that an exception can
221 * 	be serviced).  This is needed because enabling the FPU can
222 *	cause other exceptions to happen, and the whole system is
223 *	in a rather precarious state and so special cautions must
224 * 	be taken.
225 */
226#define FLAG_IGNORE_DATA_EXCEPTION	0
227#define FLAG_ENABLING_FPU		1
228#define FLAG_FROM_KERNEL		2
229
230/* GENeral REGister OFFset into the E.F. (exception frame) */
231#define GENREG_OFF(num)		(EF_R0 + (num) * 4)
232
233/* Invoke a C function with 2 arguments */
234#define	CALL(NAME, ARG1, ARG2) \
235	or	%r2, %r0, ARG1; \
236	bsr.n	NAME; \
237	 or	%r3, %r0, ARG2
238
239/* Invoke a function and return elsewhere */
240/* CAREFUL: needs to have `RET' after the XCALL in memory */
241#define	XCALL(NAME, RET) \
242	bsr.n	NAME; \
243	 addu	%r1, %r1, RET - . - 4
244
245/*
246 * Some registers used during the setting up of the new exception frame.
247 * Don't choose r1, r30, or r31 for any of them.
248 *
249 * Also, if any are 'r2' or 'r3', be careful using with CALL above!
250 */
251#define	FLAGS			%r2
252#define	TMP			%r3
253#define	TMP2			%r10
254#define	TMP3			%r11
255#define	SAVE_TMP2(ef)		st	%r10, ef, GENREG_OFF(10)
256#define	SAVE_TMP3(ef)		st	%r11, ef, GENREG_OFF(11)
257#define	RESTORE_TMP2(ef)	ld	%r10, ef, GENREG_OFF(10)
258#define	RESTORE_TMP3(ef)	ld	%r11, ef, GENREG_OFF(11)
259
260/*
261 * EF_SR3
262 *   A place to save the exception-time SR3 from just after the
263 *   time when an exception is raised until just after the FPU
264 *   has been restarted.  This does not necessarily conflict with
265 *   the general registers (though it can if you're not careful)
266 *   and so we can use a spot later used to save a general register.
267 */
268#define	EF_SR3		GENREG_OFF(5)
269
270	.text
271	.align 3
272
273/*
274 *
275 * #define PREP881x0(NAME, NUM, SSBR_STUFF, FLAG_CHECK)
276 *
277 * This is the "exception processing preparation" common to all exception
278 * processing.  It is used in the following manner:
279 *
280 *	ASGLOBAL(foo_handler)
281 *		PREP881x0("foo", 11, SSBR_Stuff, Precheck_Stuff)
282 *		or	%r2, %r0, T_FOO_FAULT
283 *		or	%r3, %r0, %r30
284 *		XCALL(trapXXX, check_ast)
285 *
286 * This defines the exception handler for the "foo" exception.
287 * The arguments are:
288 * NAME
289 *	String for debugging (more info later)
290 * NUM
291 *	The exception number [see the manual, Table 6-1]
292 * SSBR_STUFF
293 *	If the exception might leave some bits in the SSBR set,
294 *	this should indicate how they are cleared.
295 * FLAG_PRECHECK
296 *	This is for the data access exception only. See it for
297 *	more info.
298 *
299 * What's in between PREP881x0() and check_ast (usually a XCALL)
300 * is the actual servicing of the interrupt.  During this time, any
301 * register may be used freely as they've all been saved in the
302 * exception frame (which is pointed to by r30).
303 */
304
305#ifdef M88100
306#define PREP88100(NAME, NUM, SSBR_STUFF, FLAG_PRECHECK) \
307	xcr	FLAGS, FLAGS, SR1			; \
308	FLAG_PRECHECK					  \
309	/* the bsr later clobbers r1, so save now */	  \
310	stcr	%r1, SR2	/* r1 now free */	; \
311	/* set or clear the FLAG_FROM_KERNEL bit */	  \
312	ldcr	%r1, EPSR				; \
313	bb0.n	PSR_SUPERVISOR_MODE_BIT, %r1, 1f	; \
314	 clr	FLAGS, FLAGS, 1<FLAG_FROM_KERNEL>	; \
315	set	FLAGS, FLAGS, 1<FLAG_FROM_KERNEL>	; \
316	/* get a stack (exception frame) */		  \
3171:	bsr	m88100_setup_phase_one			; \
318	/* TMP2 now free -- use to set EF_VECTOR */	  \
319	or	TMP2, %r0, NUM				; \
320	st	TMP2, %r31, EF_VECTOR			; \
321	/* Clear any bits in the SSBR (held in TMP) */	  \
322	/* SSBR_STUFF may be empty, though.         */	  \
323	SSBR_STUFF					  \
324	/* call setup_phase_two to restart the FPU  */	  \
325	/* and to save all general registers.       */	  \
326	bsr	m88100_setup_phase_two
327#endif
328
329#ifdef M88110
330#define PREP88110(NAME, NUM, FLAG_PRECHECK) \
331	xcr	FLAGS, FLAGS, SR1			; \
332	FLAG_PRECHECK					  \
333	/* the bsr later clobbers r1, so save now */	; \
334	stcr	%r1, SR2	/* r1 now free */	; \
335	/* set or clear the FLAG_FROM_KERNEL bit */	; \
336	ldcr	%r1, EPSR 				; \
337	clr	FLAGS, FLAGS, 1<FLAG_FROM_KERNEL> 	; \
338	bb0	PSR_SUPERVISOR_MODE_BIT, %r1, 1f 	; \
339	set	FLAGS, FLAGS, 1<FLAG_FROM_KERNEL>	; \
340	/* get a stack and an exception frame */	; \
3411:	bsr	m88110_setup_phase_one			; \
342	/* TMP2 now free -- use to set EF_VECTOR */	; \
343	or	TMP2, %r0, NUM				; \
344	/* call setup_phase_two to save all general */	; \
345	/* registers.                               */	; \
346	st	TMP2, %r30, EF_VECTOR			; \
347	bsr	m88110_setup_phase_two
348#endif
349
350/* Some defines for use with PREP88100() */
351#define	Clear_SSBR_Dest \
352	bsr	clear_dest_ssbr_bit;
353#define	M88100_Data_Precheck \
354	bb1.n	FLAG_IGNORE_DATA_EXCEPTION, FLAGS, \
355	    m88100_ignore_data_exception;
356#define	M88110_Data_Precheck \
357	bb1.n	FLAG_IGNORE_DATA_EXCEPTION, FLAGS, \
358	    m88110_ignore_data_exception;
359
360#ifdef M88100
361/*
362 * 88100 exception handlers
363 */
364
365/* unknown exception handler */
366GLOBAL(unknown_handler)
367	PREP88100("unknown", 0,,)
368	or	%r2, %r0, T_UNKNOWNFLT
369	or	%r3, %r0, %r30
370	XCALL(m88100_trap, check_ast)
371
372/* interrupt exception handler */
373GLOBAL(interrupt_handler)
374	PREP88100("interrupt", 1,,)
375	or	%r2, %r0, %r30
376	XCALL(interrupt, check_ast)
377
378/* instruction access exception handler */
379GLOBAL(instruction_access_handler)
380	PREP88100("inst", 2,,)
381	or	%r2, %r0, T_INSTFLT
382	or	%r3, %r0, %r30
383	XCALL(m88100_trap, check_ast)
384
385/*
386 * data access exception handler --
387 *  See badaddr() below for info about Data_Precheck.
388 */
389GLOBAL(data_exception_handler_bootstrap)
390	PREP88100("data", 3,, M88100_Data_Precheck)
391	/* No need to call m88100_trap(T_DATAFLT) as PREP will do this for us */
392	br	check_ast
393GLOBAL(data_exception_handler)
394	PREP88100("data", 3,,)
395	/* No need to call m88100_trap(T_DATAFLT) as PREP will do this for us */
396	br	check_ast
397
398/* misaligned access exception handler */
399GLOBAL(misaligned_handler)
400	PREP88100("misalign", 4, Clear_SSBR_Dest,)
401	or	%r2, %r0, T_MISALGNFLT
402	or	%r3, %r0, %r30
403	XCALL(m88100_trap, check_ast)
404
405/* unimplemented opcode exception handler */
406GLOBAL(unimplemented_handler)
407	PREP88100("unimp", 5,,)
408	or	%r2, %r0, T_ILLFLT
409	or	%r3, %r0, %r30
410	XCALL(m88100_trap, check_ast)
411
412/*
413 * Some versions of the chip have a bug whereby false privilege
414 * violation exceptions are raised. If the valid bit in the SXIP is clear,
415 * it is false.  If so, just return.  The code before PREP handles this....
416 */
417GLOBAL(privilege_handler)
418	stcr	%r1, SR2	/* hold r1 for a moment */
419	ldcr	%r1, SXIP	/* look at the sxip... valid bit set? */
420	bb1.n	RTE_VALID_BIT, %r1, 1f	/* skip over if a valid exception */
421	 ldcr	%r1, SR2	/* restore r1 */
422	RTE
4231:	PREP88100("privilege", 6, Clear_SSBR_Dest,)
424	or	%r2, %r0, T_PRIVINFLT
425	or	%r3, %r0, %r30
426	XCALL(m88100_trap, check_ast)
427
428/* bounds checking exception handler */
429GLOBAL(bounds_handler)
430	PREP88100("bounds", 7, Clear_SSBR_Dest,)
431	or	%r2, %r0, T_BNDFLT
432	or	%r3, %r0, %r30
433	XCALL(m88100_trap, check_ast)
434
435/* integer divide-by-zero exception handler */
436GLOBAL(divide_handler)
437	PREP88100("divide", 8, Clear_SSBR_Dest,)
438	or	%r2, %r0, T_ZERODIV
439	or	%r3, %r0, %r30
440	XCALL(m88100_trap, check_ast)
441
442/* integer overflow exception handler */
443GLOBAL(overflow_handler)
444	PREP88100("overflow", 9,,)
445	or	%r2, %r0, T_OVFFLT
446	or	%r3, %r0, %r30
447	XCALL(m88100_trap, check_ast)
448
449/* Floating-point precise handler */
450#define	FPp_SSBR_STUFF \
451	bsr	clear_FPp_ssbr_bit;
452GLOBAL(fp_precise_handler)
453	PREP88100("FPU precise", 114, FPp_SSBR_STUFF,)
454	or	%r2, %r0, T_FPEPFLT
455	or	%r3, %r0, %r30
456	XCALL(m88100_trap, check_ast)
457
458/* Floating-point imprecise handler */
459#define	FPi_SSBR_STUFF \
460	bsr	clear_FPi_ssbr_bit;
461GLOBAL(fp_imprecise_handler)
462	PREP88100("FPU imprecise", 115, FPi_SSBR_STUFF,)
463	or	%r2, %r0, T_FPEIFLT
464	or	%r3, %r0, %r30
465	XCALL(m88100_trap, check_ast)
466
467/* trap 450: system calls */
468GLOBAL(syscall_handler)
469	PREP88100("syscall", 450,,)
470	ld	%r2, %r30, GENREG_OFF(13)
471	or	%r3, %r0, %r30
472	XCALL(m88100_syscall, check_ast)
473
474/* trap 451: cache flush (necessary for trampolines) */
475GLOBAL(cache_flush_handler)
476	PREP88100("cache_flush", 451,,)
477	or	%r2, %r0, %r30
478	XCALL(cache_flush, check_ast)
479
480GLOBAL(sigsys)
481	PREP88100("sigsys", 501,,)
482	or	%r2, %r0, T_SIGSYS
483	or	%r3, %r0, %r30
484	XCALL(m88100_trap, check_ast)
485
486GLOBAL(stepbpt)
487	PREP88100("stepbpt", 504,,)
488	or	%r2, %r0, T_STEPBPT
489	or	%r3, %r0, %r30
490	XCALL(m88100_trap, check_ast)
491
492GLOBAL(userbpt)
493	PREP88100("userbpt", 511,,)
494	or	%r2, %r0, T_USERBPT
495	or	%r3, %r0, %r30
496	XCALL(m88100_trap, check_ast)
497
498#ifdef DDB
499GLOBAL(break)
500	PREP88100("break", 130,,)
501	or	%r2, %r0, T_KDB_BREAK
502	or	%r3, %r0, %r30
503	XCALL(m88100_trap, check_ast)
504
505GLOBAL(trace)
506	PREP88100("trace", 131,,)
507	or	%r2, %r0, T_KDB_TRACE
508	or	%r3, %r0, %r30
509	XCALL(m88100_trap, check_ast)
510
511GLOBAL(entry)
512	PREP88100("kdb", 132,,)
513	or	%r2, %r0, T_KDB_ENTRY
514	or	%r3, %r0, %r30
515	XCALL(m88100_trap, check_ast)
516#endif
517
518/*
519 * The error exception and reset exception handler.
520 *
521 * The error exception is raised when any other non-trap exception is raised
522 * while shadowing is off. This is Bad News.
523 *
524 * The reset exception is raised when the RST signal is asserted (machine
525 * is reset), the value of VBR is changed after exceptions are enabled,
526 * or when a jmp, br/bsr to addr 0 (accidents do happen :-)
527 * To tell the difference, you should check the value of r1 and the valid
528 * bit of SXIP.
529 * Upon a real reset, VBR is set to zero (0), so code must be at addr 0
530 * to handle it!!!
531 *
532 * The shadow registers are not valid in this case (shadowing was off, if this
533 * was an error exception, and may not be on, if this was a reset exception).
534 * R1-R31 may be interesting though, so we'll save them.
535 *
536 * We'll not worry about trashing r26-29 here,
537 * since they aren't generally used.
538 */
539GLOBAL(error_handler)
540	br.n	1f
541	 or	%r29, %r0, 10
542GLOBAL(reset_handler)
543	or	%r29, %r0, 0
5441:
545	or	%r26, %r0,  %r31	/* save old stack */
546	or.u	%r31, %r0,  %hi16(initstack_end)
547	or	%r31, %r31, %lo16(initstack_end)
548
549#ifdef DEBUG
550	/* zero the stack, so we'll know what we're lookin' at */
551	or.u	%r27, %r0,  %hi16(initstack)
552	or	%r27, %r27, %lo16(initstack)
5531:	cmp	%r28, %r27, %r31
554	bb1	ge,   %r28, 2f	/* branch if at the end of the stack */
555	st	%r0,  %r0,  %r27
556	br.n	1b
557	 addu	%r27, %r27, 4	/* bump up */
5582:	/* stack has been cleared */
559#endif
560
561	/* ensure that stack is 8-byte aligned */
562	clr	%r31, %r31, 3<0>	/* round down to 8-byte boundary */
563
564	/* create exception frame on stack */
565	subu	%r31, %r31, TRAPFRAME_SIZEOF	/* r31 now our E.F. */
566
567	/* save old R31 and other R registers */
568	st.d	%r0 , %r31, GENREG_OFF(0)
569	st.d	%r2 , %r31, GENREG_OFF(2)
570	st.d	%r4 , %r31, GENREG_OFF(4)
571	st.d	%r6 , %r31, GENREG_OFF(6)
572	st.d	%r8 , %r31, GENREG_OFF(8)
573	st.d	%r10, %r31, GENREG_OFF(10)
574	st.d	%r12, %r31, GENREG_OFF(12)
575	st.d	%r14, %r31, GENREG_OFF(14)
576	st.d	%r16, %r31, GENREG_OFF(16)
577	st.d	%r18, %r31, GENREG_OFF(18)
578	st.d	%r20, %r31, GENREG_OFF(20)
579	st.d	%r22, %r31, GENREG_OFF(22)
580	st.d	%r24, %r31, GENREG_OFF(24)
581	st	%r30, %r31, GENREG_OFF(30)
582	st	%r26, %r31, GENREG_OFF(31)
583
584	/* save shadow registers (are OLD if error_handler, though) */
585	ldcr	%r10, EPSR
586	st	%r10, %r31, EF_EPSR
587	ldcr	%r10, SXIP
588	st	%r10, %r31, EF_SXIP
589	ldcr	%r10, SNIP
590	st	%r10, %r31, EF_SNIP
591	ldcr	%r10, SR1
592	st	%r10, %r31, EF_FLAGS
593	ldcr	%r10, SFIP
594	st	%r10, %r31, EF_SFIP
595	ldcr	%r10, SSBR
596	st	%r10, %r31, EF_SSBR
597	stcr	%r0,  SSBR	/* won't want shadow bits bothering us later */
598
599	ldcr	%r10, DMT0
600	st	%r10, %r31, EF_DMT0
601	ldcr	%r11, DMD0
602	st	%r11, %r31, EF_DMD0
603	ldcr	%r12, DMA0
604
605	st	%r12, %r31, EF_DMA0
606	ldcr	%r10, DMT1
607	st	%r10, %r31, EF_DMT1
608	FLUSH_PIPELINE
609	ldcr	%r11, DMD1
610	st 	%r11, %r31, EF_DMD1
611	ldcr	%r12, DMA1
612	st	%r12, %r31, EF_DMA1
613
614	ldcr	%r10, DMT2
615	st	%r10, %r31, EF_DMT2
616	ldcr	%r11, DMD2
617	st	%r11, %r31, EF_DMD2
618	ldcr	%r12, DMA2
619	st	%r12, %r31, EF_DMA2
620
621	/* shove sr2 into EF_FPLS1 */
622	ldcr	%r10, SR2
623	st	%r10, %r31, EF_FPLS1
624
625	/* shove sr3 into EF_FPHS2 */
626	ldcr	%r10, SR3
627	st	%r10, %r31, EF_FPHS2
628
629	/* save error vector */
630	st	%r29, %r31, EF_VECTOR
631
632	/*
633	 * Cheap way to enable FPU and start shadowing again.
634	 */
635	ldcr	%r10, PSR
636	clr	%r10, %r10, 1<PSR_FPU_DISABLE_BIT>	/* enable the FPU */
637	clr	%r10, %r10, 1<PSR_SHADOW_FREEZE_BIT>	/* and shadowing */
638	stcr	%r10, PSR
639	FLUSH_PIPELINE
640
641	/* put pointer to regs into r30... r31 will become a simple stack */
642	or	%r30, %r31, %r0
643
644	subu	%r31, %r31, 0x10	/* make some breathing space */
645	st	%r30, %r31, 0x0c	/* store frame pointer on the stack */
646#ifdef DDB
647	st	%r30, %r31, 0x08	/* store again for the debugger to recognize */
648	or.u	%r20, %r0,  %hi16(0x87654321)
649	or	%r20, %r20, %lo16(0x87654321)
650	st	%r20, %r31, 0x04
651	st	%r20, %r31, 0x00
652#endif
653
654	bsr.n	error_fatal
655	 or	%r2, %r0, %r30
656
657	/* turn interrupts back on */
658	ldcr	%r1, PSR
659	clr	%r1, %r1, 1<PSR_INTERRUPT_DISABLE_BIT>
660	stcr	%r1, PSR
661	FLUSH_PIPELINE
662
6631:
664	br	1b
665	/* NOTREACHED */
666#endif	/* M88100 */
667
668/*
669 * This is part of baddadr (below).
670 */
671#ifdef M88100
672ASLOCAL(m88100_ignore_data_exception)
673	/*
674	 * SR1: previous FLAGS reg
675	 * SR2: free
676	 * SR3: must preserve
677	 * FLAGS: CPU status flags
678	 */
679	xcr	FLAGS, FLAGS, SR1	/* replace SR1, FLAGS */
680
681	/*
682	 * For more info, see badaddr() below.
683	 *
684	 * We just want to jump to "badaddr__return_nonzero" below.
685	 *
686	 * We don't worry about trashing r2 here because we're
687	 * jumping back to the function badaddr() where we're allowed
688	 * to blast r2..r9 as we see fit.
689	 */
690
691	/* the "+2" below is to set the VALID bit. */
692	or.u	%r2, %r0, %hi16(badaddr__return_nonzero + 2)
693	or	%r2, %r2, %lo16(badaddr__return_nonzero + 2)
694	stcr	%r2, SNIP	/* Make it the next instruction to execute */
695	addu	%r2, %r2, 4
696	stcr	%r2, SFIP	/* and the next one after that, too. */
697	stcr	%r0, SSBR	/* make the scoreboard happy. */
698	RTE
699#endif /* M88100 */
700
701#ifdef M88110
702/*
703 * This is part of baddadr (below).
704 */
705ASLOCAL(m88110_ignore_data_exception)
706	/*
707	 * SR1: previous FLAGS reg
708	 * SR2: free
709	 * SR3: must preserve
710	 * FLAGS: CPU status flags
711	 */
712	xcr	FLAGS, FLAGS, SR1	/* replace SR1, FLAGS */
713
714	/*
715	 * For more info, see badaddr() below.
716	 *
717	 * We just want to jump to "badaddr__return_nonzero" below.
718	 *
719	 * We don't worry about trashing R2 here because we're
720	 * jumping back to the function badaddr() where we're allowed
721	 * to blast r2..r9 as we see fit.
722	 */
723
724	or.u	%r2, %r0, %hi16(badaddr__return_nonzero)
725	or	%r2, %r2, %lo16(badaddr__return_nonzero)
726	stcr	%r2, EXIP	/* Make it the next instruction to execute */
727	stcr	%r0, DSR	/* Clear exception status */
728	RTE
729#endif /* M88110 */
730
731/*
732 * extern int badaddr(vaddr_t addr, int len)
733 *
734 * Returns true (non-zero) if the given LEN bytes starting at ADDR are
735 * not all currently accessible by the kernel.
736 *
737 * If all LEN bytes starting at ADDR are accessible, zero is returned.
738 *
739 * Len may be be 1, 2, 4 or 8.
740 *
741 * This is implemented by setting a special flag in SR1 before trying to access
742 * the given address. If a data access exception is raised, the address
743 * is inaccessible. The exception handler will notice the special CPU flag
744 * and not try to swap the address in. Rather, it will return to
745 * "badaddr__return_nonzero" in this routine so that we may return non-zero
746 * to the calling routine.
747 *
748 * If no fault is raised, we continue to where we return zero to the calling
749 * routine (after removing the special CPU flag).
750 */
751
752GLOBAL(badaddr)
753	/*
754	 * Disable interrupts ... don't want a context switch while we're
755	 * doing this! Also, save the old PSR in R8 to restore later.
756	 */
757	ldcr	%r8, PSR
758	set	%r4, %r8, 1<PSR_INTERRUPT_DISABLE_BIT>
759	stcr	%r4, PSR
760	FLUSH_PIPELINE
761
762	ldcr	%r5, SR1
763	set	%r5, %r5, 1<FLAG_IGNORE_DATA_EXCEPTION>
764	/* resetting r5 to SR1 done in the delay slot below. */
765
766	/* make sure the upper 28 bits of the size are zero... */
767	ext	%r6, %r3, 0<4>
768	bcnd.n	ne0, %r6, badaddr__return_nonzero
769	 stcr	%r5, SR1
770
771	or.u	%r6, %r0, %hi16(badaddr_switch)
772	or	%r6, %r6, %lo16(badaddr_switch)
773	lda	%r3, %r6[%r3]
774	jmp	%r3
775
776ASLOCAL(badaddr_switch)
777	br	badaddr__return_nonzero
778	br	badaddr__b
779	br	badaddr__h
780	br	badaddr__return_nonzero
781	br	badaddr__w
782	br	badaddr__return_nonzero
783	br	badaddr__return_nonzero
784	br	badaddr__return_nonzero
785	br	badaddr__d
786	br	badaddr__return_nonzero
787	br	badaddr__return_nonzero
788	br	badaddr__return_nonzero
789	br	badaddr__return_nonzero
790	br	badaddr__return_nonzero
791	br	badaddr__return_nonzero
792	br	badaddr__return_nonzero
793
794	/*
795	 * The load attempts below will either fault or not. If they fault,
796	 * execution will go to data_access_handler, then to
797	 * ignore_data_exception, then to badaddr__return_nonzero, which
798	 * will return to the calling function.
799	 * If there is no fault, execution will just continue as normal.
800	 */
801
802ASLOCAL(badaddr__b)
803	FLUSH_PIPELINE
804	ld.b	%r6, %r2, 0
805	FLUSH_PIPELINE
806	br.n	badaddr__return
807	 or	%r2, %r0, %r0
808
809ASLOCAL(badaddr__h)
810	/* It's a bad address if it's misaligned. */
811	bb1	0, %r2, badaddr__return_nonzero
812
813	FLUSH_PIPELINE
814	ld.h	%r6, %r2, 0
815	FLUSH_PIPELINE
816	br.n	badaddr__return
817	 or	%r2, %r0, %r0
818
819ASLOCAL(badaddr__w)
820	/* It's a bad address if it's misaligned. */
821	bb1	0, %r2, badaddr__return_nonzero
822	bb1	1, %r2, badaddr__return_nonzero
823
824	FLUSH_PIPELINE
825	ld	%r6, %r2, 0
826	FLUSH_PIPELINE
827	br.n	badaddr__return
828	 or	%r2, %r0, %r0	/* indicate a zero (address not bad) return.*/
829
830ASLOCAL(badaddr__d)
831	/* It's a bad address if it's misaligned. */
832	bb1	0, %r2, badaddr__return_nonzero
833	bb1	1, %r2, badaddr__return_nonzero
834	bb1	2, %r2, badaddr__return_nonzero
835
836	FLUSH_PIPELINE
837	ld.d	%r6, %r2, 0
838	FLUSH_PIPELINE
839	br.n	badaddr__return
840	 or	%r2, %r0, %r0	/* indicate a zero (address not bad) return.*/
841
842ASLOCAL(badaddr__return_nonzero)
843	or	%r2, %r0, 1
844	/* FALLTHROUGH */
845
846ASLOCAL(badaddr__return)
847	ldcr	%r4, SR1
848	clr	%r4, %r4, 1<FLAG_IGNORE_DATA_EXCEPTION>
849	stcr	%r4, SR1
850
851	/*
852	 * Restore the PSR to what it was before.
853	 * The only difference is that we might be enabling interrupts
854	 * (which we turned off above).  If interrupts were already off,
855	 * we do not want to turn them on now, so we just restore from
856	 * where we saved it.
857	 */
858	stcr	%r8, PSR
859	FLUSH_PIPELINE
860	jmp	%r1
861
862#ifdef M88100
863ASLOCAL(m88100_setup_phase_one)
864	/*
865	 * SR1: saved copy of exception-time register now holding FLAGS
866	 * SR2: saved copy of exception-time r1
867	 * SR3: must be preserved .. may be the exception-time stack
868	 * r1: return address to calling exception handler
869	 * FLAGS: CPU status flags
870	 *
871	 * immediate goal:
872	 *   Decide where we're going to put the exception frame.
873	 *   Might be at the end of R31, SR3, or the process pcb.
874	 */
875
876	/* Check if we are coming in from a FPU restart exception.
877	   If so, the pcb will be in SR3 */
878	NOP
879	xcr	%r1, %r1, SR2
880	NOP
881	NOP
882	NOP
883
884	bb1	FLAG_ENABLING_FPU, FLAGS, m88100_use_SR3_pcb
885	/* are we coming in from user mode? If so, pick up process pcb */
886	bb0	FLAG_FROM_KERNEL, FLAGS, m88100_pickup_stack
887
888	/* Interrupt in kernel mode, not FPU restart */
889	/*
890	 * SR1: saved copy of exception-time register now holding FLAGS
891	 * SR2: return address to the calling exception handler
892	 * SR3: must be preserved; may be important for other exceptions
893	 * FLAGS: CPU status flags
894	 *
895	 * immediate goal:
896	 *   We're already on the kernel stack, but not having
897	 *   needed to use SR3. We can just make room on the
898	 *   stack (r31) for our exception frame.
899	 */
900	subu	%r31, %r31, TRAPFRAME_SIZEOF	/* r31 now our E.F. */
901	st	FLAGS,%r31, EF_FLAGS		/* save flags */
902	st	%r1,  %r31, GENREG_OFF(1)	/* save prev. r1 (now free)*/
903
904	ldcr	%r1,  SR3			/* save previous SR3 */
905	st	%r1,  %r31, EF_SR3
906
907	addu	%r1,  %r31, TRAPFRAME_SIZEOF	/* save previous r31 */
908	br.n	m88100_have_pcb
909	 st 	%r1,  %r31, GENREG_OFF(31)
910
911ASLOCAL(m88100_use_SR3_pcb)
912	/*
913	 * SR1: saved copy of exception-time register now holding FLAGS
914	 * SR2: return address to the calling exception handler
915	 * SR3: must be preserved; exception-time stack pointer
916	 * FLAGS: CPU status flags
917	 *
918	 * immediate goal:
919	 *   An exception occurred while enabling the FPU. Since r31
920	 *   is the user's r31 while enabling the FPU, we had put
921	 *   our pcb pointer into SR3, so make room from
922	 *   there for our stack pointer.
923	 *   We need to check if SR3 is the old stack pointer or the
924	 *   pointer off to the user pcb. If it pointing to the user
925	 *   pcb, we need to pick up the kernel stack. Otherwise
926	 *   we need to allocate a frame upon it.
927	 *   We look at the EPSR to see if it was from user mode
928	 *   Unfortunately, we have no registers free at the moment
929	 *   But we know register 0 in the pcb frame will always be
930	 *   zero, so we can use it as scratch storage.
931	 */
932	xcr	%r30, %r30, SR3			/* r30 = old exception frame */
933	st	%r1,  %r30, GENREG_OFF(0)	/* free up r1 */
934	ld	%r1,  %r30, EF_EPSR		/* get back the epsr */
935	bb0.n	PSR_SUPERVISOR_MODE_BIT, %r1, 1f/* if user mode */
936	 ld	%r1,  %r30, GENREG_OFF(0)	/* restore r1 */
937	/* we were in kernel mode - dump frame upon the stack */
938	st	%r0,  %r30, GENREG_OFF(0)	/* repair old frame */
939	subu	%r30, %r30, TRAPFRAME_SIZEOF	/* r30 now our E.F. */
940	st	FLAGS,%r30, EF_FLAGS		/* save flags */
941	st	%r1,  %r30, GENREG_OFF(1)	/* save prev r1 (now free) */
942
943	st	%r31, %r30, GENREG_OFF(31)	/* save previous r31 */
944	or	%r31, %r0,  %r30		/* make r31 our pointer. */
945	addu	%r30, %r30, TRAPFRAME_SIZEOF	/* r30 now has previous SR3 */
946	st	%r30, %r31, EF_SR3		/* save previous SR3 */
947	br.n	m88100_have_pcb
948	 xcr	%r30, %r30, SR3			/* restore r30 */
9491:
950	/* we took an exception while restarting the FPU from user space.
951	 * Consequently, we never picked up a stack. Do so now.
952	 * R1 is currently free (saved in the exception frame pointed at by
953	 * r30) */
954	ldcr	%r1,  CPU
955	ld	%r1,  %r1,  CI_CURPCB
956	addu	%r1,  %r1,  USPACE - TRAPFRAME_SIZEOF
957	st	FLAGS,%r1,  EF_FLAGS		/* store flags */
958	st	%r31, %r1,  GENREG_OFF(31)	/* store r31 - now free */
959	st	%r30, %r1,  EF_SR3		/* store old SR3 (pcb) */
960	or	%r31, %r1,  %r0			/* make r31 our exception fp */
961	ld	%r1,  %r30, GENREG_OFF(0)	/* restore old r1 */
962	st	%r0,  %r30, GENREG_OFF(0)	/* repair that frame */
963	st	%r1,  %r31, GENREG_OFF(1)	/* store r1 */
964	br.n	m88100_have_pcb
965	 xcr	%r30, %r30, SR3			/* restore r30 */
966
967ASLOCAL(m88100_pickup_stack)
968	/*
969	 * SR1: saved copy of exception-time register now holding FLAGS
970	 * SR2: return address to the calling exception handler
971	 * SR3: free
972	 * FLAGS: CPU status flags
973	 *
974	 * immediate goal:
975	 *   Since we're servicing an exception from user mode, we
976	 *   know that SR3 is free.  We use it to free up a temp.
977	 *   register to be used in getting the process pcb
978	 */
979	stcr	%r31, SR3	/* save previous r31 */
980
981	/* switch to the process kernel stack. */
982	ldcr	%r31, CPU
983	ld	%r31, %r31, CI_CURPCB
984	addu	%r31, %r31, PCB_USER_STATE	/* point to user save area */
985
986	/*
987	 * WARNING! Using pcb->user_state as the exception frame
988	 * AND stack pointer, means we can not afford using the stack
989	 * until we have saved enough and can go back to the top of the u area,
990	 * after the FPU is enabled.
991	 */
992
993	st	FLAGS,%r31, EF_FLAGS		/* save flags */
994	st	%r1,  %r31, GENREG_OFF(1)	/* save prev. r1 (now free) */
995	ldcr	%r1,  SR3			/* save previous r31 */
996	st	%r1,  %r31, GENREG_OFF(31)
997	/* FALLTHROUGH */
998
999ASLOCAL(m88100_have_pcb)
1000	/*
1001	 * SR1: saved copy of exception-time register now holding FLAGS
1002	 * SR2: return address to the calling exception handler
1003	 * SR3: free
1004	 * r1:  free
1005	 * FLAGS: CPU status flags
1006	 * r31: our exception frame
1007	 * Valid in the exception frame:
1008	 *   Exception-time r1, r31, FLAGS.
1009	 *   Exception SR3, if appropriate.
1010	 *
1011	 * immediate goal:
1012	 *   Save the shadow registers that need to be saved to
1013	 *   the exception frame.
1014	 */
1015	stcr	TMP, SR3	/* free up TMP, TMP2, TMP3 */
1016	SAVE_TMP2(%r31)
1017	SAVE_TMP3(%r31)
1018
1019	/* save some exception-time registers to the exception frame */
1020	ldcr	TMP,  EPSR
1021	st	TMP,  %r31, EF_EPSR
1022	ldcr	TMP3, SNIP
1023	st	TMP3, %r31, EF_SNIP
1024	ldcr	TMP2, SFIP
1025	st	TMP2, %r31, EF_SFIP
1026	/* get and store the cpu_info pointer */
1027	ldcr	TMP,  CPU
1028	st	TMP,  %r31, EF_CPU
1029
1030	/*
1031	 * Save Pbus fault status register from data and inst CMMU.
1032	 * We can afford calling a function since r1 is safe to use here.
1033	 */
1034GLOBAL(pfsr_save)
1035	PFSR_SAVE
1036ASLOCAL(pfsr_done)
1037
1038	ldcr	TMP,  SSBR
1039	ldcr	TMP2, SXIP
1040	ldcr	TMP3, DMT0
1041	st	TMP2, %r31, EF_SXIP
1042
1043/*
1044 * The above shadow registers are obligatory for any and all
1045 * exceptions.  Now, if the data access pipeline is not clear,
1046 * we must save the DMx shadow registers, as well as clear
1047 * the appropriate SSBR bits for the destination registers of
1048 * loads or xmems.
1049 */
1050	bb0.n	DMT_VALID_BIT, TMP3, 8f
1051	 st	TMP3, %r31, EF_DMT0
1052
1053	ldcr	TMP2, DMT1
1054	ldcr	TMP3, DMT2
1055	st	TMP2, %r31, EF_DMT1
1056	st	TMP3, %r31, EF_DMT2
1057
1058	ldcr	TMP2, DMA0
1059	ldcr	TMP3, DMA1
1060	st	TMP2, %r31, EF_DMA0
1061	st	TMP3, %r31, EF_DMA1
1062
1063	ldcr	TMP2, DMA2
1064	ldcr	TMP3, DMD0
1065	st	TMP2, %r31, EF_DMA2
1066	st	TMP3, %r31, EF_DMD0
1067
1068	FLUSH_PIPELINE
1069	ldcr	TMP2, DMD1
1070	ldcr	TMP3, DMD2
1071	st	TMP2, %r31, EF_DMD1
1072	st	TMP3, %r31, EF_DMD2
1073
1074	/* make sure an exception in fpu_enable will not see our DMT0 */
1075	stcr	%r0,   DMT0
1076
1077	/*
1078 	 * need to clear "appropriate" bits in the SSBR before
1079 	 * we restart the FPU
1080 	 */
1081	ld	TMP2, %r31, EF_DMT0
1082	bb1	DMT_LOCK_BIT,  TMP2, 1f
1083	bb1	DMT_WRITE_BIT, TMP2, 2f
10841:
1085	extu	TMP2, TMP2, DMT_DREG_WIDTH <DMT_DREG_OFFSET>
1086	set	TMP2, TMP2, 1<5>
1087	clr	TMP,  TMP,  TMP2
10882:
1089	ldcr	TMP2, DMT1
1090	bb0	DMT_VALID_BIT, TMP2, 4f
1091	bb1	DMT_LOCK_BIT,  TMP2, 3f
1092	bb1	DMT_WRITE_BIT, TMP2, 4f
10933:
1094	extu	TMP2, TMP2, DMT_DREG_WIDTH <DMT_DREG_OFFSET>
1095	set	TMP2, TMP2, 1<5>
1096	clr	TMP,  TMP,  TMP2
10974:
1098	ldcr	TMP2, DMT2
1099	bb0	DMT_VALID_BIT, TMP2, 8f
1100	bb1	DMT_LOCK_BIT,  TMP2, 5f
1101	bb1	DMT_WRITE_BIT, TMP2, 8f
1102	bb1	DMT_DOUBLE_BIT,TMP2, 6f
11035:
1104	extu	TMP2, TMP2, DMT_DREG_WIDTH <DMT_DREG_OFFSET>
1105	br.n	7f
1106	 set	TMP2, TMP2, 1<5>	/* single */
11076:
1108	extu	TMP2, TMP2, DMT_DREG_WIDTH <DMT_DREG_OFFSET>
1109	set	TMP2, TMP2, 1<6>	/* double */
11107:
1111	clr	TMP,  TMP,  TMP2
11128:
1113	/*
1114	 * SR1: saved copy of exception-time register now holding FLAGS
1115	 * SR2: return address to the calling exception handler
1116	 * SR3: saved TMP
1117	 * r1:  free
1118	 * TMP: possibly revised SSBR
1119	 * TMP2: free
1120	 * TMP3: free
1121	 * FLAGS: CPU status flags
1122	 * r31: exception frame
1123	 * Valid in the exception frame:
1124	 *   Exception-time r1, r31, FLAGS.
1125	 *   Exception-time TMP2, TMP3.
1126	 *   Exception-time epsr, sfip, snip, sxip.
1127	 *   Dmt0.
1128	 *   Other data pipeline control registers, if appropriate.
1129	 *   Exception SR3, if appropriate.
1130	 */
1131	ldcr	%r1,  SR2
1132	jmp	%r1	/* allow the handler to clear more SSBR bits */
1133
1134ASLOCAL(clear_FPi_ssbr_bit)
1135	/*
1136	 * Clear floating point imprecise ssbr bits.
1137	 * Also, save appropriate FPU control registers to the E.F.
1138	 *
1139	 * r1:  return address to calling exception handler
1140	 * TMP: (possibly) revised ssbr
1141	 * TMP2: free
1142	 * TMP3: free
1143	 */
1144	fldcr	TMP2, FPSR
1145	fldcr	TMP3, FPCR
1146	st	TMP2, %r31, EF_FPSR
1147	st	TMP3, %r31, EF_FPCR
1148
1149	fldcr	TMP2, FPECR
1150	fldcr	TMP3, FPRH
1151	st	TMP2, %r31, EF_FPECR
1152	st	TMP3, %r31, EF_FPRH
1153
1154	fldcr 	TMP2, FPIT
1155	fldcr	TMP3, FPRL
1156	st	TMP2, %r31, EF_FPIT
1157	st	TMP3, %r31, EF_FPRL
1158
1159	/*
1160	 * We only need clear the bit in the SSBR for the
1161	 * 2nd reg of a double result [see section 6.8.5]
1162	 */
1163#define FPIT_SIZE_BIT   10
1164	bb0	FPIT_SIZE_BIT, TMP2, 1f
1165	extu	TMP2, TMP2, 5<0>	/* get the reg. */
1166	set	TMP2, TMP2, 1<6>	/* set width */
1167	clr	TMP,  TMP,  TMP2
11681:
1169	jmp	%r1
1170
1171
1172ASLOCAL(clear_FPp_ssbr_bit)
1173	/*
1174	 * Clear floating point precise ssbr bits.
1175	 * Also, save appropriate FPU control registers to the E.F.
1176	 *
1177	 * r1:  return address to calling exception handler
1178	 * TMP: (possibly) revised ssbr
1179	 * TMP2: free
1180	 * TMP3: free
1181	 */
1182	fldcr	TMP2, FPSR
1183	fldcr	TMP3, FPCR
1184	st	TMP2, %r31, EF_FPSR
1185	st	TMP3, %r31, EF_FPCR
1186
1187	fldcr	TMP3, FPECR
1188	st	TMP3, %r31, EF_FPECR
1189	fldcr	TMP2, FPHS1
1190	fldcr	TMP3, FPHS2
1191	st	TMP2, %r31, EF_FPHS1
1192	st	TMP3, %r31, EF_FPHS2
1193
1194	fldcr	TMP2, FPLS1
1195	fldcr	TMP3, FPLS2
1196	st	TMP2, %r31, EF_FPLS1
1197	st	TMP3, %r31, EF_FPLS2
1198
1199	fldcr	TMP2, FPPT
1200	st	TMP2, %r31, EF_FPPT
1201
1202#define FPPT_SIZE_BIT   5
1203	bb1.n	FPPT_SIZE_BIT, TMP2, 2f
1204	 extu	TMP3, TMP2, 5<0>	/* get FP operation dest reg */
1205	br.n	3f
1206	 set	TMP3, TMP3, 1<5>	/* size=1 - clear one bit for float */
12072:
1208	set	TMP3, TMP3, 1<6>	/* size=2 - clear two bits for double */
12093:
1210	jmp.n	%r1
1211	 clr	TMP,  TMP,  TMP3	/* clear bit(s) in ssbr. */
1212
1213
1214ASLOCAL(clear_dest_ssbr_bit)
1215	/*
1216	 * There are various cases where an exception can leave the
1217	 * destination register's bit in the SB set.
1218	 * Examples:
1219	 *   misaligned or privilege exception on a LD or XMEM
1220	 *   DIV or DIVU by zero.
1221	 *
1222	 * I think that if the instruction is LD.D, then two bits must
1223	 * be cleared.
1224	 *
1225	 * Even though there are a number of instructions/exception
1226	 * combinations that could fire this code up, it's only required
1227	 * to be run for the above cases.  However, I don't think it'll
1228	 * ever be a problem to run this in other cases (ST instructions,
1229	 * for example), so I don't bother checking.  If we had to check
1230	 * for every possible instruction, this code would be much larger.
1231	 *
1232	 * The only checking, then, is to see if it's a LD.D or not.
1233	 *
1234	 * At the moment....
1235	 *  r1:  return address to calling exception handler
1236	 *  TMP: (possibly) revised ssbr
1237	 *  TMP2: free
1238	 *  TMP3: free
1239	 */
1240
1241	ldcr	TMP3, EPSR	/* going to check: user or system memory? */
1242	ldcr	TMP2, SXIP	/* get the instruction's address */
1243	bb1.n	PSR_SUPERVISOR_MODE_BIT, TMP3, 2f
1244	 clr	TMP2, TMP2, 2<0>	/* get rid of valid and error bits. */
1245
1246	/* user space load here */
1247#if ERRATA__XXX_USR
1248	NOP
1249	ld.usr	TMP2, TMP2, %r0	/* get the instruction itself */
1250	NOP
1251	NOP
1252	NOP
1253	br    3f
1254#else
1255	br.n  3f
1256	 ld.usr	TMP2, TMP2, %r0	/* get the instruction itself */
1257#endif
1258
12592:	/* system space load here */
1260	ld	TMP2, TMP2, %r0	/* get the instruction itself */
1261
12623:	/* now we have the instruction..... */
1263	/*
1264	 * Now see if it's a double load
1265	 * There are three forms of double load [IMM16, scaled, unscaled],
1266	 * which can be checked by matching against two templates:
1267	 *                    -- 77776666555544443333222211110000 --
1268	 *   if (((instruction & 11111100000000000000000000000000) ==
1269	 *                       00010000000000000000000000000000) ||
1270	 *       ((instruction & 11111100000000001111110011100000) ==
1271	 *                       11110100000000000001000000000000))
1272	 *   {
1273	 *      It's a load double, so
1274	 *      clear two SSBR bits.
1275	 *   } else {
1276	 *      It's not a load double.
1277	 *      Must be a load single, xmem, or st
1278	 *      Thus, clear one SSBR bit.
1279	 *   }
1280	 */
1281	/* check the first pattern for ld.d */
1282	extu	TMP3, TMP2, 16<16>	/* get the upper 16 bits */
1283	mask	TMP3, TMP3, 0xfc00	/* apply the mask */
1284	cmp	TMP3, TMP3, 0x1000	/* if equal, it's a load double */
1285	bb1	eq,   TMP3, 2f
1286
1287	/* still could be -- check the second pattern for ld.d */
1288	/* look at the upper 16 bits first */
1289	extu	TMP3, TMP2, 16<16>	/* get the upper 16 bits */
1290	mask	TMP3, TMP3, 0xfc00	/* apply the mask */
1291	cmp	TMP3, TMP3, 0xf400	/* if equal, might be a load double */
1292	bb1	ne,   TMP3, 1f		/* not equal, must be single */
1293
1294	/* now look at the lower 16 bits */
1295	extu	TMP3, TMP2, 16<0>	/* get the lower 16 bits */
1296	mask	TMP3, TMP3, 0xfce0	/* apply the mask */
1297	cmp	TMP3, TMP3, 0x1000	/* if equal, it's a load double */
1298	bb1	eq,   TMP3, 2f
1299
13001:	/* misaligned single */
1301	extu	TMP2, TMP2, 5<21>	/* get the destination register */
1302	br.n	3f
1303	 set	TMP2, TMP2, 1<5>	/* set size=1 */
1304
13052:	/* misaligned double */
1306	extu	TMP2, TMP2, 5<21>	/* get the destination register */
1307	set	TMP2, TMP2, 1<6>	/* set size=2 -- clear two bits */
13083:
1309	jmp.n	%r1
1310	 clr	TMP,  TMP,  TMP2	/* clear bit(s) in ssbr. */
1311
1312ASLOCAL(m88100_setup_phase_two)
1313	/*
1314	 * SR1: saved copy of exception-time register now holding FLAGS
1315	 * SR2: free
1316	 * SR3: saved TMP
1317	 * r1:  return address to calling exception handler
1318	 * TMP: possibly revised SSBR
1319	 * TMP2: free
1320	 * TMP3: free
1321	 * FLAGS: CPU status flags
1322	 * r31: our exception frame
1323	 *    Valid in the exception frame:
1324	 *   Exception-time r1, r31, FLAGS.
1325	 *   Exception-time TMP2, TMP3.
1326	 *   Exception-time epsr, sfip, snip, sxip.
1327	 *   Exception number (EF_VECTOR).
1328	 *   Dmt0
1329	 *   Other data pipeline control registers, if appropriate.
1330	 *   FPU control registers, if appropriate.
1331	 *   Exception SR3, if appropriate.
1332	 *
1333	 * immediate goal:
1334	 *   restore the system to the exception-time state (except
1335	 *   SR3 will be OUR stack pointer) so that we may restart the FPU.
1336	 */
1337
1338	stcr	TMP,  SSBR	/* done with SSBR, TMP now free */
1339	RESTORE_TMP2(%r31)	/* done with extra temp regs */
1340	RESTORE_TMP3(%r31)	/* done with extra temp regs */
1341
1342	/* Get the current PSR and modify for the rte to enable the FPU */
1343	ldcr	TMP,  PSR
1344	clr	TMP,  TMP, 1<PSR_FPU_DISABLE_BIT>	/* enable the FPU */
1345	clr	TMP,  TMP, 1<PSR_SHADOW_FREEZE_BIT>	/* and shadowing */
1346	stcr	TMP,  EPSR
1347
1348	/* the "+2" below is to set the VALID_BIT */
1349	or.u	TMP,  %r0, %hi16(m88100_fpu_enable + 2)
1350	or	TMP,  TMP, %lo16(m88100_fpu_enable + 2)
1351	stcr	TMP,  SNIP
1352	addu	TMP,  TMP, 4
1353	stcr	TMP,  SFIP
1354
1355	set	FLAGS, FLAGS, 1<FLAG_ENABLING_FPU>
1356	xcr	FLAGS, FLAGS, SR1
1357	st	%r1,   %r31,  EF_RET		/* save the return address */
1358	ld	%r1,   %r31,  GENREG_OFF(1)	/* get original r1 */
1359
1360	xcr	TMP,   %r31,  SR3	/* TMP now restored. R31 now saved in SR3 */
1361	ld	%r31,  %r31,  GENREG_OFF(31)	/* get original r31 */
1362
1363	/*
1364	 * SR1: CPU flags
1365	 * SR2: free
1366	 * SR3: pointer to our exception frame (our stack pointer)
1367	 * r1 through r31: original exception-time values
1368	 *
1369	 * Valid in the exception frame:
1370	 *   Exception-time FLAGS.
1371	 *   Exception-time epsr, sfip, snip, sxip.
1372	 *   Exception number (EF_VECTOR).
1373	 *   Dmt0
1374	 *   Other data pipeline control registers, if appropriate.
1375	 *   FPU control registers, if appropriate.
1376	 *   Exception SR3, if appropriate.
1377	 *   Held temporarily in the exception frame:
1378	 *   Return address to the calling exception handler.
1379	 *
1380	 * immediate goal:
1381	 *   Do an RTE to restart the fpu and jump to "fpu_enable"
1382	 *   Another exception (or exceptions) may be raised in
1383	 *   this, which is why FLAG_ENABLING_FPU is set in SR1.
1384	 */
1385
1386	RTE	/* jumps to "m88100_fpu_enable" to enable the FPU. */
1387
1388ASLOCAL(m88100_fpu_enable)
1389	FLUSH_PIPELINE
1390	xcr	TMP,  TMP,  SR3			/* get E.F. pointer */
1391	st	%r30, TMP,  GENREG_OFF(30)	/* save previous r30, r31 */
1392	st	%r31, TMP,  GENREG_OFF(31)	/* save previous r30, r31 */
1393	or	%r31, TMP,  %r0			/* transfer E.F. pointer to r31 */
1394	ld	TMP,  %r31, EF_SR3		/* get previous SR3 */
1395
1396	/* make sure that the FLAG_ENABLING_FPU bit is off */
1397	xcr	FLAGS,FLAGS,SR1
1398	clr	FLAGS,FLAGS,1<FLAG_ENABLING_FPU>
1399	xcr	FLAGS,FLAGS,SR1
1400
1401	xcr	TMP,  TMP,  SR3	/* replace TMP, SR3 */
1402
1403	/* now save all regs to the exception frame. */
1404	st	%r0,  %r31, GENREG_OFF(0)
1405	st	%r1,  %r31, GENREG_OFF(1)
1406	st	%r2,  %r31, GENREG_OFF(2)
1407	st	%r3,  %r31, GENREG_OFF(3)
1408	st	%r4,  %r31, GENREG_OFF(4)
1409	st	%r5,  %r31, GENREG_OFF(5)
1410	st	%r6,  %r31, GENREG_OFF(6)
1411	st	%r7,  %r31, GENREG_OFF(7)
1412	st	%r8,  %r31, GENREG_OFF(8)
1413	st	%r9,  %r31, GENREG_OFF(9)
1414	st	%r10, %r31, GENREG_OFF(10)
1415	st	%r11, %r31, GENREG_OFF(11)
1416	st	%r12, %r31, GENREG_OFF(12)
1417	st	%r13, %r31, GENREG_OFF(13)
1418	st	%r14, %r31, GENREG_OFF(14)
1419	st	%r15, %r31, GENREG_OFF(15)
1420	st	%r16, %r31, GENREG_OFF(16)
1421	st	%r17, %r31, GENREG_OFF(17)
1422	st	%r18, %r31, GENREG_OFF(18)
1423	st	%r19, %r31, GENREG_OFF(19)
1424	st	%r20, %r31, GENREG_OFF(20)
1425	st	%r21, %r31, GENREG_OFF(21)
1426	st	%r22, %r31, GENREG_OFF(22)
1427	st	%r23, %r31, GENREG_OFF(23)
1428	st	%r24, %r31, GENREG_OFF(24)
1429	st	%r25, %r31, GENREG_OFF(25)
1430	st	%r26, %r31, GENREG_OFF(26)
1431	st	%r27, %r31, GENREG_OFF(27)
1432	st	%r28, %r31, GENREG_OFF(28)
1433	st	%r29, %r31, GENREG_OFF(29)
1434
1435	/*
1436	 * SR1: free
1437	 * SR2: free
1438	 * SR3: previous exception-time SR3
1439	 * r1: return address to the calling exception handler
1440	 * r2 through r30: free
1441	 * r31: our exception frame
1442	 *
1443	 * Valid in the exception frame:
1444	 *   Exception-time r0 through r31.
1445	 *   Exception-time FLAGS.
1446	 *   Exception-time epsr, sfip, snip, sxip.
1447	 *   Exception number (EF_VECTOR).
1448	 *   Dmt0
1449	 *   Other data pipeline control registers, if appropriate.
1450	 *   FPU control registers, if appropriate.
1451	 *   Exception SR3, if appropriate.
1452	 *
1453	 * immediate goal:
1454	 *   Pick up a stack if we came in from user mode.
1455	 *   Put a copy of the exception frame pointer into r30
1456	 *   Bump the stack a doubleword and write the exception frame pointer.
1457	 *   If not an interrupt exception, turn on interrupts and service any
1458	 *     outstanding data access exceptions.
1459	 *   Return to calling exception handler to service the exception.
1460	 */
1461
1462	/*
1463	 * If it's not the interrupt exception, enable interrupts and
1464	 * take care of any data access exceptions......
1465	 */
1466	or	%r30, %r0,  %r31	/* get a copy of the e.f. pointer */
1467	ld	%r6,  %r31, EF_EPSR
1468	bb1	PSR_SUPERVISOR_MODE_BIT, %r6, 1f	/* if in kernel mode */
1469
1470	ldcr	%r31, CPU
1471	ld	%r31, %r31, CI_CURPCB
1472	addu	%r31, %r31, USPACE	/* point at proper end */
14731:
1474
1475	/* get and save IPL */
1476	bsr	getipl
1477	st	%r2, %r30, EF_MASK
1478
1479	/*
1480	 * here - r30 holds a pointer to the exception frame.
1481	 * r31 is a pointer to the kernel stack/interrupt stack.
1482	 */
1483	subu	%r31, %r31, 8	/* make some breathing space */
1484	st	%r30, %r31, 0	/* store frame pointer on the stack */
1485#ifdef DDB
1486	st	%r30, %r31, 4	/* store it for the debugger to recognize */
1487#endif
1488
1489	ld	%r6,  %r30, EF_EPSR
1490	ld	%r2,  %r30, EF_VECTOR
1491	bcnd.n	eq0,  %r2,  8f			/* error exception */
1492	 ld	%r14, %r30, EF_RET
1493
1494	/*
1495	 * Do not process possible data exceptions here if this is an interrupt.
1496	 * Instead, the interrupt handler will take care of this by itself.
1497	 */
1498	cmp	%r3,  %r2,  1			/* is an interrupt? */
1499	bb1.n	eq,   %r3,  8f			/* skip if so */
1500
1501#ifdef DDB
1502	 cmp	%r3,  %r2,  130			/* DDB break exception */
1503	bb1.n	eq,   %r3,  8f
1504	 cmp	%r3,  %r2,  132			/* DDB entry exception */
1505	bb1	eq,   %r3,  8f
1506#else
1507	 NOP
1508#endif
1509
1510	/* turn interrupts back on unless they were not enabled when the
1511	   trap occurred */
1512	bb1.n	PSR_INTERRUPT_DISABLE_BIT, %r6, 7f
1513	 ld	%r3,  %r30, EF_DMT0
1514
1515	ldcr	%r2,  PSR
1516	clr	%r2,  %r2,  1<PSR_INTERRUPT_DISABLE_BIT>
1517	stcr	%r2,  PSR
1518	FLUSH_PIPELINE
15197:
1520	/* service any outstanding data pipeline stuff */
1521	bb0	DMT_VALID_BIT, %r3, 8f
1522
1523	/*
1524	 * r30 can be clobbered by calls. So stuff its value into a preserved
1525	 * register, say r15. R14 is in use (see return_to_... below).
1526	 */
1527	or	%r15, %r0,  %r30
1528	CALL(m88100_trap, T_DATAFLT, %r15)
1529	or	%r30, %r0,  %r15
1530
15318:
1532	jmp	%r14	/* loaded above */
1533#endif /* M88100 */
1534
1535#ifdef M88110
1536/*
1537 * 88110 exception handlers
1538 */
1539
1540/* unknown exception handler */
1541GLOBAL(m88110_unknown_handler)
1542	PREP88110("unknown", 0,)
1543	or	%r2, %r0, T_UNKNOWNFLT
1544	or	%r3, %r0, %r30
1545	XCALL(m88110_trap, check_ast)
1546
1547/* interrupt exception handler */
1548GLOBAL(m88110_interrupt_handler)
1549	PREP88110("interrupt", 1,)
1550	or	%r2, %r0, %r30
1551	XCALL(interrupt, check_ast)
1552
1553/* instruction access exception handler */
1554GLOBAL(m88110_instruction_access_handler)
1555	PREP88110("inst", 2,)
1556	or	%r2, %r0, T_INSTFLT
1557	or	%r3, %r0, %r30
1558	XCALL(m88110_trap, check_ast)
1559/*
1560 * data access exception handler --
1561 *  See badaddr() below for info about Data_Precheck.
1562 */
1563GLOBAL(m88110_data_exception_handler_bootstrap)
1564	PREP88110("data", 3, M88110_Data_Precheck)
1565	or	%r2, %r0, T_DATAFLT
1566	or	%r3, %r0, %r30
1567	XCALL(m88110_trap, check_ast)
1568GLOBAL(m88110_data_exception_handler)
1569	PREP88110("data", 3,)
1570	or	%r2, %r0, T_DATAFLT
1571	or	%r3, %r0, %r30
1572	XCALL(m88110_trap, check_ast)
1573
1574/* misaligned access exception handler */
1575GLOBAL(m88110_misaligned_handler)
1576	PREP88110("misalign", 4,)
1577	or	%r2, %r0, T_MISALGNFLT
1578	or	%r3, %r0, %r30
1579	XCALL(m88110_trap, check_ast)
1580
1581/* unimplemented opcode exception handler */
1582GLOBAL(m88110_unimplemented_handler)
1583	PREP88110("unimp", 5,)
1584	or	%r2, %r0, T_ILLFLT
1585	or	%r3, %r0, %r30
1586	XCALL(m88110_trap, check_ast)
1587
1588/* privilege exception handler */
1589GLOBAL(m88110_privilege_handler)
1590	PREP88110("privilege", 6,)
1591	or	%r2, %r0, T_PRIVINFLT
1592	or	%r3, %r0, %r30
1593	XCALL(m88110_trap, check_ast)
1594
1595/* bounds checking exception handler */
1596GLOBAL(m88110_bounds_handler)
1597	PREP88110("bounds", 7,)
1598	or	%r2, %r0, T_BNDFLT
1599	or	%r3, %r0, %r30
1600	XCALL(m88110_trap, check_ast)
1601
1602/* integer divide-by-zero exception handler */
1603GLOBAL(m88110_divide_handler)
1604	PREP88110("divide", 8,)
1605	or	%r2, %r0, T_ZERODIV
1606	or	%r3, %r0, %r30
1607	XCALL(m88110_trap, check_ast)
1608
1609/* integer overflow exception handler */
1610GLOBAL(m88110_overflow_handler)
1611	PREP88110("overflow", 9,)
1612	or	%r2, %r0, T_OVFFLT
1613	or	%r3, %r0, %r30
1614	XCALL(m88110_trap, check_ast)
1615
1616/* Floating-point precise handler */
1617GLOBAL(m88110_fpu_handler)
1618	PREP88110("FPU", 114,)
1619	or	%r2, %r0, T_FPEPFLT
1620	or	%r3, %r0, %r30
1621	XCALL(m88110_trap, check_ast)
1622
1623/* non-maskable interrupt handler (IPIs, ABORT button) */
1624GLOBAL(m88110_nonmaskable)
1625	PREP88110("NMI", 11,)
1626	or	%r2, %r0, %r30
1627	XCALL(nmi, nmi_return)
1628
1629/* software walk data MMU read miss handler */
1630GLOBAL(m88110_data_read_miss)
1631	PREP88110("88110 data read miss", 12,)
1632	or	%r2, %r0, T_110_DRM
1633	or	%r3, %r0, %r30
1634	XCALL(m88110_trap, check_ast)
1635
1636/* software walk data MMU write miss handler */
1637GLOBAL(m88110_data_write_miss)
1638	PREP88110("88110 data write miss", 13,)
1639	or	%r2, %r0, T_110_DWM
1640	or	%r3, %r0, %r30
1641	XCALL(m88110_trap, check_ast)
1642
1643/* software walk inst MMU ATC miss handler */
1644GLOBAL(m88110_inst_atc_miss)
1645	PREP88110("88110 inst ATC miss", 14,)
1646	or	%r2, %r0, T_110_IAM
1647	or	%r3, %r0, %r30
1648	XCALL(m88110_trap, check_ast)
1649
1650/* trap 450: system calls */
1651GLOBAL(m88110_syscall_handler)
1652	PREP88110("syscall", 450,)
1653	ld	%r2, %r30, GENREG_OFF(13)
1654	or	%r3, %r0, %r30
1655	XCALL(m88110_syscall, check_ast)
1656
1657/* trap 451: cache flush (necessary for trampolines) */
1658GLOBAL(m88110_cache_flush_handler)
1659	PREP88110("cache_flush", 451,)
1660	or	%r2, %r0, %r30
1661	XCALL(cache_flush, check_ast)
1662
1663GLOBAL(m88110_sigsys)
1664	PREP88110("sigsys", 501,)
1665	or	%r2, %r0, T_SIGSYS
1666	or	%r3, %r0, %r30
1667	XCALL(m88110_trap, check_ast)
1668
1669GLOBAL(m88110_stepbpt)
1670	PREP88110("stepbpt", 504,)
1671	or	%r2, %r0, T_STEPBPT
1672	or	%r3, %r0, %r30
1673	XCALL(m88110_trap, check_ast)
1674
1675GLOBAL(m88110_userbpt)
1676	PREP88110("userbpt", 511,)
1677	or	%r2, %r0, T_USERBPT
1678	or	%r3, %r0, %r30
1679	XCALL(m88110_trap, check_ast)
1680
1681#ifdef DDB
1682GLOBAL(m88110_break)
1683	PREP88110("break", 130,)
1684	or	%r2, %r0, T_KDB_BREAK
1685	or	%r3, %r0, %r30
1686	XCALL(m88110_trap, check_ast)
1687
1688GLOBAL(m88110_trace)
1689	PREP88110("trace", 131,)
1690	or	%r2, %r0, T_KDB_TRACE
1691	or	%r3, %r0, %r30
1692	XCALL(m88110_trap, check_ast)
1693
1694GLOBAL(m88110_entry)
1695	PREP88110("kdb", 132,)
1696	or	%r2, %r0, T_KDB_ENTRY
1697	or	%r3, %r0, %r30
1698	XCALL(m88110_trap, check_ast)
1699#endif
1700
1701/*
1702 * The error exception and reset exception handler.
1703 *
1704 * The error exception is raised when any other non-trap exception is raised
1705 * while shadowing is off. This is Bad News.
1706 *
1707 * The reset exception is raised when the RST signal is asserted (machine
1708 * is reset), the value of VBR is changed after exceptions are enabled,
1709 * or when a jmp, br/bsr to addr 0 (accidents do happen :-)
1710 * Upon a real reset, VBR is set to zero (0), so code must be at addr 0
1711 * to handle it!!!
1712 *
1713 * The shadow registers are not valid in this case (shadowing was off, if this
1714 * was an error exception, and may not be on, if this was a reset exception).
1715 * R1-R31 may be interesting though, so we'll save them.
1716 *
1717 * We'll not worry about trashing r26-29 here,
1718 * since they aren't generally used.
1719 */
1720GLOBAL(m88110_error_handler)
1721	or	%r29, %r0, 10
1722	br	1f
1723GLOBAL(m88110_reset_handler)
1724	or	%r29, %r0, 0
17251:
1726	or	%r26, %r0,  %r31	/* save old stack */
1727	or.u	%r31, %r0,  %hi16(initstack_end)
1728	or	%r31, %r31, %lo16(initstack_end)
1729
1730#ifdef DEBUG
1731	/* zero the stack, so we'll know what we're lookin' at */
1732	or.u	%r27, %r0,  %hi16(initstack)
1733	or	%r27, %r27, %lo16(initstack)
17341:	cmp	%r28, %r27, %r31
1735	bb1	ge,   %r28, 2f	/* branch if at the end of the stack */
1736	st	%r0,  %r0,  %r27
1737	addu	%r27, %r27, 4	/* bump up */
1738	br	1b
17392:	/* stack has been cleared */
1740#endif
1741
1742	/* ensure that stack is 8-byte aligned */
1743	clr	%r31, %r31, 3<0>	/* round down to 8-byte boundary */
1744
1745	/* create exception frame on stack */
1746	subu	%r31, %r31, TRAPFRAME_SIZEOF	/* r31 now our E.F. */
1747
1748	/* save old R31 and other R registers */
1749	st.d	%r0,  %r31, GENREG_OFF(0)
1750	st.d	%r2,  %r31, GENREG_OFF(2)
1751	st.d	%r4,  %r31, GENREG_OFF(4)
1752	st.d	%r6,  %r31, GENREG_OFF(6)
1753	st.d	%r8,  %r31, GENREG_OFF(8)
1754	st.d	%r10, %r31, GENREG_OFF(10)
1755	st.d	%r12, %r31, GENREG_OFF(12)
1756	st.d	%r14, %r31, GENREG_OFF(14)
1757	st.d	%r16, %r31, GENREG_OFF(16)
1758	st.d	%r18, %r31, GENREG_OFF(18)
1759	st.d	%r20, %r31, GENREG_OFF(20)
1760	st.d	%r22, %r31, GENREG_OFF(22)
1761	st.d	%r24, %r31, GENREG_OFF(24)
1762	st	%r30, %r31, GENREG_OFF(30)
1763	st	%r26, %r31, GENREG_OFF(31)
1764
1765	/* vector is put in SRO (either 0 or 10 at this point) */
1766	st	%r29, %r31, EF_VECTOR
1767
1768	/* save shadow registers (are OLD if error_handler, though) */
1769	ldcr	%r10, EPSR
1770	st	%r10, %r31, EF_EPSR
1771	ldcr	%r10, EXIP
1772	st	%r10, %r31, EF_EXIP
1773	ldcr	%r10, ENIP
1774	st	%r10, %r31, EF_ENIP
1775	ldcr	%r10, DSR
1776	st	%r10, %r31, EF_DSR
1777	ldcr	%r10, DLAR
1778	st	%r10, %r31, EF_DLAR
1779	ldcr	%r10, DPAR
1780	st	%r10, %r31, EF_DPAR
1781	ldcr	%r10, ISR
1782	st	%r10, %r31, EF_ISR
1783	ldcr	%r10, ILAR
1784	st	%r10, %r31, EF_ILAR
1785	ldcr	%r10, IPAR
1786	st	%r10, %r31, EF_IPAR
1787	ldcr	%r10, SR1
1788	st	%r10, %r31, EF_FLAGS
1789
1790	/* shove sr2 into EF_FPLS1 */
1791	ldcr	%r10, SR2
1792	st	%r10, %r31, EF_FPLS1
1793
1794	/* shove sr3 into EF_FPHS2 */
1795	ldcr	%r10, SR3
1796	st	%r10, %r31, EF_FPHS2
1797
1798	/*
1799	 * Cheap way to enable FPU and start shadowing again.
1800	 */
1801	ldcr	%r10, PSR
1802	clr	%r10, %r10, 1<PSR_FPU_DISABLE_BIT>	/* enable the FPU */
1803	clr	%r10, %r10, 1<PSR_SHADOW_FREEZE_BIT>	/* and shadowing */
1804	stcr	%r10, PSR
1805	FLUSH_PIPELINE
1806
1807	/* put pointer to regs into r30... r31 will become a simple stack */
1808	or	%r30, %r31, %r0
1809
1810	subu	%r31, %r31, 0x10	/* make some breathing space */
1811	st	%r30, %r31, 0x0c	/* store frame pointer on the stack */
1812#ifdef DDB
1813	st	%r30, %r31, 0x08	/* store again for the debugger to recognize */
1814	or.u	%r20,  %r0, %hi16(0x87654321)
1815	or	%r20, %r20, %lo16(0x87654321)
1816	st	%r20, %r31, 0x04
1817	st	%r20, %r31, 0x00
1818#endif
1819
1820	or	%r2, %r0, %r30
1821	bsr	error_fatal
1822
1823	/* turn interrupts back on */
1824	ldcr	%r1, PSR
1825	clr	%r1, %r1, 1<PSR_INTERRUPT_DISABLE_BIT>
1826	stcr	%r1, PSR
1827	FLUSH_PIPELINE
1828
18291:
1830	br	1b
1831	/* NOTREACHED */
1832
1833/*
1834 * 88110 exception handling setup
1835 *
1836 * This is much simpler than for 88100, because all exception are
1837 * precise. Therefore, when reenabling shadowing, we do not risk
1838 * getting new exceptions caught by the execution pipeline and not
1839 * reported yet.
1840 *
1841 * However, as soon as shadow freezing is over, we can receive a
1842 * non-maskable interrupt at any time. The code below will cope with
1843 * this, as long as the stack pointer (r31) is valid in the kernel
1844 * all the time shadowing is enabled.
1845 *
1846 * Thus, unlike the 88100 code, we setup both the exception frame
1847 * (in r30) and the exception stack (in r31) as early as possible.
1848 */
1849
1850ASLOCAL(m88110_setup_phase_one)
1851	/*
1852	 * SR1: saved copy of exception-time register now holding FLAGS
1853	 * SR2: saved copy of exception-time r1
1854	 * SR3: free
1855	 * r1: return address to calling exception handler
1856	 * FLAGS: CPU status flags
1857	 *
1858	 * immediate goal:
1859	 *   Find out where to put the exception frame, and which
1860	 *   stack to use.
1861	 */
1862
1863	NOP
1864	xcr	%r1,   %r1,   SR2	/* recover exception-time r1 */
1865	NOP
1866	NOP
1867	NOP
1868
1869	/*
1870	 * If we were in the kernel when the exception occurred, we have
1871	 * a valid stack. Keep using it, and build the frame on it.
1872	 *
1873	 * Note that if this exception is an NMI, we might be currently
1874	 * switching processes, and curpcb and curproc won't match. It
1875	 * is nevertheless safe to use curpcb, since nmi are processed
1876	 * with interrupts disabled, and we won't check for AST or soft
1877	 * interrupts before returning to the cpu_switchto kernel code.
1878	 */
1879	bb1	FLAG_FROM_KERNEL, FLAGS, m88110_kernel_stack
1880
1881	/*
1882	 * Otherwise, this is an exception in user mode, we'll use the PCB
1883	 * for the exception frame and the top of the PCB as the stack.
1884	 */
1885
1886	/* compute frame address: in PCB */
1887	stcr	%r30, SR3			/* save r30, now free */
1888	ldcr	%r30, CPU
1889	ld	%r30, %r30, CI_CURPCB
1890	addu	%r30, %r30, PCB_USER_STATE	/* point to user save area */
1891
1892	/* save a few registers before we lose them*/
1893	st	%r1,  %r30, GENREG_OFF(1)	/* save prev. r1 (now free)*/
1894	ldcr	%r1,  SR3			/* save previous r30 */
1895	st	%r31, %r30, GENREG_OFF(31)
1896	st	%r1,  %r30, GENREG_OFF(30)
1897
1898	/* compute stack address: top of U area */
1899	ldcr	%r1,  CPU
1900	ld	%r31, %r1,  CI_CURPCB
1901	addu	%r31, %r31, USPACE
1902
1903	br	m88110_have_stack
1904
1905ASLOCAL(m88110_kernel_stack)		/* Exception in kernel mode */
1906
1907	/* compute stack and frame address: allocate them on current stack */
1908	subu	%r31, %r31, TRAPFRAME_SIZEOF	/* r31 now our E.F. */
1909
1910	/* save a few registers before we lose them */
1911	st	%r1,  %r31, GENREG_OFF(1)	/* save prev. r1 (now free) */
1912	addu	%r1,  %r31, TRAPFRAME_SIZEOF	/* save previous r31 */
1913	st	%r30, %r31, GENREG_OFF(30)
1914	st	%r1,  %r31, GENREG_OFF(31)
1915
1916	/* frame = stack */
1917	or	%r30, %r31, %r0
1918
1919	/* FALLTHROUGH */
1920
1921ASLOCAL(m88110_have_stack)
1922	/*
1923	 * SR1: saved copy of exception-time register now holding FLAGS
1924	 * SR2: return address to the calling exception handler
1925	 * SR3: free
1926	 * r1:  free
1927	 * FLAGS: CPU status flags
1928	 * r30: incomplete exception frame
1929	 * r31: exception stack
1930	 * Valid in the exception frame:
1931	 *   Exception-time r1, r30, r31, FLAGS.
1932	 */
1933
1934	stcr	TMP, SR3	/* free up TMP, TMP2, TMP3 */
1935	SAVE_TMP2(%r30)
1936	SAVE_TMP3(%r30)
1937
1938	/* save some exception-time registers to the exception frame */
1939	st	FLAGS,%r30, EF_FLAGS		/* save flags */
1940
1941	ldcr	TMP,  EPSR
1942	st	TMP,  %r30, EF_EPSR
1943	ldcr	TMP2, EXIP
1944	ldcr	TMP3, ENIP
1945	st	TMP2, %r30, EF_EXIP
1946	st	TMP3, %r30, EF_ENIP
1947
1948	/* get and store the cpu_info pointer */
1949	ldcr	TMP,  CPU
1950	st	TMP,  %r30, EF_CPU
1951
1952	/*
1953	 * Save and clear fault status registers.
1954	 */
1955	ldcr	TMP,  ISR
1956	st	TMP,  %r30, EF_ISR
1957	bcnd	eq0,  TMP,  1f
1958	ldcr	TMP2, ILAR
1959	ldcr	TMP3, IPAR
1960	st	TMP2, %r30, EF_ILAR
1961	st	TMP3, %r30, EF_IPAR
1962	ldcr	TMP,  ISAP
1963	ldcr	TMP2, IUAP
1964	st	TMP,  %r30, EF_ISAP
1965	st	TMP2, %r30, EF_IUAP
1966	stcr	%r0,  ISR
19671:
1968	ldcr	TMP,  DSR
1969	st	TMP,  %r30,  EF_DSR
1970	bcnd	eq0,  TMP,  1f
1971	ldcr	TMP2, DLAR
1972	ldcr	TMP3, DPAR
1973	st	TMP2, %r30,  EF_DLAR
1974	st	TMP3, %r30,  EF_DPAR
1975	ldcr	TMP,  DSAP
1976	ldcr	TMP2, DUAP
1977	st	TMP,  %r30,  EF_DSAP
1978	st	TMP2, %r30,  EF_DUAP
1979	stcr	%r0,  DSR
19801:
1981	ldcr	%r1,  SR2
1982	jmp	%r1
1983
1984ASLOCAL(m88110_setup_phase_two)
1985	/*
1986	 * SR1: saved copy of exception-time register now holding FLAGS
1987	 * SR2: free
1988	 * SR3: saved TMP
1989	 * r1:  return address to calling exception handler
1990	 * TMP2: free
1991	 * TMP3: free
1992	 * FLAGS: CPU status flags
1993	 * r30: incomplete exception frame
1994	 * r31: exception stack
1995	 * Valid in the exception frame:
1996	 *   Exception-time r1, r30, r31, FLAGS.
1997	 *   Exception-time TMP2, TMP3.
1998	 *   Exception-time epsr, enip, exip.
1999	 *   Exception number (EF_VECTOR).
2000	 *
2001	 * immediate goal:
2002	 *   restore the system to the exception-time state.
2003	 */
2004
2005	RESTORE_TMP2(%r30)	/* done with extra temp regs */
2006	RESTORE_TMP3(%r30)	/* done with extra temp regs */
2007
2008	ldcr	TMP,  PSR
2009	clr	TMP,  TMP,  1<PSR_SHADOW_FREEZE_BIT>	/* enable shadowing */
2010	stcr	TMP,  EPSR
2011
2012	or.u	TMP,  %r0,  %hi16(m88110_shadow_enable)
2013	or	TMP,  TMP,  %lo16(m88110_shadow_enable)
2014	stcr	TMP,  EXIP
2015
2016	xcr	FLAGS,FLAGS,SR1
2017	st	%r1,  %r30, EF_RET		/* save the return address */
2018
2019	xcr	TMP,  %r31, SR3	/* TMP now restored. R31 now saved in SR3 */
2020
2021	/*
2022	 * SR1: CPU flags
2023	 * SR2: free
2024	 * SR3: pointer to our exception frame (our stack pointer)
2025	 * r2 through r29: original exception-time values
2026	 * r30: exception frame
2027	 * r31: exception stack
2028	 *
2029	 * Valid in the exception frame:
2030	 *   Exception-time r1, r30, r31, FLAGS.
2031	 *   Exception-time epsr, sfip, enip, exip.
2032	 *   Exception number (EF_VECTOR).
2033	 *   DSR/ISR, fault registers, if appropriate.
2034	 * Held temporarily in the exception frame:
2035	 *   Return address to the calling exception handler.
2036	 *
2037	 * immediate goal:
2038	 *   Do an RTE to unfreeze the shadow registers.
2039	 *   Another exception (NMI) may be raised in this.
2040	 */
2041	RTE	/* jumps to "m88110_shadow_enable" */
2042
2043ASLOCAL(m88110_shadow_enable)
2044	FLUSH_PIPELINE				/* XXX necessary? */
2045
2046	/* now save all missing regs to the exception frame. */
2047	st	%r0,  %r30, GENREG_OFF(0)
2048	st	%r2,  %r30, GENREG_OFF(2)
2049	st	%r3,  %r30, GENREG_OFF(3)
2050	st	%r4,  %r30, GENREG_OFF(4)
2051	st	%r5,  %r30, GENREG_OFF(5)
2052	st	%r6,  %r30, GENREG_OFF(6)
2053	st	%r7,  %r30, GENREG_OFF(7)
2054	st	%r8,  %r30, GENREG_OFF(8)
2055	st	%r9,  %r30, GENREG_OFF(9)
2056	st	%r10, %r30, GENREG_OFF(10)
2057	st	%r11, %r30, GENREG_OFF(11)
2058	st	%r12, %r30, GENREG_OFF(12)
2059	st	%r13, %r30, GENREG_OFF(13)
2060	st	%r14, %r30, GENREG_OFF(14)
2061	st	%r15, %r30, GENREG_OFF(15)
2062	st	%r16, %r30, GENREG_OFF(16)
2063	st	%r17, %r30, GENREG_OFF(17)
2064	st	%r18, %r30, GENREG_OFF(18)
2065	st	%r19, %r30, GENREG_OFF(19)
2066	st	%r20, %r30, GENREG_OFF(20)
2067	st	%r21, %r30, GENREG_OFF(21)
2068	st	%r22, %r30, GENREG_OFF(22)
2069	st	%r23, %r30, GENREG_OFF(23)
2070	st	%r24, %r30, GENREG_OFF(24)
2071	st	%r25, %r30, GENREG_OFF(25)
2072	st	%r26, %r30, GENREG_OFF(26)
2073	st	%r27, %r30, GENREG_OFF(27)
2074	st	%r28, %r30, GENREG_OFF(28)
2075	st	%r29, %r30, GENREG_OFF(29)
2076
2077	/*
2078	 * SR1: free
2079	 * SR2: free
2080	 * SR3: free
2081	 * r1 through r29: free
2082	 * r30: exception frame
2083	 * r31: exception stack
2084	 *
2085	 * Valid in the exception frame:
2086	 *   Exception-time r0 through r31.
2087	 *   Exception-time FLAGS.
2088	 *   Exception-time epsr, enip, exip.
2089	 *   Exception number (EF_VECTOR).
2090	 *   Return value (EF_RET).
2091	 *   DSR/ISR, fault registers, if appropriate.
2092	 *
2093	 * immediate goal:
2094	 *   Bump the stack a doubleword and write the exception frame pointer.
2095	 *   If not an interrupt exception or an NMI, turn on interrupts.
2096	 *   Return to calling exception handler to service the exception.
2097	 */
2098
2099	/* get and save IPL */
2100	bsr	getipl
2101	st	%r2,  %r30, EF_MASK
2102
2103	subu	%r31, %r31, 8	/* make some breathing space */
2104	st	%r30, %r31, 0	/* store frame pointer on the stack */
2105#ifdef DDB
2106	st	%r30, %r31, 4	/* store it again for the debugger */
2107#endif
2108
2109	ld	%r6,  %r30, EF_EPSR
2110	ld	%r14, %r30, EF_RET
2111
2112	/* don't turn interrupts back on unless they were enabled when the
2113	   trap occurred */
2114	bb1	PSR_INTERRUPT_DISABLE_BIT, %r6, 8f
2115
2116	ld	%r2,  %r30, EF_VECTOR
2117	bcnd	eq0,  %r2,  8f
2118	cmp	%r3,  %r2,  1		/* is this an interrupt? */
2119	bb1	eq,   %r3,  8f
2120	cmp	%r3,  %r2,  11		/* or NMI? */
2121	bb1	eq,   %r3,  8f
2122
2123#ifdef DDB
2124	cmp	%r3,  %r2,  130		/* DDB break exception */
2125	bb1	eq,   %r3,  8f
2126	cmp	%r3,  %r2,  132		/* DDB entry exception */
2127	bb1	eq,   %r3,  8f
2128#endif
2129
2130	ldcr	%r2,  PSR
2131	clr	%r2,  %r2,  1<PSR_INTERRUPT_DISABLE_BIT>
2132	stcr	%r2,  PSR
2133	FLUSH_PIPELINE
2134
21358:
2136	jmp	%r14		/* loaded above */
2137#endif	/* M88110 */
2138
2139	.text
2140
2141#define	FPTR	%r14
2142
2143ASGLOBAL(check_ast)
2144	/*
2145	 * Regs r1-r30 are free. r31 is pointing at the word
2146	 * on the kernel stack where our pointer to the exception frame
2147	 * it stored. Reload it now.
2148	 *
2149	 * We load it into r14 since it is preserved across function
2150	 * calls, and we may have to call some routines from within here.
2151	 *
2152	 * Control is transferred here from obvious places in this file.
2153	 */
2154	ld	FPTR, %r31, 0	/* grab exception frame pointer */
2155
2156	/*
2157	 * If the saved ipl is 0, then call spl0() to process soft
2158	 * interrupts. And if returning to userland, look for ASTs.
2159	 */
2160
2161	/* do not service AST and soft interrupts if interrupts were disabled */
2162	ld	%r2, FPTR, EF_EPSR
2163	bb1	PSR_INTERRUPT_DISABLE_BIT, %r2, ast_done
2164	/* ...or we were not at spl0 */
2165	ld	%r2, FPTR, EF_MASK
2166	bcnd	ne0, %r2, ast_done
2167
2168#ifdef MULTIPROCESSOR
2169	/*
2170	 * Check for IPI soft interrupt
2171	 */
2172	ldcr	%r3,  CPU
2173	or	%r15, %r0,  %r0
2174	addu	%r3,  %r3,  CI_SOFTIPI_CB
2175	xmem	%r15, %r3,  %r0
2176	bcnd	eq0,  %r15, do_softint
2177
2178	bsr.n	setipl
2179	 or	%r2,  %r0,  IPL_NONE
2180
2181	jsr	%r15
2182ASLOCAL(do_softint)
2183#endif
2184
2185	/*
2186	 * Process soft interrupts, if any.
2187	 */
2188	bsr	spl0
2189
2190	/* do not service AST if not returning to user mode */
2191	ld	%r2, FPTR, EF_EPSR
2192	bb1	PSR_SUPERVISOR_MODE_BIT, %r2, ast_done
21931:
2194	ldcr	%r2, CPU
2195	ld	%r3, %r2, CI_CURPROC
2196	ld	%r2, %r3, P_ASTPENDING
2197	bcnd	eq0, %r2, ast_done
2198
2199	bsr.n	ast
2200	 or	%r2, %r0, FPTR
2201
2202	br	1b
2203
2204/*
2205 * void proc_trampoline()
2206 *
2207 * When a process setup by cpu_fork() resumes, it will find itself in
2208 * proc_trampoline, with r14 and r15 referring to a function and its
2209 * argument. proc_trampoline will call the function, and return to userland.
2210 */
2211
2212ENTRY(proc_trampoline)
2213	bsr	proc_trampoline_mi
2214
2215	jsr.n	%r14
2216	 or	%r2,  %r15, 0		/* arg */
2217
2218/*
2219 * Load FPTR with a pointer to the trap frame for the current proc and
2220 * continue near the end of check_ast, bypassing soft interrupts and AST
2221 * checks, to load all the registers and do an RTE.
2222 */
2223
2224	ldcr	%r3,  CPU
2225	ld	%r2,  %r3,  CI_CURPROC
2226
2227	ld	FPTR, %r2,   P_ADDR		/* p->p_addr */
2228	addu	FPTR, FPTR, PCB_USER_STATE	/* p->p_addr.u_pcb.user_state */
2229
2230	/* FALLTHROUGH */
2231
2232ASGLOBAL(ast_done)
2233	/* disable interrupts */
2234	ldcr	%r1, PSR
2235	set	%r1, %r1, 1<PSR_INTERRUPT_DISABLE_BIT>
2236	stcr	%r1, PSR
2237	FLUSH_PIPELINE
2238
2239	/* now ready to return....*/
2240	bsr.n	setipl
2241	 ld	%r2, FPTR, EF_MASK		/* get pre-exception ipl */
2242
2243#if defined(M88100) && defined(M88110)
2244	ldcr	%r2, PID
2245	extu	%r3, %r2, 8<8>
2246	bcnd	ne0, %r3, m88110_user_rte
2247	/* FALLTHROUGH */
2248#endif
2249
2250#ifdef M88100
2251ASGLOBAL(m88100_user_rte)
2252	/*
2253	 * Transfer the frame pointer to r31, since we no longer need a stack.
2254	 * No page faults here, and interrupts are disabled.
2255	 */
2256	or	%r31, %r0,  FPTR
2257
2258	/* restore r1 later */
2259	ld	%r2,  %r31, GENREG_OFF(2)
2260	ld	%r3,  %r31, GENREG_OFF(3)
2261	ld	%r4,  %r31, GENREG_OFF(4)
2262	ld	%r5,  %r31, GENREG_OFF(5)
2263	ld	%r6,  %r31, GENREG_OFF(6)
2264	ld	%r7,  %r31, GENREG_OFF(7)
2265	ld	%r8,  %r31, GENREG_OFF(8)
2266	ld	%r9,  %r31, GENREG_OFF(9)
2267	ld	%r10, %r31, GENREG_OFF(10)
2268	ld	%r11, %r31, GENREG_OFF(11)
2269	ld	%r12, %r31, GENREG_OFF(12)
2270	ld	%r13, %r31, GENREG_OFF(13)
2271	ld	%r14, %r31, GENREG_OFF(14)
2272	ld	%r15, %r31, GENREG_OFF(15)
2273	ld	%r16, %r31, GENREG_OFF(16)
2274	ld	%r17, %r31, GENREG_OFF(17)
2275	ld	%r18, %r31, GENREG_OFF(18)
2276	ld	%r19, %r31, GENREG_OFF(19)
2277	ld	%r20, %r31, GENREG_OFF(20)
2278	ld	%r21, %r31, GENREG_OFF(21)
2279	ld	%r22, %r31, GENREG_OFF(22)
2280	ld	%r23, %r31, GENREG_OFF(23)
2281	ld	%r24, %r31, GENREG_OFF(24)
2282	ld	%r25, %r31, GENREG_OFF(25)
2283	ld	%r26, %r31, GENREG_OFF(26)
2284	ld	%r27, %r31, GENREG_OFF(27)
2285	ld	%r28, %r31, GENREG_OFF(28)
2286	ld	%r29, %r31, GENREG_OFF(29)
2287	/* restore r1, r30, r31 later */
2288
2289	/* disable shadowing */
2290	ldcr	%r1, PSR
2291	set	%r1, %r1, 1<PSR_SHADOW_FREEZE_BIT>
2292	stcr	%r1, PSR
2293	FLUSH_PIPELINE
2294
2295	/* reload the control regs*/
2296	/*
2297	 * RTE will cause execution to continue first with the
2298	 * instruction pointed to by the NIP and then the FIP;
2299	 * it is not necessary to restore XIP.
2300	 */
2301	stcr	%r0,  SSBR
2302	ld	%r30, %r31, EF_SNIP
2303	ld	%r1,  %r31, EF_SFIP
2304	stcr	%r30, SNIP
2305	stcr	%r1,  SFIP
2306
2307	ld	%r30, %r31, EF_EPSR
2308	stcr	%r30, EPSR
2309
2310	/* Now restore r1, r30, and r31 */
2311	ld	%r1,  %r31, GENREG_OFF(1)
2312	ld	%r30, %r31, GENREG_OFF(30)
2313	ld	%r31, %r31, GENREG_OFF(31)
2314
2315	RTE
2316#endif
2317
2318#ifdef M88110
2319ASGLOBAL(m88110_user_rte)
2320	/*
2321	 * Disable shadowing. This used to be done after all the registers
2322	 * from the E.F. have been restored, but on 88110 we may receive
2323	 * an NMI anytime, unless shadowing is frozen, and we rely on r31
2324	 * being valid.
2325	 */
2326	ldcr	%r1, PSR
2327	set	%r1, %r1, 1<PSR_SHADOW_FREEZE_BIT>
2328	stcr	%r1, PSR
2329	FLUSH_PIPELINE
2330
2331ASLOCAL(m88110_restore)
2332	/*
2333	 * Transfer the frame pointer to r31, since we no longer need a stack.
2334	 * No page faults here, and interrupts are disabled.
2335	 */
2336	or	%r31, %r0,  FPTR
2337	/* restore r1 later */
2338	ld	%r2,  %r31, GENREG_OFF(2)
2339	ld	%r3,  %r31, GENREG_OFF(3)
2340	ld	%r4,  %r31, GENREG_OFF(4)
2341	ld	%r5,  %r31, GENREG_OFF(5)
2342	ld	%r6,  %r31, GENREG_OFF(6)
2343	ld	%r7,  %r31, GENREG_OFF(7)
2344	ld	%r8,  %r31, GENREG_OFF(8)
2345	ld	%r9,  %r31, GENREG_OFF(9)
2346	ld	%r10, %r31, GENREG_OFF(10)
2347	ld	%r11, %r31, GENREG_OFF(11)
2348	ld	%r12, %r31, GENREG_OFF(12)
2349	ld	%r13, %r31, GENREG_OFF(13)
2350	ld	%r14, %r31, GENREG_OFF(14)
2351	ld	%r15, %r31, GENREG_OFF(15)
2352	ld	%r16, %r31, GENREG_OFF(16)
2353	ld	%r17, %r31, GENREG_OFF(17)
2354	ld	%r18, %r31, GENREG_OFF(18)
2355	ld	%r19, %r31, GENREG_OFF(19)
2356	ld	%r20, %r31, GENREG_OFF(20)
2357	ld	%r21, %r31, GENREG_OFF(21)
2358	ld	%r22, %r31, GENREG_OFF(22)
2359	ld	%r23, %r31, GENREG_OFF(23)
2360	ld	%r24, %r31, GENREG_OFF(24)
2361	ld	%r25, %r31, GENREG_OFF(25)
2362	ld	%r26, %r31, GENREG_OFF(26)
2363	ld	%r27, %r31, GENREG_OFF(27)
2364	ld	%r28, %r31, GENREG_OFF(28)
2365	ld	%r29, %r31, GENREG_OFF(29)
2366	/* restore r1, r30, r31 later */
2367
2368	/* reload the control regs*/
2369	ld	%r30, %r31, EF_ENIP
2370	ld	%r1,  %r31, EF_EXIP
2371	stcr	%r30, ENIP
2372	stcr	%r1,  EXIP
2373
2374	ld	%r30, %r31, EF_EPSR
2375	stcr	%r30, EPSR
2376
2377	/* Now restore r1, r30, and r31 */
2378	ld	%r1,  %r31, GENREG_OFF(1)
2379	ld	%r30, %r31, GENREG_OFF(30)
2380	ld	%r31, %r31, GENREG_OFF(31)
2381
2382	/*
2383	 * 88110 errata #18 (fixed in revision 5 cpus):
2384	 * ``An rte to user mode where the logical address of the rte
2385	 *   instruction is within two cache lines of the logical address
2386	 *   in the exip can cause the wrong instruction to be returned
2387	 *   to if the rte instruction misses in the icache.''
2388	 *
2389	 * Since we run with interrupts disabled at this point, all we
2390	 * need is make sure that the rte will not appear as the first
2391	 * instruction of a cache line.
2392	 */
2393	br	1f
2394
2395	.align 6	/* 32 bytes might not be enough */
23961:
2397	NOP
2398	RTE
2399
2400	/*
2401	 * NMI return here after processing.
2402	 * We then decide whether to check for AST and soft interrupts,
2403	 * or not.
2404	 */
2405ASLOCAL(nmi_return)
2406	bcnd	ne0, %r2, check_ast
2407
2408	ld	FPTR, %r31, 0	/* grab exception frame pointer */
2409
2410	/*
2411	 * Disable interrupts and shadowing. The latter used to be done
2412	 * after all the registers from the E.F. have been restored, but
2413	 * on 88110 we may receive an NMI anytime, unless shadowing is frozen,
2414	 * and we rely on r31 being valid.
2415	 */
2416	ldcr	%r1, PSR
2417	set	%r1, %r1, 1<PSR_INTERRUPT_DISABLE_BIT>
2418	set	%r1, %r1, 1<PSR_SHADOW_FREEZE_BIT>
2419	stcr	%r1, PSR
2420	FLUSH_PIPELINE
2421
2422	/* now ready to return....*/
2423	bsr.n	setipl
2424	 ld	%r2, FPTR, EF_MASK		/* get pre-exception ipl */
2425
2426#ifdef MULTIPROCESSOR
2427	/*
2428	 * Reenable NMIs if necessary.
2429	 */
2430	or	%r2,   FPTR,  %r0
2431	bsr	nmi_wrapup
2432#endif
2433
2434	br	m88110_restore
2435#endif
2436