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