1 1.7 snj /* $NetBSD: start.S,v 1.7 2020/04/06 01:43:26 snj Exp $ */ 2 1.1 matt /* 3 1.1 matt * Copyright (c) 1995 Ludd, University of Lule}, Sweden. 4 1.1 matt * All rights reserved. 5 1.1 matt * 6 1.1 matt * This code is derived from software contributed to Ludd by 7 1.1 matt * Bertram Barth. 8 1.1 matt * 9 1.1 matt * Redistribution and use in source and binary forms, with or without 10 1.1 matt * modification, are permitted provided that the following conditions 11 1.1 matt * are met: 12 1.1 matt * 1. Redistributions of source code must retain the above copyright 13 1.1 matt * notice, this list of conditions and the following disclaimer. 14 1.1 matt * 2. Redistributions in binary form must reproduce the above copyright 15 1.1 matt * notice, this list of conditions and the following disclaimer in the 16 1.1 matt * documentation and/or other materials provided with the distribution. 17 1.1 matt * 18 1.1 matt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 1.1 matt * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 1.1 matt * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 1.1 matt * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 1.1 matt * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 1.1 matt * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 1.1 matt * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 1.1 matt * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 1.1 matt * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 1.1 matt * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 1.1 matt */ 29 1.1 matt 30 1.1 matt /* All bugs are subject to removal without further notice */ 31 1.1 matt 32 1.1 matt 33 1.1 matt #define _LOCORE 34 1.1 matt 35 1.5 martin #define __HAVE_OLD_DISKLABEL /* not automatically added due to _LOCORE */ 36 1.3 he #define OMIT_DKTYPENUMS 37 1.3 he #define OMIT_FSTYPENUMS 38 1.1 matt #include "sys/disklabel.h" 39 1.1 matt 40 1.1 matt #include "../include/mtpr.h" 41 1.1 matt #include "../include/asm.h" 42 1.1 matt 43 1.1 matt _C_LABEL(_start): 44 1.1 matt _C_LABEL(start): 45 1.1 matt .globl _C_LABEL(start) # this is the symbolic name for the start 46 1.1 matt .globl _C_LABEL(_start) # of code to be relocated. We can use this 47 1.2 wiz # to get the actual/real address (pc-rel) 48 1.1 matt # or to get the relocated address (abs). 49 1.1 matt 50 1.1 matt .org 0x00 # uVAX booted from TK50 starts here 51 1.1 matt brb from_0x00 # continue behind dispatch-block 52 1.1 matt 53 1.5 martin # At offset 0x02 we have a dual used area: VMB.EXE starts execution here, 54 1.5 martin # and uVAX-ROM looks for a pointer to a parameter block. We arrange for 55 1.7 snj # the parameter block offset to disassemble as a CASEL instructions which 56 1.5 martin # falls through to 0x08. 57 1.1 matt .org 0x02 # information used by uVAX-ROM 58 1.5 martin .byte 0xcf # offset in words to identification area 59 1.1 matt .byte 1 # this byte must be 1 60 1.1 matt .word 0 # logical block number (word swapped) 61 1.1 matt .word 0 # of the secondary image 62 1.1 matt 63 1.1 matt .org 0x08 # 64 1.1 matt brb from_0x08 # skip ... 65 1.1 matt 66 1.1 matt .org 0x0C # 11/750 & 8200 starts here 67 1.1 matt movzbl $1,_C_LABEL(from)# We booted from "old" rom. 68 1.1 matt brw cont_750 69 1.1 matt 70 1.1 matt 71 1.1 matt from_0x00: # uVAX from TK50 72 1.1 matt brw start_uvax # all uVAXen continue there 73 1.1 matt 74 1.1 matt from_0x08: # Any machine from VMB 75 1.1 matt movzbl $4,_C_LABEL(from) # Booted from full VMB 76 1.1 matt /* 77 1.1 matt * Read in block 1-15. 78 1.1 matt */ 79 1.1 matt movl 52(%r11), %r7 # load iovec/bqo into %r7 80 1.1 matt addl3 (%r7), %r7, %r6 # load qio into %r6 81 1.1 matt pushl %r11 # base of rpb 82 1.1 matt pushl $0 # virtual-flag 83 1.1 matt pushl $33 # read-logical-block 84 1.1 matt pushl $1 # lbn to start reading 85 1.1 matt pushl $7680 # number of bytes to read 86 1.1 matt pushab start_uvax # buffer-address 87 1.1 matt calls $6, (%r6) # call the qio-routine 88 1.1 matt brw start_uvax 89 1.1 matt 90 1.5 martin # the complete area reserved for label 91 1.5 martin # must be empty (i.e. filled with zeroes). 92 1.5 martin # disklabel(8) checks that before installing 93 1.5 martin # the bootblocks over existing label. 94 1.5 martin 95 1.5 martin .org LABELOFFSET 96 1.5 martin .globl _C_LABEL(romlabel) 97 1.5 martin _C_LABEL(romlabel): 98 1.5 martin .long 0 99 1.5 martin 100 1.5 martin .org LABELOFFSET + d_end_ 101 1.5 martin # Make sure the parameter block is past the disklabel. 102 1.5 martin # If not, the next .org would try to move backwards. 103 1.5 martin 104 1.1 matt /* 105 1.1 matt * Parameter block for uVAX boot. 106 1.1 matt */ 107 1.1 matt #define VOLINFO 0 /* 1=single-sided 81=double-sided volumes */ 108 1.1 matt #define SISIZE 16 /* size in blocks of secondary image */ 109 1.1 matt #define SILOAD 0 /* load offset (usually 0) from the default */ 110 1.1 matt #define SIOFF 0x200 /* byte offset into secondary image */ 111 1.1 matt 112 1.5 martin .org 0x19e # do not move, see comment earlier about CASEL 113 1.1 matt .byte 0x18 # must be 0x18 114 1.1 matt .byte 0x00 # must be 0x00 (MBZ) 115 1.1 matt .byte 0x00 # any value 116 1.1 matt .byte 0xFF - (0x18 + 0x00 + 0x00) 117 1.1 matt /* 4th byte holds 1s' complement of sum of previous 3 bytes */ 118 1.1 matt 119 1.1 matt .byte 0x00 # must be 0x00 (MBZ) 120 1.1 matt .byte VOLINFO 121 1.1 matt .byte 0x00 # any value 122 1.1 matt .byte 0x00 # any value 123 1.1 matt 124 1.1 matt .long SISIZE # size in blocks of secondary image 125 1.1 matt .long SILOAD # load offset (usually 0) 126 1.1 matt .long SIOFF # byte offset into secondary image 127 1.1 matt .long (SISIZE + SILOAD + SIOFF) # sum of previous 3 128 1.1 matt 129 1.1 matt 130 1.1 matt .align 2 131 1.1 matt .globl _C_LABEL(from) 132 1.1 matt _C_LABEL(from): 133 1.1 matt .long 0 134 1.1 matt 135 1.1 matt /* 136 1.1 matt * After bootblock (LBN0) has been loaded into the first page 137 1.1 matt * of good memory by 11/750's ROM-code (transfer address 138 1.1 matt * of bootblock-code is: base of good memory + 0x0C) registers 139 1.1 matt * are initialized as: 140 1.1 matt * R0: type of boot-device 141 1.1 matt * 0: Massbus device 142 1.1 matt * 1: RK06/RK07 143 1.1 matt * 2: RL02 144 1.1 matt * 17: UDA50 145 1.1 matt * 35: TK50 146 1.1 matt * 64: TU58 147 1.1 matt * R1: (UBA) address of UNIBUS I/O-page 148 1.1 matt * (MBA) address of boot device's adapter 149 1.1 matt * R2: (UBA) address of the boot device's CSR 150 1.1 matt * (MBA) controller number of boot device 151 1.1 matt * R6: address of driver subroutine in ROM 152 1.1 matt * 153 1.1 matt * cont_750 reads in LBN1-15 for further execution. 154 1.1 matt */ 155 1.1 matt cont_750: 156 1.1 matt movl $_C_LABEL(start), %sp # move stack to avoid clobbering the code 157 1.1 matt pushr $0x131 # save clobbered registers 158 1.1 matt clrl %r4 # %r4 == # of blocks transferred 159 1.1 matt movab _C_LABEL(start),%r5 # %r5 have base address for next transfer 160 1.1 matt pushl %r5 # ...on stack also (Why?) 161 1.1 matt 1: incl %r4 # increment block count 162 1.1 matt movl %r4,%r8 # LBN is in %r8 for rom routine 163 1.1 matt addl2 $0x200,%r5 # Increase address for next read 164 1.1 matt cmpl $16,%r4 # read 15 blocks? 165 1.1 matt beql 2f # Yep 166 1.1 matt movl %r5,(%sp) # move address to stack also 167 1.1 matt jsb (%r6) # read 512 bytes 168 1.1 matt blbs %r0,1b # jump if read succeeded 169 1.1 matt halt # otherwise die... 170 1.1 matt 2: tstl (%sp)+ # remove boring arg from stack 171 1.1 matt popr $0x131 # restore clobbered registers 172 1.1 matt brw start_all # Ok, continue... 173 1.1 matt 174 1.1 matt /* uVAX main entry is at the start of the second disk block. This is 175 1.1 matt * needed for multi-arch CD booting where multiple architecture need 176 1.1 matt * to shove stuff in boot block 0. 177 1.1 matt */ 178 1.1 matt .org 0x200 # uVAX booted from disk starts here 179 1.1 matt 180 1.1 matt start_uvax: 181 1.1 matt movzbl $2,_C_LABEL(from) # Booted from subset-VMB 182 1.1 matt brb start_all 183 1.1 matt 184 1.1 matt /* 185 1.1 matt * start_all: stack already at RELOC, we save registers, move ourself 186 1.1 matt * to RELOC and loads boot. 187 1.1 matt */ 188 1.1 matt start_all: 189 1.1 matt movl $_C_LABEL(start), %sp # move stack to a better 190 1.1 matt pushr $0x1fff # save all regs, used later. 191 1.1 matt 192 1.1 matt subl3 $_C_LABEL(start), $_C_LABEL(edata), %r0 193 1.1 matt # get size of text+data (w/o bss) 194 1.1 matt moval _C_LABEL(start), %r1 # get actual base-address of code 195 1.1 matt subl3 $_C_LABEL(start), $_C_LABEL(end), %r2 196 1.1 matt # get complete size (incl. bss) 197 1.1 matt movl $_C_LABEL(start), %r3 # get relocated base-address of code 198 1.1 matt movc5 %r0, (%r1), $0, %r2, (%r3) # copy code to new location 199 1.1 matt 200 1.1 matt movpsl -(%sp) 201 1.1 matt movl $relocated, -(%sp) # return-address on top of stack 202 1.1 matt rei # can be replaced with new address 203 1.1 matt relocated: # now relocation is done !!! 204 1.1 matt movl %sp, _C_LABEL(bootregs) 205 1.1 matt calls $0, _C_LABEL(Xmain) # call Xmain (gcc workaround)which is 206 1.1 matt halt # not intended to return ... 207 1.1 matt 208 1.1 matt /* 209 1.1 matt * hoppabort() is called when jumping to the newly loaded program. 210 1.1 matt */ 211 1.1 matt ENTRY(hoppabort, 0) 212 1.1 matt movl 4(%ap),%r6 213 1.1 matt movl _C_LABEL(rpb),%r11 214 1.1 matt mnegl $1,%ap # Hack to figure out boot device. 215 1.1 matt movpsl -(%sp) 216 1.1 matt pushab 2(%r6) 217 1.1 matt mnegl $1,_C_LABEL(vax_load_failure) 218 1.1 matt rei 219 1.1 matt # calls $0,(%r6) 220 1.1 matt halt 221 1.1 matt 222 1.1 matt ENTRY(unit_init, R6|R7|R8|R9|R10|R11) 223 1.1 matt mfpr $17,%r7 # Wanted bu KDB 224 1.1 matt movl 4(%ap),%r0 # init routine address 225 1.1 matt movl 8(%ap),%r9 # RPB in %r9 226 1.1 matt movl 12(%ap),%r1 # VMB argument list 227 1.1 matt callg (%r1),(%r0) 228 1.1 matt ret 229 1.1 matt 230 1.1 matt # A bunch of functions unwanted in boot blocks. 231 1.1 matt ENTRY(getchar, 0) 232 1.1 matt halt 233 1.1 matt 234 1.1 matt #ifndef USE_PRINTF 235 1.1 matt ENTRY(putchar, 0) 236 1.1 matt ret 237 1.1 matt 238 1.1 matt ENTRY(printf, 0) 239 1.1 matt ret 240 1.1 matt #endif 241 1.1 matt 242 1.1 matt ENTRY(panic, 0) 243 1.1 matt halt 244