os.S (10552B)
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