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
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,"ax"
383 .even
3841: 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

source code of linux/arch/m68k/ifpsp060/os.S