summaryrefslogtreecommitdiffstats
path: root/arch/ppc/boot/head.S
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1998-08-25 09:12:35 +0000
committerRalf Baechle <ralf@linux-mips.org>1998-08-25 09:12:35 +0000
commitc7fc24dc4420057f103afe8fc64524ebc25c5d37 (patch)
tree3682407a599b8f9f03fc096298134cafba1c9b2f /arch/ppc/boot/head.S
parent1d793fade8b063fde3cf275bf1a5c2d381292cd9 (diff)
o Merge with Linux 2.1.116.
o New Newport console code. o New G364 console code.
Diffstat (limited to 'arch/ppc/boot/head.S')
-rw-r--r--arch/ppc/boot/head.S117
1 files changed, 108 insertions, 9 deletions
diff --git a/arch/ppc/boot/head.S b/arch/ppc/boot/head.S
index 26a0be180..fe03a46f7 100644
--- a/arch/ppc/boot/head.S
+++ b/arch/ppc/boot/head.S
@@ -7,6 +7,8 @@
.text
/*
+ * $Id: head.S,v 1.24 1998/07/21 02:43:50 cort 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.
*
@@ -38,11 +40,35 @@ start_:
mr r11,r3 /* Save pointer to residual/board data */
#ifndef CONFIG_MBX
- mfmsr r3 /* Turn off interrupts */
+ 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
+ cmp 0,r3,r4
+ bne 1010f
+/* compute size of whole image in words. this should be moved to
+ * start_ldr() -- Cort
+ */
+ lis r4,start@h
+ ori r4,r4,start@l
+ lis r5,end@h
+ ori r5,r5,end@l
+ addi r5,r5,3 /* round up */
+ sub r5,r5,r4
+ srwi r5,r5,2
+ mr r7,r5
+ b start_ldr
+1010:
+#if 0
/* Copy relocation code down to location 0x0100 (where we hope it's safe!) */
mflr r3
addi r5,r3,start_ldr-start_
@@ -60,6 +86,7 @@ start_:
mtlr r21
mtctr r22
bctr /* Jump to code */
+#endif
/*
* no matter where we're loaded, move ourselves to -Ttext address
*/
@@ -88,13 +115,12 @@ relocate:
stwu r5,4(r4)
xor r6,r6,r5
bdnz 00b
- lis r3,start_ldr@h
+ lis r3,start_ldr@h
ori r3,r3,start_ldr@l
mtlr r3 /* Easiest way to do an absolute jump */
blr
-start_ldr:
+start_ldr:
#endif /* ndef CONFIG_MBX */
-
/* Clear all of BSS */
lis r3,edata@h
ori r3,r3,edata@l
@@ -115,13 +141,19 @@ start_ldr:
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)
+ mr r3, r11
+ mr r21, r11
+ bl serial_init /* Init MBX serial port */
+ mr r11, r21
+ lis r8,start@h
+ ori r8,r8,start@l
li r9,end@h
ori r9,r9,end@l
sub r7,r8,r9
+ srwi r7,r7,2
+#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 */
@@ -129,6 +161,7 @@ start_ldr:
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
@@ -160,7 +193,7 @@ start_ldr:
ori r10,r10,0xdeadc0de@l
stw r10,0(r9)
#endif
- blr
+ blr
hang:
b hang
@@ -202,5 +235,71 @@ udelay:
cmp 0,r6,r9
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
+ blr
+
+.globl _put_MSR
+_put_MSR:
+ mtmsr r3
+ blr
+
+/*
+ * Flush instruction cache
+ * *** I'm really paranoid here!
+ */
+_GLOBAL(flush_instruction_cache)
+ mflr r5
+ bl flush_data_cache
+#ifndef CONFIG_MBX
+ 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
+#endif
+ mtlr r5
+ blr
+#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 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
.comm .stack,4096*2,4