Annotation of sys/arch/mvme68k/mvme68k/locore.s, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: locore.s,v 1.54 2007/05/15 13:46:22 martin Exp $ */
! 2:
! 3: /*
! 4: * Copyright (c) 1995 Theo de Raadt
! 5: * Copyright (c) 1999 Steve Murphree, Jr. (68060 support)
! 6: *
! 7: * Redistribution and use in source and binary forms, with or without
! 8: * modification, are permitted provided that the following conditions
! 9: * are met:
! 10: * 1. Redistributions of source code must retain the above copyright
! 11: * notice, this list of conditions and the following disclaimer.
! 12: * 2. Redistributions in binary form must reproduce the above copyright
! 13: * notice, this list of conditions and the following disclaimer in the
! 14: * documentation and/or other materials provided with the distribution.
! 15: *
! 16: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
! 17: * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
! 18: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 19: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
! 20: * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 21: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 22: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 23: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 24: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 25: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 26: * SUCH DAMAGE.
! 27: *
! 28: * Copyright (c) 1988 University of Utah.
! 29: * Copyright (c) 1980, 1990, 1993
! 30: * The Regents of the University of California. All rights reserved.
! 31: *
! 32: * This code is derived from software contributed to Berkeley by
! 33: * the Systems Programming Group of the University of Utah Computer
! 34: * Science Department.
! 35: *
! 36: * Redistribution and use in source and binary forms, with or without
! 37: * modification, are permitted provided that the following conditions
! 38: * are met:
! 39: * 1. Redistributions of source code must retain the above copyright
! 40: * notice, this list of conditions and the following disclaimer.
! 41: * 2. Redistributions in binary form must reproduce the above copyright
! 42: * notice, this list of conditions and the following disclaimer in the
! 43: * documentation and/or other materials provided with the distribution.
! 44: * 3. Neither the name of the University nor the names of its contributors
! 45: * may be used to endorse or promote products derived from this software
! 46: * without specific prior written permission.
! 47: *
! 48: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
! 49: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 50: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 51: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 52: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 53: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 54: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 55: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 56: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 57: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 58: * SUCH DAMAGE.
! 59: *
! 60: * from: Utah $Hdr: locore.s 1.66 92/12/22$
! 61: *
! 62: * @(#)locore.s 8.6 (Berkeley) 5/27/94
! 63: */
! 64:
! 65: #include "assym.h"
! 66: #include "ksyms.h"
! 67: #include <machine/asm.h>
! 68: #include <machine/prom.h>
! 69: #include <machine/trap.h>
! 70:
! 71: /*
! 72: * Relocate a symbol, used before MMU is enabled.
! 73: */
! 74: #define _RELOC(var, ar) \
! 75: lea var,ar
! 76:
! 77: #define RELOC(var, ar) _RELOC(_C_LABEL(var), ar)
! 78: #define ASRELOC(var, ar) _RELOC(_ASM_LABEL(var), ar)
! 79:
! 80: /*
! 81: * Invoke a BUG routine.
! 82: */
! 83: #define BUGCALL(id) \
! 84: trap #15; \
! 85: .short id
! 86:
! 87: /*
! 88: * Temporary stack for a variety of purposes.
! 89: * Try and make this the first thing is the data segment so it
! 90: * is page aligned. Note that if we overflow here, we run into
! 91: * our text segment.
! 92: */
! 93: .data
! 94: .space NBPG
! 95: ASLOCAL(tmpstk)
! 96:
! 97: /*
! 98: * Initialization
! 99: *
! 100: * The bootstrap loader loads us in starting at 0, and VBR is non-zero.
! 101: * On entry, args on stack are boot device, boot filename, console unit,
! 102: * boot flags (howto), boot device name, filesystem type name.
! 103: */
! 104: BSS(esym, 4)
! 105: BSS(emini, 4)
! 106: BSS(smini, 4)
! 107: BSS(promvbr, 4)
! 108: BSS(promcall, 4)
! 109:
! 110: .text
! 111: /*
! 112: GLOBAL(edata)
! 113: GLOBAL(etext)
! 114: GLOBAL(end)
! 115: */
! 116: GLOBAL(kernel_text)
! 117:
! 118: ASENTRY_NOPROFILE(start)
! 119: movw #PSL_HIGHIPL,sr | no interrupts
! 120: movl sp@(4), d7 | get boothowto
! 121: movl sp@(8), d6 | get bootaddr
! 122: movl sp@(12),d5 | get bootctrllun
! 123: movl sp@(16),d4 | get bootdevlun
! 124: movl sp@(20),d3 | get bootpart
! 125: movl sp@(24),d2 | get esyms
! 126: /* note: d2-d7 in use */
! 127:
! 128: ASRELOC(tmpstk, a0)
! 129: movl a0,sp | give ourselves a temporary stack
! 130:
! 131: RELOC(edata, a0) | clear out BSS
! 132: movl #_C_LABEL(end)-4,d0 | (must be <= 256 kB)
! 133: subl #_C_LABEL(edata),d0
! 134: lsrl #2,d0
! 135: 1: clrl a0@+
! 136: dbra d0,1b
! 137:
! 138: movc vbr,d0 | save prom's trap #15 vector
! 139: RELOC(promvbr, a0)
! 140: movl d0, a0@
! 141: RELOC(esym, a0)
! 142: movl d2,a0@ | store end of symbol table
! 143: /* note: d2 now free, d3-d7 still in use */
! 144:
! 145: clrl sp@-
! 146: BUGCALL(MVMEPROM_GETBRDID)
! 147: movl sp@+, a1
! 148:
! 149: movl #SIZEOF_MVMEPROM_BRDID, d0 | copy to local variables
! 150: RELOC(brdid, a0)
! 151: 1: movb a1@+, a0@+
! 152: subql #1, d0
! 153: bne 1b
! 154:
! 155: clrl d0
! 156: RELOC(brdid, a1)
! 157: movw a1@(MVMEPROM_BRDID_MODEL), d0
! 158: RELOC(cputyp, a0)
! 159: movl d0, a0@ | init _cputyp
! 160:
! 161: #ifdef MVME147
! 162: cmpw #CPU_147, d0
! 163: beq is147
! 164: #endif
! 165:
! 166: #ifdef MVME162
! 167: cmpw #CPU_162, d0
! 168: beq is162
! 169: #endif
! 170:
! 171: #ifdef MVME167
! 172: cmpw #CPU_166, d0
! 173: beq is167
! 174: cmpw #CPU_167, d0
! 175: beq is167
! 176: #endif
! 177:
! 178: #ifdef MVME177
! 179: #ifdef notyet
! 180: cmpw #CPU_176, d0
! 181: beq is177
! 182: #endif
! 183: cmpw #CPU_177, d0
! 184: beq is177
! 185: #endif
! 186:
! 187: #ifdef MVME172
! 188: cmpw #CPU_172, d0
! 189: beq is172
! 190: #endif
! 191:
! 192: .data
! 193: notsup: .asciz "kernel does not support this model."
! 194: notsupend:
! 195: .even
! 196: .text
! 197:
! 198: | first we bitch, then we die.
! 199: movl #notsupend, sp@-
! 200: movl #notsup, sp@-
! 201: BUGCALL(MVMEPROM_OUTSTRCRLF)
! 202: addql #8,sp
! 203:
! 204: BUGCALL(MVMEPROM_EXIT) | return to m68kbug
! 205: /*NOTREACHED*/
! 206:
! 207: #ifdef MVME147
! 208: is147:
! 209: RELOC(mmutype, a0) | no, we have 68030
! 210: movl #MMU_68030,a0@ | set to reflect 68030 PMMU
! 211:
! 212: RELOC(cputype, a0) | no, we have 68030
! 213: movl #CPU_68030,a0@ | set to reflect 68030 CPU
! 214:
! 215: movl #CACHE_OFF,d0
! 216: movc d0,cacr | clear and disable on-chip cache(s)
! 217:
! 218: movb #0, 0xfffe1026 | XXX serial interrupt off
! 219: movb #0, 0xfffe1018 | XXX timer 1 off
! 220: movb #0, 0xfffe1028 | XXX ethernet off
! 221:
! 222: movl #0xfffe0000, a0 | mvme147 nvram base
! 223: | move nvram component of etheraddr (only last 3 bytes)
! 224: RELOC(myea, a1)
! 225: movw a0@(NVRAM_147_ETHER+0), a1@(3+0)
! 226: movb a0@(NVRAM_147_ETHER+2), a1@(3+2)
! 227: movl a0@(NVRAM_147_EMEM), d1 | pass memory size
! 228:
! 229: RELOC(iiomapsize, a1)
! 230: movl #INTIOSIZE_147, a1@
! 231: RELOC(iiomapbase, a1)
! 232: movl #INTIOBASE_147, a1@
! 233: bra Lstart1
! 234: #endif
! 235:
! 236: #ifdef MVME162
! 237: is162:
! 238: #if 0
! 239: | the following 3 things are "just in case". they won't make
! 240: | the kernel work properly, but they will at least let it get
! 241: | far enough that you can figure out that something had an
! 242: | interrupt pending. which the bootrom shouldn't allow, i don't
! 243: | think..
! 244: clrb 0xfff42002 | XXX MCchip irq off
! 245: clrl 0xfff42018 | XXX MCchip timers irq off
! 246: clrb 0xfff4201d | XXX MCchip scc irq off
! 247: #endif
! 248: RELOC(memsize162, a1) | how much memory?
! 249: jbsr a1@
! 250: movl d0, d2
! 251:
! 252: RELOC(mmutype, a0)
! 253: movl #MMU_68040,a0@ | with a 68040 MMU
! 254:
! 255: RELOC(cputype, a0) | no, we have 68040
! 256: movl #CPU_68040,a0@ | set to reflect 68040 CPU
! 257:
! 258: RELOC(fputype, a0)
! 259: movl #FPU_68040,a0@ | and a 68040 FPU
! 260:
! 261: RELOC(vectab, a1)
! 262: movl #_C_LABEL(buserr40),a1@(8)
! 263: movl #_C_LABEL(addrerr4060),a1@(12)
! 264:
! 265: bra is16x
! 266: #endif
! 267:
! 268: #ifdef MVME167
! 269: is167:
! 270: RELOC(memsize1x7, a1) | how much memory?
! 271: jbsr a1@
! 272:
! 273: RELOC(mmutype, a0)
! 274: movl #MMU_68040,a0@ | with a 68040 MMU
! 275:
! 276: RELOC(cputype, a0) | no, we have 68040
! 277: movl #CPU_68040,a0@ | set to reflect 68040 CPU
! 278:
! 279: RELOC(fputype, a0)
! 280: movl #FPU_68040,a0@ | and a 68040 FPU
! 281:
! 282: RELOC(vectab, a1)
! 283: movl #_C_LABEL(buserr40),a1@(8)
! 284: movl #_C_LABEL(addrerr4060),a1@(12)
! 285:
! 286: bra is16x
! 287: #endif
! 288:
! 289: #ifdef MVME172
! 290: is172:
! 291:
! 292: RELOC(memsize162, a1) | how much memory?
! 293: jbsr a1@
! 294: movl d0, d2
! 295:
! 296: /* enable Super Scalar Dispatch */
! 297: .word 0x4e7a,0x0808 | movc pcr,d0
! 298: bset #0,d0 | turn on bit 0.
! 299: .word 0x4e7b,0x0808 | movc d0,pcr Bang!
! 300:
! 301: RELOC(mmutype, a0)
! 302: movl #MMU_68060,a0@ | with a 68060 MMU
! 303:
! 304: RELOC(cputype, a0) | no, we have 68060
! 305: movl #CPU_68060,a0@ | set to reflect 68060 CPU
! 306:
! 307: RELOC(fputype, a0)
! 308: movl #FPU_68060,a0@ | and a 68060 FPU
! 309:
! 310: RELOC(vectab, a1)
! 311: movl #_C_LABEL(buserr60),a1@(8)
! 312: movl #_C_LABEL(addrerr4060),a1@(12)
! 313:
! 314: bra is16x
! 315: #endif
! 316:
! 317: #ifdef MVME177
! 318: is177:
! 319: RELOC(memsize1x7, a1) | how much memory?
! 320: jbsr a1@
! 321:
! 322: /* enable Super Scalar Dispatch */
! 323: .word 0x4e7a,0x0808 | movc pcr,d0
! 324: bset #0,d0 | turn on bit 0.
! 325: .word 0x4e7b,0x0808 | movc d0,pcr Bang! We are smokin' !
! 326:
! 327: RELOC(mmutype, a0)
! 328: movl #MMU_68060,a0@ | with a 68060 MMU
! 329:
! 330: RELOC(cputype, a0) | no, we have 68060
! 331: movl #CPU_68060,a0@ | set to reflect 68060 CPU
! 332:
! 333: RELOC(fputype, a0)
! 334: movl #FPU_68060,a0@ | and a 68060 FPU
! 335:
! 336: RELOC(vectab, a1)
! 337: movl #_C_LABEL(buserr60),a1@(8)
! 338: movl #_C_LABEL(addrerr4060),a1@(12)
! 339:
! 340: bra is16x
! 341: #endif
! 342:
! 343: #if defined(MVME162) || defined(MVME167) || defined(MVME177) || defined(MVME172)
! 344: #define ROMPKT_LEN 200
! 345: BSS(rompkt, ROMPKT_LEN)
! 346: .even
! 347: .text
! 348: is16x:
! 349: RELOC(iiomapsize, a1)
! 350: movl #INTIOSIZE_162, a1@
! 351: RELOC(iiomapbase, a1)
! 352: movl #INTIOBASE_162, a1@
! 353:
! 354: /* get ethernet address */
! 355: RELOC(rompkt, a0) | build a .NETCTRL packet
! 356: movb #0, a0@(NETCTRL_DEV) | onboard ethernet
! 357: movb #0, a0@(NETCTRL_CTRL) | onboard ethernet
! 358: movl #NETCTRLCMD_GETETHER, a0@(NETCTRL_CMD)
! 359: RELOC(myea, a1)
! 360: movl a1, a0@(NETCTRL_ADDR) | where to put it
! 361: movl #6, a0@(NETCTRL_LEN) | it is 6 bytes long
! 362:
! 363: movl a0, sp@-
! 364: BUGCALL(MVMEPROM_NETCTRL) | ask the rom
! 365: addl #4, sp
! 366:
! 367: | if memory size is unknown, print a diagnostic and make an
! 368: | assumption
! 369: movl d2, d1
! 370: cmpl #0, d1
! 371: bne Lstart1
! 372:
! 373: movl #unkmemend, sp@-
! 374: movl #unkmem, sp@-
! 375: BUGCALL(MVMEPROM_OUTSTRCRLF)
! 376: addql #8,sp
! 377:
! 378: movl #4*1024*1024, d1 | XXX assume 4M of ram
! 379: bra Lstart1
! 380:
! 381: .data
! 382: unkmem: .asciz "could not figure out how much memory; assuming 4M."
! 383: unkmemend:
! 384: .even
! 385: .text
! 386:
! 387: #endif
! 388:
! 389: Lstart1:
! 390: /* initialize source/destination control registers for movs */
! 391: moveq #FC_USERD,d0 | user space
! 392: movc d0,sfc | as source
! 393: movc d0,dfc | and destination of transfers
! 394: moveq #PGSHIFT,d2
! 395: lsrl d2,d1 | convert to pages
! 396: RELOC(physmem, a0)
! 397: movl d1,a0@ | save as physmem
! 398:
! 399: /* configure kernel and proc0 VA space so we can get going */
! 400: #if defined(DDB) || NKSYMS > 0
! 401: RELOC(esym,a0) | end of static kernel text/data/syms
! 402: movl a0@,d2
! 403: jne Lstart2
! 404: #endif
! 405: movl #_C_LABEL(end),d2 | end of static kernel text/data
! 406: Lstart2:
! 407: addl #NBPG-1,d2
! 408: andl #PG_FRAME,d2 | round to a page
! 409: movl d2,a4
! 410: #if 0
! 411: | XXX clear from end-of-kernel to 1M, as a workaround for an
! 412: | insane pmap_bootstrap bug I cannot find (68040-specific)
! 413: movl a4,a0
! 414: movl #1024*1024,d0
! 415: cmpl a0,d0 | end of kernel is beyond 1M?
! 416: jlt 2f
! 417: subl a0,d0
! 418: 1: clrb a0@+
! 419: subql #1,d0
! 420: bne 1b
! 421: 2:
! 422: #endif
! 423:
! 424: /* do pmap_bootstrap stuff */
! 425: clrl sp@- | firstpa
! 426: pea a4@ | nextpa
! 427: RELOC(pmap_bootstrap,a0)
! 428: jbsr a0@ | pmap_bootstrap(firstpa, nextpa)
! 429: addql #8,sp
! 430:
! 431: /*
! 432: * While still running physical, override copypage() with the 68040
! 433: * optimized version, copypage040(), if possible.
! 434: * This relies upon the fact that copypage() immediately follows
! 435: * copypage040() in memory.
! 436: */
! 437: RELOC(mmutype, a0)
! 438: cmpl #MMU_68040,a0@
! 439: jgt Lmmu_enable
! 440: RELOC(copypage040, a0)
! 441: RELOC(copypage, a1)
! 442: movl a1, a2
! 443: 1:
! 444: movw a0@+, a2@+
! 445: cmpl a0, a1
! 446: jgt 1b
! 447:
! 448: /*
! 449: * Enable the MMU.
! 450: * Since the kernel is mapped logical == physical, we just turn it on.
! 451: */
! 452: Lmmu_enable:
! 453: RELOC(Sysseg, a0) | system segment table addr
! 454: movl a0@,d1 | read value (a KVA)
! 455: RELOC(mmutype, a0)
! 456: cmpl #MMU_68040,a0@ | 68040 or 68060?
! 457: jgt Lmotommu1 | no, skip
! 458: .long 0x4e7b1807 | movc d1,srp
! 459: .long 0x4e7b1806 | movc d1,urp
! 460: jra Lstploaddone
! 461: Lmotommu1:
! 462: RELOC(protorp, a0)
! 463: movl #0x80000202,a0@ | nolimit + share global + 4 byte PTEs
! 464: movl d1,a0@(4) | + segtable address
! 465: pmove a0@,srp | load the supervisor root pointer
! 466: movl #0x80000002,a0@ | reinit upper half for CRP loads
! 467: Lstploaddone:
! 468: RELOC(mmutype, a0)
! 469: cmpl #MMU_68040,a0@ | 68040 or 68060?
! 470: jgt Lmotommu2 | no, skip
! 471:
! 472: moveq #0,d0 | ensure TT regs are disabled
! 473: .long 0x4e7b0004 | movc d0,itt0
! 474: .long 0x4e7b0005 | movc d0,itt1
! 475: .long 0x4e7b0006 | movc d0,dtt0
! 476: .long 0x4e7b0007 | movc d0,dtt1
! 477:
! 478: .word 0xf4d8 | cinva bc
! 479: .word 0xf518 | pflusha
! 480: movl #0x8000,d0
! 481: .long 0x4e7b0003 | movc d0,tc
! 482: /* Enable 68060 extensions here */
! 483: RELOC(mmutype, a0)
! 484: cmpl #MMU_68060,a0@ | 68060?
! 485: jne Lchache040
! 486: movl #CACHE60_ON,d0 | branch cache, etc...
! 487: movc d0,cacr | turn on both caches
! 488: jmp Lenab1
! 489: Lchache040:
! 490: movl #CACHE40_ON,d0
! 491: movc d0,cacr | turn on both caches
! 492: jmp Lenab1
! 493: Lmotommu2:
! 494: movl #0x82c0aa00,a2@ | value to load TC with
! 495: pmove a2@,tc | load it
! 496: Lenab1:
! 497:
! 498: /*
! 499: * Should be running mapped from this point on
! 500: */
! 501: /* select the software page size now */
! 502: lea _ASM_LABEL(tmpstk),sp | temporary stack
! 503: jbsr _C_LABEL(uvm_setpagesize) | select software page size
! 504: /* set kernel stack, user SP, and initial pcb */
! 505: movl _C_LABEL(proc0paddr),a1 | get proc0 pcb addr
! 506: lea a1@(USPACE-4),sp | set kernel stack to end of area
! 507: lea _C_LABEL(proc0), a2 | initialize proc0.p_addr so that
! 508: movl a1,a2@(P_ADDR) | we don't deref NULL in trap()
! 509: movl #USRSTACK-4,a2
! 510: movl a2,usp | init user SP
! 511: movl a1,_C_LABEL(curpcb) | proc0 is running
! 512:
! 513: tstl _C_LABEL(fputype) | Have an FPU?
! 514: jeq Lenab2 | No, skip.
! 515: clrl a1@(PCB_FPCTX) | ensure null FP context
! 516: movl a1,sp@-
! 517: jbsr _C_LABEL(m68881_restore) | restore it (does not kill a1)
! 518: addql #4,sp
! 519: Lenab2:
! 520: /* flush TLB and turn on caches */
! 521: jbsr _ASM_LABEL(TBIA) | invalidate TLB
! 522: cmpl #MMU_68040,_C_LABEL(mmutype) | 68040 or 68060?
! 523: jle Lnocache0 | yes, cache already on
! 524: movl #CACHE_ON,d0
! 525: movc d0,cacr | clear cache(s)
! 526: Lnocache0:
! 527: /* final setup for C code */
! 528: #if 1
! 529: movl #_vectab,d2 | set VBR
! 530: movc d2,vbr
! 531: #endif
! 532: movw #PSL_LOWIPL,sr | lower SPL
! 533: movl d3, _C_LABEL(bootpart) | save bootpart
! 534: movl d4, _C_LABEL(bootdevlun) | save bootdevlun
! 535: movl d5, _C_LABEL(bootctrllun) | save bootctrllun
! 536: movl d6, _C_LABEL(bootaddr) | save bootaddr
! 537: movl d7, _C_LABEL(boothowto) | save boothowto
! 538: /* d3-d7 now free */
! 539:
! 540: /* Final setup for call to main(). */
! 541: jbsr _C_LABEL(mvme68k_init)
! 542:
! 543: /*
! 544: * Create a fake exception frame so that cpu_fork() can copy it.
! 545: * main() never returns; we exit to user mode from a forked process
! 546: * later on.
! 547: */
! 548: clrw sp@- | vector offset/frame type
! 549: clrl sp@- | PC - filled in by "execve"
! 550: movw #PSL_USER,sp@- | in user mode
! 551: clrl sp@- | stack adjust count and padding
! 552: lea sp@(-64),sp | construct space for D0-D7/A0-A7
! 553: lea _C_LABEL(proc0),a0 | save pointer to frame
! 554: movl sp,a0@(P_MD_REGS) | in proc0.p_md.md_regs
! 555:
! 556: jra _C_LABEL(main) | main()
! 557: PANIC("main() returned")
! 558: /* NOTREACHED */
! 559:
! 560: #if defined(MVME162) || defined(MVME167) || defined(MVME177) || defined(MVME172)
! 561: /*
! 562: * Figure out the size of onboard DRAM by querying the memory controller(s).
! 563: * This has to be done in locore as badaddr() can not yet be used at this
! 564: * point.
! 565: */
! 566: GLOBAL(memsize1x7)
! 567: movl #0xfff43008,a0 | MEMC040/MEMECC Controller #1
! 568: jbsr memc040read
! 569: movl d0,d2
! 570:
! 571: movl #0xfff43108,a0 | MEMC040/MEMECC Controller #2
! 572: jbsr memc040read
! 573: addl d0,d2
! 574:
! 575: rts
! 576:
! 577: /*
! 578: * Probe for a memory controller ASIC (MEMC040 or MEMECC) at the
! 579: * address in a0. If found, return the size in bytes of any RAM
! 580: * controller by the ASIC in d0. Otherwise return zero.
! 581: */
! 582: ASLOCAL(memc040read)
! 583: moveml d1-d2/a1-a2,sp@- | save scratch regs
! 584: movc vbr,d2 | Save vbr
! 585: RELOC(vectab,a2) | Install our own vectab, temporarily
! 586: movc a2,vbr
! 587: ASRELOC(Lmemc040berr,a1) | get address of bus error handler
! 588: movl a2@(8),sp@- | Save current bus error handler addr
! 589: movl a1,a2@(8) | Install our own handler
! 590: movl sp,d0 | Save current stack pointer value
! 591: movql #0x07,d1
! 592: andb a0@,d1 | Access MEMC040/MEMECC
! 593: movl #0x400000,d0
! 594: lsll d1,d0 | Convert to memory size, in bytes
! 595: Lmemc040ret:
! 596: movc d2,vbr | Restore original vbr
! 597: movl sp@+,a2@(8) | Restore original bus error handler
! 598: moveml sp@+,d1-d2/a1-a2
! 599: rts
! 600: /*
! 601: * If the memory controller doesn't exist, we get a bus error trying
! 602: * to access a0@ above. Control passes here, where we flag 'no bytes',
! 603: * ditch the exception frame and return as normal.
! 604: */
! 605: Lmemc040berr:
! 606: movl d0,sp | Get rid of the exception frame
! 607: clrl d0 | No ASIC at this location, then!
! 608: jbra Lmemc040ret | Done
! 609: #endif
! 610:
! 611: /*
! 612: * proc_trampoline: call function in register a2 with a3 as an arg
! 613: * and then rei.
! 614: */
! 615: GLOBAL(proc_trampoline)
! 616: movl a3,sp@- | push function arg
! 617: jbsr a2@ | call function
! 618: addql #4,sp | pop arg
! 619: movl sp@(FR_SP),a0 | grab and load
! 620: movl a0,usp | user SP
! 621: moveml sp@+,#0x7FFF | restore most user regs
! 622: addql #8,sp | toss SP and stack adjust
! 623: jra _ASM_LABEL(rei) | and return
! 624:
! 625:
! 626: /*
! 627: * Trap/interrupt vector routines - new for 060
! 628: */
! 629: #include <m68k/m68k/trap_subr.s>
! 630:
! 631: #if defined(M68040) || defined(M68060)
! 632: ENTRY_NOPROFILE(addrerr4060)
! 633: clrl sp@- | stack adjust count
! 634: moveml #0xFFFF,sp@- | save user registers
! 635: movl usp,a0 | save the user SP
! 636: movl a0,sp@(FR_SP) | in the savearea
! 637: movl sp@(FR_HW+8),sp@-
! 638: clrl sp@- | dummy code
! 639: movl #T_ADDRERR,sp@- | mark address error
! 640: jra _ASM_LABEL(faultstkadj) | and deal with it
! 641: #endif
! 642:
! 643: #if defined(M68060)
! 644: ENTRY_NOPROFILE(buserr60)
! 645: clrl sp@- | stack adjust count
! 646: moveml #0xFFFF,sp@- | save user registers
! 647: movl usp,a0 | save the user SP
! 648: movl a0,sp@(FR_SP) | in the savearea
! 649: movel sp@(FR_HW+12),d0 | FSLW
! 650: btst #2,d0 | branch prediction error?
! 651: jeq Lnobpe
! 652: movc cacr,d2
! 653: orl #IC60_CABC,d2 | clear all branch cache entries
! 654: movc d2,cacr
! 655: movl d0,d1
! 656: andl #0x7ffd,d1
! 657: jeq _ASM_LABEL(faultstkadjnotrap2)
! 658: Lnobpe:
! 659: | we need to adjust for misaligned addresses
! 660: movl sp@(FR_HW+8),d1 | grab VA
! 661: btst #27,d0 | check for mis-aligned access
! 662: jeq Lberr3 | no, skip
! 663: addl #28,d1 | yes, get into next page
! 664: | operand case: 3,
! 665: | instruction case: 4+12+12
! 666: andl #PG_FRAME,d1 | and truncate
! 667: Lberr3:
! 668: movl d1,sp@-
! 669: movl d0,sp@- | code is FSLW now.
! 670: andw #0x1f80,d0
! 671: jeq Lbuserr60 | no, handle as usual
! 672: movl #T_MMUFLT,sp@- | show that we are an MMU fault
! 673: jra _ASM_LABEL(faultstkadj) | and deal with it
! 674: Lbuserr60:
! 675: tstl _C_LABEL(nofault) | device probe?
! 676: jeq Lisberr | Bus Error?
! 677: movl _C_LABEL(nofault),sp@- | yes,
! 678: jbsr _C_LABEL(longjmp) | longjmp(nofault)
! 679: #endif
! 680: #if defined(M68040)
! 681: ENTRY_NOPROFILE(buserr40)
! 682: clrl sp@- | stack adjust count
! 683: moveml #0xFFFF,sp@- | save user registers
! 684: movl usp,a0 | save the user SP
! 685: movl a0,sp@(FR_SP) | in the savearea
! 686: movl sp@(FR_HW+20),d1 | get fault address
! 687: moveq #0,d0
! 688: movw sp@(FR_HW+12),d0 | get SSW
! 689: btst #11,d0 | check for mis-aligned
! 690: jeq Lbe1stpg | no skip
! 691: addl #3,d1 | get into next page
! 692: andl #PG_FRAME,d1 | and truncate
! 693: Lbe1stpg:
! 694: movl d1,sp@- | pass fault address.
! 695: movl d0,sp@- | pass SSW as code
! 696: btst #10,d0 | test ATC
! 697: jeq Lbuserr40 | no, handle as usual
! 698: movl #T_MMUFLT,sp@- | show that we are an MMU fault
! 699: jra _ASM_LABEL(faultstkadj) | and deal with it
! 700: Lbuserr40:
! 701: tstl _C_LABEL(nofault) | device probe?
! 702: jeq Lisberr | it is a bus error
! 703: movl _C_LABEL(nofault),sp@- | yes,
! 704: jbsr _C_LABEL(longjmp) | longjmp(nofault)
! 705: /* NOTREACHED */
! 706: #endif
! 707:
! 708: ENTRY_NOPROFILE(busaddrerr2030)
! 709: clrl sp@- | stack adjust count
! 710: moveml #0xFFFF,sp@- | save user registers
! 711: movl usp,a0 | save the user SP
! 712: movl a0,sp@(FR_SP) | in the savearea
! 713: lea sp@(FR_HW),a1 | grab base of HW berr frame
! 714: moveq #0,d0
! 715: movw a1@(10),d0 | grab SSW for fault processing
! 716: btst #12,d0 | RB set?
! 717: jeq LbeX0 | no, test RC
! 718: bset #14,d0 | yes, must set FB
! 719: movw d0,a1@(10) | for hardware too
! 720: LbeX0:
! 721: btst #13,d0 | RC set?
! 722: jeq LbeX1 | no, skip
! 723: bset #15,d0 | yes, must set FC
! 724: movw d0,a1@(10) | for hardware too
! 725: LbeX1:
! 726: btst #8,d0 | data fault?
! 727: jeq Lbe0 | no, check for hard cases
! 728: movl a1@(16),d1 | fault address is as given in frame
! 729: jra Lbe10 | thats it
! 730: Lbe0:
! 731: btst #4,a1@(6) | long (type B) stack frame?
! 732: jne Lbe4 | yes, go handle
! 733: movl a1@(2),d1 | no, can use save PC
! 734: btst #14,d0 | FB set?
! 735: jeq Lbe3 | no, try FC
! 736: addql #4,d1 | yes, adjust address
! 737: jra Lbe10 | done
! 738: Lbe3:
! 739: btst #15,d0 | FC set?
! 740: jeq Lbe10 | no, done
! 741: addql #2,d1 | yes, adjust address
! 742: jra Lbe10 | done
! 743: Lbe4:
! 744: movl a1@(36),d1 | long format, use stage B address
! 745: btst #15,d0 | FC set?
! 746: jeq Lbe10 | no, all done
! 747: subql #2,d1 | yes, adjust address
! 748: Lbe10:
! 749: movl d1,sp@- | push fault VA
! 750: movl d0,sp@- | and padded SSW
! 751: movw a1@(6),d0 | get frame format/vector offset
! 752: andw #0x0FFF,d0 | clear out frame format
! 753: cmpw #12,d0 | address error vector?
! 754: jeq Lisaerr | yes, go to it
! 755: movl d1,a0 | fault address
! 756: movl sp@,d0 | function code from ssw
! 757: btst #8,d0 | data fault?
! 758: jne Lbe10a
! 759: movql #1,d0 | user program access FC
! 760: | (we dont separate data/program)
! 761: btst #5,a1@ | supervisor mode?
! 762: jeq Lbe10a | if no, done
! 763: movql #5,d0 | else supervisor program access
! 764: Lbe10a:
! 765: ptestr d0,a0@,#7 | do a table search
! 766: pmove psr,sp@ | save result
! 767: movb sp@,d1
! 768: btst #2,d1 | invalid (incl. limit viol. and berr)?
! 769: jeq Lmightnotbemerr | no -> wp check
! 770: btst #7,d1 | is it MMU table berr?
! 771: jeq Lismerr | no, must be fast
! 772: jra Lisberr1 | real bus err needs not be fast.
! 773: Lmightnotbemerr:
! 774: btst #3,d1 | write protect bit set?
! 775: jeq Lisberr1 | no: must be bus error
! 776: movl sp@,d0 | ssw into low word of d0
! 777: andw #0xc0,d0 | Write protect is set on page:
! 778: cmpw #0x40,d0 | was it read cycle?
! 779: jeq Lisberr1 | yes, was not WPE, must be bus err
! 780: Lismerr:
! 781: movl #T_MMUFLT,sp@- | show that we are an MMU fault
! 782: jra _ASM_LABEL(faultstkadj) | and deal with it
! 783: Lisaerr:
! 784: movl #T_ADDRERR,sp@- | mark address error
! 785: jra _ASM_LABEL(faultstkadj) | and deal with it
! 786: Lisberr1:
! 787: clrw sp@ | re-clear pad word
! 788: Lisberr:
! 789: movl #T_BUSERR,sp@- | mark bus error
! 790: jra _ASM_LABEL(faultstkadj) | and deal with it
! 791:
! 792: /*
! 793: * FP exceptions.
! 794: */
! 795: ENTRY_NOPROFILE(fpfline)
! 796: #if defined(M68040) || defined(M68060)
! 797: cmpl #FPU_68040,_C_LABEL(fputype) | 68040 or 68060 FPU?
! 798: jlt Lfp_unimp | no, skip FPSP
! 799: cmpw #0x202c,sp@(6) | format type 2?
! 800: jne _C_LABEL(illinst) | no, not an FP emulation
! 801: Ldofp_unimp:
! 802: #ifdef FPSP
! 803: jmp _ASM_LABEL(fpsp_unimp) | yes, go handle it
! 804: #endif
! 805: Lfp_unimp:
! 806: #endif/* M68040 || M68060 */
! 807: #ifdef FPU_EMULATE
! 808: clrl sp@- | stack adjust count
! 809: moveml #0xFFFF,sp@- | save registers
! 810: moveq #T_FPEMULI,d0 | denote as FP emulation trap
! 811: jra _ASM_LABEL(fault) | do it
! 812: #else
! 813: jra _C_LABEL(illinst)
! 814: #endif
! 815:
! 816: ENTRY_NOPROFILE(fpunsupp)
! 817: #if defined(M68040) || defined(M68060)
! 818: cmpl #FPU_68040,_C_LABEL(fputype) | 68040 or 68060 FPU?
! 819: jlt _C_LABEL(illinst) | no, treat as illinst
! 820: #ifdef FPSP
! 821: jmp _ASM_LABEL(fpsp_unsupp) | yes, go handle it
! 822: #endif
! 823: Lfp_unsupp:
! 824: #endif /* M68040 */
! 825: #ifdef FPU_EMULATE
! 826: clrl sp@- | stack adjust count
! 827: moveml #0xFFFF,sp@- | save registers
! 828: moveq #T_FPEMULD,d0 | denote as FP emulation trap
! 829: jra _ASM_LABEL(fault) | do it
! 830: #else
! 831: jra _C_LABEL(illinst)
! 832: #endif
! 833:
! 834: /*
! 835: * Handles all other FP coprocessor exceptions.
! 836: * Note that since some FP exceptions generate mid-instruction frames
! 837: * and may cause signal delivery, we need to test for stack adjustment
! 838: * after the trap call.
! 839: */
! 840: ENTRY_NOPROFILE(fpfault)
! 841: clrl sp@- | stack adjust count
! 842: moveml #0xFFFF,sp@- | save user registers
! 843: movl usp,a0 | and save
! 844: movl a0,sp@(FR_SP) | the user stack pointer
! 845: clrl sp@- | no VA arg
! 846: movl _C_LABEL(curpcb),a0 | current pcb
! 847: lea a0@(PCB_FPCTX),a0 | address of FP savearea
! 848: fsave a0@ | save state
! 849: #if defined(M68040) || defined(M68060)
! 850: /* always null state frame on 68040, 68060 */
! 851: cmpl #CPU_68040,_C_LABEL(cputype)
! 852: jge Lfptnull
! 853: #endif
! 854: tstb a0@ | null state frame?
! 855: jeq Lfptnull | yes, safe
! 856: clrw d0 | no, need to tweak BIU
! 857: movb a0@(1),d0 | get frame size
! 858: bset #3,a0@(0,d0:w) | set exc_pend bit of BIU
! 859: Lfptnull:
! 860: fmovem fpsr,sp@- | push fpsr as code argument
! 861: frestore a0@ | restore state
! 862: movl #T_FPERR,sp@- | push type arg
! 863: jra _ASM_LABEL(faultstkadj) | call trap and deal with stack cleanup
! 864:
! 865: /*
! 866: * Other exceptions only cause four and six word stack frame and require
! 867: * no post-trap stack adjustment.
! 868: */
! 869: ENTRY_NOPROFILE(hardtrap)
! 870: moveml #0xC0C0,sp@- | save scratch regs
! 871: lea sp@(16),a1 | get pointer to frame
! 872: movl a1,sp@-
! 873: movw sp@(26),d0
! 874: movl d0,sp@- | push exception vector info
! 875: movl sp@(26),sp@- | and PC
! 876: jbsr _C_LABEL(hardintr) | doit
! 877: lea sp@(12),sp | pop args
! 878: moveml sp@+,#0x0303 | restore regs
! 879: jra _ASM_LABEL(rei) | all done
! 880:
! 881: ENTRY_NOPROFILE(badtrap)
! 882: moveml #0xC0C0,sp@- | save scratch regs
! 883: movw sp@(22),sp@- | push exception vector info
! 884: clrw sp@-
! 885: movl sp@(22),sp@- | and PC
! 886: jbsr _C_LABEL(straytrap) | report
! 887: addql #8,sp | pop args
! 888: moveml sp@+,#0x0303 | restore regs
! 889: jra _ASM_LABEL(rei) | all done
! 890:
! 891: ENTRY_NOPROFILE(trap0)
! 892: clrl sp@- | stack adjust count
! 893: moveml #0xFFFF,sp@- | save user registers
! 894: movl usp,a0 | save the user SP
! 895: movl a0,sp@(FR_SP) | in the savearea
! 896: movl d0,sp@- | push syscall number
! 897: jbsr _C_LABEL(syscall) | handle it
! 898: addql #4,sp | pop syscall arg
! 899: tstl _C_LABEL(astpending)
! 900: jne Lrei2
! 901: tstb _C_LABEL(ssir)
! 902: jeq Ltrap1
! 903: movw #SPL1,sr
! 904: tstb _C_LABEL(ssir)
! 905: jne Lsir1
! 906: Ltrap1:
! 907: movl sp@(FR_SP),a0 | grab and restore
! 908: movl a0,usp | user SP
! 909: moveml sp@+,#0x7FFF | restore most registers
! 910: addql #8,sp | pop SP and stack adjust
! 911: rte
! 912:
! 913: /*
! 914: * Trap 1 - sigreturn
! 915: */
! 916: ENTRY_NOPROFILE(trap1)
! 917: jra _ASM_LABEL(sigreturn)
! 918:
! 919: /*
! 920: * Trap 2 - trace trap
! 921: */
! 922: ENTRY_NOPROFILE(trap2)
! 923: jra _C_LABEL(trace)
! 924:
! 925: /*
! 926: * Trap 12 is the entry point for the cachectl "syscall" (both HPUX & BSD)
! 927: * cachectl(command, addr, length)
! 928: * command in d0, addr in a1, length in d1
! 929: */
! 930: ENTRY_NOPROFILE(trap12)
! 931: movl d1,sp@- | push length
! 932: movl a1,sp@- | push addr
! 933: movl d0,sp@- | push command
! 934: movl CURPROC,sp@- | push proc pointer
! 935: jbsr _C_LABEL(cachectl) | do it
! 936: lea sp@(16),sp | pop args
! 937: jra _ASM_LABEL(rei) | all done
! 938:
! 939: /*
! 940: * Trace (single-step) trap (trap 1 or 2) instruction. Kernel-mode is
! 941: * special. User mode traps are simply passed on to trap().
! 942: */
! 943: ENTRY_NOPROFILE(trace)
! 944: clrl sp@-
! 945: moveml #0xFFFF,sp@-
! 946: moveq #T_TRACE,d0
! 947:
! 948: | Check PSW and see what happened.
! 949: | T=0 S=0 (should not happen)
! 950: | T=1 S=0 trace trap from user mode
! 951: | T=0 S=1 trace trap on a trap instruction
! 952: | T=0 S=0 trace trap from system mode (kernel breakpoint)
! 953:
! 954: movw sp@(FR_HW),d1 | get SSW
! 955: notw d1 | XXX no support for T0 on 680[234]0
! 956: andw #PSL_S,d1 | from system mode (T=1, S=1)?
! 957: jeq Lkbrkpt | yes, kernel breakpoint
! 958: jra _ASM_LABEL(fault) | no, user-mode fault
! 959:
! 960: /*
! 961: * Trap 15 is used for:
! 962: * - GDB breakpoints (in user programs)
! 963: * - KGDB breakpoints (in the kernel)
! 964: * - trace traps for SUN binaries (not fully supported yet)
! 965: * - calling the prom, but only from the kernel
! 966: * We just pass it on and let trap() sort it all out
! 967: */
! 968: ENTRY_NOPROFILE(trap15)
! 969: clrl sp@- | stack adjust count
! 970: moveml #0xFFFF,sp@-
! 971:
! 972: tstl _C_LABEL(promcall)
! 973: jeq L_notpromcall
! 974: moveml sp@+,#0xFFFF
! 975: addql #4, sp
! 976: | unwind stack to put to known value
! 977: | this routine is from the 147 BUG manual
! 978: | currently save and restore are excessive.
! 979: subql #4,sp
! 980: link a6,#0
! 981: moveml #0xFFFE,sp@-
! 982: movl _C_LABEL(promvbr),a0
! 983: movw a6@(14),d0
! 984: andl #0xfff,d0
! 985: movl a0@(d0:w),a6@(4)
! 986: moveml sp@+,#0x7FFF
! 987: unlk a6
! 988: rts
! 989: | really jumps to the bug trap handler
! 990: L_notpromcall:
! 991: moveq #T_TRAP15,d0
! 992: movw sp@(FR_HW),d1 | get PSW
! 993: andw #PSL_S,d1 | from system mode?
! 994: jne Lkbrkpt | yes, kernel breakpoint
! 995: jra _ASM_LABEL(fault) | no, user-mode fault
! 996:
! 997: Lkbrkpt: | Kernel-mode breakpoint or trace trap. (d0=trap_type)
! 998: | Save the system sp rather than the user sp.
! 999: movw #PSL_HIGHIPL,sr | lock out interrupts
! 1000: lea sp@(FR_SIZE),a6 | Save stack pointer
! 1001: movl a6,sp@(FR_SP) | from before trap
! 1002:
! 1003: | If we are not on tmpstk switch to it.
! 1004: | (so debugger can change the stack pointer)
! 1005: movl a6,d1
! 1006: cmpl #_ASM_LABEL(tmpstk),d1
! 1007: jls Lbrkpt2 | already on tmpstk
! 1008: | Copy frame to the temporary stack
! 1009: movl sp,a0 | a0=src
! 1010: lea _ASM_LABEL(tmpstk)-96,a1 | a1=dst
! 1011: movl a1,sp | sp=new frame
! 1012: moveq #FR_SIZE,d1
! 1013: Lbrkpt1:
! 1014: movl a0@+,a1@+
! 1015: subql #4,d1
! 1016: bgt Lbrkpt1
! 1017:
! 1018: Lbrkpt2:
! 1019: | Call the trap handler for the kernel debugger.
! 1020: | Do not call trap() to do it, so that we can
! 1021: | set breakpoints in trap() if we want. We know
! 1022: | the trap type is either T_TRACE or T_BREAKPOINT.
! 1023: | If we have both DDB and KGDB, let KGDB see it first,
! 1024: | because KGDB will just return 0 if not connected.
! 1025: | Save args in d2, a2
! 1026: movl d0,d2 | trap type
! 1027: movl sp,a2 | frame ptr
! 1028: #ifdef KGDB
! 1029: | Let KGDB handle it (if connected)
! 1030: movl a2,sp@- | push frame ptr
! 1031: movl d2,sp@- | push trap type
! 1032: jbsr _C_LABEL(kgdb_trap) | handle the trap
! 1033: addql #8,sp | pop args
! 1034: cmpl #0,d0 | did kgdb handle it?
! 1035: jne Lbrkpt3 | yes, done
! 1036: #endif
! 1037: #ifdef DDB
! 1038: | Let DDB handle it
! 1039: movl a2,sp@- | push frame ptr
! 1040: movl d2,sp@- | push trap type
! 1041: jbsr _C_LABEL(kdb_trap) | handle the trap
! 1042: addql #8,sp | pop args
! 1043: cmpl #0,d0 | did ddb handle it?
! 1044: jne Lbrkpt3 | yes, done
! 1045: #endif
! 1046: | Drop into the prom
! 1047: BUGCALL(MVMEPROM_EXIT)
! 1048: Lbrkpt3:
! 1049: | The stack pointer may have been modified, or
! 1050: | data below it modified (by kgdb push call),
! 1051: | so push the hardware frame at the current sp
! 1052: | before restoring registers and returning.
! 1053:
! 1054: movl sp@(FR_SP),a0 | modified sp
! 1055: lea sp@(FR_SIZE),a1 | end of our frame
! 1056: movl a1@-,a0@- | copy 2 longs with
! 1057: movl a1@-,a0@- | ... predecrement
! 1058: movl a0,sp@(FR_SP) | sp = h/w frame
! 1059: moveml sp@+,#0x7FFF | restore all but sp
! 1060: movl sp@,sp | ... and sp
! 1061: rte | all done
! 1062:
! 1063: /* Use common m68k sigreturn */
! 1064: #include <m68k/m68k/sigreturn.s>
! 1065:
! 1066: /*
! 1067: * Interrupt handlers.
! 1068: * No device interrupts are auto-vectored.
! 1069: */
! 1070:
! 1071: ENTRY_NOPROFILE(spurintr)
! 1072: addql #1,_C_LABEL(uvmexp)+UVMEXP_INTRS
! 1073: jra _ASM_LABEL(rei) | all done
! 1074:
! 1075: /*
! 1076: * Emulation of VAX REI instruction.
! 1077: *
! 1078: * This code deals with checking for and servicing ASTs
! 1079: * (profiling, scheduling) and software interrupts (network, softclock).
! 1080: * We check for ASTs first, just like the VAX. To avoid excess overhead
! 1081: * the T_ASTFLT handling code will also check for software interrupts so we
! 1082: * do not have to do it here. After identifing that we need an AST we
! 1083: * drop the IPL to allow device interrupts.
! 1084: *
! 1085: * This code is complicated by the fact that sendsig may have been called
! 1086: * necessitating a stack cleanup.
! 1087: */
! 1088:
! 1089: BSS(ssir,1)
! 1090:
! 1091: ASENTRY_NOPROFILE(rei)
! 1092: tstl _C_LABEL(astpending) | AST pending?
! 1093: jeq Lchksir | no, go check for SIR
! 1094: Lrei1:
! 1095: btst #5,sp@ | yes, are we returning to user mode?
! 1096: jne Lchksir | no, go check for SIR
! 1097: movw #PSL_LOWIPL,sr | lower SPL
! 1098: clrl sp@- | stack adjust
! 1099: moveml #0xFFFF,sp@- | save all registers
! 1100: movl usp,a1 | including
! 1101: movl a1,sp@(FR_SP) | the users SP
! 1102: Lrei2:
! 1103: clrl sp@- | VA == none
! 1104: clrl sp@- | code == none
! 1105: movl #T_ASTFLT,sp@- | type == async system trap
! 1106: jbsr _C_LABEL(trap) | go handle it
! 1107: lea sp@(12),sp | pop value args
! 1108: movl sp@(FR_SP),a0 | restore user SP
! 1109: movl a0,usp | from save area
! 1110: movw sp@(FR_ADJ),d0 | need to adjust stack?
! 1111: jne Laststkadj | yes, go to it
! 1112: moveml sp@+,#0x7FFF | no, restore most user regs
! 1113: addql #8,sp | toss SP and stack adjust
! 1114: rte | and do real RTE
! 1115: Laststkadj:
! 1116: lea sp@(FR_HW),a1 | pointer to HW frame
! 1117: addql #8,a1 | source pointer
! 1118: movl a1,a0 | source
! 1119: addw d0,a0 | + hole size = dest pointer
! 1120: movl a1@-,a0@- | copy
! 1121: movl a1@-,a0@- | 8 bytes
! 1122: movl a0,sp@(FR_SP) | new SSP
! 1123: moveml sp@+,#0x7FFF | restore user registers
! 1124: movl sp@,sp | and our SP
! 1125: rte | and do real RTE
! 1126: Lchksir:
! 1127: tstb _C_LABEL(ssir) | SIR pending?
! 1128: jeq Ldorte | no, all done
! 1129: movl d0,sp@- | need a scratch register
! 1130: movw sp@(4),d0 | get SR
! 1131: andw #PSL_IPL7,d0 | mask all but IPL
! 1132: jne Lnosir | came from interrupt, no can do
! 1133: movl sp@+,d0 | restore scratch register
! 1134: Lgotsir:
! 1135: movw #SPL1,sr | prevent others from servicing int
! 1136: tstb _C_LABEL(ssir) | too late?
! 1137: jeq Ldorte | yes, oh well...
! 1138: clrl sp@- | stack adjust
! 1139: moveml #0xFFFF,sp@- | save all registers
! 1140: movl usp,a1 | including
! 1141: movl a1,sp@(FR_SP) | the users SP
! 1142: Lsir1:
! 1143: clrl sp@- | VA == none
! 1144: clrl sp@- | code == none
! 1145: movl #T_SSIR,sp@- | type == software interrupt
! 1146: jbsr _C_LABEL(trap) | go handle it
! 1147: lea sp@(12),sp | pop value args
! 1148: movl sp@(FR_SP),a0 | restore
! 1149: movl a0,usp | user SP
! 1150: moveml sp@+,#0x7FFF | and all remaining registers
! 1151: addql #8,sp | pop SP and stack adjust
! 1152: rte
! 1153: Lnosir:
! 1154: movl sp@+,d0 | restore scratch register
! 1155: Ldorte:
! 1156: rte | real return
! 1157:
! 1158: /*
! 1159: * Use common m68k signal trampoline.
! 1160: */
! 1161: #include <m68k/m68k/sigcode.s>
! 1162:
! 1163: /*
! 1164: * Use common m68k support routines.
! 1165: */
! 1166: #include <m68k/m68k/support.s>
! 1167:
! 1168: /*
! 1169: * Use common m68k process manipulation routines.
! 1170: */
! 1171: #include <m68k/m68k/proc_subr.s>
! 1172:
! 1173: .data
! 1174: GLOBAL(curpcb)
! 1175: .long 0
! 1176:
! 1177: ASBSS(nullpcb,SIZEOF_PCB)
! 1178:
! 1179: /*
! 1180: * At exit of a process, do a switch for the last time.
! 1181: * Switch to a safe stack and PCB, and deallocate the process's resources.
! 1182: */
! 1183: ENTRY(switch_exit)
! 1184: movl sp@(4),a0
! 1185: | save state into garbage pcb
! 1186: movl #_ASM_LABEL(nullpcb),_C_LABEL(curpcb)
! 1187: lea _ASM_LABEL(tmpstk),sp | goto a tmp stack
! 1188:
! 1189: /* Schedule the vmspace and stack to be freed. */
! 1190: movl a0,sp@- | exit2(p)
! 1191: jbsr _C_LABEL(exit2)
! 1192: lea sp@(4),sp | pop args
! 1193:
! 1194: jra _C_LABEL(cpu_switch)
! 1195:
! 1196: /*
! 1197: * When no processes are on the runq, Swtch branches to Idle
! 1198: * to wait for something to come ready.
! 1199: */
! 1200: ASENTRY_NOPROFILE(Idle)
! 1201: stop #PSL_LOWIPL
! 1202: movw #PSL_HIGHIPL,sr
! 1203: movl _C_LABEL(whichqs),d0
! 1204: jeq _ASM_LABEL(Idle)
! 1205: jra Lsw1
! 1206:
! 1207: Lbadsw:
! 1208: PANIC("switch")
! 1209: /*NOTREACHED*/
! 1210:
! 1211: /*
! 1212: * cpu_switch()
! 1213: *
! 1214: * NOTE: On the mc68851 we attempt to avoid flushing the
! 1215: * entire ATC. The effort involved in selective flushing may not be
! 1216: * worth it, maybe we should just flush the whole thing?
! 1217: *
! 1218: * NOTE 2: With the new VM layout we now no longer know if an inactive
! 1219: * user's PTEs have been changed (formerly denoted by the SPTECHG p_flag
! 1220: * bit). For now, we just always flush the full ATC.
! 1221: */
! 1222: ENTRY(cpu_switch)
! 1223: movl _C_LABEL(curpcb),a0 | current pcb
! 1224: movw sr,a0@(PCB_PS) | save sr before changing ipl
! 1225: #ifdef notyet
! 1226: movl CURPROC,sp@- | remember last proc running
! 1227: #endif
! 1228: clrl CURPROC
! 1229:
! 1230: /*
! 1231: * Find the highest-priority queue that isn't empty,
! 1232: * then take the first proc from that queue.
! 1233: */
! 1234: movw #PSL_HIGHIPL,sr | lock out interrupts
! 1235: movl _C_LABEL(whichqs),d0
! 1236: jeq _ASM_LABEL(Idle)
! 1237: Lsw1:
! 1238: movl d0,d1
! 1239: negl d0
! 1240: andl d1,d0
! 1241: bfffo d0{#0:#32},d1
! 1242: eorib #31,d1
! 1243:
! 1244: movl d1,d0
! 1245: lslb #3,d1 | convert queue number to index
! 1246: addl #_C_LABEL(qs),d1 | locate queue (q)
! 1247: movl d1,a1
! 1248: movl a1@(P_FORW),a0 | p = q->p_forw
! 1249: cmpal d1,a0 | anyone on queue?
! 1250: jeq Lbadsw | no, panic
! 1251: movl a0@(P_FORW),a1@(P_FORW) | q->p_forw = p->p_forw
! 1252: movl a0@(P_FORW),a1 | n = p->p_forw
! 1253: movl d1,a1@(P_BACK) | n->p_back = q
! 1254: cmpal d1,a1 | anyone left on queue?
! 1255: jne Lsw2 | yes, skip
! 1256: movl _C_LABEL(whichqs),d1
! 1257: bclr d0,d1 | no, clear bit
! 1258: movl d1,_C_LABEL(whichqs)
! 1259: Lsw2:
! 1260: movl a0,CURPROC
! 1261: clrl _C_LABEL(want_resched)
! 1262: #ifdef notyet
! 1263: movl sp@+,a1
! 1264: cmpl a0,a1 | switching to same proc?
! 1265: jeq Lswdone | yes, skip save and restore
! 1266: #endif
! 1267: /*
! 1268: * Save state of previous process in its pcb.
! 1269: */
! 1270: movl _C_LABEL(curpcb),a1
! 1271: moveml #0xFCFC,a1@(PCB_REGS) | save non-scratch registers
! 1272: movl usp,a2 | grab USP (a2 has been saved)
! 1273: movl a2,a1@(PCB_USP) | and save it
! 1274: #ifdef FPU_EMULATE
! 1275: tstl _C_LABEL(fputype) | do we have any FPU?
! 1276: jeq Lswnofpsave | no, dont save
! 1277: #endif
! 1278: lea a1@(PCB_FPCTX),a2 | pointer to FP save area
! 1279: fsave a2@ | save FP state
! 1280: #ifdef M68060
! 1281: cmpl #FPU_68060,_C_LABEL(fputype) | is 68060?
! 1282: jeq Lsavfp60 | yes, goto Lsavfp60
! 1283: #endif /* M68060 */
! 1284: tstb a2@ | null state frame?
! 1285: jeq Lswnofpsave | yes, all done
! 1286: fmovem fp0-fp7,a2@(FPF_REGS) | save FP general registers
! 1287: fmovem fpcr/fpsr/fpi,a2@(FPF_FPCR) | save FP control registers
! 1288: #ifdef M68060
! 1289: jra Lswnofpsave
! 1290: Lsavfp60:
! 1291: tstb a2@(2) | null state frame?
! 1292: jeq Lswnofpsave | yes, all done
! 1293: fmovem fp0-fp7,a2@(FPF_REGS) | save FP general registers
! 1294: fmovem fpcr,a2@(FPF_FPCR) | save FP control registers
! 1295: fmovem fpsr,a2@(FPF_FPSR)
! 1296: fmovem fpi,a2@(FPF_FPI)
! 1297: #endif /* M68060 */
! 1298: Lswnofpsave:
! 1299: #ifdef DIAGNOSTIC
! 1300: tstl a0@(P_WCHAN)
! 1301: jne Lbadsw
! 1302: cmpb #SRUN,a0@(P_STAT)
! 1303: jne Lbadsw
! 1304: #endif
! 1305: movb #SONPROC,a0@(P_STAT)
! 1306: clrl a0@(P_BACK) | clear back link
! 1307: movl a0@(P_ADDR),a1 | get p_addr
! 1308: movl a1,_C_LABEL(curpcb)
! 1309:
! 1310: /*
! 1311: * Activate process's address space.
! 1312: * XXX Should remember the last USTP value loaded, and call this
! 1313: * XXX only of it has changed.
! 1314: */
! 1315: pea a0@ | push proc
! 1316: jbsr _C_LABEL(pmap_activate) | pmap_activate(p)
! 1317: addql #4,sp
! 1318: movl _C_LABEL(curpcb),a1 | restore p_addr
! 1319:
! 1320: lea _ASM_LABEL(tmpstk),sp | now goto a tmp stack for NMI
! 1321:
! 1322: moveml a1@(PCB_REGS),#0xFCFC | and registers
! 1323: movl a1@(PCB_USP),a0
! 1324: movl a0,usp | and USP
! 1325:
! 1326: #ifdef FPU_EMULATE
! 1327: tstl _C_LABEL(fputype) | do we _have_ any fpu?
! 1328: jne Lresnonofpatall
! 1329: movw a1@(PCB_PS),sr | no, restore PS
! 1330: moveq #1,d0 | return 1 (for alternate returns)
! 1331: rts
! 1332: Lresnonofpatall:
! 1333: #endif
! 1334: lea a1@(PCB_FPCTX),a0 | pointer to FP save area
! 1335: #ifdef M68060
! 1336: cmpl #FPU_68060,_C_LABEL(fputype) | is 68060?
! 1337: jeq Lresfp60rest1 | yes, goto Lresfp60rest1
! 1338: #endif /* M68060 */
! 1339: tstb a0@ | null state frame?
! 1340: jeq Lresfprest2 | yes, easy
! 1341: fmovem a0@(FPF_FPCR),fpcr/fpsr/fpi | restore FP control registers
! 1342: fmovem a0@(FPF_REGS),fp0-fp7 | restore FP general registers
! 1343: Lresfprest2:
! 1344: frestore a0@ | restore state
! 1345: movw a1@(PCB_PS),sr | no, restore PS
! 1346: moveq #1,d0 | return 1 (for alternate returns)
! 1347: rts
! 1348:
! 1349: #ifdef M68060
! 1350: Lresfp60rest1:
! 1351: tstb a0@(2) | null state frame?
! 1352: jeq Lresfp60rest2 | yes, easy
! 1353: fmovem a0@(FPF_FPCR),fpcr | restore FP control registers
! 1354: fmovem a0@(FPF_FPSR),fpsr
! 1355: fmovem a0@(FPF_FPI),fpi
! 1356: fmovem a0@(FPF_REGS),fp0-fp7 | restore FP general registers
! 1357: Lresfp60rest2:
! 1358: frestore a0@ | restore state
! 1359: movw a1@(PCB_PS),sr | no, restore PS
! 1360: moveq #1,d0 | return 1 (for alternate returns)
! 1361: rts
! 1362: #endif /* M68060 */
! 1363:
! 1364:
! 1365: /*
! 1366: * savectx(pcb)
! 1367: * Update pcb, saving current processor state.
! 1368: */
! 1369: ENTRY(savectx)
! 1370: movl sp@(4),a1
! 1371: movw sr,a1@(PCB_PS)
! 1372: movl usp,a0 | grab USP
! 1373: movl a0,a1@(PCB_USP) | and save it
! 1374: moveml #0xFCFC,a1@(PCB_REGS) | save non-scratch registers
! 1375: #ifdef FPU_EMULATE
! 1376: tstl _C_LABEL(fputype)
! 1377: jeq Lsavedone
! 1378: #endif
! 1379: lea a1@(PCB_FPCTX),a0 | pointer to FP save area
! 1380: fsave a0@ | save FP state
! 1381: #ifdef M68060
! 1382: cmpl #FPU_68060,_C_LABEL(fputype) | is 68060?
! 1383: jeq Lsavctx60 | yes, goto Lsavctx60
! 1384: #endif
! 1385: tstb a0@ | null state frame?
! 1386: jeq Lsavedone | yes, all done
! 1387: fmovem fp0-fp7,a0@(FPF_REGS) | save FP general registers
! 1388: fmovem fpcr/fpsr/fpi,a0@(FPF_FPCR) | save FP control registers
! 1389: moveq #0,d0
! 1390: rts
! 1391: #ifdef M68060
! 1392: Lsavctx60:
! 1393: tstb a0@(2)
! 1394: jeq Lsavedone
! 1395: fmovem fp0-fp7,a0@(FPF_REGS) | save FP general registers
! 1396: fmovem fpcr,a0@(FPF_FPCR) | save FP control registers
! 1397: fmovem fpsr,a0@(FPF_FPSR)
! 1398: fmovem fpi,a0@(FPF_FPI)
! 1399: #endif
! 1400: Lsavedone:
! 1401: moveq #0,d0 | return 0
! 1402: rts
! 1403:
! 1404: #if defined(M68040) || defined(M68060)
! 1405: ENTRY(suline)
! 1406: movl sp@(4),a0 | address to write
! 1407: movl _C_LABEL(curpcb),a1 | current pcb
! 1408: movl #Lslerr,a1@(PCB_ONFAULT) | where to return to on a fault
! 1409: movl sp@(8),a1 | address of line
! 1410: movl a1@+,d0 | get lword
! 1411: movsl d0,a0@+ | put lword
! 1412: nop | sync
! 1413: movl a1@+,d0 | get lword
! 1414: movsl d0,a0@+ | put lword
! 1415: nop | sync
! 1416: movl a1@+,d0 | get lword
! 1417: movsl d0,a0@+ | put lword
! 1418: nop | sync
! 1419: movl a1@+,d0 | get lword
! 1420: movsl d0,a0@+ | put lword
! 1421: nop | sync
! 1422: moveq #0,d0 | indicate no fault
! 1423: jra Lsldone
! 1424: Lslerr:
! 1425: moveq #-1,d0
! 1426: Lsldone:
! 1427: movl _C_LABEL(curpcb),a1 | current pcb
! 1428: clrl a1@(PCB_ONFAULT) | clear fault address
! 1429: rts
! 1430: #endif
! 1431:
! 1432: /*
! 1433: * Invalidate entire TLB.
! 1434: */
! 1435: ASENTRY_NOPROFILE(TBIA)
! 1436: cmpl #MMU_68040,_C_LABEL(mmutype) | 68040 or 68060?
! 1437: jle Ltbia040 | yes, goto Ltbia040
! 1438: pflusha | flush entire TLB
! 1439: tstl _C_LABEL(mmutype)
! 1440: jpl Lmc68851a | 68851 implies no d-cache
! 1441: movl #DC_CLEAR,d0
! 1442: movc d0,cacr | invalidate on-chip d-cache
! 1443: Lmc68851a:
! 1444: rts
! 1445: Ltbia040:
! 1446: .word 0xf518 | pflusha
! 1447: #ifdef M68060
! 1448: cmpl #MMU_68060,_C_LABEL(mmutype) | is 68060?
! 1449: jne Ltbiano60 | no, skip
! 1450: movc cacr,d0
! 1451: orl #IC60_CABC,d0 | and clear all branch cache entries
! 1452: movc d0,cacr
! 1453: #endif
! 1454: Ltbiano60:
! 1455: rts
! 1456:
! 1457:
! 1458: /*
! 1459: * Invalidate any TLB entry for given VA (TB Invalidate Single)
! 1460: */
! 1461: ENTRY(TBIS)
! 1462: movl sp@(4),a0 | get addr to flush
! 1463: cmpl #MMU_68040,_C_LABEL(mmutype) | 68040 or 68060 ?
! 1464: jle Ltbis040 | yes, goto Ltbis040
! 1465: tstl _C_LABEL(mmutype)
! 1466: jpl Lmc68851b | is 68851?
! 1467: pflush #0,#0,a0@ | flush address from both sides
! 1468: movl #DC_CLEAR,d0
! 1469: movc d0,cacr | invalidate on-chip data cache
! 1470: rts
! 1471: Lmc68851b:
! 1472: pflushs #0,#0,a0@ | flush address from both sides
! 1473: rts
! 1474: Ltbis040:
! 1475: moveq #FC_SUPERD,d0 | select supervisor
! 1476: movc d0,dfc
! 1477: .word 0xf508 | pflush a0@
! 1478: moveq #FC_USERD,d0 | select user
! 1479: movc d0,dfc
! 1480: .word 0xf508 | pflush a0@
! 1481: #ifdef M68060
! 1482: cmpl #MMU_68060,_C_LABEL(mmutype) | is 68060?
! 1483: jne Ltbisno60 | no, skip
! 1484: movc cacr,d0
! 1485: orl #IC60_CABC,d0 | and clear all branch cache entries
! 1486: movc d0,cacr
! 1487: Ltbisno60:
! 1488: #endif
! 1489: rts
! 1490:
! 1491: /*
! 1492: * Invalidate supervisor side of TLB
! 1493: */
! 1494: #if defined(M68060)
! 1495: ENTRY(TBIAS)
! 1496: | 68060 cannot specify supervisor/user on pflusha, so we flush all
! 1497: .word 0xf518 | pflusha
! 1498: movc cacr,d0
! 1499: orl #IC60_CABC,d0 | and clear all branch cache entries
! 1500: movc d0,cacr
! 1501: rts
! 1502: #endif
! 1503:
! 1504: #if defined(COMPAT_HPUX) || defined(M68060)
! 1505: /*
! 1506: * Invalidate user side of TLB
! 1507: */
! 1508: ENTRY(TBIAU)
! 1509: cmpl #MMU_68040,_C_LABEL(mmutype)
! 1510: jle Ltbiau040
! 1511: tstl _C_LABEL(mmutype)
! 1512: jpl Lmc68851d | 68851?
! 1513: pflush #0,#4 | flush user TLB entries
! 1514: movl #DC_CLEAR,d0
! 1515: movc d0,cacr | invalidate on-chip d-cache
! 1516: rts
! 1517: Lmc68851d:
! 1518: pflushs #0,#4 | flush user TLB entries
! 1519: rts
! 1520: Ltbiau040:
! 1521: | 68040 cannot specify supervisor/user on pflusha, so we flush all
! 1522: .word 0xf518 | pflusha
! 1523: #ifdef M68060
! 1524: cmpl #MMU_68060,_C_LABEL(mmutype)
! 1525: jne Ltbiauno60
! 1526: movc cacr,d0
! 1527: orl #IC60_CUBC,d0 | but only user branch cache entries
! 1528: movc d0,cacr
! 1529: Ltbiauno60:
! 1530: #endif
! 1531: rts
! 1532: #endif /* defined(COMPAT_HPUX) || defined(M68060) */
! 1533:
! 1534: /*
! 1535: * Invalidate instruction cache
! 1536: */
! 1537: ENTRY(ICIA)
! 1538: #if defined(M68040) || defined(M68060)
! 1539: cmpl #MMU_68040,_C_LABEL(mmutype) | 68040 or 68060?
! 1540: jgt 1f | no, skip
! 1541: .word 0xf498 | cinva ic
! 1542: rts
! 1543: 1:
! 1544: #endif
! 1545: movl #IC_CLEAR,d0
! 1546: movc d0,cacr | invalidate i-cache
! 1547: rts
! 1548:
! 1549: /*
! 1550: * Invalidate data cache.
! 1551: *
! 1552: * NOTE: we do not flush 68030 on-chip cache as there are no aliasing
! 1553: * problems with DC_WA. The only cases we have to worry about are context
! 1554: * switch and TLB changes, both of which are handled "in-line" in resume
! 1555: * and TBI*.
! 1556: * Because of this, since there is no way on 68040 and 68060 to flush
! 1557: * user and supervisor modes specfically, DCIS and DCIU are the same entry
! 1558: * point as DCIA.
! 1559: */
! 1560: ENTRY(DCIA)
! 1561: ENTRY(DCIS)
! 1562: ENTRY(DCIU)
! 1563: #if defined(M68040) || defined(M68060)
! 1564: cmpl #MMU_68040,_C_LABEL(mmutype) | 68040 or 68060?
! 1565: jgt 1f | no, skip
! 1566: .word 0xf478 | cpusha dc
! 1567: #endif
! 1568: rts
! 1569:
! 1570: #if defined(M68040) || defined(M68060)
! 1571: ENTRY(ICPA)
! 1572: .word 0xf498 | cinva ic
! 1573: rts
! 1574: ENTRY(DCFA)
! 1575: .word 0xf478 | cpusha dc
! 1576: rts
! 1577: ENTRY(ICPL)
! 1578: movl sp@(4),a0 | address
! 1579: .word 0xf488 | cinvl ic,a0@
! 1580: rts
! 1581: ENTRY(ICPP)
! 1582: movl sp@(4),a0 | address
! 1583: .word 0xf490 | cinvp ic,a0@
! 1584: rts
! 1585: ENTRY(DCPL)
! 1586: movl sp@(4),a0 | address
! 1587: .word 0xf448 | cinvl dc,a0@
! 1588: rts
! 1589: ENTRY(DCPP)
! 1590: movl sp@(4),a0 | address
! 1591: .word 0xf450 | cinvp dc,a0@
! 1592: rts
! 1593: ENTRY(DCFL)
! 1594: movl sp@(4),a0 | address
! 1595: .word 0xf468 | cpushl dc,a0@
! 1596: rts
! 1597: ENTRY(DCFP)
! 1598: movl sp@(4),a0 | address
! 1599: .word 0xf470 | cpushp dc,a0@
! 1600: rts
! 1601: #endif
! 1602:
! 1603: ENTRY(getsfc)
! 1604: movc sfc,d0
! 1605: rts
! 1606:
! 1607: ENTRY(getdfc)
! 1608: movc dfc,d0
! 1609: rts
! 1610:
! 1611: /*
! 1612: * Load a new user segment table pointer.
! 1613: */
! 1614: ENTRY(loadustp)
! 1615: movl sp@(4),d0 | new USTP
! 1616: moveq #PGSHIFT,d1
! 1617: lsll d1,d0 | convert to addr
! 1618: #if defined(M68040) || defined(M68060)
! 1619: cmpl #MMU_68040,_C_LABEL(mmutype)
! 1620: #ifdef M68060
! 1621: jlt Lldustp060
! 1622: #endif
! 1623: #ifdef M68040
! 1624: jeq Lldustp040
! 1625: #endif
! 1626: #endif
! 1627: pflusha | flush entire TLB
! 1628: lea _C_LABEL(protorp),a0 | CRP prototype
! 1629: movl d0,a0@(4) | stash USTP
! 1630: pmove a0@,crp | load root pointer
! 1631: movl #CACHE_CLR,d0
! 1632: movc d0,cacr | invalidate cache(s)
! 1633: rts
! 1634:
! 1635: #ifdef M68060
! 1636: Lldustp060:
! 1637: movc cacr,d1
! 1638: orl #IC60_CUBC,d1 | clear user branch cache entries
! 1639: movc d1,cacr
! 1640: /* FALLTHROUGH */
! 1641: #endif
! 1642: Lldustp040:
! 1643: .word 0xf518 | pflusha
! 1644: .long 0x4e7b0806 | movec d0,URP
! 1645: rts
! 1646:
! 1647: /*
! 1648: * Set processor priority level calls. Most are implemented with
! 1649: * inline asm expansions. However, spl0 requires special handling
! 1650: * as we need to check for our emulated software interrupts.
! 1651: */
! 1652:
! 1653: ENTRY(spl0)
! 1654: moveq #0,d0
! 1655: movw sr,d0 | get old SR for return
! 1656: movw #PSL_LOWIPL,sr | restore new SR
! 1657: tstb _C_LABEL(ssir) | software interrupt pending?
! 1658: jeq Lspldone | no, all done
! 1659: subql #4,sp | make room for RTE frame
! 1660: movl sp@(4),sp@(2) | position return address
! 1661: clrw sp@(6) | set frame type 0
! 1662: movw #PSL_LOWIPL,sp@ | and new SR
! 1663: jra Lgotsir | go handle it
! 1664: Lspldone:
! 1665: rts
! 1666:
! 1667: /*
! 1668: * Save and restore 68881 state.
! 1669: * Pretty awful looking since our assembler does not
! 1670: * recognize FP mnemonics.
! 1671: */
! 1672: ENTRY(m68881_save)
! 1673: movl sp@(4),a0 | save area pointer
! 1674: fsave a0@ | save state
! 1675: #ifdef M68060
! 1676: cmpl #FPU_68060,_C_LABEL(fputype) | is 68060?
! 1677: jeq Lm68060fpsave | yes, goto Lm68060fpsave
! 1678: #endif
! 1679: tstb a0@ | null state frame?
! 1680: jeq Lm68881sdone | yes, all done
! 1681: fmovem fp0-fp7,a0@(FPF_REGS) | save FP general registers
! 1682: fmovem fpcr/fpsr/fpi,a0@(FPF_FPCR) | save FP control registers
! 1683: Lm68881sdone:
! 1684: rts
! 1685:
! 1686: #ifdef M68060
! 1687: Lm68060fpsave:
! 1688: tstb a0@(2) | null state frame?
! 1689: jeq Lm68060sdone | yes, all done
! 1690: fmovem fp0-fp7,a0@(FPF_REGS) | save FP general registers
! 1691: fmovem fpcr,a0@(FPF_FPCR) | save FP control registers
! 1692: fmovem fpsr,a0@(FPF_FPSR)
! 1693: fmovem fpi,a0@(FPF_FPI)
! 1694: Lm68060sdone:
! 1695: rts
! 1696: #endif
! 1697:
! 1698: ENTRY(m68881_restore)
! 1699: movl sp@(4),a0 | save area pointer
! 1700: #ifdef M68060
! 1701: cmpl #FPU_68060,_C_LABEL(fputype) | is 68060?
! 1702: jeq Lm68060fprestore | yes, goto Lm68060fprestore
! 1703: #endif
! 1704: tstb a0@ | null state frame?
! 1705: jeq Lm68881rdone | yes, easy
! 1706: fmovem a0@(FPF_FPCR),fpcr/fpsr/fpi | restore FP control registers
! 1707: fmovem a0@(FPF_REGS),fp0-fp7 | restore FP general registers
! 1708: Lm68881rdone:
! 1709: frestore a0@ | restore state
! 1710: rts
! 1711:
! 1712: #ifdef M68060
! 1713: Lm68060fprestore:
! 1714: tstb a0@(2) | null state frame?
! 1715: jeq Lm68060fprdone | yes, easy
! 1716: fmovem a0@(FPF_FPCR),fpcr | restore FP control registers
! 1717: fmovem a0@(FPF_FPSR),fpsr
! 1718: fmovem a0@(FPF_FPI),fpi
! 1719: fmovem a0@(FPF_REGS),fp0-fp7 | restore FP general registers
! 1720: Lm68060fprdone:
! 1721: frestore a0@ | restore state
! 1722: rts
! 1723: #endif
! 1724:
! 1725: /*
! 1726: * Handle the nitty-gritty of rebooting the machine.
! 1727: * Basically we just turn off the MMU and jump to the appropriate ROM routine.
! 1728: * XXX add support for rebooting -- that means looking at boothowto and doing
! 1729: * the right thing
! 1730: */
! 1731: ENTRY_NOPROFILE(doboot)
! 1732: lea _ASM_LABEL(tmpstk),sp | physical SP in case of NMI
! 1733: #if defined(M68040) || defined(M68060)
! 1734: cmpl #MMU_68040,_C_LABEL(mmutype) | 68040?
! 1735: jgt Lbootnot040 | no, skip
! 1736: movl #0,d0
! 1737: movc d0,cacr | caches off
! 1738: .long 0x4e7b0003 | movc d0,tc (turn off MMU)
! 1739: bra 1f
! 1740: Lbootnot040:
! 1741: #endif
! 1742: movl #CACHE_OFF,d0
! 1743: movc d0,cacr | disable on-chip cache(s)
! 1744: movl #0,a7@ | value for pmove to TC (turn off MMU)
! 1745: pmove a7@,tc | disable MMU
! 1746:
! 1747: 1: movl #0,d0
! 1748: movc d0,vbr | ROM VBR
! 1749:
! 1750: /*
! 1751: * We're going down. Make various sick attempts to reset the board.
! 1752: */
! 1753: RELOC(cputyp, a0)
! 1754: movl a0@,d0
! 1755: cmpw #CPU_147,d0
! 1756: bne not147
! 1757: movl #0xfffe2000,a0 | MVME147: "struct vme1reg *"
! 1758: movw a0@,d0
! 1759: movl d0,d1
! 1760: andw #0x0001,d1 | is VME1_SCON_SWITCH set?
! 1761: beq 1f | not SCON. may not use SRESET.
! 1762: orw #0x0002,d0 | ok, assert VME1_SCON_SRESET
! 1763: movw d0,a0@
! 1764: 1:
! 1765: movl #0xff800000,a0 | if we get here, SRESET did not work.
! 1766: movl a0@(4),a0 | try jumping directly to the ROM.
! 1767: jsr a0@
! 1768: | still alive! just return to the prom..
! 1769: bra 3f
! 1770:
! 1771: not147:
! 1772: movl #0xfff40000,a0 | MVME16x: "struct vme2reg *"
! 1773: movl a0@(0x60),d0
! 1774: movl d0,d1
! 1775: andl #0x40000000,d1 | is VME2_TCTL_SCON set?
! 1776: beq 1f | not SCON. may not use SRESET.
! 1777: orl #0x00800000,d0 | ok, assert VME2_TCTL_SRST
! 1778: movl d0,a0@(0x60)
! 1779: 1:
! 1780: | lets try the local bus reset
! 1781: movl #0xfff40000,a0 | MVME16x: "struct vme2reg *"
! 1782: movl a0@(0x104),d0
! 1783: orw #0x00000080,d0
! 1784: movl d0,a0@(0x104)
! 1785: | lets try jumping off to rom.
! 1786: movl #0xff800000,a0 | if we get here, SRESET did not work.
! 1787: movl a0@(4),a0 | try jumping directly to the ROM.
! 1788: jsr a0@
! 1789: | still alive! just return to the prom..
! 1790:
! 1791: 3: BUGCALL(MVMEPROM_EXIT) | return to m68kbug
! 1792: /*NOTREACHED*/
! 1793:
! 1794: #if defined(M68060) && defined(M060SP)
! 1795: GLOBAL(intemu60)
! 1796: jra _I_CALL_TOP+128+0x00
! 1797: GLOBAL(fpiemu60)
! 1798: jra _FP_CALL_TOP+128+0x30
! 1799: GLOBAL(fpdemu60)
! 1800: jra _FP_CALL_TOP+128+0x38
! 1801: GLOBAL(fpeaemu60)
! 1802: jra _FP_CALL_TOP+128+0x40
! 1803: #endif
! 1804:
! 1805: .data
! 1806: GLOBAL(mmutype)
! 1807: .long MMU_68030 | default to MMU_68030
! 1808: GLOBAL(cputype)
! 1809: .long CPU_68030 | default to CPU_68030
! 1810: GLOBAL(fputype)
! 1811: .long FPU_68881 | default to 68881 FPU
! 1812: GLOBAL(protorp)
! 1813: .long 0,0 | prototype root pointer
! 1814: GLOBAL(cold)
! 1815: .long 1 | cold start flag
! 1816: GLOBAL(want_resched)
! 1817: .long 0
! 1818: GLOBAL(proc0paddr)
! 1819: .long 0 | KVA of proc0 u-area
! 1820: GLOBAL(intiobase)
! 1821: .long 0 | KVA of base of internal IO space
! 1822: GLOBAL(intiolimit)
! 1823: .long 0 | KVA of end of internal IO space
! 1824: GLOBAL(extiobase)
! 1825: .long 0 | KVA of base of external IO space
! 1826:
! 1827: #include <mvme68k/mvme68k/vectors.s>
CVSweb