patch-1.3.4 linux/arch/sparc/boot/bare.S

Next file: linux/arch/sparc/boot/bare.h
Previous file: linux/arch/sparc/boot/README
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v1.3.3/linux/arch/sparc/boot/bare.S linux/arch/sparc/boot/bare.S
@@ -0,0 +1,158 @@
+/* base.S:      Ugly low-level boot program entry code.  The job of this
+ *              module is to parse the boot flags, try to mount the remote
+ *              root filesystem and load the kernel into virtual memory.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#include "bare.h"
+
+	.data
+	.globl C_LABEL(romvec)
+	.globl C_LABEL(idp_ptr)
+
+C_LABEL(romvec):
+	.word 0
+C_LABEL(idp_ptr):
+	.word 0
+
+	.text
+	.align 8
+	.globl C_LABEL(first_adr_in_text)
+
+C_LABEL(first_adr_in_text):
+
+	/* Grrr, boot block, scratching my head... */
+	.globl C_LABEL(b_block)       /* Start of actual boot block */
+	.globl C_LABEL(b_block_size)  /* In bytes */
+	.globl C_LABEL(b_block_cksum) /* Checksum of boot block bytes */
+
+	b	start_of_execution    /* XXX Hack */
+	nop
+
+	.align	8
+C_LABEL(b_block):	
+	.skip	(BOOTBLOCK_NENTRIES * BOOTBLOCK_ENTSIZE)
+
+C_LABEL(b_block_size):
+	.word	0
+
+C_LABEL(b_block_cksum):
+	.word	0
+
+/* Ok, the prom has left in %o0 the PROM pointer.  We leave it here
+ * for when we jump into the kernel.  So save out of this window before
+ * you dick with %o0.  As far as I know we could be loaded *anywhere*, so
+ * we relocate ourselves to the "linked" location.  Self modifying code rules.
+ */
+
+start_of_execution:
+	sethi	%hi(C_LABEL(first_adr_in_text)), %o1		! This is our top
+	or	%o1, %lo(C_LABEL(first_adr_in_text)), %o1	! of stack too.
+	sub	%o1, C_STACK, %o1
+	add	%o1, 0x7, %o1
+	andn	%o1, 0x7, %o1
+	save	%o1, 0x0, %sp					! save is an add
+here:
+	call	there
+	sethi	%hi(here), %o4
+there:	
+	sub	%o7, here-C_LABEL(first_adr_in_text), %o5
+	or	%o4, %lo(here), %o4
+	cmp	%o4, %o7
+	be	loaded_ok
+	nop
+
+	/* Gotta relocate, compute our size sans bss segment. */
+	set	C_LABEL(edata)+4, %o3
+	set	C_LABEL(first_adr_in_text), %o2
+	sub	%o3, %o2, %o3
+rel_loop:
+	ld	[%o5], %o4
+	add	%o5, 0x4, %o5
+	st	%o4, [%o2]
+	subcc	%o3, 0x4, %o3
+	bg	rel_loop
+	add	%o2, 0x4, %o2
+
+	/* Pray that we are now in a sane place in memory */
+	sethi	%hi(loaded_ok), %o2
+	or	%o2, %lo(loaded_ok), %o2
+	jmp	%o2
+	nop
+
+loaded_ok:
+	/* Save the PROM pointer */
+	sethi	%hi(C_LABEL(romvec)), %o1
+	or	%o1, %lo(C_LABEL(romvec)), %o1
+	st	%i0, [%o1]
+
+	/* Build a PSR we can live with */
+	rd	%psr, %o1
+
+#if 0
+	andn	%o1, PSR_PIL, %o1
+	sethi	%hi(SANE_PSR), %g4
+	or	%g4, %lo(SANE_PSR), %g4
+	or	%o1, %g4, %o1
+#endif
+
+	/* V8 book says this works to calculate num_windows */
+	sethi	%hi(0xffffffff), %g2
+	rd	%wim, %g3
+	or	%g2, %lo(0xffffffff), %g2
+	wr	%g2, 0x0, %wim
+	WRITE_PAUSE
+
+	rd	%wim, %g4
+	WRITE_PAUSE
+
+	wr	%g3, 0x0, %wim
+	WRITE_PAUSE
+
+	/* Restore old %psr */
+	wr	%o1, 0x0, %psr
+	WRITE_PAUSE
+
+	or	%g0, 0x0, %g3
+1:
+	srl	%g4, 0x1, %g4
+	subcc	%g4, 0x0, %g0
+	bne	1b
+	add	%g3, 0x1, %g3
+	
+	/* %g3 now contains nwindows */
+	sethi	%hi(C_LABEL(nwindows)), %o4
+	st	%g3, [%o4 + %lo(C_LABEL(nwindows))]
+
+	/* Now zero out our bss segment, lord knows the nasty prom monster
+	 * didn't do it for us.
+	 */
+	sethi	%hi(C_LABEL(end)), %g1
+	or	%g1, %lo(C_LABEL(end)), %g1
+	add	%g1, 0x4, %g1
+	sethi	%hi(C_LABEL(edata)), %g2
+	or	%g2, %lo(C_LABEL(edata)), %g2
+
+	/* Slow, inefficient, who cares, this is messy boot code */
+bzero_bss_loop:
+	st	%g0, [%g2]
+	add	%g2, 0x4, %g2
+	cmp	%g2, %g1
+	bl	bzero_bss_loop
+	nop
+
+	call	C_LABEL(init_me)	! Fun with imperical constants and prom
+	nop
+
+	/* Dump back into the prom */
+get_me_out_of_here:
+	set	C_LABEL(romvec), %g2
+	ld	[%g2], %g2
+	ld	[%g2 + 0x74], %g2
+	restore
+	call	%g2
+	nop
+
+
+

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov with Sam's (original) version
of this