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
7 |M68060 Software Package Copyright © 1993, 1994 Motorola Inc. All rights reserved.
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.
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.
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 |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
32 | - example "Call-Out"s required by both the ISP and FPSP.
35 #include <linux/linkage.h>
37 |################################
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() #
53 | _060_real_access() #
54 |################################
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.
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.
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
76 | Writes to data memory while in supervisor mode.
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
84 | d1 - 0 = success, !0 = failure
86 .global _060_dmem_write
89 btst #0x5,0x4(%a6) | check for supervisor state
92 move.b (%a0)+,(%a1)+ | copy 1 byte
93 dbra %d0,super_write | quit if --ctr < 0
94 clr.l %d1 | return success
97 move.b (%a0)+,%d1 | copy 1 byte
100 dbra %d0,user_write | quit if --ctr < 0
101 clr.l %d1 | return success
105 | _060_imem_read(), _060_dmem_read():
107 | Reads from data/instruction memory while in supervisor mode.
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
115 | d1 - 0 = success, !0 = failure
117 .global _060_imem_read
118 .global _060_dmem_read
122 btst #0x5,0x4(%a6) | check for supervisor state
125 move.b (%a0)+,(%a1)+ | copy 1 byte
126 dbra %d0,super_read | quit if --ctr < 0
127 clr.l %d1 | return success
132 move.b %d1,(%a1)+ | copy 1 byte
133 dbra %d0,user_read | quit if --ctr < 0
134 clr.l %d1 | return success
138 | _060_dmem_read_byte():
140 | Read a data byte from user memory.
143 | a0 - user source address
144 | 0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
146 | d0 - data byte in d0
147 | d1 - 0 = success, !0 = failure
149 .global _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
157 dmrbs: move.b (%a0),%d0 | fetch super byte
161 | _060_dmem_read_word():
163 | Read a data word from user memory.
166 | a0 - user source address
167 | 0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
169 | d0 - data word in d0
170 | d1 - 0 = success, !0 = failure
172 | _060_imem_read_word():
174 | Read an instruction word from user memory.
177 | a0 - user source address
178 | 0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
180 | d0 - instruction word in d0
181 | d1 - 0 = success, !0 = failure
183 .global _060_dmem_read_word
184 .global _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
193 dmrws: move.w (%a0), %d0 | fetch super word
197 | _060_dmem_read_long():
202 | a0 - user source address
203 | 0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
205 | d0 - data longword in d0
206 | d1 - 0 = success, !0 = failure
208 | _060_imem_read_long():
210 | Read an instruction longword from user memory.
213 | a0 - user source address
214 | 0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
216 | d0 - instruction longword in d0
217 | d1 - 0 = success, !0 = failure
219 .global _060_dmem_read_long
220 .global _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
228 dmrls: move.l (%a0),%d0 | fetch super longword
232 | _060_dmem_write_byte():
234 | Write a data byte to user memory.
237 | a0 - user destination address
238 | d0 - data byte in d0
239 | 0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
241 | d1 - 0 = success, !0 = failure
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
250 dmwbs: move.b %d0,(%a0) | store super byte
254 | _060_dmem_write_word():
256 | Write a data word to user memory.
259 | a0 - user destination address
260 | d0 - data word in d0
261 | 0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
263 | d1 - 0 = success, !0 = failure
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
271 dmwwuae:movs.w %d0,(%a0) | store user word
273 dmwws: move.w %d0,(%a0) | store super word
274 dmwwr: clr.l %d1 | return success
278 | _060_dmem_write_long():
280 | Write a data longword to user memory.
283 | a0 - user destination address
284 | d0 - data longword in d0
285 | 0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
287 | d1 - 0 = success, !0 = failure
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
296 dmwls: move.l %d0,(%a0) | store super longword
301 |###############################################
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.
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?
314 | int _copyout(supervisor_addr, user_addr, nbytes)
318 move.l 4(%sp),%a0 | source
319 move.l 8(%sp),%a1 | destination
320 move.l 12(%sp),%d0 | count
323 move.b (%a0)+,%d1 | fetch supervisor byte
325 movs.b %d1,(%a1)+ | store user byte
326 dbra %d0,moreout | are we through yet?
327 moveq #0,%d0 | return success
331 | int _copyin(user_addr, supervisor_addr, nbytes)
335 move.l 4(%sp),%a0 | source
336 move.l 8(%sp),%a1 | destination
337 move.l 12(%sp),%d0 | count
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
348 |###########################################################################
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.
357 | The sample code below simply executes an "rte".
359 .global _060_real_trace
364 | _060_real_access():
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.
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.
375 .global _060_real_access
381 | Execption handling for movs access to illegal memory
382 .section .fixup,#alloc,#execinstr
386 .section __ex_table,#alloc