patch-1.3.94 linux/arch/m68k/ifpsp060/os.S
Next file: linux/arch/m68k/ifpsp060/pfpsp.sa
Previous file: linux/arch/m68k/ifpsp060/itest.sa
Back to the patch index
Back to the overall index
- Lines: 433
- Date:
Sun Feb 18 19:33:51 1996
- Orig file:
v1.3.93/linux/arch/m68k/ifpsp060/os.S
- Orig date:
Thu Jan 1 02:00:00 1970
diff -u --recursive --new-file v1.3.93/linux/arch/m68k/ifpsp060/os.S linux/arch/m68k/ifpsp060/os.S
@@ -0,0 +1,432 @@
+|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+|MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
+|M68000 Hi-Performance Microprocessor Division
+|M68060 Software Package
+|Production Release P1.00 -- October 10, 1994
+|
+|M68060 Software Package Copyright © 1993, 1994 Motorola Inc. All rights reserved.
+|
+|THE SOFTWARE is provided on an "AS IS" basis and without warranty.
+|To the maximum extent permitted by applicable law,
+|MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
+|INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+|and any warranty against infringement with regard to the SOFTWARE
+|(INCLUDING ANY MODIFIED VERSIONS THEREOF) and any accompanying written materials.
+|
+|To the maximum extent permitted by applicable law,
+|IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
+|(INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
+|BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS)
+|ARISING OF THE USE OR INABILITY TO USE THE SOFTWARE.
+|Motorola assumes no responsibility for the maintenance and support of the SOFTWARE.
+|
+|You are hereby granted a copyright license to use, modify, and distribute the SOFTWARE
+|so long as this entire notice is retained without alteration in any modified and/or
+|redistributed versions, and that such modified versions are clearly identified as such.
+|No licenses are granted by implication, estoppel or otherwise under any patents
+|or trademarks of Motorola, Inc.
+|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+| os.s
+|
+| This file contains:
+| - example "Call-Out"s required by both the ISP and FPSP.
+|
+
+
+|################################
+| EXAMPLE CALL-OUTS #
+| #
+| _060_dmem_write() #
+| _060_dmem_read() #
+| _060_imem_read() #
+| _060_dmem_read_byte() #
+| _060_dmem_read_word() #
+| _060_dmem_read_long() #
+| _060_imem_read_word() #
+| _060_imem_read_long() #
+| _060_dmem_write_byte() #
+| _060_dmem_write_word() #
+| _060_dmem_write_long() #
+| #
+| _060_real_trace() #
+| _060_real_access() #
+|################################
+
+|
+| Each IO routine checks to see if the memory write/read is to/from user
+| or supervisor application space. The examples below use simple "move"
+| instructions for supervisor mode applications and call _copyin()/_copyout()
+| for user mode applications.
+| When installing the 060SP, the _copyin()/_copyout() equivalents for a
+| given operating system should be substituted.
+|
+| The addresses within the 060SP are guaranteed to be on the stack.
+| The result is that Unix processes are allowed to sleep as a consequence
+| of a page fault during a _copyout.
+|
+
+|
+| _060_dmem_write():
+|
+| Writes to data memory while in supervisor mode.
+|
+| INPUTS:
+| a0 - supervisor source address
+| a1 - user destination address
+| d0 - number of bytes to write
+| 0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
+| OUTPUTS:
+| d1 - 0 = success, !0 = failure
+|
+ .global _060_dmem_write
+_060_dmem_write:
+ btst #0x5,0x4(%a6) | check for supervisor state
+ beqs user_write
+super_write:
+ move.b (%a0)+,(%a1)+ | copy 1 byte
+ subq.l #0x1,%d0 | decr byte counter
+ bnes super_write | quit if ctr = 0
+ clr.l %d1 | return success
+ rts
+user_write:
+ move.l %d0,-(%sp) | pass: counter
+ move.l %a1,-(%sp) | pass: user dst
+ move.l %a0,-(%sp) | pass: supervisor src
+ bsr.l _copyout | write byte to user mem
+ move.l %d0,%d1 | return success
+ add.l #0xc, %sp | clear 3 lw params
+ rts
+
+|
+| _060_imem_read(), _060_dmem_read():
+|
+| Reads from data/instruction memory while in supervisor mode.
+|
+| INPUTS:
+| a0 - user source address
+| a1 - supervisor destination address
+| d0 - number of bytes to read
+| 0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
+| OUTPUTS:
+| d1 - 0 = success, !0 = failure
+|
+ .global _060_imem_read
+ .global _060_dmem_read
+_060_imem_read:
+_060_dmem_read:
+ btst #0x5,0x4(%a6) | check for supervisor state
+ beqs user_read
+super_read:
+ move.b (%a0)+,(%a1)+ | copy 1 byte
+ subq.l #0x1,%d0 | decr byte counter
+ bnes super_read | quit if ctr = 0
+ clr.l %d1 | return success
+ rts
+user_read:
+ move.l %d0,-(%sp) | pass: counter
+ move.l %a1,-(%sp) | pass: super dst
+ move.l %a0,-(%sp) | pass: user src
+ bsr.l _copyin | read byte from user mem
+ move.l %d0,%d1 | return success
+ add.l #0xc,%sp | clear 3 lw params
+ rts
+
+|
+| _060_dmem_read_byte():
+|
+| Read a data byte from user memory.
+|
+| INPUTS:
+| a0 - user source address
+| 0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
+| OUTPUTS:
+| d0 - data byte in d0
+| d1 - 0 = success, !0 = failure
+|
+ .global _060_dmem_read_byte
+_060_dmem_read_byte:
+ btst #0x5,0x4(%a6) | check for supervisor state
+ bnes dmrbs | supervisor
+dmrbu: clr.l -(%sp) | clear space on stack for result
+ move.l #0x1,-(%sp) | pass: # bytes to copy
+ pea 0x7(%sp) | pass: dst addr (stack)
+ move.l %a0,-(%sp) | pass: src addr (user mem)
+ bsr.l _copyin | "copy in" the data
+ move.l %d0,%d1 | return success
+ add.l #0xc,%sp | delete params
+ move.l (%sp)+,%d0 | put answer in d0
+ rts
+dmrbs: clr.l %d0 | clear whole longword
+ move.b (%a0),%d0 | fetch super byte
+ clr.l %d1 | return success
+ rts
+
+|
+| _060_dmem_read_word():
+|
+| Read a data word from user memory.
+|
+| INPUTS:
+| a0 - user source address
+| 0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
+| OUTPUTS:
+| d0 - data word in d0
+| d1 - 0 = success, !0 = failure
+|
+ .global _060_dmem_read_word
+_060_dmem_read_word:
+ btst #0x5,0x4(%a6) | check for supervisor state
+ bnes dmrws | supervisor
+dmrwu: clr.l -(%sp) | clear space on stack for result
+ move.l #0x2,-(%sp) | pass: # bytes to copy
+ pea 0x6(%sp) | pass: dst addr (stack)
+ move.l %a0,-(%sp) | pass: src addr (user mem)
+ bsr.l _copyin | "copy in" the data
+ move.l %d0,%d1 | return success
+ add.l #0xc,%sp | delete params
+ move.l (%sp)+,%d0 | put answer in d0
+ rts
+dmrws: clr.l %d0 | clear whole longword
+ move.w (%a0), %d0 | fetch super word
+ clr.l %d1 | return success
+ rts
+
+|
+| _060_dmem_read_long():
+|
+
+|
+| INPUTS:
+| a0 - user source address
+| 0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
+| OUTPUTS:
+| d0 - data longword in d0
+| d1 - 0 = success, !0 = failure
+|
+ .global _060_dmem_read_long
+_060_dmem_read_long:
+ btst #0x5,0x4(%a6) | check for supervisor state
+ bnes dmrls | supervisor
+dmrlu: subq.l #0x4,%sp | clear space on stack for result
+ move.l #0x4,-(%sp) | pass: # bytes to copy
+ pea 0x4(%sp) | pass: dst addr (stack)
+ move.l %a0,-(%sp) | pass: src addr (user mem)
+ bsr.l _copyin | "copy in" the data
+ move.l %d0,%d1 | return success
+ add.l #0xc,%sp | delete params
+ move.l (%sp)+,%d0 | put answer in d0
+ rts
+dmrls: move.l (%a0),%d0 | fetch super longword
+ clr.l %d1 | return success
+ rts
+
+|
+| _060_dmem_write_byte():
+|
+| Write a data byte to user memory.
+|
+| INPUTS:
+| a0 - user destination address
+| d0 - data byte in d0
+| 0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
+| OUTPUTS:
+| d1 - 0 = success, !0 = failure
+|
+ .global _060_dmem_write_byte
+_060_dmem_write_byte:
+ btst #0x5,0x4(%a6) | check for supervisor state
+ bnes dmwbs | supervisor
+dmwbu: move.l %d0,-(%sp) | put src on stack
+ move.l #0x1,-(%sp) | pass: # bytes to copy
+ move.l %a0,-(%sp) | pass: dst addr (user mem)
+ pea 0xb(%sp) | pass: src addr (stack)
+ bsr.l _copyout | "copy out" the data
+ move.l %d0,%d1 | return success
+ add.l #0x10,%sp | delete params + src
+ rts
+dmwbs: move.b %d0,(%a0) | store super byte
+ clr.l %d1 | return success
+ rts
+
+|
+| _060_dmem_write_word():
+|
+| Write a data word to user memory.
+|
+| INPUTS:
+| a0 - user destination address
+| d0 - data word in d0
+| 0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
+| OUTPUTS:
+| d1 - 0 = success, !0 = failure
+|
+ .global _060_dmem_write_word
+_060_dmem_write_word:
+ btst #0x5,0x4(%a6) | check for supervisor state
+ bnes dmwws | supervisor
+dmwwu: move.l %d0,-(%sp) | put src on stack
+ move.l #0x2,-(%sp) | pass: # bytes to copy
+ move.l %a0,-(%sp) | pass: dst addr (user mem)
+ pea 0xa(%sp) | pass: src addr (stack)
+ bsr.l _copyout | "copy out" the data
+ move.l %d0,%d1 | return success
+ add.l #0x10,%sp | delete params + src
+ rts
+dmwws: move.w %d0,(%a0) | store super word
+ clr.l %d1 | return success
+ rts
+
+|
+| _060_dmem_write_long():
+|
+| Write a data longword to user memory.
+|
+| INPUTS:
+| a0 - user destination address
+| d0 - data longword in d0
+| 0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
+| OUTPUTS:
+| d1 - 0 = success, !0 = failure
+|
+ .global _060_dmem_write_long
+_060_dmem_write_long:
+ btst #0x5,0x4(%a6) | check for supervisor state
+ bnes dmwls | supervisor
+dmwlu: move.l %d0,-(%sp) | put src on stack
+ move.l #0x4,-(%sp) | pass: # bytes to copy
+ move.l %a0,-(%sp) | pass: dst addr (user mem)
+ pea 0x8(%sp) | pass: src addr (stack)
+ bsr.l _copyout | "copy out" the data
+ move.l %d0,%d1 | return success
+ add.l #0x10,%sp | delete params + src
+ rts
+dmwls: move.l %d0,(%a0) | store super longword
+ clr.l %d1 | return success
+ rts
+
+|
+| _060_imem_read_word():
+|
+| Read an instruction word from user memory.
+|
+| INPUTS:
+| a0 - user source address
+| 0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
+| OUTPUTS:
+| d0 - instruction word in d0
+| d1 - 0 = success, !0 = failure
+|
+ .global _060_imem_read_word
+_060_imem_read_word:
+ btst #0x5,0x4(%a6) | check for supervisor state
+ bnes imrws | supervisor
+imrwu: clr.l -(%sp) | clear space on stack for result
+ move.l #0x2,-(%sp) | pass: # bytes to copy
+ pea 0x6(%sp) | pass: dst addr (stack)
+ move.l %a0,-(%sp) | pass: src addr (user mem)
+ bsr.l _copyin | "copy in" the data
+ move.l %d0,%d1 | return success
+ add.l #0xc,%sp | delete params
+ move.l (%sp)+,%d0 | put answer in d0
+ rts
+imrws: move.w (%a0),%d0 | fetch super word
+ clr.l %d1 | return success
+ rts
+
+|
+| _060_imem_read_long():
+|
+| Read an instruction longword from user memory.
+|
+| INPUTS:
+| a0 - user source address
+| 0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode
+| OUTPUTS:
+| d0 - instruction longword in d0
+| d1 - 0 = success, !0 = failure
+|
+ .global _060_imem_read_long
+_060_imem_read_long:
+ btst #0x5,0x4(%a6) | check for supervisor state
+ bnes imrls | supervisor
+imrlu: subq.l #0x4,%sp | clear space on stack for result
+ move.l #0x4,-(%sp) | pass: # bytes to copy
+ pea 0x4(%sp) | pass: dst addr (stack)
+ move.l %a0,-(%sp) | pass: src addr (user mem)
+ bsr.l _copyin | "copy in" the data
+ move.l %d0,%d1 | return success
+ add.l #0xc,%sp | delete params
+ move.l (%sp)+,%d0 | put answer in d0
+ rts
+imrls: move.l (%a0),%d0 | fetch super longword
+ clr.l %d1 | return success
+ rts
+
+|###############################################
+
+|
+| Use these routines if your kernel doesn't have _copyout/_copyin equivalents.
+| Assumes that D0/D1/A0/A1 are scratch registers. The _copyin/_copyout
+| below assume that the SFC/DFC have been set previously.
+|
+
+|
+| int _copyout(supervisor_addr, user_addr, nbytes)
+|
+ .global _copyout
+_copyout:
+ move.l 4(%sp),%a0 | source
+ move.l 8(%sp),%a1 | destination
+ move.l 12(%sp),%d0 | count
+moreout:
+ move.b (%a0)+,%d1 | fetch supervisor byte
+ movs.b %d1,(%a1)+ | store user byte
+ subq.l #0x1,%d0 | are we through yet?
+ bne moreout | no; so, continue
+ rts
+
+|
+| int _copyin(user_addr, supervisor_addr, nbytes)
+|
+ .global _copyin
+_copyin:
+ move.l 4(%sp),%a0 | source
+ move.l 8(%sp),%a1 | destination
+ move.l 12(%sp),%d0 | count
+morein:
+ movs.b (%a0)+,%d1 | fetch user byte
+ move.b %d1,(%a1)+ | write supervisor byte
+ subq.l #0x1,%d0 | are we through yet?
+ bne morein | no; so, continue
+ rts
+
+|###########################################################################
+
+|
+| _060_real_trace():
+|
+| This is the exit point for the 060FPSP when an instruction is being traced
+| and there are no other higher priority exceptions pending for this instruction
+| or they have already been processed.
+|
+| The sample code below simply executes an "rte".
+|
+ .global _060_real_trace
+_060_real_trace:
+ rte
+
+|
+| _060_real_access():
+|
+| This is the exit point for the 060FPSP when an access error exception
+| is encountered. The routine below should point to the operating system
+| handler for access error exceptions. The exception stack frame is an
+| 8-word access error frame.
+|
+| The sample routine below simply executes an "rte" instruction which
+| is most likely the incorrect thing to do and could put the system
+| into an infinite loop.
+|
+ .global _060_real_access
+_060_real_access:
+ rte
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this