1 # 2 # $NetBSD: os.s,v 1.1 2000/04/14 20:24:39 is Exp $ 3 # 4 5 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 6 # MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP 7 # M68000 Hi-Performance Microprocessor Division 8 # M68060 Software Package Production Release 9 # 10 # M68060 Software Package Copyright (C) 1993, 1994, 1995, 1996 Motorola Inc. 11 # All rights reserved. 12 # 13 # THE SOFTWARE is provided on an "AS IS" basis and without warranty. 14 # To the maximum extent permitted by applicable law, 15 # MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, 16 # INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS 17 # FOR A PARTICULAR PURPOSE and any warranty against infringement with 18 # regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF) 19 # and any accompanying written materials. 20 # 21 # To the maximum extent permitted by applicable law, 22 # IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER 23 # (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, 24 # BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) 25 # ARISING OF THE USE OR INABILITY TO USE THE SOFTWARE. 26 # 27 # Motorola assumes no responsibility for the maintenance and support 28 # of the SOFTWARE. 29 # 30 # You are hereby granted a copyright license to use, modify, and distribute the 31 # SOFTWARE so long as this entire notice is retained without alteration 32 # in any modified and/or redistributed versions, and that such modified 33 # versions are clearly identified as such. 34 # No licenses are granted by implication, estoppel or otherwise under any 35 # patents or trademarks of Motorola, Inc. 36 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 38 # 39 # os.s 40 # 41 # This file contains: 42 # - example "Call-Out"s required by both the ISP and FPSP. 43 # 44 45 46 ################################# 47 # EXAMPLE CALL-OUTS # 48 # # 49 # _060_dmem_write() # 50 # _060_dmem_read() # 51 # _060_imem_read() # 52 # _060_dmem_read_byte() # 53 # _060_dmem_read_word() # 54 # _060_dmem_read_long() # 55 # _060_imem_read_word() # 56 # _060_imem_read_long() # 57 # _060_dmem_write_byte() # 58 # _060_dmem_write_word() # 59 # _060_dmem_write_long() # 60 # # 61 # _060_real_trace() # 62 # _060_real_access() # 63 ################################# 64 65 # 66 # Each IO routine checks to see if the memory write/read is to/from user 67 # or supervisor application space. The examples below use simple "move" 68 # instructions for supervisor mode applications and call _copyin()/_copyout() 69 # for user mode applications. 70 # When installing the 060SP, the _copyin()/_copyout() equivalents for a 71 # given operating system should be substituted. 72 # 73 # The addresses within the 060SP are guaranteed to be on the stack. 74 # The result is that Unix processes are allowed to sleep as a consequence 75 # of a page fault during a _copyout. 76 # 77 78 # 79 # _060_dmem_write(): 80 # 81 # Writes to data memory while in supervisor mode. 82 # 83 # INPUTS: 84 # a0 - supervisor source address 85 # a1 - user destination address 86 # d0 - number of bytes to write 87 # 0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode 88 # OUTPUTS: 89 # d1 - 0 = success, !0 = failure 90 # 91 global _060_dmem_write 92 _060_dmem_write: 93 btst &0x5,0x4(%a6) # check for supervisor state 94 beq.b user_write 95 super_write: 96 mov.b (%a0)+,(%a1)+ # copy 1 byte 97 subq.l &0x1,%d0 # decr byte counter 98 bne.b super_write # quit if ctr = 0 99 clr.l %d1 # return success 100 rts 101 user_write: 102 mov.l %d0,-(%sp) # pass: counter 103 mov.l %a1,-(%sp) # pass: user dst 104 mov.l %a0,-(%sp) # pass: supervisor src 105 bsr.l _copyout # write byte to user mem 106 mov.l %d0,%d1 # return success 107 add.l &0xc, %sp # clear 3 lw params 108 rts 109 110 # 111 # _060_imem_read(), _060_dmem_read(): 112 # 113 # Reads from data/instruction memory while in supervisor mode. 114 # 115 # INPUTS: 116 # a0 - user source address 117 # a1 - supervisor destination address 118 # d0 - number of bytes to read 119 # 0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode 120 # OUTPUTS: 121 # d1 - 0 = success, !0 = failure 122 # 123 global _060_imem_read 124 global _060_dmem_read 125 _060_imem_read: 126 _060_dmem_read: 127 btst &0x5,0x4(%a6) # check for supervisor state 128 beq.b user_read 129 super_read: 130 mov.b (%a0)+,(%a1)+ # copy 1 byte 131 subq.l &0x1,%d0 # decr byte counter 132 bne.b super_read # quit if ctr = 0 133 clr.l %d1 # return success 134 rts 135 user_read: 136 mov.l %d0,-(%sp) # pass: counter 137 mov.l %a1,-(%sp) # pass: super dst 138 mov.l %a0,-(%sp) # pass: user src 139 bsr.l _copyin # read byte from user mem 140 mov.l %d0,%d1 # return success 141 add.l &0xc,%sp # clear 3 lw params 142 rts 143 144 # 145 # _060_dmem_read_byte(): 146 # 147 # Read a data byte from user memory. 148 # 149 # INPUTS: 150 # a0 - user source address 151 # 0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode 152 # OUTPUTS: 153 # d0 - data byte in d0 154 # d1 - 0 = success, !0 = failure 155 # 156 global _060_dmem_read_byte 157 _060_dmem_read_byte: 158 btst &0x5,0x4(%a6) # check for supervisor state 159 bne.b dmrbs # supervisor 160 dmrbu: clr.l -(%sp) # clear space on stack for result 161 mov.l &0x1,-(%sp) # pass: # bytes to copy 162 pea 0x7(%sp) # pass: dst addr (stack) 163 mov.l %a0,-(%sp) # pass: src addr (user mem) 164 bsr.l _copyin # "copy in" the data 165 mov.l %d0,%d1 # return success 166 add.l &0xc,%sp # delete params 167 mov.l (%sp)+,%d0 # put answer in d0 168 rts 169 dmrbs: clr.l %d0 # clear whole longword 170 mov.b (%a0),%d0 # fetch super byte 171 clr.l %d1 # return success 172 rts 173 174 # 175 # _060_dmem_read_word(): 176 # 177 # Read a data word from user memory. 178 # 179 # INPUTS: 180 # a0 - user source address 181 # 0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode 182 # OUTPUTS: 183 # d0 - data word in d0 184 # d1 - 0 = success, !0 = failure 185 # 186 global _060_dmem_read_word 187 _060_dmem_read_word: 188 btst &0x5,0x4(%a6) # check for supervisor state 189 bne.b dmrws # supervisor 190 dmrwu: clr.l -(%sp) # clear space on stack for result 191 mov.l &0x2,-(%sp) # pass: # bytes to copy 192 pea 0x6(%sp) # pass: dst addr (stack) 193 mov.l %a0,-(%sp) # pass: src addr (user mem) 194 bsr.l _copyin # "copy in" the data 195 mov.l %d0,%d1 # return success 196 add.l &0xc,%sp # delete params 197 mov.l (%sp)+,%d0 # put answer in d0 198 rts 199 dmrws: clr.l %d0 # clear whole longword 200 mov.w (%a0), %d0 # fetch super word 201 clr.l %d1 # return success 202 rts 203 204 # 205 # _060_dmem_read_long(): 206 # 207 208 # 209 # INPUTS: 210 # a0 - user source address 211 # 0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode 212 # OUTPUTS: 213 # d0 - data longword in d0 214 # d1 - 0 = success, !0 = failure 215 # 216 global _060_dmem_read_long 217 _060_dmem_read_long: 218 btst &0x5,0x4(%a6) # check for supervisor state 219 bne.b dmrls # supervisor 220 dmrlu: subq.l &0x4,%sp # clear space on stack for result 221 mov.l &0x4,-(%sp) # pass: # bytes to copy 222 pea 0x4(%sp) # pass: dst addr (stack) 223 mov.l %a0,-(%sp) # pass: src addr (user mem) 224 bsr.l _copyin # "copy in" the data 225 mov.l %d0,%d1 # return success 226 add.l &0xc,%sp # delete params 227 mov.l (%sp)+,%d0 # put answer in d0 228 rts 229 dmrls: mov.l (%a0),%d0 # fetch super longword 230 clr.l %d1 # return success 231 rts 232 233 # 234 # _060_dmem_write_byte(): 235 # 236 # Write a data byte to user memory. 237 # 238 # INPUTS: 239 # a0 - user destination address 240 # d0 - data byte in d0 241 # 0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode 242 # OUTPUTS: 243 # d1 - 0 = success, !0 = failure 244 # 245 global _060_dmem_write_byte 246 _060_dmem_write_byte: 247 btst &0x5,0x4(%a6) # check for supervisor state 248 bne.b dmwbs # supervisor 249 dmwbu: mov.l %d0,-(%sp) # put src on stack 250 mov.l &0x1,-(%sp) # pass: # bytes to copy 251 mov.l %a0,-(%sp) # pass: dst addr (user mem) 252 pea 0xb(%sp) # pass: src addr (stack) 253 bsr.l _copyout # "copy out" the data 254 mov.l %d0,%d1 # return success 255 add.l &0x10,%sp # delete params + src 256 rts 257 dmwbs: mov.b %d0,(%a0) # store super byte 258 clr.l %d1 # return success 259 rts 260 261 # 262 # _060_dmem_write_word(): 263 # 264 # Write a data word to user memory. 265 # 266 # INPUTS: 267 # a0 - user destination address 268 # d0 - data word in d0 269 # 0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode 270 # OUTPUTS: 271 # d1 - 0 = success, !0 = failure 272 # 273 global _060_dmem_write_word 274 _060_dmem_write_word: 275 btst &0x5,0x4(%a6) # check for supervisor state 276 bne.b dmwws # supervisor 277 dmwwu: mov.l %d0,-(%sp) # put src on stack 278 mov.l &0x2,-(%sp) # pass: # bytes to copy 279 mov.l %a0,-(%sp) # pass: dst addr (user mem) 280 pea 0xa(%sp) # pass: src addr (stack) 281 bsr.l _copyout # "copy out" the data 282 mov.l %d0,%d1 # return success 283 add.l &0x10,%sp # delete params + src 284 rts 285 dmwws: mov.w %d0,(%a0) # store super word 286 clr.l %d1 # return success 287 rts 288 289 # 290 # _060_dmem_write_long(): 291 # 292 # Write a data longword to user memory. 293 # 294 # INPUTS: 295 # a0 - user destination address 296 # d0 - data longword in d0 297 # 0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode 298 # OUTPUTS: 299 # d1 - 0 = success, !0 = failure 300 # 301 global _060_dmem_write_long 302 _060_dmem_write_long: 303 btst &0x5,0x4(%a6) # check for supervisor state 304 bne.b dmwls # supervisor 305 dmwlu: mov.l %d0,-(%sp) # put src on stack 306 mov.l &0x4,-(%sp) # pass: # bytes to copy 307 mov.l %a0,-(%sp) # pass: dst addr (user mem) 308 pea 0x8(%sp) # pass: src addr (stack) 309 bsr.l _copyout # "copy out" the data 310 mov.l %d0,%d1 # return success 311 add.l &0x10,%sp # delete params + src 312 rts 313 dmwls: mov.l %d0,(%a0) # store super longword 314 clr.l %d1 # return success 315 rts 316 317 # 318 # _060_imem_read_word(): 319 # 320 # Read an instruction word from user memory. 321 # 322 # INPUTS: 323 # a0 - user source address 324 # 0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode 325 # OUTPUTS: 326 # d0 - instruction word in d0 327 # d1 - 0 = success, !0 = failure 328 # 329 global _060_imem_read_word 330 _060_imem_read_word: 331 btst &0x5,0x4(%a6) # check for supervisor state 332 bne.b imrws # supervisor 333 imrwu: clr.l -(%sp) # clear space on stack for result 334 mov.l &0x2,-(%sp) # pass: # bytes to copy 335 pea 0x6(%sp) # pass: dst addr (stack) 336 mov.l %a0,-(%sp) # pass: src addr (user mem) 337 bsr.l _copyin # "copy in" the data 338 mov.l %d0,%d1 # return success 339 add.l &0xc,%sp # delete params 340 mov.l (%sp)+,%d0 # put answer in d0 341 rts 342 imrws: mov.w (%a0),%d0 # fetch super word 343 clr.l %d1 # return success 344 rts 345 346 # 347 # _060_imem_read_long(): 348 # 349 # Read an instruction longword from user memory. 350 # 351 # INPUTS: 352 # a0 - user source address 353 # 0x4(%a6),bit5 - 1 = supervisor mode, 0 = user mode 354 # OUTPUTS: 355 # d0 - instruction longword in d0 356 # d1 - 0 = success, !0 = failure 357 # 358 global _060_imem_read_long 359 _060_imem_read_long: 360 btst &0x5,0x4(%a6) # check for supervisor state 361 bne.b imrls # supervisor 362 imrlu: subq.l &0x4,%sp # clear space on stack for result 363 mov.l &0x4,-(%sp) # pass: # bytes to copy 364 pea 0x4(%sp) # pass: dst addr (stack) 365 mov.l %a0,-(%sp) # pass: src addr (user mem) 366 bsr.l _copyin # "copy in" the data 367 mov.l %d0,%d1 # return success 368 add.l &0xc,%sp # delete params 369 mov.l (%sp)+,%d0 # put answer in d0 370 rts 371 imrls: mov.l (%a0),%d0 # fetch super longword 372 clr.l %d1 # return success 373 rts 374 375 ################################################ 376 377 # 378 # Use these routines if your kernel doesn't have _copyout/_copyin equivalents. 379 # Assumes that D0/D1/A0/A1 are scratch registers. The _copyin/_copyout 380 # below assume that the SFC/DFC have been set previously. 381 # 382 383 # 384 # int _copyout(supervisor_addr, user_addr, nbytes) 385 # 386 global _copyout 387 _copyout: 388 mov.l 4(%sp),%a0 # source 389 mov.l 8(%sp),%a1 # destination 390 mov.l 12(%sp),%d0 # count 391 moreout: 392 mov.b (%a0)+,%d1 # fetch supervisor byte 393 movs.b %d1,(%a1)+ # store user byte 394 subq.l &0x1,%d0 # are we through yet? 395 bne.w moreout # no; so, continue 396 rts 397 398 # 399 # int _copyin(user_addr, supervisor_addr, nbytes) 400 # 401 global _copyin 402 _copyin: 403 mov.l 4(%sp),%a0 # source 404 mov.l 8(%sp),%a1 # destination 405 mov.l 12(%sp),%d0 # count 406 morein: 407 movs.b (%a0)+,%d1 # fetch user byte 408 mov.b %d1,(%a1)+ # write supervisor byte 409 subq.l &0x1,%d0 # are we through yet? 410 bne.w morein # no; so, continue 411 rts 412 413 ############################################################################ 414 415 # 416 # _060_real_trace(): 417 # 418 # This is the exit point for the 060FPSP when an instruction is being traced 419 # and there are no other higher priority exceptions pending for this instruction 420 # or they have already been processed. 421 # 422 # The sample code below simply executes an "rte". 423 # 424 global _060_real_trace 425 _060_real_trace: 426 rte 427 428 # 429 # _060_real_access(): 430 # 431 # This is the exit point for the 060FPSP when an access error exception 432 # is encountered. The routine below should point to the operating system 433 # handler for access error exceptions. The exception stack frame is an 434 # 8-word access error frame. 435 # 436 # The sample routine below simply executes an "rte" instruction which 437 # is most likely the incorrect thing to do and could put the system 438 # into an infinite loop. 439 # 440 global _060_real_access 441 _060_real_access: 442 rte 443