linux/arch/m68k/ifpsp060/os.S
<<
>>
Prefs
   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
  91super_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
  96user_write:
  97        move.b          (%a0)+,%d1              | copy 1 byte
  98copyoutae:
  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
 124super_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
 129user_read:
 130copyinae:
 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
 155dmrbuae:movs.b          (%a0),%d0               | fetch user byte
 156        rts
 157dmrbs:  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
 191dmrwuae:movs.w          (%a0), %d0              | fetch user word
 192        rts
 193dmrws:  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
 226dmrluae:movs.l          (%a0),%d0               | fetch user longword
 227        rts
 228dmrls:  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
 248dmwbuae:movs.b          %d0,(%a0)               | store user byte
 249        rts
 250dmwbs:  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
 270dmwwu:
 271dmwwuae:movs.w          %d0,(%a0)               | store user word
 272        bras            dmwwr
 273dmwws:  move.w          %d0,(%a0)               | store super word
 274dmwwr:  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
 294dmwluae:movs.l          %d0,(%a0)               | store user longword
 295        rts
 296dmwls:  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
 322moreout:
 323        move.b          (%a0)+,%d1              | fetch supervisor byte
 324copyoutae:
 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
 339morein:
 340copyinae:
 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
 3841:      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
 397