patch-2.3.20 linux/arch/ppc/mbxboot/head.S

Next file: linux/arch/ppc/mbxboot/iic.c
Previous file: linux/arch/ppc/mbxboot/embed_config.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.19/linux/arch/ppc/mbxboot/head.S linux/arch/ppc/mbxboot/head.S
@@ -1,3 +1,4 @@
+#include <linux/config.h>
 #include "../kernel/ppc_defs.h"
 #include "../kernel/ppc_asm.tmpl"
 #include <asm/processor.h>
@@ -6,37 +7,101 @@
 	.text
 
 /*
- * $Id: head.S,v 1.4 1999/04/22 06:32:09 davem Exp $
+ * $Id: head.S,v 1.6 1999/09/15 00:02:25 dmalek Exp $
  *	
  * This code is loaded by the ROM loader at some arbitrary location.
  * Move it to high memory so that it can load the kernel at 0x0000.
  *
- * The MBX EPPC-Bug understands ELF, so it loads us into the location
- * specified in the header.  This is a two step process.  First, EPPC-Bug
- * loads the file into the intermediate buffer memory location specified
- * by the environment parameters.  When it discovers this is an ELF
- * binary, it relocates to the link address for us.  Unfortunately, the
- * header does not move with the file, so we have to find the
- * intermediate load location and read the header from there.  From
- * information provided by Motorola (thank you), we know this intermediate
- * location can be found from the NVRAM environment.
- * All of these addresses must be somewhat carefully chosen to make sure
- * we don't overlap the regions.  I chose to load the kernel at 0, the
- * compressed image loads at 0x00100000, and the MBX intermediate buffer
- * was set to 0x00200000.  Provided the loaded kernel image never grows
- * over one megabyte (which I am going to ensure never happens :-), these
- * will work fine.  When we get called from EPPC-Bug, registers are:
+ * This is a three step process that will also work when booting from
+ * a Flash PROM normally located in high memory.
+ *
+ * First, the entire image is loaded into some high memory address.
+ * This is usually at or above 0x02000000.  This is done by a network
+ * boot function supported by the board or a debugger over BDM port.
+ *
+ * Second, the start up function here will relocate the decompress
+ * function to run at the link address of 0x01000000.
+ *
+ * Last, the decompression function will reloate the initrd, zImage, and
+ * the residual data to locations under 8 Meg.  This is necessary because
+ * the embedded kernel start up uses 8 Meg translations to access physical
+ * space before the MMU is enabled.  Finally, the zImage is uncompressed
+ * to location 0 and we jump to it.
+ *
+ * On the MBX,
  *              R1 - Stack pointer at a high memory address.
  *              R3 - Pointer to Board Information Block.
  *              R4 - Pointer to argument string.
  *              Interrupts masked, cache and MMU disabled.
+ *
+ *		...and the first and second functions listed above are
+ *			done for us (it knows ELF images).
+ *
+ * For other embedded boards we build the Board Information Block.
  */
 
 	.globl	start
 start:
 	bl	start_
 start_:
-	mr	r11,r3		/* Save pointer to residual/board data */
+#ifndef CONFIG_MBX
+	lis	r11, local_bd_info@h
+	ori	r11, r11, local_bd_info@l
+#else
+	mr	r11, r3
+#endif
+
+	mfmsr	r3		/* Turn off interrupts  */
+	li	r4,0
+	ori	r4,r4,MSR_EE
+	andc	r3,r3,r4
+	mtmsr	r3
+
+/* check if we need to relocate ourselves to the link addr or were we
+   loaded there to begin with -- Cort */
+	lis	r4,start@h
+	ori	r4,r4,start@l
+	mflr	r3
+	subi	r3,r3,4		/* we get the nip, not the ip of the branch */
+	mr	r8,r3
+#if 0
+	cmp	0,r3,r4
+	beq	start_ldr	/* Branch if loaded OK */
+#endif
+
+/* 
+ * no matter where we're loaded, move ourselves to -Ttext address
+ * This computes the sizes we need to determine other things.
+ */
+	lis	r5,end@h
+	ori	r5,r5,end@l
+	addi	r5,r5,3			/* Round up - just in case */
+	sub	r5,r5,r4		/* Compute # longwords to move */
+	srwi	r5,r5,2
+	mtctr	r5
+	mr	r7,r5
+	li	r6,0
+	subi	r3,r3,4			/* Set up for loop */
+	subi	r4,r4,4
+00:	lwzu	r5,4(r3)
+	stwu	r5,4(r4)
+	xor	r6,r6,r5
+	bdnz	00b
+
+  	lis	r3,start_ldr@h
+	ori	r3,r3,start_ldr@l
+	mtlr	r3			/* Easiest way to do an absolute jump */
+	blr
+
+start_ldr:
+/* Most 8xx boards don't boot up with the I-cache enabled.  Do that
+ * now because the decompress runs much faster that way.
+ */
+	lis	r3, IDC_INVALL@h
+	mtspr	IC_CST, r3
+	lis	r3, IDC_ENABLE@h
+	mtspr	IC_CST, r3
+
 /* Clear all of BSS */
 	lis	r3,edata@h
 	ori	r3,r3,edata@l
@@ -48,39 +113,60 @@
 50:	stwu	r0,4(r3)
 	cmp	0,r3,r4
 	bne	50b
-90:	mr	r9,r1			/* Save old stack pointer (in case it matters) */
+
 	lis	r1,.stack@h
 	ori	r1,r1,.stack@l
 	addi	r1,r1,4096*2
 	subi	r1,r1,256
 	li	r2,0x000F		/* Mask pointer to 16-byte boundary */
 	andc	r1,r1,r2
-/* Run loader */
+
+	/* Perform configuration of the various boards.  This is done
+	 * by reading some configuration data from EEPROM and building
+	 * the board information structure.
+	 */
 	mr	r3, r11
         mr      r21, r11
+	mr	r22, r8
+	mr	r23, r7
+	mr	r24, r6
+
+#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC)
+	bl	rpx_cfg
+	mr	r3, r21
+#endif
+#ifdef CONFIG_BSEIP
+	bl	bseip_cfg
+	mr	r3, r21
+#endif
 	bl      serial_init		/* Init MBX serial port */
 
-	lis	r8, 0xfa200000@h	/* Disable Ethernet SCC */
+	mr      r11, r21
+	mr	r8, r22
+	mr	r7, r23
+	mr	r6, r24
+
+#ifdef CONFIG_MBX
+	lis	r18, 0xfa200000@h	/* Disable Ethernet SCC */
 	li	r0, 0
-	stw	r0, 0x0a00(r8)
+	stw	r0, 0x0a00(r18)
 
-	mr      r11, r21
-	lis	r8,start@h
-	ori	r8,r8,start@l
-	lis	r9,end@h
-	ori	r9,r9,end@l
-	sub	r7,r8,r9
-	srwi	r7,r7,2
+	/* On the MBX (or anything that will TFTP load an ELF image),
+	 * we have to find the intermediate address.  The ELF loader
+	 * only moves the Linux boostrap/decompress, not the zImage.
+	 */
 #define ILAP_ADDRESS    0xfa000020
         lis     r8, ILAP_ADDRESS@h
         lwz     r8, ILAP_ADDRESS@l(r8)
         addis   r8, r8, 1               /* Add 64K */
+#endif
+
 	mr	r3,r8			/* Load point */
 	mr	r4,r7			/* Program length */
 	mr	r5,r6			/* Checksum */
 	mr	r6,r11			/* Residual data */
 	bl	decompress_kernel
-	
+
 	/* changed to use r3 (as firmware does) for kernel
 	   as ptr to residual -- Cort*/
 	lis	r6,cmd_line@h
@@ -99,14 +185,17 @@
 	ori	r2,r2,initrd_end@l
 	lwz	r5,0(r2)
 	
-	/* tell kernel we're prep */
-	/* 
-	 * get start address of kernel code which is stored as a coff
-	 * entry.  see boot/head.S -- Cort 
-	 */
+	/* The world starts from the beginning.
+	*/
 	li	r9,0x0
-	lwz	r9,0(r9)
 	mtlr	r9
+
+	/* Invalidate the instruction cache because we just copied a
+	 * bunch of kernel instructions.
+	 */
+	lis	r9, IDC_INVALL@h
+	mtspr	IC_CST, r9
+
 	blr
 hang:
 	b	hang	
@@ -117,19 +206,6 @@
  */
 	.globl	udelay
 udelay:		
-	mfspr	r4,PVR
-	srwi	r4,r4,16
-	cmpi	0,r4,1		/* 601 ? */
-	bne	.udelay_not_601
-00:	li	r0,86	/* Instructions / microsecond? */
-	mtctr	r0
-10:	addi	r0,r0,0 /* NOP */
-	bdnz	10b
-	subic.	r3,r3,1
-	bne	00b
-	blr
-
-.udelay_not_601:		
 	mulli	r4,r3,1000	/* nanoseconds */
 	addi	r4,r4,59
 	li	r5,60
@@ -150,16 +226,6 @@
 	blt	2b
 3:	blr		
 
-.globl _get_HID0
-_get_HID0:		
-	mfspr	r3,HID0
-	blr
-
-.globl _put_HID0
-_put_HID0:		
-	mtspr	HID0,r3
-	blr
-		
 .globl _get_MSR
 _get_MSR:		
 	mfmsr	r3
@@ -170,31 +236,14 @@
 	mtmsr	r3
 	blr
 
-/*
- * Flush instruction cache
- * *** I'm really paranoid here!
- */
-_GLOBAL(flush_instruction_cache)
-	mflr	r5
-	bl	flush_data_cache
-	mtlr	r5
-	blr
-	
-#define NUM_CACHE_LINES 128*8
-#define CACHE_LINE_SIZE 32 
-#define cache_flush_buffer 0x1000
-
-/*
- * Flush data cache
- * *** I'm really paranoid here!
- */
-_GLOBAL(flush_data_cache)
-	lis	r3,cache_flush_buffer@h
-	ori	r3,r3,cache_flush_buffer@l
-	li	r4,NUM_CACHE_LINES
-	mtctr	r4
-00:	lwz	r4,0(r3)
-	addi	r3,r3,CACHE_LINE_SIZE	/* Next line, please */
-	bdnz	00b	
-10:	blr
 	.comm	.stack,4096*2,4
+#ifndef CONFIG_MBX
+local_bd_info:
+	.long	0
+	.long	0x01000000
+	.long	64
+	.long	64
+	.long	0
+	.long	0
+	.long	0
+#endif

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)