xref: /openbmc/linux/arch/m68k/ifpsp060/iskeleton.S (revision e5451c8f8330e03ad3cfa16048b4daf961af434f)
11da177e4SLinus Torvalds|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
21da177e4SLinus Torvalds|MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
31da177e4SLinus Torvalds|M68000 Hi-Performance Microprocessor Division
41da177e4SLinus Torvalds|M68060 Software Package
51da177e4SLinus Torvalds|Production Release P1.00 -- October 10, 1994
61da177e4SLinus Torvalds|
7*96de0e25SJan Engelhardt|M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
81da177e4SLinus Torvalds|
91da177e4SLinus Torvalds|THE SOFTWARE is provided on an "AS IS" basis and without warranty.
101da177e4SLinus Torvalds|To the maximum extent permitted by applicable law,
111da177e4SLinus Torvalds|MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
121da177e4SLinus Torvalds|INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
131da177e4SLinus Torvalds|and any warranty against infringement with regard to the SOFTWARE
141da177e4SLinus Torvalds|(INCLUDING ANY MODIFIED VERSIONS THEREOF) and any accompanying written materials.
151da177e4SLinus Torvalds|
161da177e4SLinus Torvalds|To the maximum extent permitted by applicable law,
171da177e4SLinus Torvalds|IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
181da177e4SLinus Torvalds|(INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
191da177e4SLinus Torvalds|BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS)
201da177e4SLinus Torvalds|ARISING OF THE USE OR INABILITY TO USE THE SOFTWARE.
211da177e4SLinus Torvalds|Motorola assumes no responsibility for the maintenance and support of the SOFTWARE.
221da177e4SLinus Torvalds|
231da177e4SLinus Torvalds|You are hereby granted a copyright license to use, modify, and distribute the SOFTWARE
241da177e4SLinus Torvalds|so long as this entire notice is retained without alteration in any modified and/or
251da177e4SLinus Torvalds|redistributed versions, and that such modified versions are clearly identified as such.
261da177e4SLinus Torvalds|No licenses are granted by implication, estoppel or otherwise under any patents
271da177e4SLinus Torvalds|or trademarks of Motorola, Inc.
281da177e4SLinus Torvalds|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
291da177e4SLinus Torvalds| iskeleton.s
301da177e4SLinus Torvalds|
311da177e4SLinus Torvalds| This file contains:
321da177e4SLinus Torvalds|	(1) example "Call-out"s
331da177e4SLinus Torvalds|	(2) example package entry code
341da177e4SLinus Torvalds|	(3) example "Call-out" table
351da177e4SLinus Torvalds|
361da177e4SLinus Torvalds
371da177e4SLinus Torvalds#include <linux/linkage.h>
381da177e4SLinus Torvalds#include <asm/entry.h>
390013a854SSam Ravnborg#include <asm/asm-offsets.h>
401da177e4SLinus Torvalds
411da177e4SLinus Torvalds
421da177e4SLinus Torvalds|################################
431da177e4SLinus Torvalds| (1) EXAMPLE CALL-OUTS		#
441da177e4SLinus Torvalds|				#
451da177e4SLinus Torvalds| _060_isp_done()		#
461da177e4SLinus Torvalds| _060_real_chk()		#
471da177e4SLinus Torvalds| _060_real_divbyzero()		#
481da177e4SLinus Torvalds|				#
491da177e4SLinus Torvalds| _060_real_cas()		#
501da177e4SLinus Torvalds| _060_real_cas2()		#
511da177e4SLinus Torvalds| _060_real_lock_page()		#
521da177e4SLinus Torvalds| _060_real_unlock_page()	#
531da177e4SLinus Torvalds|################################
541da177e4SLinus Torvalds
551da177e4SLinus Torvalds|
561da177e4SLinus Torvalds| _060_isp_done():
571da177e4SLinus Torvalds|
581da177e4SLinus Torvalds| This is and example main exit point for the Unimplemented Integer
591da177e4SLinus Torvalds| Instruction exception handler. For a normal exit, the
601da177e4SLinus Torvalds| _isp_unimp() branches to here so that the operating system
611da177e4SLinus Torvalds| can do any clean-up desired. The stack frame is the
621da177e4SLinus Torvalds| Unimplemented Integer Instruction stack frame with
631da177e4SLinus Torvalds| the PC pointing to the instruction following the instruction
641da177e4SLinus Torvalds| just emulated.
651da177e4SLinus Torvalds| To simply continue execution at the next instruction, just
661da177e4SLinus Torvalds| do an "rte".
671da177e4SLinus Torvalds|
681da177e4SLinus Torvalds| Linux/68k: If returning to user space, check for needed reselections.
691da177e4SLinus Torvalds
701da177e4SLinus Torvalds	.global		_060_isp_done
711da177e4SLinus Torvalds_060_isp_done:
721da177e4SLinus Torvalds	btst	#0x5,%sp@		| supervisor bit set in saved SR?
731da177e4SLinus Torvalds	beq	.Lnotkern
741da177e4SLinus Torvalds	rte
751da177e4SLinus Torvalds.Lnotkern:
761da177e4SLinus Torvalds	SAVE_ALL_INT
771da177e4SLinus Torvalds	GET_CURRENT(%d0)
783b66a1edSRoman Zippel	| deliver signals, reschedule etc..
793b66a1edSRoman Zippel	jra	ret_from_exception
801da177e4SLinus Torvalds
811da177e4SLinus Torvalds|
821da177e4SLinus Torvalds| _060_real_chk():
831da177e4SLinus Torvalds|
841da177e4SLinus Torvalds| This is an alternate exit point for the Unimplemented Integer
851da177e4SLinus Torvalds| Instruction exception handler. If the instruction was a "chk2"
861da177e4SLinus Torvalds| and the operand was out of bounds, then _isp_unimp() creates
871da177e4SLinus Torvalds| a CHK exception stack frame from the Unimplemented Integer Instrcution
881da177e4SLinus Torvalds| stack frame and branches to this routine.
891da177e4SLinus Torvalds|
901da177e4SLinus Torvalds| Linux/68k: commented out test for tracing
911da177e4SLinus Torvalds
921da177e4SLinus Torvalds	.global		_060_real_chk
931da177e4SLinus Torvalds_060_real_chk:
941da177e4SLinus Torvalds|	tst.b		(%sp)			| is tracing enabled?
951da177e4SLinus Torvalds|	bpls		real_chk_end		| no
961da177e4SLinus Torvalds
971da177e4SLinus Torvalds|
981da177e4SLinus Torvalds|	    CHK FRAME		   TRACE FRAME
991da177e4SLinus Torvalds|	*****************	*****************
1001da177e4SLinus Torvalds|	*   Current PC	*	*   Current PC	*
1011da177e4SLinus Torvalds|	*****************	*****************
1021da177e4SLinus Torvalds|	* 0x2 *  0x018	*	* 0x2 *  0x024	*
1031da177e4SLinus Torvalds|	*****************	*****************
1041da177e4SLinus Torvalds|	*     Next	*	*     Next	*
1051da177e4SLinus Torvalds|	*      PC	*	*      PC	*
1061da177e4SLinus Torvalds|	*****************	*****************
1071da177e4SLinus Torvalds|	*      SR	*	*      SR	*
1081da177e4SLinus Torvalds|	*****************	*****************
1091da177e4SLinus Torvalds|
1101da177e4SLinus Torvalds|	move.b		#0x24,0x7(%sp)		| set trace vecno
1111da177e4SLinus Torvalds|	bral		_060_real_trace
1121da177e4SLinus Torvalds
1131da177e4SLinus Torvaldsreal_chk_end:
1141da177e4SLinus Torvalds	bral		trap			| jump to trap handler
1151da177e4SLinus Torvalds
1161da177e4SLinus Torvalds|
1171da177e4SLinus Torvalds| _060_real_divbyzero:
1181da177e4SLinus Torvalds|
1191da177e4SLinus Torvalds| This is an alternate exit point for the Unimplemented Integer
1201da177e4SLinus Torvalds| Instruction exception handler isp_unimp(). If the instruction is a 64-bit
1211da177e4SLinus Torvalds| integer divide where the source operand is a zero, then the _isp_unimp()
1221da177e4SLinus Torvalds| creates a Divide-by-zero exception stack frame from the Unimplemented
1231da177e4SLinus Torvalds| Integer Instruction stack frame and branches to this routine.
1241da177e4SLinus Torvalds|
1251da177e4SLinus Torvalds| Remember that a trace exception may be pending. The code below performs
1261da177e4SLinus Torvalds| no action associated with the "chk" exception. If tracing is enabled,
1271da177e4SLinus Torvalds| then it create a Trace exception stack frame from the "chk" exception
1281da177e4SLinus Torvalds| stack frame and branches to the _real_trace() entry point.
1291da177e4SLinus Torvalds|
1301da177e4SLinus Torvalds| Linux/68k: commented out test for tracing
1311da177e4SLinus Torvalds
1321da177e4SLinus Torvalds	.global		_060_real_divbyzero
1331da177e4SLinus Torvalds_060_real_divbyzero:
1341da177e4SLinus Torvalds|	tst.b		(%sp)			| is tracing enabled?
1351da177e4SLinus Torvalds|	bpls		real_divbyzero_end	| no
1361da177e4SLinus Torvalds
1371da177e4SLinus Torvalds|
1381da177e4SLinus Torvalds|	 DIVBYZERO FRAME	   TRACE FRAME
1391da177e4SLinus Torvalds|	*****************	*****************
1401da177e4SLinus Torvalds|	*   Current PC	*	*   Current PC	*
1411da177e4SLinus Torvalds|	*****************	*****************
1421da177e4SLinus Torvalds|	* 0x2 *  0x014	*	* 0x2 *  0x024	*
1431da177e4SLinus Torvalds|	*****************	*****************
1441da177e4SLinus Torvalds|	*     Next	*	*     Next	*
1451da177e4SLinus Torvalds|	*      PC	*	*      PC	*
1461da177e4SLinus Torvalds|	*****************	*****************
1471da177e4SLinus Torvalds|	*      SR	*	*      SR	*
1481da177e4SLinus Torvalds|	*****************	*****************
1491da177e4SLinus Torvalds|
1501da177e4SLinus Torvalds|	move.b		#0x24,0x7(%sp)		| set trace vecno
1511da177e4SLinus Torvalds|	bral		_060_real_trace
1521da177e4SLinus Torvalds
1531da177e4SLinus Torvaldsreal_divbyzero_end:
1541da177e4SLinus Torvalds	bral		trap			| jump to trap handler
1551da177e4SLinus Torvalds
1561da177e4SLinus Torvalds|##########################
1571da177e4SLinus Torvalds
1581da177e4SLinus Torvalds|
1591da177e4SLinus Torvalds| _060_real_cas():
1601da177e4SLinus Torvalds|
1611da177e4SLinus Torvalds| Entry point for the selected cas emulation code implementation.
1621da177e4SLinus Torvalds| If the implementation provided by the 68060ISP is sufficient,
1631da177e4SLinus Torvalds| then this routine simply re-enters the package through _isp_cas.
1641da177e4SLinus Torvalds|
1651da177e4SLinus Torvalds	.global		_060_real_cas
1661da177e4SLinus Torvalds_060_real_cas:
1671da177e4SLinus Torvalds	bral		_I_CALL_TOP+0x80+0x08
1681da177e4SLinus Torvalds
1691da177e4SLinus Torvalds|
1701da177e4SLinus Torvalds| _060_real_cas2():
1711da177e4SLinus Torvalds|
1721da177e4SLinus Torvalds| Entry point for the selected cas2 emulation code implementation.
1731da177e4SLinus Torvalds| If the implementation provided by the 68060ISP is sufficient,
1741da177e4SLinus Torvalds| then this routine simply re-enters the package through _isp_cas2.
1751da177e4SLinus Torvalds|
1761da177e4SLinus Torvalds	.global		_060_real_cas2
1771da177e4SLinus Torvalds_060_real_cas2:
1781da177e4SLinus Torvalds	bral		_I_CALL_TOP+0x80+0x10
1791da177e4SLinus Torvalds
1801da177e4SLinus Torvalds|
1811da177e4SLinus Torvalds| _060_lock_page():
1821da177e4SLinus Torvalds|
1831da177e4SLinus Torvalds| Entry point for the operating system`s routine to "lock" a page
1841da177e4SLinus Torvalds| from being paged out. This routine is needed by the cas/cas2
1851da177e4SLinus Torvalds| algorithms so that no page faults occur within the "core" code
1861da177e4SLinus Torvalds| region. Note: the routine must lock two pages if the operand
1871da177e4SLinus Torvalds| spans two pages.
1881da177e4SLinus Torvalds| NOTE: THE ROUTINE SHOULD RETURN AN FSLW VALUE IN D0 ON FAILURE
1891da177e4SLinus Torvalds| SO THAT THE 060SP CAN CREATE A PROPER ACCESS ERROR FRAME.
1901da177e4SLinus Torvalds| Arguments:
1911da177e4SLinus Torvalds|	a0 = operand address
1921da177e4SLinus Torvalds|	d0 = `xxxxxxff -> supervisor; `xxxxxx00 -> user
1931da177e4SLinus Torvalds|	d1 = `xxxxxxff -> longword; `xxxxxx00 -> word
1941da177e4SLinus Torvalds| Expected outputs:
1951da177e4SLinus Torvalds|	d0 = 0 -> success; non-zero -> failure
1961da177e4SLinus Torvalds|
1971da177e4SLinus Torvalds| Linux/m68k: Make sure the page is properly paged in, so we use
1981da177e4SLinus Torvalds| plpaw and handle any exception here. The kernel must not be
1991da177e4SLinus Torvalds| preempted until _060_unlock_page(), so that the page stays mapped.
2001da177e4SLinus Torvalds|
2011da177e4SLinus Torvalds	.global		_060_real_lock_page
2021da177e4SLinus Torvalds_060_real_lock_page:
2031da177e4SLinus Torvalds	move.l	%d2,-(%sp)
2041da177e4SLinus Torvalds	| load sfc/dfc
2051da177e4SLinus Torvalds	tst.b	%d0
2061da177e4SLinus Torvalds	jne	1f
2071da177e4SLinus Torvalds	moveq	#1,%d0
2081da177e4SLinus Torvalds	jra	2f
2091da177e4SLinus Torvalds1:	moveq	#5,%d0
2101da177e4SLinus Torvalds2:	movec.l	%dfc,%d2
2111da177e4SLinus Torvalds	movec.l	%d0,%dfc
2121da177e4SLinus Torvalds	movec.l	%d0,%sfc
2131da177e4SLinus Torvalds
2141da177e4SLinus Torvalds	clr.l	%d0
2151da177e4SLinus Torvalds	| prefetch address
2161da177e4SLinus Torvalds	.chip	68060
2171da177e4SLinus Torvalds	move.l	%a0,%a1
2181da177e4SLinus Torvalds1:	plpaw	(%a1)
2191da177e4SLinus Torvalds	addq.w	#1,%a0
2201da177e4SLinus Torvalds	tst.b	%d1
2211da177e4SLinus Torvalds	jeq	2f
2221da177e4SLinus Torvalds	addq.w	#2,%a0
2231da177e4SLinus Torvalds2:	plpaw	(%a0)
2241da177e4SLinus Torvalds3:	.chip	68k
2251da177e4SLinus Torvalds
2261da177e4SLinus Torvalds	| restore sfc/dfc
2271da177e4SLinus Torvalds	movec.l	%d2,%dfc
2281da177e4SLinus Torvalds	movec.l	%d2,%sfc
2291da177e4SLinus Torvalds	move.l	(%sp)+,%d2
2301da177e4SLinus Torvalds	rts
2311da177e4SLinus Torvalds
2321da177e4SLinus Torvalds.section __ex_table,"a"
2331da177e4SLinus Torvalds	.align	4
2341da177e4SLinus Torvalds	.long	1b,11f
2351da177e4SLinus Torvalds	.long	2b,21f
2361da177e4SLinus Torvalds.previous
2371da177e4SLinus Torvalds.section .fixup,"ax"
2381da177e4SLinus Torvalds	.even
2391da177e4SLinus Torvalds11:	move.l	#0x020003c0,%d0
2401da177e4SLinus Torvalds	or.l	%d2,%d0
2411da177e4SLinus Torvalds	swap	%d0
2421da177e4SLinus Torvalds	jra	3b
2431da177e4SLinus Torvalds21:	move.l	#0x02000bc0,%d0
2441da177e4SLinus Torvalds	or.l	%d2,%d0
2451da177e4SLinus Torvalds	swap	%d0
2461da177e4SLinus Torvalds	jra	3b
2471da177e4SLinus Torvalds.previous
2481da177e4SLinus Torvalds
2491da177e4SLinus Torvalds|
2501da177e4SLinus Torvalds| _060_unlock_page():
2511da177e4SLinus Torvalds|
2521da177e4SLinus Torvalds| Entry point for the operating system`s routine to "unlock" a
2531da177e4SLinus Torvalds| page that has been "locked" previously with _real_lock_page.
2541da177e4SLinus Torvalds| Note: the routine must unlock two pages if the operand spans
2551da177e4SLinus Torvalds| two pages.
2561da177e4SLinus Torvalds| Arguments:
2571da177e4SLinus Torvalds|	a0 = operand address
2581da177e4SLinus Torvalds|	d0 = `xxxxxxff -> supervisor; `xxxxxx00 -> user
2591da177e4SLinus Torvalds|	d1 = `xxxxxxff -> longword; `xxxxxx00 -> word
2601da177e4SLinus Torvalds|
2611da177e4SLinus Torvalds| Linux/m68k: perhaps reenable preemption here...
2621da177e4SLinus Torvalds
2631da177e4SLinus Torvalds	.global		_060_real_unlock_page
2641da177e4SLinus Torvalds_060_real_unlock_page:
2651da177e4SLinus Torvalds	clr.l		%d0
2661da177e4SLinus Torvalds	rts
2671da177e4SLinus Torvalds
2681da177e4SLinus Torvalds|###########################################################################
2691da177e4SLinus Torvalds
2701da177e4SLinus Torvalds|#################################
2711da177e4SLinus Torvalds| (2) EXAMPLE PACKAGE ENTRY CODE #
2721da177e4SLinus Torvalds|#################################
2731da177e4SLinus Torvalds
2741da177e4SLinus Torvalds	.global		_060_isp_unimp
2751da177e4SLinus Torvalds_060_isp_unimp:
2761da177e4SLinus Torvalds	bral		_I_CALL_TOP+0x80+0x00
2771da177e4SLinus Torvalds
2781da177e4SLinus Torvalds	.global		_060_isp_cas
2791da177e4SLinus Torvalds_060_isp_cas:
2801da177e4SLinus Torvalds	bral		_I_CALL_TOP+0x80+0x08
2811da177e4SLinus Torvalds
2821da177e4SLinus Torvalds	.global		_060_isp_cas2
2831da177e4SLinus Torvalds_060_isp_cas2:
2841da177e4SLinus Torvalds	bral		_I_CALL_TOP+0x80+0x10
2851da177e4SLinus Torvalds
2861da177e4SLinus Torvalds	.global		_060_isp_cas_finish
2871da177e4SLinus Torvalds_060_isp_cas_finish:
2881da177e4SLinus Torvalds	bra.l		_I_CALL_TOP+0x80+0x18
2891da177e4SLinus Torvalds
2901da177e4SLinus Torvalds	.global		_060_isp_cas2_finish
2911da177e4SLinus Torvalds_060_isp_cas2_finish:
2921da177e4SLinus Torvalds	bral		_I_CALL_TOP+0x80+0x20
2931da177e4SLinus Torvalds
2941da177e4SLinus Torvalds	.global		_060_isp_cas_inrange
2951da177e4SLinus Torvalds_060_isp_cas_inrange:
2961da177e4SLinus Torvalds	bral		_I_CALL_TOP+0x80+0x28
2971da177e4SLinus Torvalds
2981da177e4SLinus Torvalds	.global		_060_isp_cas_terminate
2991da177e4SLinus Torvalds_060_isp_cas_terminate:
3001da177e4SLinus Torvalds	bral		_I_CALL_TOP+0x80+0x30
3011da177e4SLinus Torvalds
3021da177e4SLinus Torvalds	.global		_060_isp_cas_restart
3031da177e4SLinus Torvalds_060_isp_cas_restart:
3041da177e4SLinus Torvalds	bral		_I_CALL_TOP+0x80+0x38
3051da177e4SLinus Torvalds
3061da177e4SLinus Torvalds|###########################################################################
3071da177e4SLinus Torvalds
3081da177e4SLinus Torvalds|###############################
3091da177e4SLinus Torvalds| (3) EXAMPLE CALL-OUT SECTION #
3101da177e4SLinus Torvalds|###############################
3111da177e4SLinus Torvalds
3121da177e4SLinus Torvalds| The size of this section MUST be 128 bytes!!!
3131da177e4SLinus Torvalds
3141da177e4SLinus Torvalds_I_CALL_TOP:
3151da177e4SLinus Torvalds	.long	_060_real_chk		- _I_CALL_TOP
3161da177e4SLinus Torvalds	.long	_060_real_divbyzero	- _I_CALL_TOP
3171da177e4SLinus Torvalds	.long	_060_real_trace		- _I_CALL_TOP
3181da177e4SLinus Torvalds	.long	_060_real_access	- _I_CALL_TOP
3191da177e4SLinus Torvalds	.long	_060_isp_done		- _I_CALL_TOP
3201da177e4SLinus Torvalds
3211da177e4SLinus Torvalds	.long	_060_real_cas		- _I_CALL_TOP
3221da177e4SLinus Torvalds	.long	_060_real_cas2		- _I_CALL_TOP
3231da177e4SLinus Torvalds	.long	_060_real_lock_page	- _I_CALL_TOP
3241da177e4SLinus Torvalds	.long	_060_real_unlock_page	- _I_CALL_TOP
3251da177e4SLinus Torvalds
3261da177e4SLinus Torvalds	.long	0x00000000, 0x00000000, 0x00000000, 0x00000000
3271da177e4SLinus Torvalds	.long	0x00000000, 0x00000000, 0x00000000
3281da177e4SLinus Torvalds
3291da177e4SLinus Torvalds	.long	_060_imem_read		- _I_CALL_TOP
3301da177e4SLinus Torvalds	.long	_060_dmem_read		- _I_CALL_TOP
3311da177e4SLinus Torvalds	.long	_060_dmem_write		- _I_CALL_TOP
3321da177e4SLinus Torvalds	.long	_060_imem_read_word	- _I_CALL_TOP
3331da177e4SLinus Torvalds	.long	_060_imem_read_long	- _I_CALL_TOP
3341da177e4SLinus Torvalds	.long	_060_dmem_read_byte	- _I_CALL_TOP
3351da177e4SLinus Torvalds	.long	_060_dmem_read_word	- _I_CALL_TOP
3361da177e4SLinus Torvalds	.long	_060_dmem_read_long	- _I_CALL_TOP
3371da177e4SLinus Torvalds	.long	_060_dmem_write_byte	- _I_CALL_TOP
3381da177e4SLinus Torvalds	.long	_060_dmem_write_word	- _I_CALL_TOP
3391da177e4SLinus Torvalds	.long	_060_dmem_write_long	- _I_CALL_TOP
3401da177e4SLinus Torvalds
3411da177e4SLinus Torvalds	.long	0x00000000
3421da177e4SLinus Torvalds	.long	0x00000000, 0x00000000, 0x00000000, 0x00000000
3431da177e4SLinus Torvalds
3441da177e4SLinus Torvalds|###########################################################################
3451da177e4SLinus Torvalds
3461da177e4SLinus Torvalds| 060 INTEGER KERNEL PACKAGE MUST GO HERE!!!
3471da177e4SLinus Torvalds#include "isp.sa"
348