Import 2.3.18pre1
[davej-history.git] / arch / ppc / boot / head.S
blob79377a2ac6676ed77b73e747d09901b53d3f81e4
1 #include "../kernel/ppc_defs.h"
2 #include "../kernel/ppc_asm.tmpl"
3 #include <asm/processor.h>
4 #include <asm/cache.h>
6         .text
8 /*
9  * $Id: head.S,v 1.33 1999/09/08 01:06:58 cort Exp $
10  *      
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
18  *            -- Cort
19  */
20         .globl  start
21 start:
22         bl      start_
23 start_:
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 */
27         mtmsr   r3
29 /* check if we need to relocate ourselves to the link addr or were we
30    loaded there to begin with -- Cort */
31         lis     r4,start@h
32         ori     r4,r4,start@l
33         mflr    r3
34         subi    r3,r3,4         /* we get the nip, not the ip of the branch */
35         mr      r8,r3
36         cmp     0,r3,r4
37         bne     1010f
38 /* compute size of whole image in words.  this should be moved to
39  * start_ldr() -- Cort
40  */
41         lis     r4,start@h
42         ori     r4,r4,start@l
43         lis     r5,end@h
44         ori     r5,r5,end@l
45         addi    r5,r5,3         /* round up */
46         sub     r5,r5,r4
47         srwi    r5,r5,2
48         mr      r7,r5
49         b       start_ldr
50 1010:
51 /* 
52  * no matter where we're loaded, move ourselves to -Ttext address
53  */
54 relocate:
55         mflr    r3              /* Compute code bias */
56         subi    r3,r3,4
57         mr      r8,r3
58         lis     r4,start@h
59         ori     r4,r4,start@l
60         lis     r5,end@h
61         ori     r5,r5,end@l
62         addi    r5,r5,3                 /* Round up - just in case */
63         sub     r5,r5,r4                /* Compute # longwords to move */
64         srwi    r5,r5,2
65         mtctr   r5
66         mr      r7,r5
67         li      r6,0
68         subi    r3,r3,4                 /* Set up for loop */
69         subi    r4,r4,4
70 00:     lwzu    r5,4(r3)
71         stwu    r5,4(r4)
72         xor     r6,r6,r5
73         bdnz    00b
74         lis     r3,start_ldr@h
75         ori     r3,r3,start_ldr@l
76         mtlr    r3                      /* Easiest way to do an absolute jump */
77         blr
78 start_ldr:
79 /* Clear all of BSS */
80         lis     r3,edata@h
81         ori     r3,r3,edata@l
82         lis     r4,end@h
83         ori     r4,r4,end@l
84         subi    r3,r3,4
85         subi    r4,r4,4
86         li      r0,0
87 50:     stwu    r0,4(r3)
88         cmp     0,r3,r4
89         bne     50b
90 90:     mr      r9,r1                   /* Save old stack pointer (in case it matters) */
91         lis     r1,.stack@h
92         ori     r1,r1,.stack@l
93         addi    r1,r1,4096*2
94         subi    r1,r1,256
95         li      r2,0x000F               /* Mask pointer to 16-byte boundary */
96         andc    r1,r1,r2
97 /* Run loader */
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 */
103         bl      decompress_kernel
104         
105         /* changed to use r3 (as firmware does) for kernel
106            as ptr to residual -- Cort*/
107         lis     r6,cmd_line@h
108         ori     r6,r6,cmd_line@l
109         lwz     r6, 0(r6)
110         subi    r7,r6,1
111 00:     lbzu    r2,1(r7)
112         cmpi    0,r2,0
113         bne     00b
115         /* r4,r5 have initrd_start, size */
116         lis     r2,initrd_start@h
117         ori     r2,r2,initrd_start@l
118         lwz     r4,0(r2)
119         lis     r2,initrd_end@h
120         ori     r2,r2,initrd_end@l
121         lwz     r5,0(r2)
122         
123         /* tell kernel we're prep */
124         /* 
125          * get start address of kernel code which is stored as a coff
126          * entry.  see boot/head.S -- Cort 
127          */
128         li      r9,0x4
129         mtlr    r9
130         lis     r10,0xdeadc0de@h
131         ori     r10,r10,0xdeadc0de@l
132         li      r9,0
133         stw     r10,0(r9)
135  * The Radstone firmware maps PCI memory at 0xc0000000 using BAT2
136  * so disable BATs before setting this to avoid a clash
137  */
138         li      r8,0
139         mtspr   DBAT0U,r8
140         mtspr   DBAT1U,r8
141         mtspr   DBAT2U,r8
142         mtspr   DBAT3U,r8
143         mtspr   IBAT0U,r8
144         mtspr   IBAT1U,r8
145         mtspr   IBAT2U,r8
146         mtspr   IBAT3U,r8
148         blr
149 hang:
150         b       hang    
153  * Delay for a number of microseconds
154  * -- Use the BUS timer (assumes 66MHz)
155  */
156         .globl  udelay
157 udelay:         
158         mfspr   r4,PVR
159         srwi    r4,r4,16
160         cmpi    0,r4,1          /* 601 ? */
161         bne     .udelay_not_601
162 00:     li      r0,86   /* Instructions / microsecond? */
163         mtctr   r0
164 10:     addi    r0,r0,0 /* NOP */
165         bdnz    10b
166         subic.  r3,r3,1
167         bne     00b
168         blr
170 .udelay_not_601:                
171         mulli   r4,r3,1000      /* nanoseconds */
172         addi    r4,r4,59
173         li      r5,60
174         divw    r4,r4,r5        /* BUS ticks */
175 1:      mftbu   r5
176         mftb    r6
177         mftbu   r7
178         cmp     0,r5,r7
179         bne     1b              /* Get [synced] base time */
180         addc    r9,r6,r4        /* Compute end time */
181         addze   r8,r5
182 2:      mftbu   r5
183         cmp     0,r5,r8
184         blt     2b
185         bgt     3f
186         mftb    r6
187         cmp     0,r6,r9
188         blt     2b
189 3:      blr             
191 .globl _get_HID0
192 _get_HID0:              
193         mfspr   r3,HID0
194         blr
196 .globl _put_HID0
197 _put_HID0:              
198         mtspr   HID0,r3
199         blr
200                 
201 .globl _get_MSR
202 _get_MSR:               
203         mfmsr   r3
204         blr
205         
206 .globl _put_MSR
207 _put_MSR:               
208         mtmsr   r3
209         blr
212  * Flush instruction cache
213  * *** I'm really paranoid here!
214  */
215 _GLOBAL(flush_instruction_cache)
216         mflr    r5
217         bl      flush_data_cache
218         mfspr   r3,HID0 /* Caches are controlled by this register */
219         li      r4,0
220         ori     r4,r4,(HID0_ICE|HID0_ICFI)
221         or      r3,r3,r4        /* Need to enable+invalidate to clear */
222         mtspr   HID0,r3
223         andc    r3,r3,r4
224         ori     r3,r3,HID0_ICE  /* Enable cache */
225         mtspr   HID0,r3
226         mtlr    r5
227         blr
228         
229 #define NUM_CACHE_LINES 128*8
230 #define CACHE_LINE_SIZE 32 
231 #define cache_flush_buffer 0x1000
234  * Flush data cache
235  * *** I'm really paranoid here!
236  */
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
241         mtctr   r4
242 00:     lwz     r4,0(r3)
243         addi    r3,r3,CACHE_LINE_SIZE   /* Next line, please */
244         bdnz    00b     
245 10:     blr
246         .comm   .stack,4096*2,4