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
- Lines: 300
- Date:
Thu Oct 7 10:17:08 1999
- Orig file:
v2.3.19/linux/arch/ppc/mbxboot/head.S
- Orig date:
Thu Apr 29 12:39:01 1999
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)