1 1.1 skrll ; $NetBSD: start.S,v 1.1 2014/02/24 07:23:43 skrll Exp $ 2 1.1 skrll 3 1.1 skrll ; Copyright (c) 2003 ITOH Yasufumi. 4 1.1 skrll ; All rights reserved. 5 1.1 skrll ; 6 1.1 skrll ; Redistribution and use in source and binary forms, with or without 7 1.1 skrll ; modification, are permitted provided that the following conditions 8 1.1 skrll ; are met: 9 1.1 skrll ; 1. Redistributions of source code must retain the above copyright 10 1.1 skrll ; notice, this list of conditions and the following disclaimer. 11 1.1 skrll ; 2. Redistributions in binary forms are unlimited. 12 1.1 skrll ; 13 1.1 skrll ; THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' 14 1.1 skrll ; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 1.1 skrll ; THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 1.1 skrll ; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS 17 1.1 skrll ; BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 1.1 skrll ; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 1.1 skrll ; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 1.1 skrll ; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 1.1 skrll ; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 1.1 skrll ; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 1.1 skrll ; THE POSSIBILITY OF SUCH DAMAGE. 24 1.1 skrll 25 1.1 skrll .level 1.0 26 1.1 skrll 27 1.1 skrll .code 28 1.1 skrll .origin 0 29 1.1 skrll ; 30 1.1 skrll ; LIF (Logical Interchange Format) header 31 1.1 skrll ; 32 1.1 skrll lifhdr: .byte 0x80,0x00 ; LIF magic 33 1.1 skrll .string "NetBSD" ; volume label (6 chars, fill with space) 34 1.1 skrll .origin 0xf0 35 1.1 skrll ; 0xf0 36 1.1 skrll lif_ipl_addr: 37 1.1 skrll .word top-lifhdr ; start at 4KB (must be 2KB aligned) 38 1.1 skrll lif_ipl_size: 39 1.1 skrll .word 0x00001000 ; size 4KB (must be 2KB aligned) 40 1.1 skrll lif_ipl_entry: 41 1.1 skrll .word $START$-top ; entry offset 42 1.1 skrll 43 1.1 skrll ; ipl part 1 starts here 44 1.1 skrll .origin 4096 45 1.1 skrll top: 46 1.1 skrll ; 47 1.1 skrll ; IPL startup 48 1.1 skrll ; 49 1.1 skrll ; arg0 = interact flag (1: interactive, 0: otherwise) 50 1.1 skrll ; arg1 = address of first doubleword past the end of ipl part 1 51 1.1 skrll ; 52 1.1 skrll .export $START$,entry 53 1.1 skrll $START$: 54 1.1 skrll b,n start ; 0: entry address 55 1.1 skrll 56 1.1 skrll ; version of interface of primary to secondary boot 57 1.1 skrll BOOT_IF_VERSION: .equ 0 58 1.1 skrll ; version 0: arg0 = interact flag, arg1 = version (0), 59 1.1 skrll ; arg2 = end addr, arg3 = selected boot partition 60 1.1 skrll ; r1, r3 - r22, r28, r29, r31 = cleared to zeros 61 1.1 skrll 62 1.1 skrll cksum: .word 0 ; 4: checksum will be stored here 63 1.1 skrll version: .word BOOT_IF_VERSION ; 8: version of interface 64 1.1 skrll rsvd1: .word 0 ; 12: future use 65 1.1 skrll rsvd2: .word 0 ; 16: future use 66 1.1 skrll rsvd3: .word 0 ; 20: future use 67 1.1 skrll 68 1.1 skrll start: 69 1.1 skrll ; set data pointer for relocatable data access 70 1.1 skrll blr %r0,%r27 71 1.1 skrll ; get PSW at entry 72 1.1 skrll ssm 0,%r4 73 1.1 skrll .export $global$,data 74 1.1 skrll $global$: 75 1.1 skrll 76 1.1 skrll ; save parameters for main 77 1.1 skrll copy %arg0,%r3 78 1.1 skrll 79 1.1 skrll tmpdiskbufsz: .equ 0x1000 ; 4KB 80 1.1 skrll tmpdiskbuf_labelsec: .equ 0x0200 ; dbtob(LABELSECTOR) 81 1.1 skrll tmpdiskbuf_labelsecsz: .equ 512 82 1.1 skrll tmpdiskbuf_part2: .equ 0x0400 83 1.1 skrll tmpdiskbuf_part2sz: .equ 0x0400 84 1.1 skrll tmpdiskbuf_part3: .equ 0x0A00 85 1.1 skrll tmpdiskbuf_part3sz: .equ 0x0600 86 1.1 skrll 87 1.1 skrll part1sz: .equ 0x1000 88 1.1 skrll 89 1.1 skrll ; get next free address 90 1.1 skrll .import _end,data 91 1.1 skrll addil L%_end-$global$,%r27;%r1 92 1.1 skrll ldo R%_end-$global$(%r1),%r1 93 1.1 skrll 94 1.1 skrll ; 32bit environment (and this code) requires stack is 64byte aligned. 95 1.1 skrll ldi 64-1,%r2 96 1.1 skrll add %r1,%r2,%r1 97 1.1 skrll andcm %r1,%r2,%r6 ; r6 = tmp disk buffer 98 1.1 skrll ldo tmpdiskbufsz+64(%r6),%sp ; tmp stack 99 1.1 skrll 100 1.1 skrll bl print,%rp 101 1.1 skrll ldo str_startup-$global$(%r27),%arg0 102 1.1 skrll 103 1.1 skrll ; 104 1.1 skrll ; read part 2 and 3 of ipl (see README.ipl) 105 1.1 skrll ; 106 1.1 skrll 107 1.1 skrll ; read disk blocks which contains ipl part 2 and part 3 108 1.1 skrll copy %r6,%arg0 109 1.1 skrll ldi 0,%arg2 ; offset = 0 110 1.1 skrll bl boot_input,%rp 111 1.1 skrll ldi tmpdiskbufsz,%arg1 ; read size 112 1.1 skrll 113 1.1 skrll ; part 2 address 114 1.1 skrll ldo top-$global$+part1sz(%r27),%r19 115 1.1 skrll 116 1.1 skrll ; copy part 2 117 1.1 skrll ldo tmpdiskbuf_part2(%r6),%r20 118 1.1 skrll addi,tr tmpdiskbuf_part2sz/4,%r0,%r2 ; loop count, skip next 119 1.1 skrll cpipl2: stws,ma %r1,4(0,%r19) ; write to dst 120 1.1 skrll addib,uv,n -1,%r2,cpipl2 ; check loop condition 121 1.1 skrll ldws,ma 4(0,%r20),%r1 ; read from src 122 1.1 skrll 123 1.1 skrll ; copy part 3 124 1.1 skrll ; (r19 already has destination address of part 3) 125 1.1 skrll ldo tmpdiskbuf_part3(%r6),%r20 126 1.1 skrll addi,tr tmpdiskbuf_part3sz/4,%r0,%r2 ; loop count, skip next 127 1.1 skrll cpipl3: stws,ma %r1,4(0,%r19) ; write to dst 128 1.1 skrll addib,uv,n -1,%r2,cpipl3 ; check loop condition 129 1.1 skrll ldws,ma 4(0,%r20),%r1 ; read from src 130 1.1 skrll 131 1.1 skrll ; flush data cache / invalidate instruction cache 132 1.1 skrll ldo top-$global$+part1sz(%r27),%r1 ; part 2 address 133 1.1 skrll ldi 16,%r20 ; 16: cache line size 134 1.1 skrll flipl: fdc 0(0,%r1) ; flush data cache line at r1 135 1.1 skrll comb,< %r1,%r19,flipl 136 1.1 skrll fic,m %r20(0,%r1) ; flush instruction cache line at r1, r1 += 16 137 1.1 skrll sync ; I/O operation is guaranteed to finish 138 1.1 skrll ; in eight instructions after sync 139 1.1 skrll ; 140 1.1 skrll ; Now, whole the IPL is loaded 141 1.1 skrll ; 142 1.1 skrll 143 1.1 skrll ; clear BSS 144 1.1 skrll .import _edata,data 145 1.1 skrll addil L%_edata-$global$,%r27;%r1 146 1.1 skrll ldo R%_edata-$global$(%r1),%r1 147 1.1 skrll clrbss: comb,< %r1,%r6,clrbss 148 1.1 skrll stws,ma %r0,4(0,%r1) 149 1.1 skrll 150 1.1 skrll ; we have read disklabel -- save it for later use 151 1.1 skrll .import labelsector,data 152 1.1 skrll addil L%labelsector-$global$,%r27;%r1 153 1.1 skrll ldo R%labelsector-$global$(%r1),%r20 154 1.1 skrll ldo tmpdiskbuf_labelsec(%r6),%r21 155 1.1 skrll addi,tr tmpdiskbuf_labelsecsz/4,%r0,%r2 ; loop count, skip next 156 1.1 skrll cplbl: stws,ma %r1,4(0,%r20) ; write to dst 157 1.1 skrll addib,uv,n -1,%r2,cplbl ; check loop condition 158 1.1 skrll ldws,ma 4(0,%r21),%r1 ; read from src 159 1.1 skrll 160 1.1 skrll ; set stack 161 1.1 skrll ; (r6 points at free space, 64byte aligned) 162 1.1 skrll ; 32bit environment (and this code) requires stack is 64byte aligned. 163 1.1 skrll ldo 64(%r6),%sp ; 64 > 48: frame marker (32) + args(up to 4) 164 1.1 skrll 165 1.1 skrll ; stack usage 166 1.1 skrll ; 12bytes arguments 167 1.1 skrll ; 32 frame marker 168 1.1 skrll 169 1.1 skrll ; parameters for main 170 1.1 skrll copy %r3,%arg0 171 1.1 skrll copy %r4,%arg2 172 1.1 skrll 173 1.1 skrll .import ipl_main,entry 174 1.1 skrll bl ipl_main,%rp 175 1.1 skrll copy %sp,%arg1 176 1.1 skrll 177 1.1 skrll ; main returned --- perform reset 178 1.1 skrll bl print,%rp 179 1.1 skrll ldo str_reset-$global$(%r27),%arg0 180 1.1 skrll ; FALLTHROUGH 181 1.1 skrll 182 1.1 skrll IOMOD_CMD: .equ 0xFFFC0000 + (4*12) 183 1.1 skrll IOMOD_CMD_STOP: .equ 0 184 1.1 skrll IOMOD_CMD_RESET: .equ 5 185 1.1 skrll 186 1.1 skrll ; void reboot(void) 187 1.1 skrll ; void halt(void) 188 1.1 skrll .export reboot,entry 189 1.1 skrll .export halt,entry 190 1.1 skrll reboot: 191 1.1 skrll addi,tr IOMOD_CMD_RESET,%r0,%r1 ; %r1 = IOMOD_CMD_RESET, skip next 192 1.1 skrll halt: ldi IOMOD_CMD_STOP,%r1 193 1.1 skrll iomcmd: ldil L%IOMOD_CMD,%r2 194 1.1 skrll ldo R%IOMOD_CMD(%r2),%r2 195 1.1 skrll stwas %r1,0(%r2) 196 1.1 skrll b,n . 197 1.1 skrll 198 1.1 skrll str_startup: 199 1.1 skrll .string "\r\n\n" 200 1.1 skrll .stringz "NetBSD/hppa FFS/LFS Primary Bootstrap\r\n\n" 201 1.1 skrll str_reset: 202 1.1 skrll .stringz "\r\nresetting..." 203 1.1 skrll .align 4 204 1.1 skrll 205 1.1 skrll ; void dispatch(unsigned interactive, unsigned top, unsigned end, int part, 206 1.1 skrll ; unsigned entry) 207 1.1 skrll .export dispatch,entry 208 1.1 skrll dispatch: 209 1.1 skrll ; flush data cache / invalidate instruction cache 210 1.1 skrll ldi 16,%r20 ; 16: cache line size 211 1.1 skrll flush: fdc 0(0,%arg1) ; flush data cache line at arg1 212 1.1 skrll comb,< %arg1,%arg2,flush 213 1.1 skrll fic,m %r20(0,%arg1) ; flush instruction cache line at arg1, arg1+=16 214 1.1 skrll sync 215 1.1 skrll copy %r0,%r1 ; I/O operation is guaranteed to finish 216 1.1 skrll copy %r0,%r3 ; in eight instructions after sync 217 1.1 skrll copy %r0,%r4 218 1.1 skrll copy %r0,%r5 ; while waiting, clear unused registers 219 1.1 skrll copy %r0,%r6 ; for future compatibility 220 1.1 skrll copy %r0,%r7 221 1.1 skrll copy %r0,%r8 222 1.1 skrll copy %r0,%r9 223 1.1 skrll copy %r0,%r10 224 1.1 skrll copy %r0,%r11 225 1.1 skrll copy %r0,%r12 226 1.1 skrll copy %r0,%r13 227 1.1 skrll copy %r0,%r14 228 1.1 skrll copy %r0,%r15 229 1.1 skrll copy %r0,%r16 230 1.1 skrll copy %r0,%r17 231 1.1 skrll copy %r0,%r18 232 1.1 skrll copy %r0,%r19 233 1.1 skrll copy %r0,%r20 234 1.1 skrll copy %r0,%r21 235 1.1 skrll copy %r0,%r22 236 1.1 skrll copy %r0,%r28 ; r23-r26: arg3-arg0, r27: dp 237 1.1 skrll copy %r0,%r29 ; r30: sp 238 1.1 skrll copy %r0,%r31 239 1.1 skrll ldw -52(%sp),%arg1 ; arg4: exec address 240 1.1 skrll ldo reboot-$global$(%r27),%rp ; reboot if returns 241 1.1 skrll bv %r0(%arg1) ; execute 242 1.1 skrll ldi BOOT_IF_VERSION,%arg1 243 1.1 skrll 244 1.1 skrll ; 245 1.1 skrll ; IODC subroutines 246 1.1 skrll ; 247 1.1 skrll PZ_MEM_CONSOLE: .equ 0x3a0 248 1.1 skrll PZ_MEM_BOOT: .equ 0x3d0 249 1.1 skrll PZ_MEM_KEYBOARD: .equ 0x400 250 1.1 skrll 251 1.1 skrll DEV_PATH: .equ 0x00 252 1.1 skrll DEV_LAYERS: .equ 0x08 253 1.1 skrll DEV_HPA: .equ 0x20 ; hard physical address space 254 1.1 skrll DEV_SPA: .equ 0x24 ; soft physical address space 255 1.1 skrll DEV_IODC_ENTRY: .equ 0x28 256 1.1 skrll DEV_CLASS: .equ 0x2c 257 1.1 skrll DEV_CL_DUPLEX: .equ 0x7 ; full-duplex console class 258 1.1 skrll 259 1.1 skrll IODC_ENTRY_IO_BOOTIN: .equ 0 260 1.1 skrll IODC_ENTRY_IO_CONSOLEIN: .equ 2 261 1.1 skrll IODC_ENTRY_IO_CONSOLEOUT: .equ 3 262 1.1 skrll 263 1.1 skrll ; call_iodc 264 1.1 skrll ; inputs: 265 1.1 skrll ; %ret0 IODC base in page zero 266 1.1 skrll ; %rp return address 267 1.1 skrll ; %r29 arg 8 268 1.1 skrll ; %r19 arg 7 269 1.1 skrll ; %r20 arg 6 270 1.1 skrll ; %r21 arg 5 271 1.1 skrll ; %r25 arg 1 272 1.1 skrll ; outputs 273 1.1 skrll ; all scratch regs undefined, unless defined by the IODC call 274 1.1 skrll call_iodc: 275 1.1 skrll ; set common arguments in registers 276 1.1 skrll addil L%retbuf-$global$,%r27;%r1 277 1.1 skrll ldo R%retbuf-$global$(%r1),%r22 ; arg4: return buffer 278 1.1 skrll ldo DEV_LAYERS(%ret0),%arg3 ; arg3: layer 279 1.1 skrll ldw DEV_SPA(%ret0),%arg2 ; arg2: spa 280 1.1 skrll ldw DEV_HPA(%ret0),%arg0 ; arg0: hpa 281 1.1 skrll ; check if narrow or wide mode 282 1.1 skrll ssm 0,%r1 ; get PSW 283 1.1 skrll bb,< %r1,4,call_iodc_64 ; if W, call in 64bit mode 284 1.1 skrll ldw DEV_IODC_ENTRY(%ret0),%r1 ; ENTRY_IO address 285 1.1 skrll 286 1.1 skrll ; narrow mode 287 1.1 skrll stw %r29,-68(%sp) ; arg8: maxsize / lang 288 1.1 skrll stw %r19,-64(%sp) ; arg7: size 289 1.1 skrll stw %r20,-60(%sp) ; arg6: buf 290 1.1 skrll stw %r21,-56(%sp) ; arg5: devaddr / unused 291 1.1 skrll bv %r0(%r1) ; call ENTRY_IO 292 1.1 skrll stw %r22,-52(%sp) ; arg4: return buffer 293 1.1 skrll 294 1.1 skrll call_iodc_64: 295 1.1 skrll .allow 2.0 296 1.1 skrll ; On PA64 convention, arg0 - arg7 are passed in registers. 297 1.1 skrll ; Parameters are placed in INCREASING order. 298 1.1 skrll ; The argument pointer points at the first stack parameter. 299 1.1 skrll ; stack usage: 300 1.1 skrll ; 64bytes allocated for register arguments arg0-arg7 301 1.1 skrll ; 8 arg8 (argument pointer points here) 302 1.1 skrll ; 16 frame marker 303 1.1 skrll std %r29,-16-8(%sp) ; arg8: maxsize / lang 304 1.1 skrll ; std %sp,-8(%sp) ; psp in frame marker 305 1.1 skrll bv %r0(%r1) ; call ENTRY_IO 306 1.1 skrll ldo -16-8(%sp),%r29 ; argument pointer 307 1.1 skrll .allow 308 1.1 skrll 309 1.1 skrll ; 310 1.1 skrll ; console output 311 1.1 skrll ; 312 1.1 skrll ; void putch(int) 313 1.1 skrll ; void print(const char *string) 314 1.1 skrll .align 4 315 1.1 skrll .export putch,entry 316 1.1 skrll .export print,entry 317 1.1 skrll putch: 318 1.1 skrll stwm %arg0,128(%sp) ; fake up a string on the stack 319 1.1 skrll stb %r0,-124(%sp) ; (see stack usage below) 320 1.1 skrll addi,tr -125,%sp,%arg0 ; string address, skip next 321 1.1 skrll print: 322 1.1 skrll .proc 323 1.1 skrll .callinfo frame=128,save_rp,no_unwind 324 1.1 skrll .entry 325 1.1 skrll ldo 128(%sp),%sp 326 1.1 skrll stw %rp,-128-20(%sp) 327 1.1 skrll 328 1.1 skrll ; stack usage: 329 1.1 skrll ; 36byte IODC buffer (assume %sp was 64byte aligned) 330 1.1 skrll ; 4 saved reg 331 1.1 skrll ; 88 arguments, frame marker 332 1.1 skrll ; 32bit: 36 (arguments) + 32 (frame marker) 333 1.1 skrll ; 64bit: 72 (arguments) + 16 (frame marker) 334 1.1 skrll prbufsiz: .equ 36 335 1.1 skrll 336 1.1 skrll ; save callee-saves 337 1.1 skrll stw %r3,-92(%sp) 338 1.1 skrll 339 1.1 skrll copy %arg0,%r3 340 1.1 skrll 341 1.1 skrll prloop: 342 1.1 skrll copy %r0,%r19 343 1.1 skrll ldi prbufsiz,%r20 344 1.1 skrll ldo -128(%sp),%r1 345 1.1 skrll 346 1.1 skrll strloop: 347 1.1 skrll ldb 0(%r3),%r2 348 1.1 skrll comb,= %r2,%r0,endstr 349 1.1 skrll stbs,ma %r2,1(0,%r1) 350 1.1 skrll ldo 1(%r19),%r19 351 1.1 skrll comb,<> %r19,%r20,strloop 352 1.1 skrll ldo 1(%r3),%r3 353 1.1 skrll 354 1.1 skrll endstr: 355 1.1 skrll comb,=,n %r19,%r0,endpr 356 1.1 skrll 357 1.1 skrll ; see IODC 3-51 358 1.1 skrll ; arg0 hpa 359 1.1 skrll ; arg1 option (ENTRY_IO_CONSOLEOUT (3)) 360 1.1 skrll ; arg2 spa 361 1.1 skrll ; arg3 ID_addr (pointer to LAYER) 362 1.1 skrll ; arg4 R_addr (pointer to return buffer (64word?)) 363 1.1 skrll ; arg5 unused (0) 364 1.1 skrll ; arg6 memaddr (64byte-aligned) string buffer 365 1.1 skrll ; arg7 reqsize 366 1.1 skrll ; arg8 lang (0) 367 1.1 skrll ldi PZ_MEM_CONSOLE,%ret0 ; IODC base in page zero 368 1.1 skrll copy %r0,%r29 ; arg8: lang 369 1.1 skrll ; copy %r19,%r19 ; arg7: size 370 1.1 skrll ldo -128(%sp),%r20 ; arg6: buf 371 1.1 skrll ; copy %r0,%r21 ; arg5: unused 372 1.1 skrll bl call_iodc,%rp 373 1.1 skrll ldi IODC_ENTRY_IO_CONSOLEOUT,%arg1 ; arg1: option 374 1.1 skrll b,n prloop 375 1.1 skrll 376 1.1 skrll endpr: 377 1.1 skrll ; restore callee-saves 378 1.1 skrll ldw -92(%sp),%r3 379 1.1 skrll 380 1.1 skrll ; return subroutine 381 1.1 skrll ldw -128-20(%sp),%rp 382 1.1 skrll bv %r0(%rp) 383 1.1 skrll .exit 384 1.1 skrll ldo -128(%sp),%sp 385 1.1 skrll .procend 386 1.1 skrll 387 1.1 skrll ; 388 1.1 skrll ; console input 389 1.1 skrll ; 390 1.1 skrll ; int getch(void) 391 1.1 skrll .align 4 392 1.1 skrll .export getch,entry 393 1.1 skrll getch: 394 1.1 skrll .proc 395 1.1 skrll .callinfo frame=192,save_rp,no_unwind 396 1.1 skrll .entry 397 1.1 skrll stw %rp,-20(%sp) 398 1.1 skrll ldo 192(%sp),%sp 399 1.1 skrll 400 1.1 skrll ; stack usage: 401 1.1 skrll ; 64byte IODC buffer (assume %sp was 64byte aligned) 402 1.1 skrll ; 40 unused 403 1.1 skrll ; 88 arguments, frame marker 404 1.1 skrll ; 32bit: 36 (arguments) + 32 (frame marker) 405 1.1 skrll ; 64bit: 72 (arguments) + 16 (frame marker) 406 1.1 skrll 407 1.1 skrll ; check if console is full or half duplex 408 1.1 skrll ldw PZ_MEM_CONSOLE+DEV_CLASS(%r0),%r1 ; device class 409 1.1 skrll extru %r1,31,4,%r1 ; right 4bits are valid 410 1.1 skrll ldi PZ_MEM_CONSOLE,%ret0 411 1.1 skrll comib,=,n DEV_CL_DUPLEX,%r1,getch_console ; use CONSOLE if full 412 1.1 skrll ldi PZ_MEM_KEYBOARD,%ret0 ; otherwise KEYBOARD 413 1.1 skrll getch_console: 414 1.1 skrll 415 1.1 skrll ; see IODC 3-50 416 1.1 skrll ; arg0 hpa 417 1.1 skrll ; arg1 option (ENTRY_IO_CONSOLEIN (2)) 418 1.1 skrll ; arg2 spa 419 1.1 skrll ; arg3 ID_addr (pointer to LAYER) 420 1.1 skrll ; arg4 R_addr (pointer to return buffer (64word?)) 421 1.1 skrll ; arg5 unused (0) 422 1.1 skrll ; arg6 memaddr (64byte-aligned, must have 64byte) data buffer 423 1.1 skrll ; arg7 reqsize 424 1.1 skrll ; arg8 lang (0) 425 1.1 skrll ; copy %rp,%rp ; IODC base in page zero 426 1.1 skrll copy %r0,%r29 ; arg8: lang 427 1.1 skrll ldi 1,%r19 ; arg7: size (1) 428 1.1 skrll ldo -192(%sp),%r20 ; arg6: buf 429 1.1 skrll ; copy %r0,%r21 ; arg5: unused 430 1.1 skrll bl call_iodc,%rp 431 1.1 skrll ldi IODC_ENTRY_IO_CONSOLEIN,%arg1 ; arg1: option 432 1.1 skrll 433 1.1 skrll ; make return value 434 1.1 skrll comb,<> %ret0,%r0,getch_ret ; return -1 on error 435 1.1 skrll ldi -1,%ret0 436 1.1 skrll ldi 1,%r19 437 1.1 skrll 438 1.1 skrll ; check if narrow or wide mode 439 1.1 skrll ssm 0,%r1 ; get PSW 440 1.1 skrll bb,< %r1,4,getch_64 441 1.1 skrll addil L%retbuf-$global$,%r27;%r1 442 1.1 skrll ldw R%retbuf-$global$(%r1),%r2 ; ret[0] 443 1.1 skrll comclr,<> %r19,%r2,%ret0 ; return 0 if no char available 444 1.1 skrll getch_retc: 445 1.1 skrll ldb -192(%sp),%ret0 ; otherwise return the char 446 1.1 skrll 447 1.1 skrll getch_ret: 448 1.1 skrll ; return subroutine 449 1.1 skrll ldw -192-20(%sp),%rp 450 1.1 skrll bv %r0(%rp) 451 1.1 skrll .exit 452 1.1 skrll ldo -192(%sp),%sp 453 1.1 skrll 454 1.1 skrll getch_64: 455 1.1 skrll .allow 2.0 456 1.1 skrll ldd R%retbuf-$global$(%r1),%r2 ; ret[0] (64bit) 457 1.1 skrll b getch_retc 458 1.1 skrll cmpclr,*<> %r19,%r2,%ret0 ; return 0 if no char available 459 1.1 skrll .allow 460 1.1 skrll .procend 461 1.1 skrll 462 1.1 skrll ; 463 1.1 skrll ; read boot device 464 1.1 skrll ; 465 1.1 skrll ; void boot_input(void *buf, unsigned len, unsigned pos) 466 1.1 skrll .align 4 467 1.1 skrll .export boot_input,entry 468 1.1 skrll boot_input: 469 1.1 skrll .proc 470 1.1 skrll .callinfo frame=128,save_rp,no_unwind 471 1.1 skrll .entry 472 1.1 skrll stw %rp,-20(%sp) 473 1.1 skrll ldo 128(%sp),%sp 474 1.1 skrll 475 1.1 skrll ; stack usage: 476 1.1 skrll ; 40byte unused (alignment) 477 1.1 skrll ; 88 arguments, frame marker 478 1.1 skrll ; 32bit: 36 (arguments) + 32 (frame marker) 479 1.1 skrll ; 64bit: 72 (arguments) + 16 (frame marker) 480 1.1 skrll 481 1.1 skrll ; see IODC 3-46 482 1.1 skrll ; arg0 hpa 483 1.1 skrll ; arg1 option (ENTRY_IO_BOOTIN (0)) 484 1.1 skrll ; arg2 spa 485 1.1 skrll ; arg3 ID_addr (pointer to LAYER) 486 1.1 skrll ; arg4 R_addr (pointer to return buffer (64word?)) 487 1.1 skrll ; arg5 devaddr 488 1.1 skrll ; arg6 memaddr (64byte-aligned) string buffer 489 1.1 skrll ; arg7 reqsize 490 1.1 skrll ; arg8 maxsize 491 1.1 skrll ldi PZ_MEM_BOOT,%ret0 ; IODC base in page zero 492 1.1 skrll copy %arg1,%r29 ; arg8: maxsize 493 1.1 skrll copy %arg1,%r19 ; arg7: size 494 1.1 skrll copy %arg0,%r20 ; arg6: buf 495 1.1 skrll copy %arg2,%r21 ; arg5: devaddr 496 1.1 skrll bl call_iodc,%rp 497 1.1 skrll ldi IODC_ENTRY_IO_BOOTIN,%arg1 ; arg1: option 498 1.1 skrll 499 1.1 skrll ; return subroutine 500 1.1 skrll ldw -128-20(%sp),%rp 501 1.1 skrll bv %r0(%rp) 502 1.1 skrll .exit 503 1.1 skrll ldo -128(%sp),%sp 504 1.1 skrll .procend 505 1.1 skrll 506 1.1 skrll ; 507 1.1 skrll ; utilities 508 1.1 skrll ; optimized for size 509 1.1 skrll ; 510 1.1 skrll 511 1.1 skrll ; int strcmp(const char *str1, const char *str2) 512 1.1 skrll .align 4 513 1.1 skrll .export strcmp,entry 514 1.1 skrll strcmp: 515 1.1 skrll .proc 516 1.1 skrll .callinfo frame=0,no_calls 517 1.1 skrll .entry 518 1.1 skrll ldbs,ma 1(0,%arg0),%r1 519 1.1 skrll strcmp_loop: 520 1.1 skrll comb,= %r1,%r0,strcmp_eos 521 1.1 skrll ldbs,ma 1(0,%arg1),%r19 522 1.1 skrll comb,=,n %r1,%r19,strcmp_loop 523 1.1 skrll ldbs,ma 1(0,%arg0),%r1 524 1.1 skrll strcmp_eos: 525 1.1 skrll bv %r0(%rp) 526 1.1 skrll .exit 527 1.1 skrll sub %r1,%r19,%ret0 528 1.1 skrll .procend 529 1.1 skrll 530 1.1 skrll ; void memcpy(void *dst, const void *src, unsigned len) 531 1.1 skrll .align 4 532 1.1 skrll .export memcpy,entry 533 1.1 skrll .export memmove,entry 534 1.1 skrll memcpy: 535 1.1 skrll memmove: 536 1.1 skrll .proc 537 1.1 skrll .callinfo no_unwind ; multiple exit points 538 1.1 skrll .entry 539 1.1 skrll ; copy %arg0,%ret0 ; uncomment this to conform ANSI 540 1.1 skrll comb,<<,n %arg0,%arg1,memcpy0 ; copy forward or backward? 541 1.1 skrll add %arg0,%arg2,%arg0 ; dst end address 542 1.1 skrll add,tr %arg1,%arg2,%arg1 ; src end address, skip next 543 1.1 skrll memcpy_bwd: 544 1.1 skrll stbs,mb %r1,-1(0,%arg0) ; write to dst 545 1.1 skrll addib,uv,n -1,%arg2,memcpy_bwd ; check loop condition 546 1.1 skrll ldbs,mb -1(0,%arg1),%r1 ; read from src 547 1.1 skrll bv,n %r0(%rp) ; return subroutine 548 1.1 skrll memcpy_fwd: 549 1.1 skrll stbs,ma %r1,1(0,%arg0) ; write to dst 550 1.1 skrll memcpy0: 551 1.1 skrll addib,uv,n -1,%arg2,memcpy_fwd ; check loop condition 552 1.1 skrll ldbs,ma 1(0,%arg1),%r1 ; read from src 553 1.1 skrll .exit 554 1.1 skrll bv,n %r0(%rp) ; return subroutine 555 1.1 skrll .procend 556 1.1 skrll 557 1.1 skrll ; 558 1.1 skrll ; string table 559 1.1 skrll ; placed here to save space 560 1.1 skrll ; 561 1.1 skrll .export str_seekseq, data 562 1.1 skrll .export str_startup, data 563 1.1 skrll .export str_bit_firmware, data 564 1.1 skrll .export str_crlf, data 565 1.1 skrll .export str_space, data 566 1.1 skrll .export str_rubout, data 567 1.1 skrll str_seekseq: 568 1.1 skrll .stringz "repositioning media...\r\n" 569 1.1 skrll str_bit_firmware: 570 1.1 skrll .stringz "bit firmware\r\n" 571 1.1 skrll str_rubout: 572 1.1 skrll .byte 0x08, 0x20, 0x08, 0x00 ; "\b \b" 573 1.1 skrll 574 1.1 skrll .export str_bootpart, data 575 1.1 skrll str_bootpart: 576 1.1 skrll .string "boot partition (a-p, ! to reboot) [a]:" 577 1.1 skrll str_space: 578 1.1 skrll .stringz " " 579 1.1 skrll .export str_booting_part, data 580 1.1 skrll str_booting_part: 581 1.1 skrll .string "\r\nbooting from partition _" 582 1.1 skrll str_crlf: 583 1.1 skrll .stringz "\r\n" 584 1.1 skrll .export str_warn_2GB, data 585 1.1 skrll str_warn_2GB: 586 1.1 skrll .stringz "boot partition exceeds 2GB boundary\r\n" 587 1.1 skrll .export str_warn_unused, data 588 1.1 skrll str_warn_unused: 589 1.1 skrll .stringz "unused partition\r\n" 590 1.1 skrll .export str_nolabel, data 591 1.1 skrll str_nolabel: 592 1.1 skrll .stringz "no disklabel\r\n" 593 1.1 skrll 594 1.1 skrll .export str_filesystem, data 595 1.1 skrll str_filesystem: 596 1.1 skrll .stringz "filesystem: _FS\r\n" 597 1.1 skrll .export str_nofs, data 598 1.1 skrll str_nofs: 599 1.1 skrll .stringz "no filesystem found\r\n" 600 1.1 skrll .export str_lookup, data 601 1.1 skrll .export str_loading, data 602 1.1 skrll .export str_at, data 603 1.1 skrll .export str_dddot, data 604 1.1 skrll .export str_done, data 605 1.1 skrll str_lookup: 606 1.1 skrll .stringz "looking up " 607 1.1 skrll str_loading: 608 1.1 skrll .stringz "loading " 609 1.1 skrll str_at: 610 1.1 skrll .stringz " at 0x" 611 1.1 skrll str_dddot: 612 1.1 skrll .stringz "..." 613 1.1 skrll str_done: 614 1.1 skrll .stringz "done\r\n" 615 1.1 skrll 616 1.1 skrll .export str_boot1, data 617 1.1 skrll .export str_boot2, data 618 1.1 skrll .export str_boot3, data 619 1.1 skrll str_boot1: 620 1.1 skrll .stringz "boot.hp700" 621 1.1 skrll str_boot2: 622 1.1 skrll .stringz "boot" 623 1.1 skrll str_boot3: 624 1.1 skrll .stringz "usr/mdec/boot" 625 1.1 skrll 626 1.1 skrll .export str_noboot, data 627 1.1 skrll str_noboot: 628 1.1 skrll .stringz "no secondary boot found\r\n" 629 1.1 skrll 630 1.1 skrll .export str_ukfmt, data 631 1.1 skrll str_ukfmt: 632 1.1 skrll .stringz ": unknown format -- exec from top\r\n" 633 1.1 skrll 634 1.1 skrll .bss 635 1.1 skrll .align 64 636 1.1 skrll retbuf: .block 32*8 ; *4 for narrow mode / *8 for wide mode 637 1.1 skrll 638 1.1 skrll .export diskbuf,data 639 1.1 skrll .align 64 640 1.1 skrll diskbuf: 641 1.1 skrll .block 2048 642