blob: 7a0d6e42806656a59f7b5da80f019aed1d1626c6 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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|
Jan Engelhardt96de0e22007-10-19 23:21:04 +02007|M68060 Software Package Copyright © 1993, 1994 Motorola Inc. All rights reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07008|
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
91super_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
96user_write:
97 move.b (%a0)+,%d1 | copy 1 byte
98copyoutae:
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
124super_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
129user_read:
130copyinae:
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
155dmrbuae:movs.b (%a0),%d0 | fetch user byte
156 rts
157dmrbs: 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
191dmrwuae:movs.w (%a0), %d0 | fetch user word
192 rts
193dmrws: 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
226dmrluae:movs.l (%a0),%d0 | fetch user longword
227 rts
228dmrls: 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
248dmwbuae:movs.b %d0,(%a0) | store user byte
249 rts
250dmwbs: 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
270dmwwu:
271dmwwuae:movs.w %d0,(%a0) | store user word
272 bras dmwwr
273dmwws: move.w %d0,(%a0) | store super word
274dmwwr: 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
294dmwluae:movs.l %d0,(%a0) | store user longword
295 rts
296dmwls: 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
322moreout:
323 move.b (%a0)+,%d1 | fetch supervisor byte
324copyoutae:
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
339morein:
340copyinae:
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,#alloc,#execinstr
383 .even
3841: moveq #-1,%d1
385 rts
386.section __ex_table,#alloc
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