1 #include "../kernel/ppc_defs.h"
2 #include "../kernel/ppc_asm.tmpl"
3 #include <asm/processor.h>
9 * $Id: head.S,v 1.33 1999/09/08 01:06:58 cort Exp $
11 * Boot loader philosophy:
12 * ROM loads us to some arbitrary location
13 * Move the boot code to the link address (8M)
14 * Call decompress_kernel()
15 * Relocate the initrd, zimage and residual data to 8M
16 * Decompress the kernel to 0
17 * Jump to the kernel entry
24 mr r11,r3 /* Save pointer to residual/board data */
25 mr r25,r5 /* Save OFW pointer */
26 li r3,MSR_IP /* Establish default MSR value */
29 /* check if we need to relocate ourselves to the link addr or were we
30 loaded there to begin with -- Cort */
34 subi r3,r3,4 /* we get the nip, not the ip of the branch */
38 /* compute size of whole image in words. this should be moved to
45 addi r5,r5,3 /* round up */
52 * no matter where we're loaded, move ourselves to -Ttext address
55 mflr r3 /* Compute code bias */
62 addi r5,r5,3 /* Round up - just in case */
63 sub r5,r5,r4 /* Compute # longwords to move */
68 subi r3,r3,4 /* Set up for loop */
76 mtlr r3 /* Easiest way to do an absolute jump */
79 /* Clear all of BSS */
90 90: mr r9,r1 /* Save old stack pointer (in case it matters) */
95 li r2,0x000F /* Mask pointer to 16-byte boundary */
98 mr r3,r8 /* Load point */
99 mr r4,r7 /* Program length */
100 mr r5,r6 /* Checksum */
101 mr r6,r11 /* Residual data */
102 mr r7,r25 /* OFW interfaces */
105 /* changed to use r3 (as firmware does) for kernel
106 as ptr to residual -- Cort*/
115 /* r4,r5 have initrd_start, size */
116 lis r2,initrd_start@h
117 ori r2,r2,initrd_start@l
120 ori r2,r2,initrd_end@l
123 /* tell kernel we're prep */
125 * get start address of kernel code which is stored as a coff
126 * entry. see boot/head.S -- Cort
131 ori r10,r10,0xdeadc0de@l
135 * The Radstone firmware maps PCI memory at 0xc0000000 using BAT2
136 * so disable BATs before setting this to avoid a clash
153 * Delay for a number of microseconds
154 * -- Use the BUS timer (assumes 66MHz)
160 cmpi 0,r4,1 /* 601 ? */
162 00: li r0,86 /* Instructions / microsecond? */
164 10: addi r0,r0,0 /* NOP */
171 mulli r4,r3,1000 /* nanoseconds */
174 divw r4,r4,r5 /* BUS ticks */
179 bne 1b /* Get [synced] base time */
180 addc r9,r6,r4 /* Compute end time */
212 * Flush instruction cache
213 * *** I'm really paranoid here!
215 _GLOBAL(flush_instruction_cache)
218 mfspr r3,HID0 /* Caches are controlled by this register */
220 ori r4,r4,(HID0_ICE|HID0_ICFI)
221 or r3,r3,r4 /* Need to enable+invalidate to clear */
224 ori r3,r3,HID0_ICE /* Enable cache */
229 #define NUM_CACHE_LINES 128*8
230 #define CACHE_LINE_SIZE 32
231 #define cache_flush_buffer 0x1000
235 * *** I'm really paranoid here!
237 _GLOBAL(flush_data_cache)
238 lis r3,cache_flush_buffer@h
239 ori r3,r3,cache_flush_buffer@l
240 li r4,NUM_CACHE_LINES
243 addi r3,r3,CACHE_LINE_SIZE /* Next line, please */
246 .comm .stack,4096*2,4