Ok. I didn't make 2.4.0 in 2000. Tough. I tried, but we had some
[davej-history.git] / arch / ppc / boot / head.S
blobcc9339c8eee0379a64fa77eb42715b4f25d949df
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         /* tell kernel we're prep */
116         /* 
117          * get start address of kernel code which is stored as a coff
118          * entry.  see boot/head.S -- Cort 
119          */
120         li      r9,0x4
121         mtlr    r9
122         lis     r10,0xdeadc0de@h
123         ori     r10,r10,0xdeadc0de@l
124         li      r9,0
125         stw     r10,0(r9)
127  * The Radstone firmware maps PCI memory at 0xc0000000 using BAT2
128  * so disable BATs before setting this to avoid a clash
129  */
130         li      r8,0
131         mtspr   DBAT0U,r8
132         mtspr   DBAT1U,r8
133         mtspr   DBAT2U,r8
134         mtspr   DBAT3U,r8
135         mtspr   IBAT0U,r8
136         mtspr   IBAT1U,r8
137         mtspr   IBAT2U,r8
138         mtspr   IBAT3U,r8
140         blr
141 hang:
142         b       hang    
145  * Delay for a number of microseconds
146  * -- Use the BUS timer (assumes 66MHz)
147  */
148         .globl  udelay
149 udelay:         
150         mfspr   r4,PVR
151         srwi    r4,r4,16
152         cmpi    0,r4,1          /* 601 ? */
153         bne     .udelay_not_601
154 00:     li      r0,86   /* Instructions / microsecond? */
155         mtctr   r0
156 10:     addi    r0,r0,0 /* NOP */
157         bdnz    10b
158         subic.  r3,r3,1
159         bne     00b
160         blr
162 .udelay_not_601:                
163         mulli   r4,r3,1000      /* nanoseconds */
164         addi    r4,r4,59
165         li      r5,60
166         divw    r4,r4,r5        /* BUS ticks */
167 1:      mftbu   r5
168         mftb    r6
169         mftbu   r7
170         cmp     0,r5,r7
171         bne     1b              /* Get [synced] base time */
172         addc    r9,r6,r4        /* Compute end time */
173         addze   r8,r5
174 2:      mftbu   r5
175         cmp     0,r5,r8
176         blt     2b
177         bgt     3f
178         mftb    r6
179         cmp     0,r6,r9
180         blt     2b
181 3:      blr             
183 .globl _get_HID0
184 _get_HID0:              
185         mfspr   r3,HID0
186         blr
188 .globl _put_HID0
189 _put_HID0:              
190         mtspr   HID0,r3
191         blr
192                 
193 .globl _get_MSR
194 _get_MSR:               
195         mfmsr   r3
196         blr
197         
198 .globl _put_MSR
199 _put_MSR:               
200         mtmsr   r3
201         blr
204  * Flush instruction cache
205  * *** I'm really paranoid here!
206  */
207 _GLOBAL(flush_instruction_cache)
208         mflr    r5
209         bl      flush_data_cache
210         mfspr   r3,HID0 /* Caches are controlled by this register */
211         li      r4,0
212         ori     r4,r4,(HID0_ICE|HID0_ICFI)
213         or      r3,r3,r4        /* Need to enable+invalidate to clear */
214         mtspr   HID0,r3
215         andc    r3,r3,r4
216         ori     r3,r3,HID0_ICE  /* Enable cache */
217         mtspr   HID0,r3
218         mtlr    r5
219         blr
220         
221 #define NUM_CACHE_LINES 128*8
222 #define CACHE_LINE_SIZE 32 
223 #define cache_flush_buffer 0x1000
226  * Flush data cache
227  * *** I'm really paranoid here!
228  */
229 _GLOBAL(flush_data_cache)
230         lis     r3,cache_flush_buffer@h
231         ori     r3,r3,cache_flush_buffer@l
232         li      r4,NUM_CACHE_LINES
233         mtctr   r4
234 00:     lwz     r4,0(r3)
235         addi    r3,r3,CACHE_LINE_SIZE   /* Next line, please */
236         bdnz    00b     
237 10:     blr
238         .comm   .stack,4096*2,4