summaryrefslogtreecommitdiffstats
path: root/arch/ppc/boot/head.S
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1998-05-07 02:55:41 +0000
committerRalf Baechle <ralf@linux-mips.org>1998-05-07 02:55:41 +0000
commitdcec8a13bf565e47942a1751a9cec21bec5648fe (patch)
tree548b69625b18cc2e88c3e68d0923be546c9ebb03 /arch/ppc/boot/head.S
parent2e0f55e79c49509b7ff70ff1a10e1e9e90a3dfd4 (diff)
o Merge with Linux 2.1.99.
o Fix ancient bug in the ELF loader making ldd crash. o Fix ancient bug in the keyboard code for SGI, SNI and Jazz.
Diffstat (limited to 'arch/ppc/boot/head.S')
-rw-r--r--arch/ppc/boot/head.S182
1 files changed, 51 insertions, 131 deletions
diff --git a/arch/ppc/boot/head.S b/arch/ppc/boot/head.S
index ff0030154..26a0be180 100644
--- a/arch/ppc/boot/head.S
+++ b/arch/ppc/boot/head.S
@@ -1,19 +1,43 @@
+#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.
+ *
+ * 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:
+ * 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.
*/
.globl start
start:
bl start_
start_:
- mr r11,r3 /* Save pointer to residual data */
+ mr r11,r3 /* Save pointer to residual/board data */
+
+#ifndef CONFIG_MBX
mfmsr r3 /* Turn off interrupts */
li r4,0
ori r4,r4,MSR_EE
@@ -33,7 +57,6 @@ start_:
bne 00b
mflr r21
mfctr r22
- bl flush_instruction_cache
mtlr r21
mtctr r22
bctr /* Jump to code */
@@ -70,6 +93,8 @@ relocate:
mtlr r3 /* Easiest way to do an absolute jump */
blr
start_ldr:
+#endif /* ndef CONFIG_MBX */
+
/* Clear all of BSS */
lis r3,edata@h
ori r3,r3,edata@l
@@ -89,12 +114,21 @@ start_ldr:
li r2,0x000F /* Mask pointer to 16-byte boundary */
andc r1,r1,r2
/* Run loader */
+#ifdef CONFIG_MBX
+ bl serial_init /* Init MBX serial port */
+#define ILAP_ADDRESS 0xfa000020
+ lis r8, ILAP_ADDRESS@h
+ lwz r8, ILAP_ADDRESS@l(r8)
+ li r9,end@h
+ ori r9,r9,end@l
+ sub r7,r8,r9
+ 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
@@ -111,45 +145,25 @@ start_ldr:
lis r2,initrd_end@h
ori r2,r2,initrd_end@l
lwz r5,0(r2)
-
- li r9,0x00c /* Kernel code starts here */
+
+ /* tell kernel we're prep */
+ /*
+ * get start address of kernel code which is stored as a coff
+ * entry. see boot/head.S -- Cort
+ */
+ li r9,0x0
+ lwz r9,0(r9)
mtlr r9
+#ifndef CONFIG_MBX
+ li r9,0
+ lis r10,0xdeadc0de@h
+ ori r10,r10,0xdeadc0de@l
+ stw r10,0(r9)
+#endif
blr
hang:
b hang
- .globl _get_SP
-_get_SP:
- mr r3,r1
- blr
-
- .globl _get_PVR
-_get_PVR:
- mfspr r3,PVR
- blr
-
- .globl _get_MSR
-_get_MSR:
- mfmsr r3
- blr
-
- .globl _put_MSR
-_put_MSR:
- sync
- mtmsr r3
- blr
-
- .globl _get_HID0
-_get_HID0:
- mfspr r3,HID0
- blr
-
- .globl _put_HID0
-_put_HID0:
- sync
- mtspr HID0,r3
- blr
-
/*
* Delay for a number of microseconds
* -- Use the BUS timer (assumes 66MHz)
@@ -189,98 +203,4 @@ udelay:
blt 2b
3: blr
-/*
- * This space [buffer] is used to forceably flush the data cache when
- * running in copyback mode. This is necessary IFF the data cache could
- * contain instructions for which the instruction cache has stale data.
- * Since the instruction cache NEVER snoops the data cache, memory must
- * be made coherent with the data cache to insure that the instruction
- * cache gets a valid instruction stream. Note that this flushing is
- * only performed when switching from system to user mode since this is
- * the only juncture [as far as the OS goes] where the data cache may
- * contain instructions, e.g. after a disk read.
- */
-#define NUM_CACHE_LINES 128*8
-#define CACHE_LINE_SIZE 32
-#if 0
-cache_flush_buffer:
- .space NUM_CACHE_LINES*CACHE_LINE_SIZE /* CAUTION! these need to match hardware */
-#else
-#define cache_flush_buffer 0x1000
-#endif
-
-
-/*
- * Flush instruction cache
- * *** I'm really paranoid here!
- */
-_GLOBAL(flush_instruction_cache)
- mflr r5
- bl flush_data_cache
- mfspr r3,HID0 /* Caches are controlled by this register */
- li r4,0
- ori r4,r4,(HID0_ICE|HID0_ICFI)
- or r3,r3,r4 /* Need to enable+invalidate to clear */
- mtspr HID0,r3
- andc r3,r3,r4
- ori r3,r3,HID0_ICE /* Enable cache */
- mtspr HID0,r3
- mtlr r5
- blr
-
-/*
- * 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
-#if 0
-00: dcbz 0,r3 /* Flush cache line with minimal BUS traffic */
-#else
-00: lwz r4,0(r3)
-#endif
- addi r3,r3,CACHE_LINE_SIZE /* Next line, please */
- bdnz 00b
-10: blr
-
-/*
- * Flush a particular page from the DATA cache
- * Note: this is necessary because the instruction cache does *not*
- * snoop from the data cache.
- * void flush_page(void *page)
- */
-_GLOBAL(flush_page)
- li r4,0x0FFF
- andc r3,r3,r4 /* Get page base address */
- li r4,4096/CACHE_LINE_SIZE /* Number of lines in a page */
- mtctr r4
-00: dcbf 0,r3 /* Clear line */
- icbi 0,r3
- addi r3,r3,CACHE_LINE_SIZE
- bdnz 00b
- blr
-
-/*
- * Execute a [foreign] function
- *
- * run(p1, p2, cp, ep, entry)
- *
- */
- .globl run
-run:
- mtctr r7 /* Entry point */
-#define IS_PreP 0x50726550 /* 'PreP' */
- lis r30,IS_PreP>>16
- ori r30,r30,IS_PreP&0xFFFF
- mr 11,r5
- mr 12,r6
- mr r28,r5
- mr r29,r6
- mr 11,r5
- mr 12,r6
- bctr
-
.comm .stack,4096*2,4