xref: /netbsd-src/sys/arch/sun3/sun3/locore.s (revision 6279c1e992621a887496dc9278adf6ed8aff06c5)
1/*	$NetBSD: locore.s,v 1.110 2024/01/17 12:33:50 thorpej Exp $	*/
2
3/*
4 * Copyright (c) 1980, 1990, 1993
5 *	The Regents of the University of California.  All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * the Systems Programming Group of the University of Utah Computer
9 * Science Department.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 *    notice, this list of conditions and the following disclaimer in the
18 *    documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors
20 *    may be used to endorse or promote products derived from this software
21 *    without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 *
35 *	from: Utah $Hdr: locore.s 1.66 92/12/22$
36 *	@(#)locore.s	8.6 (Berkeley) 5/27/94
37 */
38
39/*
40 * Copyright (c) 1994, 1995 Gordon W. Ross
41 * Copyright (c) 1993 Adam Glass
42 * Copyright (c) 1988 University of Utah.
43 *
44 * This code is derived from software contributed to Berkeley by
45 * the Systems Programming Group of the University of Utah Computer
46 * Science Department.
47 *
48 * Redistribution and use in source and binary forms, with or without
49 * modification, are permitted provided that the following conditions
50 * are met:
51 * 1. Redistributions of source code must retain the above copyright
52 *    notice, this list of conditions and the following disclaimer.
53 * 2. Redistributions in binary form must reproduce the above copyright
54 *    notice, this list of conditions and the following disclaimer in the
55 *    documentation and/or other materials provided with the distribution.
56 * 3. All advertising materials mentioning features or use of this software
57 *    must display the following acknowledgement:
58 *	This product includes software developed by the University of
59 *	California, Berkeley and its contributors.
60 * 4. Neither the name of the University nor the names of its contributors
61 *    may be used to endorse or promote products derived from this software
62 *    without specific prior written permission.
63 *
64 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
65 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
66 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
67 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
68 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
69 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
70 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
71 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
72 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
73 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
74 * SUCH DAMAGE.
75 *
76 *	from: Utah $Hdr: locore.s 1.66 92/12/22$
77 *	@(#)locore.s	8.6 (Berkeley) 5/27/94
78 */
79
80#include "opt_compat_netbsd.h"
81#include "opt_compat_sunos.h"
82#include "opt_kgdb.h"
83#include "opt_lockdebug.h"
84
85#include "assym.h"
86#include <machine/asm.h>
87#include <machine/trap.h>
88
89| Remember this is a fun project!
90
91| This is for kvm_mkdb, and should be the address of the beginning
92| of the kernel text segment (not necessarily the same as kernbase).
93	.text
94GLOBAL(kernel_text)
95
96| This is the entry point, as well as the end of the temporary stack
97| used during process switch (one 8K page ending at start)
98ASGLOBAL(tmpstk)
99ASGLOBAL(start)
100
101| First we need to set it up so we can access the sun MMU, and be otherwise
102| undisturbed.  Until otherwise noted, all code must be position independent
103| as the boot loader put us low in memory, but we are linked high.
104	movw	#PSL_HIGHIPL,%sr	| no interrupts
105	moveq	#FC_CONTROL,%d0		| make movs access "control"
106	movc	%d0,%sfc		| space where the sun3 designers
107	movc	%d0,%dfc		| put all the "useful" stuff
108
109| Set context zero and stay there until pmap_bootstrap.
110	moveq	#0,%d0
111	movsb	%d0,CONTEXT_REG
112
113| In order to "move" the kernel to high memory, we are going to copy the
114| first 4 Mb of pmegs such that we will be mapped at the linked address.
115| This is all done by copying in the segment map (top-level MMU table).
116| We will unscramble which PMEGs we actually need later.
117
118	movl	#(SEGMAP_BASE+0),%a0		| src
119	movl	#(SEGMAP_BASE+KERNBASE3),%a1	| dst
120	movl	#(0x400000/NBSG),%d0		| count
121
122L_per_pmeg:
123	movsb	%a0@,%d1		| copy segmap entry
124	movsb	%d1,%a1@
125	addl	#NBSG,%a0		| increment pointers
126	addl	#NBSG,%a1
127	subql	#1,%d0			| decrement count
128	bgt	L_per_pmeg
129
130| Kernel is now double mapped at zero and KERNBASE.
131| Force a long jump to the relocated code (high VA).
132	movl	#IC_CLEAR,%d0		| Flush the I-cache
133	movc	%d0,%cacr
134	jmp	L_high_code:l		| long jump
135
136L_high_code:
137| We are now running in the correctly relocated kernel, so
138| we are no longer restricted to position-independent code.
139
140| Do bootstrap stuff needed before main() gets called.
141| Make sure the initial frame pointer is zero so that
142| the backtrace algorithm used by KGDB terminates nicely.
143	lea	_ASM_LABEL(tmpstk),%sp
144	movl	#0,%a6
145	jsr	_C_LABEL(_bootstrap)	| See locore2.c
146
147| Now that _bootstrap() is done using the PROM functions,
148| we can safely set the %sfc/dfc to something != FC_CONTROL
149	moveq	#FC_USERD,%d0		| make movs access "user data"
150	movc	%d0,%sfc		| space for copyin/copyout
151	movc	%d0,%dfc
152
153| Setup process zero user/kernel stacks.
154	lea	_C_LABEL(lwp0),%a0	| lwp0
155	movl	%a0@(L_PCB),%a1		| XXXuvm_lwp_getuarea
156	lea	%a1@(USPACE-4),%sp	| set SSP to last word
157	movl	#USRSTACK3-4,%a2
158	movl	%a2,%usp		| init user SP
159
160| Note curpcb was already set in _bootstrap().
161| Will do fpu initialization during autoconfig (see fpu.c)
162| The interrupt vector table and stack are now ready.
163| Interrupts will be enabled later, AFTER  autoconfiguration
164| is finished, to avoid spurrious interrupts.
165
166/*
167 * Create a fake exception frame so that cpu_lwp_fork() can copy it.
168 * main() nevers returns; we exit to user mode from a forked process
169 * later on.
170 */
171	clrw	%sp@-			| tf_format,tf_vector
172	clrl	%sp@-			| tf_pc (filled in later)
173	movw	#PSL_USER,%sp@-		| tf_sr for user mode
174	clrl	%sp@-			| tf_stackadj
175	lea	%sp@(-64),%sp		| tf_regs[16]
176	movl	%a1,%a0@(L_MD_REGS)	| lwp0.p_md.md_regs = trapframe
177	jbsr	_C_LABEL(main)		| main(&trapframe)
178	PANIC("main() returned")
179
180| That is all the assembly startup code we need on the sun3!
181| The rest of this is like the hp300/locore.s where possible.
182
183/*
184 * Trap/interrupt vector routines
185 */
186#include <m68k/m68k/trap_subr.s>
187
188GLOBAL(buserr)
189	tstl	_C_LABEL(nofault)	| device probe?
190	jeq	_C_LABEL(addrerr)	| no, handle as usual
191	movl	_C_LABEL(nofault),%sp@-	| yes,
192	jbsr	_C_LABEL(longjmp)	|  longjmp(nofault)
193GLOBAL(addrerr)
194	clrl	%sp@-			| stack adjust count
195	moveml	#0xFFFF,%sp@-		| save user registers
196	movl	%usp,%a0		| save the user SP
197	movl	%a0,%sp@(FR_SP)		|   in the savearea
198	lea	%sp@(FR_HW),%a1		| grab base of HW berr frame
199	moveq	#0,%d0
200	movw	%a1@(10),%d0		| grab SSW for fault processing
201	btst	#12,%d0			| RB set?
202	jeq	LbeX0			| no, test RC
203	bset	#14,%d0			| yes, must set FB
204	movw	%d0,%a1@(10)		| for hardware too
205LbeX0:
206	btst	#13,%d0			| RC set?
207	jeq	LbeX1			| no, skip
208	bset	#15,%d0			| yes, must set FC
209	movw	%d0,%a1@(10)		| for hardware too
210LbeX1:
211	btst	#8,%d0			| data fault?
212	jeq	Lbe0			| no, check for hard cases
213	movl	%a1@(16),%d1		| fault address is as given in frame
214	jra	Lbe10			| thats it
215Lbe0:
216	btst	#4,%a1@(6)		| long (type B) stack frame?
217	jne	Lbe4			| yes, go handle
218	movl	%a1@(2),%d1		| no, can use save PC
219	btst	#14,%d0			| FB set?
220	jeq	Lbe3			| no, try FC
221	addql	#4,%d1			| yes, adjust address
222	jra	Lbe10			| done
223Lbe3:
224	btst	#15,%d0			| FC set?
225	jeq	Lbe10			| no, done
226	addql	#2,%d1			| yes, adjust address
227	jra	Lbe10			| done
228Lbe4:
229	movl	%a1@(36),%d1		| long format, use stage B address
230	btst	#15,%d0			| FC set?
231	jeq	Lbe10			| no, all done
232	subql	#2,%d1			| yes, adjust address
233Lbe10:
234	movl	%d1,%sp@-		| push fault VA
235	movl	%d0,%sp@-		| and padded SSW
236	movw	%a1@(6),%d0		| get frame format/vector offset
237	andw	#0x0FFF,%d0		| clear out frame format
238	cmpw	#12,%d0			| address error vector?
239	jeq	Lisaerr			| yes, go to it
240
241/*
242 * the sun3 specific code
243 *
244 * our mission: figure out whether what we are looking at is
245 *              bus error in the UNIX sense, or
246 *	        a memory error i.e a page fault
247 *
248 * [this code replaces similarly mmu specific code in the hp300 code]
249 */
250sun3_mmu_specific:
251	clrl %d0			| make sure top bits are cleared too
252	movl %d1,%sp@-			| save %d1
253	movc %sfc,%d1			| save %sfc to %d1
254	moveq #FC_CONTROL,%d0		| %sfc = FC_CONTROL
255	movc %d0,%sfc
256	movsb BUSERR_REG,%d0		| get value of bus error register
257	movc %d1,%sfc			| restore %sfc
258	movl %sp@+,%d1			| restore %d1
259	andb #BUSERR_MMU,%d0		| is this an MMU fault?
260	jeq Lisberr			| non-MMU bus error
261/* End of sun3 specific code. */
262
263Lismerr:
264	movl	#T_MMUFLT,%sp@-		| show that we are an MMU fault
265	jra	_ASM_LABEL(faultstkadj)	| and deal with it
266Lisaerr:
267	movl	#T_ADDRERR,%sp@-	| mark address error
268	jra	_ASM_LABEL(faultstkadj)	| and deal with it
269Lisberr:
270	movl	#T_BUSERR,%sp@-		| mark bus error
271	jra	_ASM_LABEL(faultstkadj)	| and deal with it
272
273/*
274 * FP exceptions.
275 */
276GLOBAL(fpfline)
277	clrl	%sp@-			| stack adjust count
278	moveml	#0xFFFF,%sp@-		| save registers
279	moveq	#T_FPEMULI,%d0		| denote as FP emulation trap
280	jra	_ASM_LABEL(fault)	| do it
281
282GLOBAL(fpunsupp)
283	clrl	%sp@-			| stack adjust count
284	moveml	#0xFFFF,%sp@-		| save registers
285	moveq	#T_FPEMULD,%d0		| denote as FP emulation trap
286	jra	_ASM_LABEL(fault)	| do it
287
288/*
289 * Handles all other FP coprocessor exceptions.
290 * Note that since some FP exceptions generate mid-instruction frames
291 * and may cause signal delivery, we need to test for stack adjustment
292 * after the trap call.
293 */
294GLOBAL(fpfault)
295	clrl	%sp@-		| stack adjust count
296	moveml	#0xFFFF,%sp@-	| save user registers
297	movl	%usp,%a0	| and save
298	movl	%a0,%sp@(FR_SP)	|   the user stack pointer
299	clrl	%sp@-		| no VA arg
300	movl	_C_LABEL(curpcb),%a0	| current pcb
301	lea	%a0@(PCB_FPCTX),%a0 | address of FP savearea
302	fsave	%a0@		| save state
303	tstb	%a0@		| null state frame?
304	jeq	Lfptnull	| yes, safe
305	clrw	%d0		| no, need to tweak BIU
306	movb	%a0@(1),%d0	| get frame size
307	bset	#3,%a0@(0,%d0:w) | set exc_pend bit of BIU
308Lfptnull:
309	fmovem	%fpsr,%sp@-	| push fpsr as code argument
310	frestore %a0@		| restore state
311	movl	#T_FPERR,%sp@-	| push type arg
312	jra	_ASM_LABEL(faultstkadj) | call trap and deal with stack cleanup
313
314/*
315 * Other exceptions only cause four and six word stack frame and require
316 * no post-trap stack adjustment.
317 */
318GLOBAL(badtrap)
319	clrl	%sp@-			| stack adjust count
320	moveml	#0xFFFF,%sp@-		| save std frame regs
321	jbsr	_C_LABEL(straytrap)	| report
322	moveml	%sp@+,#0xFFFF		| restore regs
323	addql	#4,%sp			| stack adjust count
324	jra	_ASM_LABEL(rei)		| all done
325
326/*
327 * Trap 0 is for system calls
328 */
329GLOBAL(trap0)
330	clrl	%sp@-			| stack adjust count
331	moveml	#0xFFFF,%sp@-		| save user registers
332	movl	%usp,%a0		| save the user SP
333	movl	%a0,%sp@(FR_SP)		|   in the savearea
334	movl	%d0,%sp@-		| push syscall number
335	jbsr	_C_LABEL(syscall)	| handle it
336	addql	#4,%sp			| pop syscall arg
337	movl	%sp@(FR_SP),%a0		| grab and restore
338	movl	%a0,%usp		|   user SP
339	moveml	%sp@+,#0x7FFF		| restore most registers
340	addql	#8,%sp			| pop SP and stack adjust
341	jra	_ASM_LABEL(rei)		| all done
342
343/*
344 * Trap 12 is the entry point for the cachectl "syscall"
345 *	cachectl(command, addr, length)
346 * command in %d0, addr in %a1, length in %d1
347 */
348GLOBAL(trap12)
349	movl	_C_LABEL(curlwp),%a0
350	movl	%a0@(L_PROC),%sp@-	| push curproc pointer
351	movl	%d1,%sp@-		| push length
352	movl	%a1,%sp@-		| push addr
353	movl	%d0,%sp@-		| push command
354	jbsr	_C_LABEL(cachectl1)	| do it
355	lea	%sp@(16),%sp		| pop args
356	jra	_ASM_LABEL(rei)		| all done
357
358/*
359 * Trace (single-step) trap.  Kernel-mode is special.
360 * User mode traps are simply passed on to trap().
361 */
362GLOBAL(trace)
363	clrl	%sp@-			| stack adjust count
364	moveml	#0xFFFF,%sp@-
365	moveq	#T_TRACE,%d0
366
367	| Check PSW and see what happen.
368	|   T=0 S=0	(should not happen)
369	|   T=1 S=0	trace trap from user mode
370	|   T=0 S=1	trace trap on a trap instruction
371	|   T=1 S=1	trace trap from system mode (kernel breakpoint)
372
373	movw	%sp@(FR_HW),%d1		| get PSW
374	notw	%d1			| XXX no support for T0 on 680[234]0
375	andw	#PSL_TS,%d1		| from system mode (T=1, S=1)?
376	jeq	_ASM_LABEL(kbrkpt)	|  yes, kernel brkpt
377	jra	_ASM_LABEL(fault)	| no, user-mode fault
378
379/*
380 * Trap 15 is used for:
381 *	- GDB breakpoints (in user programs)
382 *	- KGDB breakpoints (in the kernel)
383 *	- trace traps for SUN binaries (not fully supported yet)
384 * User mode traps are simply passed to trap().
385 */
386GLOBAL(trap15)
387	clrl	%sp@-			| stack adjust count
388	moveml	#0xFFFF,%sp@-
389	moveq	#T_TRAP15,%d0
390	btst	#5,%sp@(FR_HW)		| was supervisor mode?
391	jne	_ASM_LABEL(kbrkpt)	|  yes, kernel brkpt
392	jra	_ASM_LABEL(fault)	| no, user-mode fault
393
394ASLOCAL(kbrkpt)
395	| Kernel-mode breakpoint or trace trap. (%d0=trap_type)
396	| Save the system sp rather than the user sp.
397	movw	#PSL_HIGHIPL,%sr	| lock out interrupts
398	lea	%sp@(FR_SIZE),%a6	| Save stack pointer
399	movl	%a6,%sp@(FR_SP)		|  from before trap
400
401	| If we are not on tmpstk switch to it.
402	| (so debugger can change the stack pointer)
403	movl	%a6,%d1
404	cmpl	#_ASM_LABEL(tmpstk),%d1
405	jls	Lbrkpt2			| already on tmpstk
406	| Copy frame to the temporary stack
407	movl	%sp,%a0			| %a0=src
408	lea	_ASM_LABEL(tmpstk)-96,%a1	| %a1=dst
409	movl	%a1,%sp			| sp=new frame
410	moveq	#FR_SIZE,%d1
411Lbrkpt1:
412	movl	%a0@+,%a1@+
413	subql	#4,%d1
414	bgt	Lbrkpt1
415
416Lbrkpt2:
417	| Call the trap handler for the kernel debugger.
418	| Do not call trap() to handle it, so that we can
419	| set breakpoints in trap() if we want.  We know
420	| the trap type is either T_TRACE or T_BREAKPOINT.
421	movl	%d0,%sp@-		| push trap type
422	jbsr	_C_LABEL(trap_kdebug)
423	addql	#4,%sp			| pop args
424
425	| The stack pointer may have been modified, or
426	| data below it modified (by kgdb push call),
427	| so push the hardware frame at the current sp
428	| before restoring registers and returning.
429	movl	%sp@(FR_SP),%a0		| modified sp
430	lea	%sp@(FR_SIZE),%a1	| end of our frame
431	movl	%a1@-,%a0@-		| copy 2 longs with
432	movl	%a1@-,%a0@-		| ... predecrement
433	movl	%a0,%sp@(FR_SP)		| sp = h/w frame
434	moveml	%sp@+,#0x7FFF		| restore all but sp
435	movl	%sp@,%sp		| ... and sp
436	rte				| all done
437
438/*
439 * Interrupt handlers.  Most are auto-vectored,
440 * and hard-wired the same way on all sun3 models.
441 * Format in the stack is:
442 *   %d0,%d1,%a0,%a1, sr, pc, vo
443 */
444
445/* clock: see clock.c */
446#ifdef __ELF__
447	.align	4
448#else
449	.align	2
450#endif
451GLOBAL(_isr_clock)
452	INTERRUPT_SAVEREG
453	jbsr	_C_LABEL(clock_intr)
454	INTERRUPT_RESTOREREG
455	jra	_ASM_LABEL(rei)
456
457/*
458 * Emulation of VAX REI instruction.
459 *
460 * This code is (mostly) un-altered from the hp300 code,
461 * except that sun machines do not need a simulated SIR
462 * because they have a real software interrupt register.
463 *
464 * This code deals with checking for and servicing ASTs
465 * (profiling, scheduling) and software interrupts (network, softclock).
466 * We check for ASTs first, just like the VAX.  To avoid excess overhead
467 * the T_ASTFLT handling code will also check for software interrupts so we
468 * do not have to do it here.  After identifying that we need an AST we
469 * drop the IPL to allow device interrupts.
470 *
471 * This code is complicated by the fact that sendsig may have been called
472 * necessitating a stack cleanup.
473 */
474
475ASGLOBAL(rei)
476#ifdef	DIAGNOSTIC
477	tstl	_C_LABEL(panicstr)	| have we panicked?
478	jne	Ldorte			| yes, do not make matters worse
479#endif
480	tstl	_C_LABEL(astpending)	| AST pending?
481	jeq	Ldorte			| no, done
482Lrei1:
483	btst	#5,%sp@			| yes, are we returning to user mode?
484	jne	Ldorte			| no, done
485	movw	#PSL_LOWIPL,%sr		| lower SPL
486	clrl	%sp@-			| stack adjust
487	moveml	#0xFFFF,%sp@-		| save all registers
488	movl	%usp,%a1		| including
489	movl	%a1,%sp@(FR_SP)		|    the users SP
490	clrl	%sp@-			| VA == none
491	clrl	%sp@-			| code == none
492	movl	#T_ASTFLT,%sp@-		| type == async system trap
493	pea	%sp@(12)		| fp == address of trap frame
494	jbsr	_C_LABEL(trap)		| go handle it
495	lea	%sp@(16),%sp		| pop value args
496	movl	%sp@(FR_SP),%a0		| restore user SP
497	movl	%a0,%usp		|   from save area
498	movw	%sp@(FR_ADJ),%d0	| need to adjust stack?
499	jne	Laststkadj		| yes, go to it
500	moveml	%sp@+,#0x7FFF		| no, restore most user regs
501	addql	#8,%sp			| toss SP and stack adjust
502	rte				| and do real RTE
503Laststkadj:
504	lea	%sp@(FR_HW),%a1		| pointer to HW frame
505	addql	#8,%a1			| source pointer
506	movl	%a1,%a0			| source
507	addw	%d0,%a0			|  + hole size = dest pointer
508	movl	%a1@-,%a0@-		| copy
509	movl	%a1@-,%a0@-		|  8 bytes
510	movl	%a0,%sp@(FR_SP)		| new SSP
511	moveml	%sp@+,#0x7FFF		| restore user registers
512	movl	%sp@,%sp		| and our SP
513Ldorte:
514	rte				| real return
515
516/*
517 * Initialization is at the beginning of this file, because the
518 * kernel entry point needs to be at zero for compatibility with
519 * the Sun boot loader.  This works on Sun machines because the
520 * interrupt vector table for reset is NOT at address zero.
521 * (The MMU has a "boot" bit that forces access to the PROM)
522 */
523
524/*
525 * Primitives
526 */
527
528/*
529 * Use common m68k process/lwp switch and context save subroutines.
530 */
531#define FPCOPROC	/* XXX: Temp. Reqd. */
532#include <m68k/m68k/switch_subr.s>
533
534
535/* suline() */
536/* TBIA, TBIS, TBIAS, TBIAU */
537
538/*
539 * Invalidate instruction cache
540 */
541ENTRY(ICIA)
542	movl	#IC_CLEAR,%d0
543	movc	%d0,%cacr		| invalidate i-cache
544	rts
545
546/* DCIA, DCIS */
547
548/*
549 * Invalidate data cache.
550 */
551ENTRY(DCIU)
552	rts
553
554/* ICPL, ICPP, DCPL, DCPP, DCPA, DCFL, DCFP */
555/* PCIA, ecacheon, ecacheoff */
556
557/* loadustp, ptest_addr */
558
559/*
560 * _delay(unsigned N)
561 * Delay for at least (N/256) microseconds.
562 * This routine depends on the variable:  delay_divisor
563 * which should be set based on the CPU clock rate.
564 * XXX: Currently this is set based on the CPU model,
565 * XXX: but this should be determined at run time...
566 */
567GLOBAL(_delay)
568	| %d0 = arg = (usecs << 8)
569	movl	%sp@(4),%d0
570	| %d1 = delay_divisor;
571	movl	_C_LABEL(delay_divisor),%d1
572	jra	L_delay			/* Jump into the loop! */
573
574	/*
575	 * Align the branch target of the loop to a half-line (8-byte)
576	 * boundary to minimize cache effects.  This guarantees both
577	 * that there will be no prefetch stalls due to cache line burst
578	 * operations and that the loop will run from a single cache
579	 * half-line.
580	 */
581#ifdef __ELF__
582	.align	8
583#else
584	.align	3
585#endif
586L_delay:
587	subl	%d1,%d0
588	jgt	L_delay
589	rts
590
591/*
592 * void set_segmap_allctx(vaddr_t va, int sme)
593 */
594ENTRY(set_segmap_allctx)
595	linkw	%fp,#0
596	moveml	#0x3000,%sp@-
597	movl	8(%fp),%d3		| d3 = va
598	andl	#0xffffffc,%d3
599	bset	#29,%d3
600	movl	%d3,%a1			| a1 = ctrladdr, d3 avail
601	movl	12(%fp),%d1		| d1 = sme
602	moveq	#FC_CONTROL,%d0
603	movl	#CONTEXT_REG,%a0	| a0 = ctxreg
604	movc	%sfc,%d3		| d3 = oldsfc
605	movc	%d0,%sfc
606	movsb	%a0@,%d2
607	andi	#7,%d2			| d2 = oldctx
608	movc	%d3,%sfc		| restore sfc, d3 avail
609	movc	%dfc,%d3		| d3 = olddfc
610	movc	%d0,%dfc
611	movl	#(CONTEXT_NUM - 1),%d0	| d0 = ctx number
6121:
613	movsb	%d0,%a0@		| change to ctx
614	movsb	%d1,%a1@		| set segmap
615	dbf	%d0,1b			| loop setting each ctx
616	movsb	%d2,%a0@		| restore ctx
617	movc	%d3,%dfc		| restore dfc
618	moveml	%sp@+,#0x000c
619	unlk	%fp
620	rts
621
622| Define some addresses, mostly so DDB can print useful info.
623| Not using _C_LABEL() here because these symbols are never
624| referenced by any C code, and if the leading underscore
625| ever goes away, these lines turn into syntax errors...
626	.set	_KERNBASE3,KERNBASE3
627	.set	_MONSTART,SUN3_MONSTART
628	.set	_PROM_BASE,SUN3_PROM_BASE
629	.set	_MONEND,SUN3_MONEND
630
631|The end!
632