source: rtems/c/src/lib/libbsp/powerpc/shared/bootloader/head.S @ cd35cf9

4.104.114.84.95
Last change on this file since cd35cf9 was cd35cf9, checked in by Joel Sherrill <joel.sherrill@…>, on 04/18/02 at 20:55:13

2002-04-18 Ralf Corsepius <corsepiu@…>

  • bootloader/exception.S: Reflect changes to <rtems/score/cpu.h>.
  • bootloader/head.S: Ditto.
  • bootloader/misc.c: Ditto.
  • console/polled_io.c: Ditto.
  • irq/irq.c: Ditto.
  • irq/irq_asm.S: Ditto.
  • irq/irq_init.c: Include <rtems/bspIo.h>.
  • start/start.S: Reflect changes to <rtems/score/cpu.h>.
  • vectors/vectors.S: Ditto.
  • Property mode set to 100644
File size: 8.3 KB
Line 
1/*
2 *  head.S -- Bootloader Entry point
3 *
4 *  Copyright (C) 1998, 1999 Gabriel Paubert, paubert@iram.es
5 *
6 *  Modified to compile in RTEMS development environment
7 *  by Eric Valette
8 *
9 *  Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
10 *
11 *  The license and distribution terms for this file may be
12 *  found in found in the file LICENSE in this distribution or at
13 *  http://www.OARcorp.com/rtems/license.html.
14 *
15 * $Id$
16 */
17
18#include <asm.h>
19#include <rtems/score/cpu.h>
20#include "bootldr.h"
21               
22#undef TEST_PPCBUG_CALLS       
23#define FRAME_SIZE 32
24#define LOCK_CACHES (HID0_DLOCK|HID0_ILOCK)
25#define INVL_CACHES (HID0_DCI|HID0_ICFI)
26#define ENBL_CACHES (HID0_DCE|HID0_ICE)
27
28#define USE_PPCBUG
29#undef  USE_PPCBUG
30
31#define MONITOR_ENTER                   \
32        mfmsr   r10             ;       \
33        ori     r10,r10,MSR_IP  ;       \
34        mtmsr   r10             ;       \
35        li      r10,0x63        ;       \
36        sc
37       
38        START_GOT
39        GOT_ENTRY(_GOT2_TABLE_)
40        GOT_ENTRY(_FIXUP_TABLE_)
41        GOT_ENTRY(.bss)
42        GOT_ENTRY(codemove)
43        GOT_ENTRY(0)
44        GOT_ENTRY(__bd)
45        GOT_ENTRY(moved)
46        GOT_ENTRY(_binary_rtems_gz_start)
47        GOT_ENTRY(_binary_initrd_gz_start)
48        GOT_ENTRY(_binary_initrd_gz_end)
49#ifdef TEST_PPCBUG_CALLS       
50        GOT_ENTRY(banner_start)
51        GOT_ENTRY(banner_end)
52#endif 
53        END_GOT
54        .globl  start
55        .type   start,@function
56/* Point the stack into the PreP partition header in the x86 reserved
57 * code area, so that simple C routines can be called.
58 */
59start: 
60#ifdef  USE_PPCBUG
61        MONITOR_ENTER   
62#endif
63        bl      1f
641:      mflr    r1
65        li      r0,0
66        stwu    r0,start-1b-0x400+0x1b0-FRAME_SIZE(r1)
67        stmw    r26,FRAME_SIZE-24(r1)
68        GET_GOT
69        mfmsr   r28             /* Turn off interrupts */
70        ori     r0,r28,MSR_EE
71        xori    r0,r0,MSR_EE
72        mtmsr   r0
73       
74/* Enable the caches, from now on cr2.eq set means processor is 601 */
75        mfpvr   r0
76        mfspr   r29,HID0
77        srwi    r0,r0,16
78        cmplwi  cr2,r0,1
79        beq     2,2f
80#ifndef USE_PPCBUG
81        ori     r0,r29,ENBL_CACHES|INVL_CACHES|LOCK_CACHES
82        xori    r0,r0,INVL_CACHES|LOCK_CACHES
83        sync
84        isync
85        mtspr   HID0,r0
86#endif
872:      bl      reloc
88       
89/* save all the parameters and the orginal msr/hid0/r31 */
90        lwz     bd,GOT(__bd)
91        stw     r3,0(bd)
92        stw     r4,4(bd)
93        stw     r5,8(bd)
94        stw     r6,12(bd)
95        lis     r3,__size@sectoff@ha
96        stw     r7,16(bd)
97        stw     r8,20(bd)
98        addi    r3,r3,__size@sectoff@l
99        stw     r9,24(bd)
100        stw     r10,28(bd)
101        stw     r28,o_msr(bd)
102        stw     r29,o_hid0(bd)
103        stw     r31,o_r31(bd)
104
105/* Call the routine to fill boot_data structure from residual data.
106 * And to find where the code has to be moved.
107 */
108        bl      early_setup
109
110/* Now we need to relocate ourselves, where we are told to. First put a
111 * copy of the codemove routine to some place in memory.
112 * (which may be where the 0x41 partition was loaded, so size is critical).
113 */
114        lwz     r4,GOT(codemove)
115        li      r5,_size_codemove
116        lwz     r3,mover(bd)
117        lwz     r6,cache_lsize(bd)
118        bl      codemove
119        mtctr   r3              # Where the temporary codemove is.
120        lwz     r3,image(bd)
121        lis     r5,_edata@sectoff@ha
122        lwz     r4,GOT(0)       # Our own address
123        addi    r5,r5,_edata@sectoff@l
124        lwz     r6,cache_lsize(bd)
125        lwz     r8,GOT(moved)
126        sub     r7,r3,r4        # Difference to adjust pointers.
127        add     r8,r8,r7
128        add     r30,r30,r7
129        add     bd,bd,r7
130/* Call the copy routine but return to the new area. */
131        mtlr    r8              # for the return address
132        bctr                    # returns to the moved instruction
133/* Establish the new top stack frame. */
134moved:  lwz     r1,stack(bd)
135        li      r0,0
136        stwu    r0,-16(r1)
137
138/* relocate again */
139        bl      reloc   
140/* Clear all of BSS */
141        lwz     r10,GOT(.bss)
142        li      r0,__bss_words@sectoff@l
143        subi    r10,r10,4
144        cmpwi   r0,0
145        mtctr   r0
146        li      r0,0
147        beq     4f
1483:      stwu    r0,4(r10)
149        bdnz    3b
150
151/* Final memory initialization. First switch to unmapped mode
152 * in case the FW had set the MMU on, and flush the TLB to avoid
153 * stale entries from interfering. No I/O access is allowed
154 * during this time!
155 */
156#ifndef USE_PPCBUG     
1574:      bl      MMUoff
158#endif 
159        bl      flush_tlb
160/* Some firmware versions leave stale values in the BATs, it's time
161 * to invalidate them to avoid interferences with our own mappings.
162 * But the 601 valid bit is in the BATL (IBAT only) and others are in
163 * the [ID]BATU. Bloat, bloat.. fortunately thrown away later.
164 */
165        li      r3,0
166        beq     cr2,5f
167        mtdbatu 0,r3
168        mtdbatu 1,r3
169        mtdbatu 2,r3
170        mtdbatu 3,r3
1715:      mtibatu 0,r3
172        mtibatl 0,r3
173        mtibatu 1,r3
174        mtibatl 1,r3
175        mtibatu 2,r3
176        mtibatl 2,r3
177        mtibatu 3,r3
178        mtibatl 3,r3
179        lis     r3,__size@sectoff@ha
180        addi    r3,r3,__size@sectoff@l
181        sync                            # We are going to touch SDR1 !
182        bl      mm_init
183        bl      MMUon
184       
185/* Now we are mapped and can perform I/O if we want */
186#ifdef TEST_PPCBUG_CALLS       
187/* Experience seems to show that PPCBug can only be called with the
188 * data cache disabled and with MMU disabled. Bummer.
189 */     
190        li      r10,0x22                # .OUTLN
191        lwz     r3,GOT(banner_start)
192        lwz     r4,GOT(banner_end)
193        sc
194#endif 
195        bl      setup_hw
196        lwz     r4,GOT(_binary_rtems_gz_start)
197        lis     r5,_rtems_gz_size@sectoff@ha
198        lwz     r6,GOT(_binary_initrd_gz_start)
199        lis     r3,_rtems_size@sectoff@ha
200        lwz     r7,GOT(_binary_initrd_gz_end)
201        addi    r5,r5,_rtems_gz_size@sectoff@l
202        addi    r3,r3,_rtems_size@sectoff@l
203        sub     r7,r7,r6
204        bl      decompress_kernel
205
206/* Back here we are unmapped and we start the kernel, passing up to eight
207 * parameters just in case, only r3 to r7 used for now. Flush the tlb so
208 * that the loaded image starts in a clean state.
209 */
210        bl      flush_tlb
211        lwz     r3,0(bd)
212        lwz     r4,4(bd)
213        lwz     r5,8(bd)
214        lwz     r6,12(bd)
215        lwz     r7,16(bd)
216        lwz     r8,20(bd)
217        lwz     r9,24(bd)
218        lwz     r10,28(bd)
219
220        lwz     r30,0(0)
221        mtctr   r30
222/*
223 *      Linux code again
224        lis     r30,0xdeadc0de@ha
225        addi    r30,r30,0xdeadc0de@l
226        stw     r30,0(0)
227        li      r30,0
228*/
229        dcbst   0,r30   /* Make sure it's in memory ! */
230/* We just flash invalidate and disable the dcache, unless it's a 601,
231 * critical areas have been flushed and we don't care about the stack
232 * and other scratch areas.
233 */
234        beq     cr2,1f
235        mfspr   r0,HID0
236        ori     r0,r0,HID0_DCI|HID0_DCE
237        sync
238        mtspr   HID0,r0
239        xori    r0,r0,HID0_DCI|HID0_DCE
240        mtspr   HID0,r0
241/* Provisional return to FW, works for PPCBug */
242#if 0
243        MONITOR_ENTER
244#else
2451:      bctr
246#endif
247               
248       
249
250/* relocation function, r30 must point to got2+0x8000 */
251reloc: 
252/* Adjust got2 pointers, no need to check for 0, this code already puts
253 * a few entries in the table.
254 */
255        li      r0,__got2_entries@sectoff@l
256        la      r12,GOT(_GOT2_TABLE_)
257        lwz     r11,GOT(_GOT2_TABLE_)
258        mtctr   r0
259        sub     r11,r12,r11
260        addi    r12,r12,-4
2611:      lwzu    r0,4(r12)
262        add     r0,r0,r11
263        stw     r0,0(r12)
264        bdnz    1b
265       
266/* Now adjust the fixups and the pointers to the fixups in case we need
267 * to move ourselves again.
268 */     
2692:      li      r0,__fixup_entries@sectoff@l
270        lwz     r12,GOT(_FIXUP_TABLE_)
271        cmpwi   r0,0
272        mtctr   r0
273        addi    r12,r12,-4
274        beqlr
2753:      lwzu    r10,4(r12)
276        lwzux   r0,r10,r11
277        add     r0,r0,r11
278        stw     r10,0(r12)
279        stw     r0,0(r10)
280        bdnz    3b
281        blr             
282
283/* Set the MMU on and off: code is always mapped 1:1 and does not need MMU,
284 * but it does not cost so much to map it also and it catches calls through
285 * NULL function pointers.
286 */
287        .globl  MMUon
288        .type   MMUon,@function
289MMUon:  mfmsr   r0
290        ori     r0,r0,MSR_IR|MSR_DR|MSR_IP
291        mflr    r11
292        xori    r0,r0,MSR_IP
293        mtsrr0  r11
294        mtsrr1  r0
295        rfi
296        .globl  MMUoff
297        .type   MMUoff,@function
298MMUoff: mfmsr   r0
299        ori     r0,r0,MSR_IR|MSR_DR|MSR_IP
300        mflr    r11
301        xori    r0,r0,MSR_IR|MSR_DR
302        mtsrr0  r11
303        mtsrr1  r0
304        rfi
305
306/* Due to the PPC architecture (and according to the specifications), a
307 * series of tlbie which goes through a whole 256 MB segment always flushes
308 * the whole TLB. This is obviously overkill and slow, but who cares ?
309 * It takes about 1 ms on a 200 MHz 603e and works even if residual data
310 * get the number of TLB entries wrong.
311 */
312flush_tlb:
313        lis     r11,0x1000
3141:      addic.  r11,r11,-0x1000
315        tlbie   r11
316        bnl     1b
317/* tlbsync is not implemented on 601, so use sync which seems to be a superset
318 * of tlbsync in all cases and do not bother with CPU dependant code
319 */
320        sync   
321        blr                                     
322
323        .globl  codemove
324codemove:
325        .type   codemove,@function
326/* r3 dest, r4 src, r5 length in bytes, r6 cachelinesize */
327        cmplw   cr1,r3,r4
328        addi    r0,r5,3
329        srwi.   r0,r0,2
330        beq     cr1,4f  /* In place copy is not necessary */
331        beq     7f      /* Protect against 0 count */
332        mtctr   r0
333        bge     cr1,2f
334       
335        la      r8,-4(r4)
336        la      r7,-4(r3)
3371:      lwzu    r0,4(r8)
338        stwu    r0,4(r7)       
339        bdnz    1b
340        b       4f
341
3422:      slwi    r0,r0,2
343        add     r8,r4,r0
344        add     r7,r3,r0
3453:      lwzu    r0,-4(r8)
346        stwu    r0,-4(r7)
347        bdnz    3b
348       
349/* Now flush the cache: note that we must start from a cache aligned
350 * address. Otherwise we might miss one cache line.
351 */
3524:      cmpwi   r6,0
353        add     r5,r3,r5
354        beq     7f      /* Always flush prefetch queue in any case */
355        subi    r0,r6,1
356        andc    r3,r3,r0
357        mr      r4,r3
3585:      cmplw   r4,r5   
359        dcbst   0,r4
360        add     r4,r4,r6
361        blt     5b
362        sync            /* Wait for all dcbst to complete on bus */
363        mr      r4,r3
3646:      cmplw   r4,r5   
365        icbi    0,r4
366        add     r4,r4,r6
367        blt     6b
3687:      sync            /* Wait for all icbi to complete on bus */
369        isync
370        blr
371        .size   codemove,.-codemove
372_size_codemove=.-codemove
373
374        .section        ".data" # .rodata
375        .align 2
376#ifdef TEST_PPCBUG_CALLS       
377banner_start:   
378        .ascii "This message was printed by PPCBug with MMU enabled"
379banner_end:     
380#endif
Note: See TracBrowser for help on using the repository browser.