patch-2.4.5 linux/arch/ppc/boot/mbx/head.S
Next file: linux/arch/ppc/boot/mbx/head_8260.S
Previous file: linux/arch/ppc/boot/mbx/gzimage.c
Back to the patch index
Back to the overall index
- Lines: 244
- Date:
Thu May 24 15:02:06 2001
- Orig file:
v2.4.4/linux/arch/ppc/boot/mbx/head.S
- Orig date:
Wed Dec 31 16:00:00 1969
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/boot/mbx/head.S linux/arch/ppc/boot/mbx/head.S
@@ -0,0 +1,243 @@
+/*
+ * BK Id: SCCS/s.head.S 1.9 05/18/01 07:54:04 patch
+ */
+#include <linux/config.h>
+#include "../../kernel/ppc_defs.h"
+#include "../../kernel/ppc_asm.tmpl"
+#include <asm/processor.h>
+#include <asm/cache.h>
+
+ .text
+
+/*
+ * 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.
+ *
+ * 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_:
+#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
+
+ li r4,0 /* Zero DER to prevent FRZ */
+ mtspr SPRN_DER,r4
+
+/* 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
+ lis r4,end@h
+ ori r4,r4,end@l
+ subi r3,r3,4
+ subi r4,r4,4
+ li r0,0
+50: stwu r0,4(r3)
+ cmp 0,r3,r4
+ bne 50b
+
+ 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
+
+ /* 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
+
+ bl embed_config
+ mr r3, r21
+ bl serial_init /* Init MBX serial port */
+
+ mr r11, r21
+ mr r8, r22
+ mr r7, r23
+ mr r6, r24
+
+#ifdef CONFIG_MBX
+ /* 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
+ ori r6,r6,cmd_line@l
+ lwz r6, 0(r6)
+ subi r7,r6,1
+00: lbzu r2,1(r7)
+ cmpi 0,r2,0
+ bne 00b
+
+ /* r4,r5 have initrd_start, size */
+ lis r2,initrd_start@h
+ ori r2,r2,initrd_start@l
+ lwz r4,0(r2)
+ lis r2,initrd_end@h
+ ori r2,r2,initrd_end@l
+ lwz r5,0(r2)
+
+ /* The world starts from the beginning.
+ */
+ li r9,0x0
+ 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
+
+/*
+ * Delay for a number of microseconds
+ * -- Use the BUS timer (assumes 66MHz)
+ */
+ .globl udelay
+udelay:
+ mulli r4,r3,1000 /* nanoseconds */
+ addi r4,r4,59
+ li r5,60
+ divw r4,r4,r5 /* BUS ticks */
+1: mftbu r5
+ mftb r6
+ mftbu r7
+ cmp 0,r5,r7
+ bne 1b /* Get [synced] base time */
+ addc r9,r6,r4 /* Compute end time */
+ addze r8,r5
+2: mftbu r5
+ cmp 0,r5,r8
+ blt 2b
+ bgt 3f
+ mftb r6
+ cmp 0,r6,r9
+ blt 2b
+3: blr
+
+.globl _get_MSR
+_get_MSR:
+ mfmsr r3
+ blr
+
+.globl _put_MSR
+_put_MSR:
+ mtmsr r3
+ 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)