Back to home page

LXR

 
 

    


0001 |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0002 |MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
0003 |M68000 Hi-Performance Microprocessor Division
0004 |M68060 Software Package
0005 |Production Release P1.00 -- October 10, 1994
0006 |
0007 |M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
0008 |
0009 |THE SOFTWARE is provided on an "AS IS" basis and without warranty.
0010 |To the maximum extent permitted by applicable law,
0011 |MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
0012 |INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
0013 |and any warranty against infringement with regard to the SOFTWARE
0014 |(INCLUDING ANY MODIFIED VERSIONS THEREOF) and any accompanying written materials.
0015 |
0016 |To the maximum extent permitted by applicable law,
0017 |IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
0018 |(INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
0019 |BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS)
0020 |ARISING OF THE USE OR INABILITY TO USE THE SOFTWARE.
0021 |Motorola assumes no responsibility for the maintenance and support of the SOFTWARE.
0022 |
0023 |You are hereby granted a copyright license to use, modify, and distribute the SOFTWARE
0024 |so long as this entire notice is retained without alteration in any modified and/or
0025 |redistributed versions, and that such modified versions are clearly identified as such.
0026 |No licenses are granted by implication, estoppel or otherwise under any patents
0027 |or trademarks of Motorola, Inc.
0028 |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0029 | os.s
0030 |
0031 | This file contains:
0032 |   - example "Call-Out"s required by both the ISP and FPSP.
0033 |
0034 
0035 #include <linux/linkage.h>
0036 
0037 |################################
0038 | EXAMPLE CALL-OUTS     #
0039 |               #
0040 | _060_dmem_write()     #
0041 | _060_dmem_read()      #
0042 | _060_imem_read()      #
0043 | _060_dmem_read_byte()     #
0044 | _060_dmem_read_word()     #
0045 | _060_dmem_read_long()     #
0046 | _060_imem_read_word()     #
0047 | _060_imem_read_long()     #
0048 | _060_dmem_write_byte()    #
0049 | _060_dmem_write_word()    #
0050 | _060_dmem_write_long()    #
0051 |               #
0052 | _060_real_trace()     #
0053 | _060_real_access()        #
0054 |################################
0055 
0056 |
0057 | Each IO routine checks to see if the memory write/read is to/from user
0058 | or supervisor application space. The examples below use simple "move"
0059 | instructions for supervisor mode applications and call _copyin()/_copyout()
0060 | for user mode applications.
0061 | When installing the 060SP, the _copyin()/_copyout() equivalents for a
0062 | given operating system should be substituted.
0063 |
0064 | The addresses within the 060SP are guaranteed to be on the stack.
0065 | The result is that Unix processes are allowed to sleep as a consequence
0066 | of a page fault during a _copyout.
0067 |
0068 | Linux/68k: The _060_[id]mem_{read,write}_{byte,word,long} functions
0069 | (i.e. all the known length <= 4) are implemented by single moves
0070 | statements instead of (more expensive) copy{in,out} calls, if
0071 | working in user space
0072 
0073 |
0074 | _060_dmem_write():
0075 |
0076 | Writes to data memory while in supervisor mode.
0077 |
0078 | INPUTS:
0079 |   a0 - supervisor source address
0080 |   a1 - user destination address
0081 |   d0 - number of bytes to write
0082 |   0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
0083 | OUTPUTS:
0084 |   d1 - 0 = success, !0 = failure
0085 |
0086     .global     _060_dmem_write
0087 _060_dmem_write:
0088     subq.l      #1,%d0
0089     btst        #0x5,0x4(%a6)       | check for supervisor state
0090     beqs        user_write
0091 super_write:
0092     move.b      (%a0)+,(%a1)+       | copy 1 byte
0093     dbra        %d0,super_write     | quit if --ctr < 0
0094     clr.l       %d1         | return success
0095     rts
0096 user_write:
0097     move.b      (%a0)+,%d1      | copy 1 byte
0098 copyoutae:
0099     movs.b      %d1,(%a1)+
0100     dbra        %d0,user_write      | quit if --ctr < 0
0101     clr.l       %d1         | return success
0102     rts
0103 
0104 |
0105 | _060_imem_read(), _060_dmem_read():
0106 |
0107 | Reads from data/instruction memory while in supervisor mode.
0108 |
0109 | INPUTS:
0110 |   a0 - user source address
0111 |   a1 - supervisor destination address
0112 |   d0 - number of bytes to read
0113 |   0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
0114 | OUTPUTS:
0115 |   d1 - 0 = success, !0 = failure
0116 |
0117     .global     _060_imem_read
0118     .global     _060_dmem_read
0119 _060_imem_read:
0120 _060_dmem_read:
0121     subq.l      #1,%d0
0122     btst        #0x5,0x4(%a6)       | check for supervisor state
0123     beqs        user_read
0124 super_read:
0125     move.b      (%a0)+,(%a1)+       | copy 1 byte
0126     dbra        %d0,super_read      | quit if --ctr < 0
0127     clr.l       %d1         | return success
0128     rts
0129 user_read:
0130 copyinae:
0131     movs.b      (%a0)+,%d1
0132     move.b      %d1,(%a1)+      | copy 1 byte
0133     dbra        %d0,user_read       | quit if --ctr < 0
0134     clr.l       %d1         | return success
0135     rts
0136 
0137 |
0138 | _060_dmem_read_byte():
0139 |
0140 | Read a data byte from user memory.
0141 |
0142 | INPUTS:
0143 |   a0 - user source address
0144 |   0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
0145 | OUTPUTS:
0146 |   d0 - data byte in d0
0147 |   d1 - 0 = success, !0 = failure
0148 |
0149     .global     _060_dmem_read_byte
0150 _060_dmem_read_byte:
0151     clr.l       %d0         | clear whole longword
0152     clr.l       %d1         | assume success
0153     btst        #0x5,0x4(%a6)       | check for supervisor state
0154     bnes        dmrbs           | supervisor
0155 dmrbuae:movs.b      (%a0),%d0       | fetch user byte
0156     rts
0157 dmrbs:  move.b      (%a0),%d0       | fetch super byte
0158     rts
0159 
0160 |
0161 | _060_dmem_read_word():
0162 |
0163 | Read a data word from user memory.
0164 |
0165 | INPUTS:
0166 |   a0 - user source address
0167 |   0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
0168 | OUTPUTS:
0169 |   d0 - data word in d0
0170 |   d1 - 0 = success, !0 = failure
0171 |
0172 | _060_imem_read_word():
0173 |
0174 | Read an instruction word from user memory.
0175 |
0176 | INPUTS:
0177 |   a0 - user source address
0178 |   0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
0179 | OUTPUTS:
0180 |   d0 - instruction word in d0
0181 |   d1 - 0 = success, !0 = failure
0182 |
0183     .global     _060_dmem_read_word
0184     .global     _060_imem_read_word
0185 _060_dmem_read_word:
0186 _060_imem_read_word:
0187     clr.l       %d1         | assume success
0188     clr.l       %d0         | clear whole longword
0189     btst        #0x5,0x4(%a6)       | check for supervisor state
0190     bnes        dmrws           | supervisor
0191 dmrwuae:movs.w      (%a0), %d0      | fetch user word
0192     rts
0193 dmrws:  move.w      (%a0), %d0      | fetch super word
0194     rts
0195 
0196 |
0197 | _060_dmem_read_long():
0198 |
0199 
0200 |
0201 | INPUTS:
0202 |   a0 - user source address
0203 |   0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
0204 | OUTPUTS:
0205 |   d0 - data longword in d0
0206 |   d1 - 0 = success, !0 = failure
0207 |
0208 | _060_imem_read_long():
0209 |
0210 | Read an instruction longword from user memory.
0211 |
0212 | INPUTS:
0213 |   a0 - user source address
0214 |   0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
0215 | OUTPUTS:
0216 |   d0 - instruction longword in d0
0217 |   d1 - 0 = success, !0 = failure
0218 |
0219     .global     _060_dmem_read_long
0220     .global     _060_imem_read_long
0221 _060_dmem_read_long:
0222 _060_imem_read_long:
0223     clr.l       %d1         | assume success
0224     btst        #0x5,0x4(%a6)       | check for supervisor state
0225     bnes        dmrls           | supervisor
0226 dmrluae:movs.l      (%a0),%d0       | fetch user longword
0227     rts
0228 dmrls:  move.l      (%a0),%d0       | fetch super longword
0229     rts
0230 
0231 |
0232 | _060_dmem_write_byte():
0233 |
0234 | Write a data byte to user memory.
0235 |
0236 | INPUTS:
0237 |   a0 - user destination address
0238 |   d0 - data byte in d0
0239 |   0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
0240 | OUTPUTS:
0241 |   d1 - 0 = success, !0 = failure
0242 |
0243     .global     _060_dmem_write_byte
0244 _060_dmem_write_byte:
0245     clr.l       %d1         | assume success
0246     btst        #0x5,0x4(%a6)       | check for supervisor state
0247     bnes        dmwbs           | supervisor
0248 dmwbuae:movs.b      %d0,(%a0)       | store user byte
0249     rts
0250 dmwbs:  move.b      %d0,(%a0)       | store super byte
0251     rts
0252 
0253 |
0254 | _060_dmem_write_word():
0255 |
0256 | Write a data word to user memory.
0257 |
0258 | INPUTS:
0259 |   a0 - user destination address
0260 |   d0 - data word in d0
0261 |   0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
0262 | OUTPUTS:
0263 |   d1 - 0 = success, !0 = failure
0264 |
0265     .global     _060_dmem_write_word
0266 _060_dmem_write_word:
0267     clr.l       %d1         | assume success
0268     btst        #0x5,0x4(%a6)       | check for supervisor state
0269     bnes        dmwws           | supervisor
0270 dmwwu:
0271 dmwwuae:movs.w      %d0,(%a0)       | store user word
0272     bras        dmwwr
0273 dmwws:  move.w      %d0,(%a0)       | store super word
0274 dmwwr:  clr.l       %d1         | return success
0275     rts
0276 
0277 |
0278 | _060_dmem_write_long():
0279 |
0280 | Write a data longword to user memory.
0281 |
0282 | INPUTS:
0283 |   a0 - user destination address
0284 |   d0 - data longword in d0
0285 |   0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
0286 | OUTPUTS:
0287 |   d1 - 0 = success, !0 = failure
0288 |
0289     .global     _060_dmem_write_long
0290 _060_dmem_write_long:
0291     clr.l       %d1         | assume success
0292     btst        #0x5,0x4(%a6)       | check for supervisor state
0293     bnes        dmwls           | supervisor
0294 dmwluae:movs.l      %d0,(%a0)       | store user longword
0295     rts
0296 dmwls:  move.l      %d0,(%a0)       | store super longword
0297     rts
0298 
0299 
0300 #if 0
0301 |###############################################
0302 
0303 |
0304 | Use these routines if your kernel doesn't have _copyout/_copyin equivalents.
0305 | Assumes that D0/D1/A0/A1 are scratch registers. The _copyin/_copyout
0306 | below assume that the SFC/DFC have been set previously.
0307 |
0308 | Linux/68k: These are basically non-inlined versions of
0309 | memcpy_{to,from}fs, but without long-transfer optimization
0310 | Note: Assumed that SFC/DFC are pointing correctly to user data
0311 | space... Should be right, or are there any exceptions?
0312 
0313 |
0314 | int _copyout(supervisor_addr, user_addr, nbytes)
0315 |
0316     .global     _copyout
0317 _copyout:
0318     move.l      4(%sp),%a0      | source
0319     move.l      8(%sp),%a1      | destination
0320     move.l      12(%sp),%d0     | count
0321     subq.l      #1,%d0
0322 moreout:
0323     move.b      (%a0)+,%d1      | fetch supervisor byte
0324 copyoutae:
0325     movs.b      %d1,(%a1)+      | store user byte
0326     dbra        %d0,moreout     | are we through yet?
0327     moveq       #0,%d0          | return success
0328     rts
0329 
0330 |
0331 | int _copyin(user_addr, supervisor_addr, nbytes)
0332 |
0333     .global     _copyin
0334 _copyin:
0335     move.l      4(%sp),%a0      | source
0336     move.l      8(%sp),%a1      | destination
0337     move.l      12(%sp),%d0     | count
0338     subq.l      #1,%d0
0339 morein:
0340 copyinae:
0341     movs.b      (%a0)+,%d1      | fetch user byte
0342     move.b      %d1,(%a1)+      | write supervisor byte
0343     dbra        %d0,morein      | are we through yet?
0344     moveq       #0,%d0          | return success
0345     rts
0346 #endif
0347 
0348 |###########################################################################
0349 
0350 |
0351 | _060_real_trace():
0352 |
0353 | This is the exit point for the 060FPSP when an instruction is being traced
0354 | and there are no other higher priority exceptions pending for this instruction
0355 | or they have already been processed.
0356 |
0357 | The sample code below simply executes an "rte".
0358 |
0359     .global     _060_real_trace
0360 _060_real_trace:
0361     bral    trap
0362 
0363 |
0364 | _060_real_access():
0365 |
0366 | This is the exit point for the 060FPSP when an access error exception
0367 | is encountered. The routine below should point to the operating system
0368 | handler for access error exceptions. The exception stack frame is an
0369 | 8-word access error frame.
0370 |
0371 | The sample routine below simply executes an "rte" instruction which
0372 | is most likely the incorrect thing to do and could put the system
0373 | into an infinite loop.
0374 |
0375     .global     _060_real_access
0376 _060_real_access:
0377     bral    buserr
0378 
0379 
0380 
0381 | Execption handling for movs access to illegal memory
0382     .section .fixup,#alloc,#execinstr
0383     .even
0384 1:  moveq       #-1,%d1
0385     rts
0386 .section __ex_table,#alloc
0387     .align 4
0388     .long   dmrbuae,1b
0389     .long   dmrwuae,1b
0390     .long   dmrluae,1b
0391     .long   dmwbuae,1b
0392     .long   dmwwuae,1b
0393     .long   dmwluae,1b
0394     .long   copyoutae,1b
0395     .long   copyinae,1b
0396     .text