diff options
Diffstat (limited to 'arch/m68k/ifpsp060/os.S')
-rw-r--r-- | arch/m68k/ifpsp060/os.S | 396 |
1 files changed, 396 insertions, 0 deletions
diff --git a/arch/m68k/ifpsp060/os.S b/arch/m68k/ifpsp060/os.S new file mode 100644 index 000000000000..aa4df87a6c42 --- /dev/null +++ b/arch/m68k/ifpsp060/os.S | |||
@@ -0,0 +1,396 @@ | |||
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,#alloc,#execinstr | ||
383 | .even | ||
384 | 1: 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 | ||