1: / 2: / SCCS id @(#)M.s 1.7 (Berkeley) 7/11/83 3: / @(#)M.s 3.1 (2.11BSD) 1995/06/01 (sms@wlv.iipo.gtegsc.com) 4: / 5: / Startup code for two-stage bootstrap with support for autoboot. 6: / Supports 11/45, 11/70, 11/53, 11/73, 11/83, 11/84, 11/93, 11/94 7: 8: / The boot options and device are placed in the last SZFLAGS bytes 9: / at the end of core by the kernel if this is an autoboot. 10: / The first-stage boot will leave them in registers for us; 11: / we clobber possible old flags so that they don't get re-used. 12: ENDCORE= 160000 / end of core, mem. management off 13: SZFLAGS= 6 / size of boot flags 14: BOOTOPTS= 2 / location of options, bytes below ENDCORE 15: BOOTDEV= 4 / makedev(major,unit) 16: CHECKWORD= 6 / ~BOOTOPTS 17: 18: .globl _end 19: .globl _main,_ubmapset 20: jmp start 21: 22: / 23: / trap vectors 24: / 25: trap;340 / bus error -- grok! 26: trap;341 / illegal instruction 27: trap;342 / BPT 28: trap;343 / IOT 29: trap;344 / POWER FAIL 30: trap;345 / EMT 31: tvec: 32: start;346 / TRAP 33: 34: / NOTE NOTE NOTE NOTE NOTE NOTE 35: / 36: / Here is a totally tacky ``fix'' if your kernel is larger than 37: / 192K and therefore overwrites boot here. Just change the .=400^. 38: / below to something like .=10240^. This will move the critical 39: / sections of boot up far enough so that the load can finish. 40: / We can't actually load boot too much higher because it can't use memory 41: / above 256-8K (to avoid UNIBUS mapping problems). 42: / 43: .=400^. 44: 45: start: 46: reset 47: mov $340,PS 48: mov $_end+512.,sp 49: 50: /save boot options, if present 51: mov r4,_bootopts 52: mov r3,_bootdev 53: mov r2,_checkword 54: mov r1,_bootcsr / 'boot' will apply ADJcsr[] correction 55: /clobber any boot flags left in memory 56: clr ENDCORE-BOOTOPTS 57: clr ENDCORE-BOOTDEV 58: clr ENDCORE-CHECKWORD 59: / 60: / determine what kind of cpu we are running on. this was totally rewritten 61: / when support for the 93 and 94 was added. 62: 63: clrb _sep_id 64: clrb _ubmap 65: jsr pc,cpuprobe / fill in _cputype, _ubmap and _sep_id 66: / also sets MSCR bits 67: clr nofault 68: 69: / 70: / Set kernel I space registers to physical 0 and I/O page 71: / 72: clr r1 73: mov $77406, r2 74: mov $KISA0, r3 75: mov $KISD0, r4 76: jsr pc, setseg 77: mov $IO, -(r3) 78: 79: 80: / Set user I space registers to physical N*64kb and I/O page. This is 81: / where boot will copy itself to. Boot is less simple minded about its 82: / I/O addressing than it used to be. Physical memory addresses are now 83: / calculated (because support was needed for running split I/D utilities) 84: / rather than assuming that boot is loaded on a 64kb boundary. 85: / 86: / The constraint forcing us to keep boot in the bottom 248Kb of 87: / memory is UNIBUS mapping. There would be little difficulty in relocating 88: / Boot much higher on a Qbus system. 89: / 90: / Unless boot's method of managing its I/O addressing and physical addressing 91: / is reworked some more, 3*64Kb +/- a couple Kb is probably the highest 92: / we'll ever relocate boot. This means that the maximum size 93: / of any program boot can load is ~192Kb. That size includes text, data 94: / and bss. 95: 96: N = 3 / 3*64Kb = 192Kb 97: 98: mov $N*64.*16., r1 / N*64 * btoc(1024) 99: mov $UISA0, r3 100: mov $UISD0, r4 101: jsr pc, setseg 102: mov $IO, -(r3) 103: 104: / 105: / If 11/40 class processor, only need set the I space registers 106: / 107: movb _sep_id, _ksep 108: jeq 1f 109: 110: / 111: / Set kernel D space registers to physical 0 and I/O page 112: / 113: clr r1 114: mov $KDSA0, r3 115: mov $KDSD0, r4 116: jsr pc, setseg 117: mov $IO, -(r3) 118: 119: / 120: / Set user D space registers to physical N*64kb and I/O page 121: / 122: mov $N*64.*16., r1 / N*64 * btoc(1024) 123: mov $UDSA0, r3 124: mov $UDSD0, r4 125: jsr pc, setseg 126: mov $IO, -(r3) 127: 128: 1: 129: / enable map 130: tstb _ubmap 131: beq 2f 132: jsr pc,_ubmapset / 24, 44, 70 -> ubmap 133: tstb _sep_id 134: bne 3f 135: mov $60,SSR3 / 24 -> !I/D 136: br 1f 137: 3: 138: mov $65,SSR3 / 44, 70 -> ubmap, I/D 139: br 1f 140: 2: 141: tstb _sep_id / 23, 34, 40, 45, 60, 73 -> no ubmap 142: beq 1f 143: mov $25,SSR3 / 45, 73 -> no ubmap, I/D; maybe 22-bit 144: 1: 145: mov $30340,PS 146: inc SSR0 / turn on memory management 147: 148: / copy program to user I space 149: mov $_end,r0 150: clc 151: ror r0 152: clr r1 153: 1: 154: mov (r1),-(sp) 155: mtpi (r1)+ 156: sob r0,1b 157: 158: / continue execution in user space copy. No sense in loading sp with 159: / anything special since the call to _main below overwrites low core. 160: 161: mov $140340,-(sp) 162: mov $user,-(sp) 163: rtt 164: user: 165: / clear bss 166: mov $_edata,r0 167: mov $_end,r1 168: sub r0,r1 169: inc r1 170: clc 171: ror r1 172: 1: 173: clr (r0)+ 174: sob r1,1b 175: mov $_end+512.,sp 176: mov sp,r5 177: 178: jsr pc,_main 179: mov _cputype,r0 180: mov _bootcsr,r1 / csr of boot controller (from ROMs) 181: mov _bootdev,r3 / makedev(major,unit) (from ROMs & bootblock) 182: mov _bootopts,r4 183: mov r4,r2 184: com r2 / checkword 185: mov $160000,-(sp) / set ksp to very top so that the trap 186: mtpi sp / puts the return address and psw at 157774,6 187: sys 0 / can't use "trap" because that's a label 188: 189: br user 190: 191: cpuprobe: 192: mov $1f,nofault / catch possible trap 193: tst *$UBMAP / look for unibus map 194: incb _ubmap / we've got one, note that and continue on 195: 1: 196: mov $1f,nofault 197: tst *$KDSA6 / look for split I/D 198: incb _sep_id 199: 1: 200: mov $nomfpt,nofault / catch possible fault from instruction 201: mfpt / 23/24, 44, and KDJ-11 have this instruction 202: cmp r0,$1 / 44? 203: bne 1f / no - br 204: mov $1,*$MSCR / disable cache parity traps 205: mov $44.,_cputype 206: rts pc 207: 1: 208: cmp r0,$5 / KDJ-11? 209: bne 2f / no - br 210: mov *$MAINT,r0 / get system maint register 211: ash $-4,r0 / move down and 212: bic $177760,r0 / isolate the module id 213: mov $1,*$MSCR / disable cache parity traps 214: movb j11typ(r0),r0 / lookup cpu type 215: movb _ubmap,r1 / unibus? 216: beq 1f / nope - br 217: bis $2,*$MSCR / disable unibus traps 218: 1: 219: add r1,r0 / bump the cpu type (93 -> 94, 83 ->84) 220: br out 221: 2: 222: cmp r0,$3 / 23 or 24? 223: bne nomfpt / mfpt returned other than 1,3,5 - HELP! 224: mov $23.,r0 / assume 23 225: movb _ubmap,r1 / add in... 226: add r1,r0 / the unibus flag (23 -> 24) 227: br out 228: nomfpt: 229: tstb _sep_id / split I/D present? 230: beq 2f / no - br 231: mov $45.,r0 / assume 45 232: tstb _ubmap / is that correct? 233: beq out / yes - br 234: mov $3,*$MSCR / disable unibus and cache traps 235: mov $70.,r0 236: br out 237: 2: 238: mov $40.,r0 / assume 40 239: mov $out,nofault 240: tst *$MSCR / 60 has MSCR, 40 doesn't 241: mov $60.,r0 242: mov $1,*$MSCR 243: out: 244: mov r0,_cputype 245: rts pc 246: 247: setseg: 248: mov $8,r0 249: 1: 250: mov r1,(r3)+ 251: add $200,r1 252: mov r2,(r4)+ 253: sob r0,1b 254: rts pc 255: 256: .globl _setseg 257: _setseg: 258: mov 2(sp),r1 259: mov r2,-(sp) 260: mov r3,-(sp) 261: mov r4,-(sp) 262: mov $77406,r2 263: mov $KISA0,r3 264: mov $KISD0,r4 265: jsr pc,setseg 266: tstb _ksep 267: bne 1f 268: mov $IO,-(r3) 269: 1: 270: mov (sp)+,r4 271: mov (sp)+,r3 272: mov (sp)+,r2 273: rts pc 274: 275: .globl _setnosep 276: _setnosep: 277: bic $4,SSR3 / turn off kernel i/d sep 278: clrb _ksep 279: rts pc 280: 281: .globl _setsep 282: _setsep: 283: bis $4,SSR3 / turn on kernel i/d sep (if not already) 284: movb $1,_ksep 285: rts pc 286: 287: / clrseg(addr,count) 288: .globl _clrseg 289: _clrseg: 290: mov 4(sp),r0 291: asr r0 292: bic $!77777,r0 293: beq 2f 294: mov 2(sp),r1 295: 1: 296: clr -(sp) 297: mtpi (r1)+ 298: sob r0,1b 299: 2: 300: rts pc 301: 302: / mtpd(word,addr) 303: .globl _mtpd 304: _mtpd: 305: mov 4(sp),r0 306: mov 2(sp),-(sp) 307: mtpd (r0)+ 308: rts pc 309: 310: / mtpi(word,addr) 311: .globl _mtpi 312: _mtpi: 313: mov 4(sp),r0 314: mov 2(sp),-(sp) 315: mtpi (r0)+ 316: rts pc 317: 318: .globl __rtt 319: __rtt: 320: br . / Can't do halt because that is an illegal 321: / instruction in 'user mode' (which Boot 322: / runs in). 323: 324: .globl _trap 325: 326: trap: 327: mov *$PS,-(sp) 328: tst nofault 329: bne 3f 330: mov r0,-(sp) 331: mov r1,-(sp) 332: jsr pc,_trap 333: mov (sp)+,r1 334: mov (sp)+,r0 335: tst (sp)+ 336: rtt 337: 3: tst (sp)+ 338: mov nofault,(sp) 339: rtt 340: 341: PS = 177776 342: SSR0 = 177572 343: SSR1 = 177574 344: SSR2 = 177576 345: SSR3 = 172516 346: KISA0 = 172340 347: KISA6 = 172354 348: KISD0 = 172300 349: KISD7 = 172316 350: KDSA0 = 172360 351: KDSA6 = 172374 352: KDSD0 = 172320 353: UISA0 = 177640 354: UISD0 = 177600 355: UDSA0 = 177660 356: UDSD0 = 177620 357: MSCR = 177746 / 11/44/60/70 memory system cache control register 358: MAINT = 177750 / KDJ-11 system maintenance register 359: IO = 177600 360: UBMAP = 170200 361: 362: .data 363: .globl _cputype 364: .globl _ksep, _sep_id, _ubmap, _ssr3copy 365: .globl _bootopts, _bootdev, _checkword, _bootcsr, _bootctlr 366: 367: _ssr3copy: .=.+2 / copy of SSR3. Always 0 in Boot because that runs 368: / in user mode. The standalone utilities which run 369: / in kernel mode have their copy of SSR3 in srt0.s 370: nofault: .=.+2 / where to go on predicted trap 371: _cputype: .=.+2 / cpu type 372: _sep_id: .=.+1 / 1 if we have separate I and D 373: _ksep: .=.+1 / 1 if kernel mode has sep I/D enabled 374: _ubmap: .=.+2 / 1 if we have a unibus map 375: _bootopts: .=.+2 / flags if an autoboot 376: _bootdev: .=.+2 / device booted from 377: _bootcsr: .=.+2 / csr of device booted from 378: _bootctlr: .=.+2 / number of controller booted from 379: _checkword: .=.+2 / saved r2, complement of bootopts if an autoboot 380: j11typ: .byte 0, 73., 83., 0, 53., 93.