Home | History | Annotate | Line # | Download | only in xxboot
start.S revision 1.1
      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