ofwboot.s

来自「一个类似windows」· S 代码 · 共 1,246 行 · 第 1/2 页

S
1,246
字号
	.section .text        .globl  setup_bats_start:		.long	0xe00000 + 12	.long	0	.long	0	_begin:	sync                    	isync	lis     %r1,stack@ha    	addi    %r1,%r1,stack@l 	addi    %r1,%r1,16384 - 0x10          	mfmsr   %r8             	li      %r0,0	mtmsr   %r0             	isync                   	bl	setup_bats	                               	li	%r8,0x3030	mtmsr	%r8	/* Store ofw call addr */	mr	%r21,%r5	lis	%r10,0xe00000@ha	stw	%r5,ofw_call_addr - _start@l(%r10)	lis	%r4,_binary_freeldr_tmp_end@ha	addi	%r4,%r4,_binary_freeldr_tmp_end@l	lis	%r3,_binary_freeldr_tmp_start@ha	addi	%r3,%r3,_binary_freeldr_tmp_start@l	lis	%r5,0x8000@ha	addi	%r5,%r5,0x8000@l	bl	copy_bits	bl	zero_registers	lis	%r3,0xe00000@ha	addi	%r3,%r3,freeldr_banner - _start	bl	ofw_print_string	bl	ofw_print_eol	bl	setup_exc	/* Zero CTR */	mtcr	%r31		lis	%r3,0x8000@ha	addi	%r3,%r3,0x8000@l	mtlr	%r3		lis	%r3,call_ofw@ha	addi	%r3,%r3,call_ofw - _start		b	call_freeldr/* * lifted from ppc/boot/openfirmware/misc.S * Copyright (C) Paul Mackerras 1997. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation	;  either version * 2 of the License, or (at your option) any later version. *//* * Use the BAT2 & 3 registers to map the 1st 16MB of RAM to * the address given as the 1st argument. */setup_bats:        mfpvr   5        rlwinm  5,5,16,16,31            /* r3 = 1 for 601, 4 for 604 */        cmpwi   0,5,1        li      0,0        bne     4f        mtibatl 3,0                     /* invalidate BAT first */        ori     3,3,4                   /* set up BAT registers for 601 */        li      4,0x7f        mtibatu 2,3        mtibatl 2,4        oris    3,3,0x80        oris    4,4,0x80        mtibatu 3,3        mtibatl 3,4        b       5f4:	mtdbatu 3,0                     /* invalidate BATs first */        mtibatu 3,0        ori     3,3,0xff                /* set up BAT registers for 604 */        li      4,2        mtdbatl 2,4        mtdbatu 2,3        mtibatl 2,4        mtibatu 2,3        oris    3,3,0x80        oris    4,4,0x80        mtdbatl 3,4        mtdbatu 3,3        mtibatl 3,4        mtibatu 3,35:	sync        isync        blr		.align	4call_freeldr:	/* Get the address of the functions list --	 * Note:	 * Because of little endian switch we must use an even number of	 * instructions here..  Pad with a nop if needed. */	mfmsr	%r10	ori	%r10,%r10,1	mtmsr	%r10	nop		/* Note that this is little-endian from here on */	blr	nop	.align  4call_ofw:	/* R3 has the function offset to call (n * 4) 	 * Other arg registers are unchanged.	 * Note that these 4 instructions are in reverse order due to	 * little-endian convention */	andi.	%r0,%r0,65534	mfmsr	%r0	mtmsr	%r0	/* Now normal ordering resumes */	subi	%r1,%r1,0x100	stw	%r8,4(%r1)	stw	%r9,8(%r1)	stw	%r10,12(%r1)	mflr	%r8	stw	%r8,16(%r1)	lis	%r10,0xe00000@ha	add	%r9,%r3,%r10	lwz	%r3,ofw_functions - _start@l(%r9)	mtctr	%r3		mr	%r3,%r4	mr	%r4,%r5	mr	%r5,%r6	mr	%r6,%r7	mr	%r7,%r8	/* Goto the swapped function */	bctrl	lwz	%r8,16(%r1)	mtlr	%r8	lwz	%r8,4(%r1)	lwz	%r9,8(%r1)	lwz	%r10,12(%r1)	addi	%r1,%r1,0x100	/* Ok, go back to little endian */	mfmsr	%r0	ori	%r0,%r0,1	mtmsr	%r0	/* Note that this is little-endian from here on */	blr	nopzero_registers:	xor	%r2,%r2,%r2	mr	%r0,%r2	mr	%r3,%r2		mr	%r4,%r2	mr	%r5,%r2	mr	%r6,%r2	mr	%r7,%r2	mr	%r8,%r2	mr	%r9,%r2	mr	%r10,%r2	mr	%r11,%r2	mr	%r12,%r2	mr	%r13,%r2	mr	%r14,%r2	mr	%r15,%r2		mr	%r12,%r2	mr	%r13,%r2	mr	%r14,%r2	mr	%r15,%r2		mr	%r16,%r2	mr	%r17,%r2	mr	%r18,%r2	mr	%r19,%r2		mr	%r20,%r2	mr	%r21,%r2	mr	%r22,%r2	mr	%r23,%r2		mr	%r24,%r2	mr	%r25,%r2	mr	%r26,%r2	mr	%r27,%r2		mr	%r28,%r2	mr	%r29,%r2	mr	%r30,%r2	mr	%r31,%r2	blr	prim_strlen:	mr	%r5,%r3prim_strlen_loop:		lbz	%r4,0(%r3)	cmpi	0,0,%r4,0	beq	prim_strlen_done	addi	%r3,%r3,1	b	prim_strlen_loop	prim_strlen_done:	sub	%r3,%r3,%r5	blr	copy_bits:	cmp	0,0,%r3,%r4	beqlr	lwz	%r6,0(%r3)	stw	%r6,0(%r5)	addi	%r3,%r3,4	addi	%r5,%r5,4	b	copy_bitsofw_print_string_hook:	bl	ofw_print_number	bl	ofw_exit	ofw_print_string:	/* Reserve some stack space */	subi	%r1,%r1,32	/* Save args */	stw	%r3,0(%r1)		/* Save the lr, a scratch register */	stw	%r8,8(%r1)	mflr	%r8	stw	%r8,12(%r1)	/* Load the package name */	lis	%r3,0xe00000@ha	addi	%r3,%r3,ofw_chosen_name - _start	/* Fire */	bl	ofw_finddevice	/* Load up for getprop */	stw	%r3,16(%r1)	lis	%r4,0xe00000@ha	addi	%r4,%r4,ofw_stdout_name - _start	addi	%r5,%r1,20	li	%r6,4	bl	ofw_getprop	/* Measure the string and remember the length */	lwz	%r3,0(%r1)	bl	prim_strlen	mr	%r5,%r3		lwz	%r3,20(%r1)	lwz	%r4,0(%r1)	/* Write the string */	bl	ofw_write	/* Return */	lwz	%r8,12(%r1)	mtlr	%r8	lwz	%r8,8(%r1)		addi	%r1,%r1,32	blr	/* Print 8 hex digits representing a number in r3 */ofw_print_number:	subi	%r1,%r1,32	stw	%r8,0(%r1)	mflr	%r8	stw	%r8,4(%r1)	stw	%r9,8(%r1)	xor	%r9,%r9,%r9	stw	%r9,12(%r1)	/* Set up and, devide, shift */	mr	%r8,%r3	lis	%r6,0xf0000000@ha	lis	%r7,0x10000000@ha	li	%r9,8ofw_number_loop:	nop	cmpi	0,0,%r9,0	beq	ofw_number_return	subi	%r9,%r9,1	/* Body: isolate digit, divide, print */	and	%r5,%r6,%r8	divwu	%r4,%r5,%r7	srwi	%r6,%r6,4	srwi	%r7,%r7,4	nop		cmpi	0,0,%r4,10	bge	ofw_number_letter	addi	%r4,%r4,'0'	b	ofw_number_digit_out	ofw_number_letter:	addi	%r4,%r4,'A' - 10ofw_number_digit_out:		stb	%r4,12(%r1)	addi	%r3,%r1,12	stw	%r6,16(%r1)	stw	%r7,20(%r1)	stw	%r8,24(%r1)	stw	%r9,28(%r1)		bl	ofw_print_string	lwz	%r6,16(%r1)	lwz	%r7,20(%r1)	lwz	%r8,24(%r1)	lwz	%r9,28(%r1)		b	ofw_number_loopofw_number_return:		/* Return */	lwz	%r9,8(%r1)	lwz	%r8,4(%r1)	mtlr	%r8	lwz	%r8,0(%r1)	addi	%r1,%r1,32	blrofw_print_eol:	subi	%r1,%r1,16	stw	%r8,0(%r1)	mflr	%r8	stw	%r8,4(%r1)	li	%r4,0x0d0a	sth	%r4,8(%r1)	xor	%r4,%r4,%r4	sth	%r4,10(%r1)	addi	%r3,%r1,8	bl	ofw_print_string	lwz	%r8,4(%r1)	mtlr	%r8	lwz	%r8,0(%r1)	addi	%r1,%r1,16	blrofw_print_nothing:	subi	%r1,%r1,16	stw	%r8,0(%r1)	mflr	%r8	stw	%r8,4(%r1)	li	%r4,0	sth	%r4,8(%r1)	xor	%r4,%r4,%r4	sth	%r4,10(%r1)	addi	%r3,%r1,8	bl	ofw_print_string	lwz	%r8,4(%r1)	mtlr	%r8	lwz	%r8,0(%r1)	addi	%r1,%r1,16	blrofw_print_space:	subi	%r1,%r1,16	stw	%r8,0(%r1)	mflr	%r8	stw	%r8,4(%r1)	li	%r4,0x2000	sth	%r4,8(%r1)	xor	%r4,%r4,%r4	sth	%r4,10(%r1)	addi	%r3,%r1,8	bl	ofw_print_string	lwz	%r8,4(%r1)	mtlr	%r8	lwz	%r8,0(%r1)	addi	%r1,%r1,16	blrofw_print_regs:		/* Construct ofw exit call */	subi	%r1,%r1,0xa0	stw	%r0,0(%r1)	stw	%r1,4(%r1)	stw	%r2,8(%r1)	stw	%r3,12(%r1)	stw	%r4,16(%r1)	stw	%r5,20(%r1)	stw	%r6,24(%r1)	stw	%r7,28(%r1)		stw	%r8,32(%r1)	stw	%r9,36(%r1)	stw	%r10,40(%r1)	stw	%r11,44(%r1)		stw	%r12,48(%r1)	stw	%r13,52(%r1)	stw	%r14,56(%r1)	stw	%r15,60(%r1)		stw	%r16,64(%r1)	stw	%r17,68(%r1)	stw	%r18,72(%r1)	stw	%r19,76(%r1)		stw	%r20,80(%r1)	stw	%r21,84(%r1)	stw	%r22,88(%r1)	stw	%r23,92(%r1)		stw	%r24,96(%r1)	stw	%r25,100(%r1)	stw	%r26,104(%r1)	stw	%r27,108(%r1)		stw	%r28,112(%r1)	stw	%r29,116(%r1)	stw	%r30,120(%r1)	stw	%r31,124(%r1)	mflr	%r0	stw	%r0,128(%r1)	mfcr	%r0	stw	%r0,132(%r1)	mfctr	%r0	stw	%r0,136(%r1)	mfmsr	%r0	stw	%r0,140(%r1)	/* Count at zero */	xor	%r0,%r0,%r0	stw	%r0,144(%r1)	mr	%r3,%r1	stw	%r3,148(%r1)		/* Body, print the regname, then the register */ofw_register_loop:	lwz	%r3,144(%r1)	cmpi	0,0,%r3,32	beq	ofw_register_special	lis	%r3,0xe00000@ha	addi	%r3,%r3,freeldr_reg_init - _start	bl	ofw_print_string	lwz	%r3,144(%r1)	bl	ofw_print_number	bl	ofw_print_space	lwz	%r3,144(%r1)	mulli	%r3,%r3,4	add	%r3,%r1,%r3	lwz	%r3,0(%r3)	stw	%r3,152(%r1)	bl	ofw_print_number	lwz	%r3,144(%r1)	addi	%r3,%r3,1	stw	%r3,144(%r1)	b	done_dumpdump_optional:		bl	ofw_print_space	bl	ofw_print_space	lwz	%r3,152(%r1)	lwz	%r3,0(%r3)	bl	ofw_print_number	bl	ofw_print_space		lwz	%r3,152(%r1)	lwz	%r3,4(%r3)	bl	ofw_print_number	bl	ofw_print_space		lwz	%r3,152(%r1)	lwz	%r3,8(%r3)	bl	ofw_print_number	bl	ofw_print_space		lwz	%r3,152(%r1)	lwz	%r3,12(%r3)	bl	ofw_print_number	bl	ofw_print_spacedone_dump:		bl	ofw_print_eol	b	ofw_register_loopofw_register_special:	/* LR */	lis	%r3,0xe00000@ha	addi	%r3,%r3,freeldr_reg_lr - _start	bl	ofw_print_string	bl	ofw_print_space	lwz	%r3,128(%r1)	bl	ofw_print_number	bl	ofw_print_eol		/* CR */	lis	%r3,0xe00000@ha	addi	%r3,%r3,freeldr_reg_cr - _start	bl	ofw_print_string	bl	ofw_print_space	lwz	%r3,132(%r1)	bl	ofw_print_number	bl	ofw_print_eol		/* CTR */	lis	%r3,0xe00000@ha	addi	%r3,%r3,freeldr_reg_ctr - _start	bl	ofw_print_string	bl	ofw_print_space	lwz	%r3,136(%r1)	bl	ofw_print_number	bl	ofw_print_eol		/* MSR */	lis	%r3,0xe00000@ha	addi	%r3,%r3,freeldr_reg_msr - _start	bl	ofw_print_string	bl	ofw_print_space	lwz	%r3,140(%r1)	bl	ofw_print_number	bl	ofw_print_eol	/* Return */	lwz	%r0,128(%r1)	mtlr	%r0		lwz	%r0,0(%r1)	lwz	%r2,8(%r1)	lwz	%r3,12(%r1)	lwz	%r4,16(%r1)	lwz	%r5,20(%r1)	lwz	%r6,24(%r1)	lwz	%r7,28(%r1)	addi	%r1,%r1,0xa0			blr	ofw_finddevice_hook:	subi	%r1,%r1,32	stw	%r3,0(%r1)	mflr	%r3	stw	%r3,4(%r1)	lwz	%r3,0(%r1)	bl	ofw_finddevice	stw	%r3,0(%r1)	lwz	%r3,4(%r1)	mtlr	%r3	lwz	%r3,0(%r1)	addi	%r1,%r1,32		blr	ofw_finddevice:	/* Reserve stack space ...	 * 20 bytes for the ofw call,	 * r8, r9, and lr */	subi	%r1,%r1,32	/* Store r8, r9, lr */	stw	%r8,20(%r1)	stw	%r9,24(%r1)	mflr	%r8	stw	%r8,28(%r1)		/* Get finddevice name */	lis	%r8,0xe00000@ha	addi	%r9,%r8,ofw_finddevice_name - _start	stw	%r9,0(%r1)	/* 1 Argument and 1 return */	li	%r9,1	stw	%r9,4(%r1)	stw	%r9,8(%r1)	stw	%r3,12(%r1)	/* Load up the call address */	lwz	%r9,ofw_call_addr - _start(%r8)	mtlr	%r9	/* Set argument */	mr	%r3,%r1		/* Fire */	blrl

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?