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