]> Git Repo - linux.git/blob - arch/m68k/ifpsp060/os.S
KVM: arm64: Add support for userspace to suspend a vCPU
[linux.git] / arch / m68k / ifpsp060 / os.S
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
This page took 0.053757 seconds and 4 git commands to generate.