xref: /netbsd/sys/arch/m68k/060sp/dist/os.s (revision bf9ec67e)
1#
2# $NetBSD: os.s,v 1.1 2000/04/14 20:24:39 is Exp $
3#
4
5#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6# MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
7# M68000 Hi-Performance Microprocessor Division
8# M68060 Software Package Production Release
9#
10# M68060 Software Package Copyright (C) 1993, 1994, 1995, 1996 Motorola Inc.
11# All rights reserved.
12#
13# THE SOFTWARE is provided on an "AS IS" basis and without warranty.
14# To the maximum extent permitted by applicable law,
15# MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
16# INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS
17# FOR A PARTICULAR PURPOSE and any warranty against infringement with
18# regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF)
19# and any accompanying written materials.
20#
21# To the maximum extent permitted by applicable law,
22# IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
23# (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
24# BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS)
25# ARISING OF THE USE OR INABILITY TO USE THE SOFTWARE.
26#
27# Motorola assumes no responsibility for the maintenance and support
28# of the SOFTWARE.
29#
30# You are hereby granted a copyright license to use, modify, and distribute the
31# SOFTWARE so long as this entire notice is retained without alteration
32# in any modified and/or redistributed versions, and that such modified
33# versions are clearly identified as such.
34# No licenses are granted by implication, estoppel or otherwise under any
35# patents or trademarks of Motorola, Inc.
36#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
37
38#
39# os.s
40#
41# This file contains:
42#	- example "Call-Out"s required by both the ISP and FPSP.
43#
44
45
46#################################
47# EXAMPLE CALL-OUTS 		#
48# 				#
49# _060_dmem_write()		#
50# _060_dmem_read()		#
51# _060_imem_read()		#
52# _060_dmem_read_byte()		#
53# _060_dmem_read_word()		#
54# _060_dmem_read_long()		#
55# _060_imem_read_word()		#
56# _060_imem_read_long()		#
57# _060_dmem_write_byte()	#
58# _060_dmem_write_word()	#
59# _060_dmem_write_long()	#
60#				#
61# _060_real_trace()		#
62# _060_real_access()		#
63#################################
64
65#
66# Each IO routine checks to see if the memory write/read is to/from user
67# or supervisor application space. The examples below use simple "move"
68# instructions for supervisor mode applications and call _copyin()/_copyout()
69# for user mode applications.
70# When installing the 060SP, the _copyin()/_copyout() equivalents for a
71# given operating system should be substituted.
72#
73# The addresses within the 060SP are guaranteed to be on the stack.
74# The result is that Unix processes are allowed to sleep as a consequence
75# of a page fault during a _copyout.
76#
77
78#
79# _060_dmem_write():
80#
81# Writes to data memory while in supervisor mode.
82#
83# INPUTS:
84#	a0 - supervisor source address
85#	a1 - user destination address
86#	d0 - number of bytes to write
87# 	0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
88# OUTPUTS:
89#	d1 - 0 = success, !0 = failure
90#
91	global		_060_dmem_write
92_060_dmem_write:
93	btst		&0x5,0x4(%a6)		# check for supervisor state
94	beq.b		user_write
95super_write:
96	mov.b		(%a0)+,(%a1)+		# copy 1 byte
97	subq.l		&0x1,%d0		# decr byte counter
98	bne.b		super_write		# quit if ctr = 0
99	clr.l		%d1			# return success
100	rts
101user_write:
102	mov.l		%d0,-(%sp)		# pass: counter
103	mov.l		%a1,-(%sp)		# pass: user dst
104	mov.l		%a0,-(%sp)		# pass: supervisor src
105	bsr.l		_copyout		# write byte to user mem
106	mov.l		%d0,%d1			# return success
107	add.l		&0xc, %sp		# clear 3 lw params
108	rts
109
110#
111# _060_imem_read(), _060_dmem_read():
112#
113# Reads from data/instruction memory while in supervisor mode.
114#
115# INPUTS:
116#	a0 - user source address
117#	a1 - supervisor destination address
118#	d0 - number of bytes to read
119# 	0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
120# OUTPUTS:
121#	d1 - 0 = success, !0 = failure
122#
123	global 		_060_imem_read
124	global		_060_dmem_read
125_060_imem_read:
126_060_dmem_read:
127	btst		&0x5,0x4(%a6)		# check for supervisor state
128	beq.b		user_read
129super_read:
130	mov.b		(%a0)+,(%a1)+		# copy 1 byte
131	subq.l		&0x1,%d0		# decr byte counter
132	bne.b		super_read		# quit if ctr = 0
133	clr.l		%d1			# return success
134	rts
135user_read:
136	mov.l		%d0,-(%sp)		# pass: counter
137	mov.l		%a1,-(%sp)		# pass: super dst
138	mov.l		%a0,-(%sp)		# pass: user src
139	bsr.l		_copyin			# read byte from user mem
140	mov.l		%d0,%d1			# return success
141	add.l		&0xc,%sp		# clear 3 lw params
142	rts
143
144#
145# _060_dmem_read_byte():
146#
147# Read a data byte from user memory.
148#
149# INPUTS:
150#	a0 - user source address
151# 	0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
152# OUTPUTS:
153#	d0 - data byte in d0
154#	d1 - 0 = success, !0 = failure
155#
156	global 		_060_dmem_read_byte
157_060_dmem_read_byte:
158	btst		&0x5,0x4(%a6)		# check for supervisor state
159	bne.b		dmrbs			# supervisor
160dmrbu:	clr.l		-(%sp)			# clear space on stack for result
161	mov.l		&0x1,-(%sp)		# pass: # bytes to copy
162	pea		0x7(%sp)		# pass: dst addr (stack)
163	mov.l		%a0,-(%sp)		# pass: src addr (user mem)
164	bsr.l		_copyin			# "copy in" the data
165	mov.l		%d0,%d1			# return success
166	add.l		&0xc,%sp		# delete params
167	mov.l		(%sp)+,%d0		# put answer in d0
168	rts
169dmrbs:	clr.l		%d0			# clear whole longword
170	mov.b		(%a0),%d0		# fetch super byte
171	clr.l		%d1			# return success
172	rts
173
174#
175# _060_dmem_read_word():
176#
177# Read a data word from user memory.
178#
179# INPUTS:
180#	a0 - user source address
181# 	0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
182# OUTPUTS:
183#	d0 - data word in d0
184#	d1 - 0 = success, !0 = failure
185#
186	global 		_060_dmem_read_word
187_060_dmem_read_word:
188	btst		&0x5,0x4(%a6)		# check for supervisor state
189	bne.b		dmrws			# supervisor
190dmrwu:	clr.l		-(%sp)			# clear space on stack for result
191	mov.l		&0x2,-(%sp)		# pass: # bytes to copy
192	pea		0x6(%sp)		# pass: dst addr (stack)
193	mov.l		%a0,-(%sp)		# pass: src addr (user mem)
194	bsr.l		_copyin			# "copy in" the data
195	mov.l		%d0,%d1			# return success
196	add.l		&0xc,%sp		# delete params
197	mov.l		(%sp)+,%d0		# put answer in d0
198	rts
199dmrws:	clr.l		%d0			# clear whole longword
200	mov.w		(%a0), %d0		# fetch super word
201	clr.l		%d1			# return success
202	rts
203
204#
205# _060_dmem_read_long():
206#
207
208#
209# INPUTS:
210#	a0 - user source address
211# 	0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
212# OUTPUTS:
213#	d0 - data longword in d0
214#	d1 - 0 = success, !0 = failure
215#
216	global 		_060_dmem_read_long
217_060_dmem_read_long:
218	btst		&0x5,0x4(%a6)		# check for supervisor state
219	bne.b		dmrls			# supervisor
220dmrlu:	subq.l		&0x4,%sp		# clear space on stack for result
221	mov.l		&0x4,-(%sp)		# pass: # bytes to copy
222	pea		0x4(%sp)		# pass: dst addr (stack)
223	mov.l		%a0,-(%sp)		# pass: src addr (user mem)
224	bsr.l		_copyin			# "copy in" the data
225	mov.l		%d0,%d1			# return success
226	add.l		&0xc,%sp		# delete params
227	mov.l		(%sp)+,%d0		# put answer in d0
228	rts
229dmrls:	mov.l		(%a0),%d0		# fetch super longword
230	clr.l		%d1			# return success
231	rts
232
233#
234# _060_dmem_write_byte():
235#
236# Write a data byte to user memory.
237#
238# INPUTS:
239#	a0 - user destination address
240# 	d0 - data byte in d0
241# 	0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
242# OUTPUTS:
243#	d1 - 0 = success, !0 = failure
244#
245	global 		_060_dmem_write_byte
246_060_dmem_write_byte:
247	btst		&0x5,0x4(%a6)		# check for supervisor state
248	bne.b		dmwbs			# supervisor
249dmwbu:	mov.l		%d0,-(%sp)		# put src on stack
250	mov.l		&0x1,-(%sp)		# pass: # bytes to copy
251	mov.l		%a0,-(%sp)		# pass: dst addr (user mem)
252	pea		0xb(%sp)		# pass: src addr (stack)
253	bsr.l		_copyout		# "copy out" the data
254	mov.l		%d0,%d1			# return success
255	add.l		&0x10,%sp		# delete params + src
256	rts
257dmwbs:	mov.b		%d0,(%a0)		# store super byte
258	clr.l		%d1			# return success
259	rts
260
261#
262# _060_dmem_write_word():
263#
264# Write a data word to user memory.
265#
266# INPUTS:
267#	a0 - user destination address
268# 	d0 - data word in d0
269# 	0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
270# OUTPUTS:
271#	d1 - 0 = success, !0 = failure
272#
273	global 		_060_dmem_write_word
274_060_dmem_write_word:
275	btst		&0x5,0x4(%a6)		# check for supervisor state
276	bne.b		dmwws			# supervisor
277dmwwu:	mov.l		%d0,-(%sp)		# put src on stack
278	mov.l		&0x2,-(%sp)		# pass: # bytes to copy
279	mov.l		%a0,-(%sp)		# pass: dst addr (user mem)
280	pea		0xa(%sp)		# pass: src addr (stack)
281	bsr.l		_copyout		# "copy out" the data
282	mov.l		%d0,%d1			# return success
283	add.l		&0x10,%sp		# delete params + src
284	rts
285dmwws:	mov.w		%d0,(%a0)		# store super word
286	clr.l		%d1			# return success
287	rts
288
289#
290# _060_dmem_write_long():
291#
292# Write a data longword to user memory.
293#
294# INPUTS:
295#	a0 - user destination address
296# 	d0 - data longword in d0
297# 	0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
298# OUTPUTS:
299#	d1 - 0 = success, !0 = failure
300#
301	global 		_060_dmem_write_long
302_060_dmem_write_long:
303	btst		&0x5,0x4(%a6)		# check for supervisor state
304	bne.b		dmwls			# supervisor
305dmwlu:	mov.l		%d0,-(%sp)		# put src on stack
306	mov.l		&0x4,-(%sp)		# pass: # bytes to copy
307	mov.l		%a0,-(%sp)		# pass: dst addr (user mem)
308	pea		0x8(%sp)		# pass: src addr (stack)
309	bsr.l		_copyout		# "copy out" the data
310	mov.l		%d0,%d1			# return success
311	add.l		&0x10,%sp		# delete params + src
312	rts
313dmwls:	mov.l		%d0,(%a0)		# store super longword
314	clr.l		%d1			# return success
315	rts
316
317#
318# _060_imem_read_word():
319#
320# Read an instruction word from user memory.
321#
322# INPUTS:
323#	a0 - user source address
324# 	0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
325# OUTPUTS:
326#	d0 - instruction word in d0
327#	d1 - 0 = success, !0 = failure
328#
329	global 		_060_imem_read_word
330_060_imem_read_word:
331	btst		&0x5,0x4(%a6)		# check for supervisor state
332	bne.b		imrws			# supervisor
333imrwu:	clr.l		-(%sp)			# clear space on stack for result
334	mov.l		&0x2,-(%sp)		# pass: # bytes to copy
335	pea		0x6(%sp)		# pass: dst addr (stack)
336	mov.l		%a0,-(%sp)		# pass: src addr (user mem)
337	bsr.l		_copyin			# "copy in" the data
338	mov.l		%d0,%d1			# return success
339	add.l		&0xc,%sp		# delete params
340	mov.l		(%sp)+,%d0		# put answer in d0
341	rts
342imrws:	mov.w		(%a0),%d0		# fetch super word
343	clr.l		%d1			# return success
344	rts
345
346#
347# _060_imem_read_long():
348#
349# Read an instruction longword from user memory.
350#
351# INPUTS:
352#	a0 - user source address
353# 	0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
354# OUTPUTS:
355#	d0 - instruction longword in d0
356#	d1 - 0 = success, !0 = failure
357#
358	global 		_060_imem_read_long
359_060_imem_read_long:
360	btst		&0x5,0x4(%a6)		# check for supervisor state
361	bne.b		imrls			# supervisor
362imrlu:	subq.l		&0x4,%sp		# clear space on stack for result
363	mov.l		&0x4,-(%sp)		# pass: # bytes to copy
364	pea		0x4(%sp)		# pass: dst addr (stack)
365	mov.l		%a0,-(%sp)		# pass: src addr (user mem)
366	bsr.l		_copyin			# "copy in" the data
367	mov.l		%d0,%d1			# return success
368	add.l		&0xc,%sp		# delete params
369	mov.l		(%sp)+,%d0		# put answer in d0
370	rts
371imrls:	mov.l		(%a0),%d0		# fetch super longword
372	clr.l		%d1			# return success
373	rts
374
375################################################
376
377#
378# Use these routines if your kernel doesn't have _copyout/_copyin equivalents.
379# Assumes that D0/D1/A0/A1 are scratch registers. The _copyin/_copyout
380# below assume that the SFC/DFC have been set previously.
381#
382
383#
384# int _copyout(supervisor_addr, user_addr, nbytes)
385#
386	global 		_copyout
387_copyout:
388	mov.l		4(%sp),%a0		# source
389	mov.l		8(%sp),%a1		# destination
390	mov.l		12(%sp),%d0		# count
391moreout:
392	mov.b		(%a0)+,%d1		# fetch supervisor byte
393	movs.b		%d1,(%a1)+		# store user byte
394	subq.l		&0x1,%d0		# are we through yet?
395	bne.w		moreout			# no; so, continue
396	rts
397
398#
399# int _copyin(user_addr, supervisor_addr, nbytes)
400#
401	global 		_copyin
402_copyin:
403	mov.l		4(%sp),%a0		# source
404	mov.l		8(%sp),%a1		# destination
405	mov.l		12(%sp),%d0		# count
406morein:
407	movs.b		(%a0)+,%d1		# fetch user byte
408	mov.b		%d1,(%a1)+		# write supervisor byte
409	subq.l		&0x1,%d0		# are we through yet?
410	bne.w		morein			# no; so, continue
411	rts
412
413############################################################################
414
415#
416# _060_real_trace():
417#
418# This is the exit point for the 060FPSP when an instruction is being traced
419# and there are no other higher priority exceptions pending for this instruction
420# or they have already been processed.
421#
422# The sample code below simply executes an "rte".
423#
424	global		_060_real_trace
425_060_real_trace:
426	rte
427
428#
429# _060_real_access():
430#
431# This is the exit point for the 060FPSP when an access error exception
432# is encountered. The routine below should point to the operating system
433# handler for access error exceptions. The exception stack frame is an
434# 8-word access error frame.
435#
436# The sample routine below simply executes an "rte" instruction which
437# is most likely the incorrect thing to do and could put the system
438# into an infinite loop.
439#
440	global		_060_real_access
441_060_real_access:
442	rte
443