1: / 2: / SCCS id @(#)M.s 1.7 (Berkeley) 7/11/83 3: / 4: / Startup code for two-stage bootstrap 5: / With support for UCB_AUTOBOOT 6: / Supports 11/40, 11/45, 11/70, 11/23, 11/23+I/O map (11/24) 7: / and similar machines 8: 9: / non-UNIX instructions 10: mfpi = 6500^tst 11: stst = 170300^tst 12: mtpi = 6600^tst 13: mfpd = 106500^tst 14: mtpd = 106600^tst 15: spl = 230 16: ldfps = 170100^tst 17: stfps = 170200^tst 18: wait = 1 19: rtt = 6 20: halt = 0 21: reset = 5 22: systrap = 104400 23: 24: / The boot options and device are placed in the last SZFLAGS bytes 25: / at the end of core by the kernel if this is an autoboot. 26: / The first-stage boot will leave them in registers for us; 27: / we clobber possible old flags so that they don't get re-used. 28: ENDCORE= 160000 / end of core, mem. management off 29: SZFLAGS= 6 / size of boot flags 30: BOOTOPTS= 2 / location of options, bytes below ENDCORE 31: BOOTDEV= 4 32: CHECKWORD= 6 33: 34: .globl _end 35: .globl _main,_ubmapset 36: jmp start 37: 38: / 39: / trap vectors 40: / 41: trap;340 / bus error -- grok! 42: trap;341 / illegal instruction 43: trap;342 / BPT 44: trap;343 / IOT 45: trap;344 / POWER FAIL 46: trap;345 / EMT 47: tvec: 48: start;346 / TRAP 49: .=400^. 50: 51: 52: start: 53: reset 54: mov $340,PS 55: mov $140100,sp 56: 57: /save boot options, if present 58: mov r4,_bootopts 59: mov r3,_bootdev 60: mov r2,_checkword 61: /clobber any boot flags left in memory 62: clr ENDCORE-BOOTOPTS 63: clr ENDCORE-BOOTDEV 64: clr ENDCORE-CHECKWORD 65: / 66: / determine what kind of cpu we are running on 67: / first, check switches. if they are 40, 24, 45 or 70 68: / set appropriately 69: / 70: clrb _sep_id 71: clrb _ubmap 72: clrb _haveCSW 73: mov $2f,nofault / check if we even have switches! 74: tst *$SWREG 75: clr nofault / apparently we do 76: incb _haveCSW 77: mov $40.,r0 78: cmp *$SWREG,$40 79: beq gotcha 80: cmp *$SWREG,$24 81: bne 1f 82: mov $24.,r0 83: incb _ubmap 84: jbr gotcha 85: 1: 86: cmp *$SWREG,$45 87: bne 1f 88: mov $45.,r0 89: incb _sep_id 90: jbr gotcha 91: 1: 92: cmp *$SWREG,$70 93: bne 2f 94: mov $70.,r0 95: incb _sep_id 96: incb _ubmap 97: jbr gotcha 98: / 99: / if we can't find out from switches, 100: / explore and see what we find 101: / 102: 2: 103: mov $40.,r0 / assume 11/40 104: mov $2f,nofault 105: mov *$KDSA6,r1 / then we have sep i/d 106: incb _sep_id 107: mov $45.,r0 108: mov $1f,nofault 109: mov *$UBMAP,r1 / then we have a unibus map 110: incb _ubmap 111: mov $70.,r0 112: br 1f 113: 2: 114: mov $1f,nofault 115: mov *$UBMAP,r1 / then we have a unibus map 116: incb _ubmap 117: mov $24.,r0 / unibus map, no sep. I/D = 24 118: 1: clr nofault 119: gotcha: 120: mov r0,_cputype 121: 122: / 123: / Set kernel I space registers to physical 0 and I/O page 124: / 125: clr r1 126: mov $77406, r2 127: mov $KISA0, r3 128: mov $KISD0, r4 129: jsr pc, setseg 130: mov $IO, -(r3) 131: 132: / 133: / Set user I space registers to physical 128kb and I/O page 134: / 135: mov $4000, r1 / 04000 = 128*1024/64 136: mov $UISA0, r3 137: mov $UISD0, r4 138: jsr pc, setseg 139: mov $IO, -(r3) 140: 141: / 142: / If 11/40 class processor, only need set the I space registers 143: / 144: tstb _sep_id 145: jeq 1f 146: 147: / 148: / Set kernel D space registers to physical 0 and I/O page 149: / 150: clr r1 151: mov $KDSA0, r3 152: mov $KDSD0, r4 153: jsr pc, setseg 154: mov $IO, -(r3) 155: 156: / 157: / Set user D space registers to physical 128kb and I/O page 158: / 159: mov $4000, r1 / 04000 = 128*1024/64 160: mov $UDSA0, r3 161: mov $UDSD0, r4 162: jsr pc, setseg 163: mov $IO, -(r3) 164: 165: 1: 166: / enable map 167: clrb _ksep 168: tstb _ubmap 169: beq 2f 170: jsr pc,_ubmapset 171: tstb _sep_id 172: bne 3f 173: mov $60,SSR3 / 22-bit map, no separation 174: br 1f 175: 3: 176: mov $65,SSR3 / 22-bit map, sep. I/D user and kernel 177: movb $1,_ksep 178: cmp _cputype,$70. 179: jne 1f 180: mov $3,MSCR 181: br 1f 182: 2: 183: tstb _sep_id / no ubmap; sep_id? 184: beq 1f 185: mov $5,SSR3 186: movb $1,_ksep 187: 1: 188: mov $30340,PS 189: inc SSR0 190: 191: 192: / copy program to user I space 193: mov $_end,r0 194: asr r0 195: clr r1 196: 1: 197: mov (r1),-(sp) 198: mtpi (r1)+ 199: sob r0,1b 200: 201: 202: / continue execution in user space copy 203: mov $140004,sp 204: tstb _sep_id 205: bne 1f 206: clr *$KISA6 207: br 2f 208: 1: 209: clr *$KDSA6 210: 2: mov $140340,-(sp) 211: mov $user,-(sp) 212: rtt 213: user: 214: / clear bss 215: mov $_edata,r0 216: mov $_end,r1 217: sub r0,r1 218: inc r1 219: clc 220: ror r1 221: 1: 222: clr (r0)+ 223: sob r1,1b 224: mov $_end+512.,sp 225: mov sp,r5 226: 227: jsr pc,_main 228: mov _cputype,r0 229: mov _bootopts,r4 230: mov r4,r2 231: com r2 / checkword 232: systrap 233: 234: br user 235: 236: setseg: 237: mov $8,r0 238: 1: 239: mov r1,(r3)+ 240: add $200,r1 241: mov r2,(r4)+ 242: sob r0,1b 243: rts pc 244: 245: .globl _setseg 246: _setseg: 247: mov 2(sp),r1 248: mov r2,-(sp) 249: mov r3,-(sp) 250: mov r4,-(sp) 251: mov $77406,r2 252: mov $KISA0,r3 253: mov $KISD0,r4 254: jsr pc,setseg 255: tstb _ksep 256: bne 1f 257: mov $IO,-(r3) 258: 1: 259: mov (sp)+,r4 260: mov (sp)+,r3 261: mov (sp)+,r2 262: rts pc 263: 264: .globl _setnosep 265: _setnosep: 266: bic $4,SSR3 / turn off kernel i/d sep 267: clrb _ksep 268: rts pc 269: 270: .globl _setsep 271: _setsep: 272: bis $4,SSR3 / turn on kernel i/d sep (if not already) 273: movb $1,_ksep 274: rts pc 275: 276: / Relocate higher in memory for large kernel. 277: .globl _reloc, _segflag 278: _reloc: 279: jsr r5, csv 280: mov $2f, nofault 281: / Set Kernel I to point to new area 282: mov $6000, r1 / 192 KB 283: mov $77406,r2 284: mov $KISA0, r3 285: mov $KISD0, r4 286: jsr pc, setseg 287: / Copy to new area 288: clr r0 289: mov $28.*1024., r1 / 28 K words 290: 1: 291: mov (r0), -(sp) 292: mtpi (r0)+ 293: sob r1, 1b 294: clr nofault 295: 296: / Repoint kernel I at 0. 297: clr -(sp) 298: jsr pc, _setseg 299: tst (sp)+ 300: 301: / Point User D at new area 302: tstb _sep_id 303: beq 1f 304: mov $6000, r1 / 192 KB 305: mov $UDSA0, r3 306: mov $UDSD0, r4 307: jsr pc, setseg 308: mov $IO, -(r3) 309: 310: / Now User I-- execution switches to new copy. 311: 1: 312: mov $6000, r1 / 192 KB 313: mov $UISA0, r3 314: mov $UISD0, r4 315: mov $7,r0 316: 1: 317: mov r1,(r3)+ 318: add $200,r1 319: mov r2,(r4)+ 320: sob r0,1b 321: 322: mov $3, _segflag / new extension bits 323: clr r0 / success 324: jmp cret 325: 326: / Trap here on bus error (not enough memory) 327: 2: 328: mov $-1, r0 329: jmp cret 330: 331: / clrseg(addr,count) 332: .globl _clrseg 333: _clrseg: 334: mov 4(sp),r0 335: beq 2f 336: asr r0 337: bic $!77777,r0 338: mov 2(sp),r1 339: 1: 340: clr -(sp) 341: mtpi (r1)+ 342: sob r0,1b 343: 2: 344: rts pc 345: 346: 347: / mtpd(word,addr) 348: .globl _mtpd 349: _mtpd: 350: mov 4(sp),r0 351: mov 2(sp),-(sp) 352: mtpd (r0)+ 353: rts pc 354: 355: / mtpi(word,addr) 356: .globl _mtpi 357: _mtpi: 358: mov 4(sp),r0 359: mov 2(sp),-(sp) 360: mtpi (r0)+ 361: rts pc 362: 363: .globl __rtt 364: __rtt: 365: halt 366: 367: .globl _trap 368: 369: trap: 370: mov *$PS,-(sp) 371: mov r0,-(sp) 372: mov r1,-(sp) 373: tst nofault 374: bne 3f 375: jsr pc,_trap 376: mov (sp)+,r1 377: mov (sp)+,r0 378: tst (sp)+ 379: rtt 380: 3: mov (sp)+,r1 381: mov (sp)+,r0 382: tst (sp)+ 383: mov nofault,(sp) 384: rtt 385: 386: PS = 177776 387: SSR0 = 177572 388: SSR1 = 177574 389: SSR2 = 177576 390: SSR3 = 172516 391: KISA0 = 172340 392: KISA1 = 172342 393: KISA6 = 172354 394: KISA7 = 172356 395: KISD0 = 172300 396: KISD7 = 172316 397: KDSA0 = 172360 398: KDSA6 = 172374 399: KDSA7 = 172376 400: KDSD0 = 172320 401: KDSD5 = 172332 402: SISA0 = 172240 403: SISA1 = 172242 404: SISD0 = 172200 405: SISD1 = 172202 406: UISA0 = 177640 407: UISD0 = 177600 408: UDSA0 = 177660 409: UDSD0 = 177620 410: MSCR = 017777746 / 11/70 memory control register 411: IO = 177600 412: SWREG = 177570 413: UBMAP = 170200 414: 415: 416: .data 417: .globl _cputype 418: .globl _ksep, _sep_id, _ubmap, _haveCSW 419: .globl _bootopts, _bootdev, _checkword 420: 421: nofault: .=.+2 / where to go on predicted trap 422: _cputype: .=.+2 / cpu type (currently 40,45 or 70) 423: _sep_id: .=.+1 / 1 if we have separate I and D 424: _ubmap: .=.+1 / 1 if we have a unibus map 425: _haveCSW: .=.+1 / 1 if we have a console switch register 426: _ksep: .=.+1 / 1 if kernel mode has sep I/D enabled 427: _bootopts: .=.+2 / flags if an autoboot 428: _bootdev: .=.+2 / device to get unix from, if not RB_ASKNAME 429: _checkword: .=.+2 / saved r2, complement of bootopts if an autoboot