Import 2.3.50pre1
[davej-history.git] / arch / m68k / ifpsp060 / os.S
blob4bbf86f96a65bf5e2d7ce1bc2a1df9e7c3a8783f
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.
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.
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 |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
29 | os.s
31 | This file contains:
32 |       - example "Call-Out"s required by both the ISP and FPSP.
35 #include <linux/linkage.h>
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 |################################
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.
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
74 | _060_dmem_write():
76 | Writes to data memory while in supervisor mode.
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
86         .global         _060_dmem_write
87 _060_dmem_write:
88         btst            #0x5,0x4(%a6)           | check for supervisor state
89         beqs            user_write
90 super_write:
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
95         rts
96 user_write:
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
103         rts
106 | _060_imem_read(), _060_dmem_read():
108 | Reads from data/instruction memory while in supervisor mode.
110 | INPUTS:
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
115 | OUTPUTS:
116 |       d1 - 0 = success, !0 = failure
118         .global                 _060_imem_read
119         .global         _060_dmem_read
120 _060_imem_read:
121 _060_dmem_read:
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         subq.l          #0x1,%d0                | decr byte counter
127         bnes            super_read              | quit if ctr = 0
128         clr.l           %d1                     | return success
129         rts
130 user_read:
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
137         rts
140 | _060_dmem_read_byte():
142 | Read a data byte from user memory.
144 | INPUTS:
145 |       a0 - user source address
146 |       0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
147 | OUTPUTS:
148 |       d0 - data byte in d0
149 |       d1 - 0 = success, !0 = failure
151         .global                 _060_dmem_read_byte
152 _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
157         bras            dmrbr
158 dmrbs:  clr.l           %d0                     | clear whole longword
159         move.b          (%a0),%d0               | fetch super byte
160 dmrbr:  clr.l           %d1                     | return success
161         rts
164 | _060_dmem_read_word():
166 | Read a data word from user memory.
168 | INPUTS:
169 |       a0 - user source address
170 |       0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
171 | OUTPUTS:
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.
179 | INPUTS:
180 |       a0 - user source address
181 |       0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
182 | OUTPUTS:
183 |       d0 - instruction word in d0
184 |       d1 - 0 = success, !0 = failure
186         .global                 _060_dmem_read_word
187         .global                 _060_imem_read_word
188 _060_dmem_read_word:
189 _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
194         bras            dmrwr
195 dmrws:  clr.l           %d0                     | clear whole longword
196         move.w          (%a0), %d0              | fetch super word
197 dmrwr:  clr.l           %d1                     | return success
198         rts
201 | _060_dmem_read_long():
205 | INPUTS:
206 |       a0 - user source address
207 |       0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
208 | OUTPUTS:
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.
216 | INPUTS:
217 |       a0 - user source address
218 |       0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
219 | OUTPUTS:
220 |       d0 - instruction longword in d0
221 |       d1 - 0 = success, !0 = failure
223         .global                 _060_dmem_read_long
224         .global                 _060_imem_read_long
225 _060_dmem_read_long:
226 _060_imem_read_long:
227         btst            #0x5,0x4(%a6)           | check for supervisor state
228         bnes            dmrls                   | supervisor
229 dmrlu:
230 dmrluae:movs.l          (%a0),%d0               | fetch user longword
231         bras            dmrlr
232 dmrls:  move.l          (%a0),%d0               | fetch super longword
233 dmrlr:  clr.l           %d1                     | return success
234         rts
237 | _060_dmem_write_byte():
239 | Write a data byte to user memory.
241 | INPUTS:
242 |       a0 - user destination address
243 |       d0 - data byte in d0
244 |       0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
245 | OUTPUTS:
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
252 dmwbu:
253 dmwbuae:movs.b          %d0,(%a0)               | store user byte
254         bras            dmwbr
255 dmwbs:  move.b          %d0,(%a0)               | store super byte
256 dmwbr:  clr.l           %d1                     | return success
257         rts
260 | _060_dmem_write_word():
262 | Write a data word to user memory.
264 | INPUTS:
265 |       a0 - user destination address
266 |       d0 - data word in d0
267 |       0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
268 | OUTPUTS:
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
275 dmwwu:
276 dmwwuae:movs.w          %d0,(%a0)               | store user word
277         bras            dmwwr
278 dmwws:  move.w          %d0,(%a0)               | store super word
279 dmwwr:  clr.l           %d1                     | return success
280         rts
283 | _060_dmem_write_long():
285 | Write a data longword to user memory.
287 | INPUTS:
288 |       a0 - user destination address
289 |       d0 - data longword in d0
290 |       0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
291 | OUTPUTS:
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
298 dmwlu:
299 dmwluae:movs.l          %d0,(%a0)               | store user longword
300         bra             dmwlr
301 dmwls:  move.l          %d0,(%a0)               | store super longword
302 dmwlr:  clr.l           %d1                     | return success
303         rts
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)
321         .global                 _copyout
322 _copyout:
323         move.l          4(%sp),%a0              | source
324         move.l          8(%sp),%a1              | destination
325         move.l          12(%sp),%d0             | count
326     subq.l      #1,%d0
327 moreout:
328         move.b          (%a0)+,%d1              | fetch supervisor byte
329 copyoutae:
330         movs.b          %d1,(%a1)+              | store user byte
331         dbra            %d0,moreout             | are we through yet?
332         moveq           #0,%d0                  | return success
333         rts
336 | int _copyin(user_addr, supervisor_addr, nbytes)
338         .global                 _copyin
339 _copyin:
340         move.l          4(%sp),%a0              | source
341         move.l          8(%sp),%a1              | destination
342         move.l          12(%sp),%d0             | count
343     subq.l      #1,%d0
344 morein:
345 copyinae:       
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
350         rts
352 |###########################################################################
355 | _060_real_trace():
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
364 _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
380 _060_real_access:
381         bral    SYMBOL_NAME(buserr)
385 | Execption handling for movs access to illegal memory  
386         .section .fixup,#alloc,#execinstr
387         .even
388 1:      moveq           #-1,%d1
389         rts
390 .section __ex_table,#alloc
391         .align 4
392         .long   dmrbuae,1b
393         .long   dmrwuae,1b
394         .long   dmrluae,1b
395         .long   dmwbuae,1b
396         .long   dmwwuae,1b
397         .long   dmwluae,1b
398         .long   copyoutae,1b
399         .long   copyinae,1b
400         .text