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
88 btst #0x5,0x4(%a6) | check for supervisor state
91 move.b (%a0)+,(%a1)+ | copy 1 byte
92 subq.l #0x1,%d0 | decr byte counter
93 bnes super_write | quit if ctr = 0
94 clr.l %d1 | return success
97 move.l %d0,-(%sp) | pass: counter
98 move.l %a1,-(%sp) | pass: user dst
99 move.l %a0,-(%sp) | pass: supervisor src
100 bsr.l _copyout | write byte to user mem
101 move.l %d0,%d1 | return success
102 add.l #0xc, %sp | clear 3 lw params
106 | _060_imem_read(), _060_dmem_read():
108 | Reads from data/instruction memory while in supervisor mode.
111 | a0 - user source address
112 | a1 - supervisor destination address
113 | d0 - number of bytes to read
114 | 0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
116 | d1 - 0 = success, !0 = failure
118 .global _060_imem_read
119 .global _060_dmem_read
122 btst #0x5,0x4(%a6) | check for supervisor state
125 move.b (%a0)+,(%a1)+ | copy 1 byte
126 subq.l #0x1,%d0 | decr byte counter
127 bnes super_read | quit if ctr = 0
128 clr.l %d1 | return success
131 move.l %d0,-(%sp) | pass: counter
132 move.l %a1,-(%sp) | pass: super dst
133 move.l %a0,-(%sp) | pass: user src
134 bsr.l _copyin | read byte from user mem
135 move.l %d0,%d1 | return success
136 add.l #0xc,%sp | clear 3 lw params
140 | _060_dmem_read_byte():
142 | Read a data byte from user memory.
145 | a0 - user source address
146 | 0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
148 | d0 - data byte in d0
149 | d1 - 0 = success, !0 = failure
151 .global _060_dmem_read_byte
153 btst #0x5,0x4(%a6) | check for supervisor state
154 bnes dmrbs | supervisor
155 dmrbu: clr.l %d0 | clear whole longword
156 dmrbuae:movs.b (%a0),%d0 | fetch user byte
158 dmrbs: clr.l %d0 | clear whole longword
159 move.b (%a0),%d0 | fetch super byte
160 dmrbr: clr.l %d1 | return success
164 | _060_dmem_read_word():
166 | Read a data word from user memory.
169 | a0 - user source address
170 | 0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
172 | d0 - data word in d0
173 | d1 - 0 = success, !0 = failure
175 | _060_imem_read_word():
177 | Read an instruction word from user memory.
180 | a0 - user source address
181 | 0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
183 | d0 - instruction word in d0
184 | d1 - 0 = success, !0 = failure
186 .global _060_dmem_read_word
187 .global _060_imem_read_word
190 btst #0x5,0x4(%a6) | check for supervisor state
191 bnes dmrws | supervisor
192 dmrwu: clr.l %d0 | clear whole longword
193 dmrwuae:movs.w (%a0), %d0 | fetch user word
195 dmrws: clr.l %d0 | clear whole longword
196 move.w (%a0), %d0 | fetch super word
197 dmrwr: clr.l %d1 | return success
201 | _060_dmem_read_long():
206 | a0 - user source address
207 | 0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
209 | d0 - data longword in d0
210 | d1 - 0 = success, !0 = failure
212 | _060_imem_read_long():
214 | Read an instruction longword from user memory.
217 | a0 - user source address
218 | 0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
220 | d0 - instruction longword in d0
221 | d1 - 0 = success, !0 = failure
223 .global _060_dmem_read_long
224 .global _060_imem_read_long
227 btst #0x5,0x4(%a6) | check for supervisor state
228 bnes dmrls | supervisor
230 dmrluae:movs.l (%a0),%d0 | fetch user longword
232 dmrls: move.l (%a0),%d0 | fetch super longword
233 dmrlr: clr.l %d1 | return success
237 | _060_dmem_write_byte():
239 | Write a data byte to user memory.
242 | a0 - user destination address
243 | d0 - data byte in d0
244 | 0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
246 | d1 - 0 = success, !0 = failure
248 .global _060_dmem_write_byte
249 _060_dmem_write_byte:
250 btst #0x5,0x4(%a6) | check for supervisor state
251 bnes dmwbs | supervisor
253 dmwbuae:movs.b %d0,(%a0) | store user byte
255 dmwbs: move.b %d0,(%a0) | store super byte
256 dmwbr: clr.l %d1 | return success
260 | _060_dmem_write_word():
262 | Write a data word to user memory.
265 | a0 - user destination address
266 | d0 - data word in d0
267 | 0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
269 | d1 - 0 = success, !0 = failure
271 .global _060_dmem_write_word
272 _060_dmem_write_word:
273 btst #0x5,0x4(%a6) | check for supervisor state
274 bnes dmwws | supervisor
276 dmwwuae:movs.w %d0,(%a0) | store user word
278 dmwws: move.w %d0,(%a0) | store super word
279 dmwwr: clr.l %d1 | return success
283 | _060_dmem_write_long():
285 | Write a data longword to user memory.
288 | a0 - user destination address
289 | d0 - data longword in d0
290 | 0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
292 | d1 - 0 = success, !0 = failure
294 .global _060_dmem_write_long
295 _060_dmem_write_long:
296 btst #0x5,0x4(%a6) | check for supervisor state
297 bnes dmwls | supervisor
299 dmwluae:movs.l %d0,(%a0) | store user longword
301 dmwls: move.l %d0,(%a0) | store super longword
302 dmwlr: clr.l %d1 | return success
306 |###############################################
309 | Use these routines if your kernel doesn't have _copyout/_copyin equivalents.
310 | Assumes that D0/D1/A0/A1 are scratch registers. The _copyin/_copyout
311 | below assume that the SFC/DFC have been set previously.
313 | Linux/68k: These are basically non-inlined versions of
314 | memcpy_{to,from}fs, but without long-transfer optimization
315 | Note: Assumed that SFC/DFC are pointing correctly to user data
316 | space... Should be right, or are there any exceptions?
319 | int _copyout(supervisor_addr, user_addr, nbytes)
323 move.l 4(%sp),%a0 | source
324 move.l 8(%sp),%a1 | destination
325 move.l 12(%sp),%d0 | count
328 move.b (%a0)+,%d1 | fetch supervisor byte
330 movs.b %d1,(%a1)+ | store user byte
331 dbra %d0,moreout | are we through yet?
332 moveq #0,%d0 | return success
336 | int _copyin(user_addr, supervisor_addr, nbytes)
340 move.l 4(%sp),%a0 | source
341 move.l 8(%sp),%a1 | destination
342 move.l 12(%sp),%d0 | count
346 movs.b (%a0)+,%d1 | fetch user byte
347 move.b %d1,(%a1)+ | write supervisor byte
348 dbra %d0,morein | are we through yet?
349 moveq #0,%d0 | return success
352 |###########################################################################
357 | This is the exit point for the 060FPSP when an instruction is being traced
358 | and there are no other higher priority exceptions pending for this instruction
359 | or they have already been processed.
361 | The sample code below simply executes an "rte".
363 .global _060_real_trace
365 bral SYMBOL_NAME(trap)
368 | _060_real_access():
370 | This is the exit point for the 060FPSP when an access error exception
371 | is encountered. The routine below should point to the operating system
372 | handler for access error exceptions. The exception stack frame is an
373 | 8-word access error frame.
375 | The sample routine below simply executes an "rte" instruction which
376 | is most likely the incorrect thing to do and could put the system
377 | into an infinite loop.
379 .global _060_real_access
381 bral SYMBOL_NAME(buserr)
385 | Execption handling for movs access to illegal memory
386 .section .fixup,#alloc,#execinstr
390 .section __ex_table,#alloc