source: rtems/c/src/lib/libbsp/powerpc/mvme5500/start/preload.S @ 7e2dcde

4.104.114.84.95
Last change on this file since 7e2dcde was 7e2dcde, checked in by Till Straumann <strauman@…>, on Nov 3, 2005 at 9:38:36 PM

2005-11-03 straumanatslacdotstanforddotedu

  • startup/linkcmds: Removed.
  • Makefile.am, start/preload.S, startup/bspstart.c: use linkcmds

from shared area - this version seemed broken anyways. Let the
preloader use the generic 'entry_point_section' rather than its own
'mvme5500_preloader_section'. Also, let zero_bss use (implicit?)
SBSSxxx symbols.

  • Property mode set to 100644
File size: 8.8 KB
Line 
1/*
2 * Mini-loader for the SVGM and MVME5500 BSP.
3 *
4 * $Id$
5 *
6 * Copyright (C) 2003, 2004
7 * Author: Till Straumann, 10/2001 <strauman@slac.stanford.edu>
8 *
9 * Some ideas are borrowed from the powerpc/shared/bootloader
10 * by
11 *  Copyright (C) 1998, 1999 Gabriel Paubert, paubert@iram.es
12 *  Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
13 *
14 *
15 * The SVGM firmware is unable to load the RTEMS image below
16 * 0x2000 (I believe their stack is growing below 0x1000) ?
17 *
18 * The code provided by this file is responsible for the performing
19 * the following steps:
20 *
21 *  1) Save commandline parameters to an area that is
22 *       a) not covered by the downloaded image
23 *       b) will not be overwritten by the moved image
24 *          nor the final BSS segment (rtems clears BSS
25 *          before saving the command line).
26 *  2) Initialize and setup the memory controller to prepare the
27 *     SDRAM before moving the image to it.
28 *  3) Move the entire image (including this very file) to
29 *     its final location starting at 0x0000.
30 *     It is important to note that _NO_STACK_ is available
31 *     during this step. Also, there is probably no return to
32 *     Monitor because relocating RTEMS will destroy vital Monitor
33 *     data (such as its stack).
34 *  3) Flush the cache to make sure the relocated image is actually
35 *     in memory.
36 *  4) setup RTEMS environment (initial register values), most
37 *     notably an initial STACK. The initial stack may be small and
38 *     is used by RTEMS only at a very early stage.
39 *     A safe place for the stack seems to be the 00..0x7f area.
40 *     NOTE: we should respect the MAILBOX area 0x80..0xff!
41 *  5) switch the MMU off (because that's what RTEMS is expecting
42 *     it to be at startup).
43 *  6) fire up rtems...
44 *
45 *
46 *  Calling convention:
47 *     R1: Monitor SP
48 *     R3: command line string start
49 *     R4: command line string end + 1
50 *     R5: where Monitor put the image
51 *         if R5 is 0, the preloader will use its entry point
52 *         as the image starting address.
53 *         See NOTE below.
54 *     R6: end of the image (i.e. R6-R5 is the image length)
55 *         if R6 is 0, _edata will be used as the image length
56 *         See NOTE below.
57 *
58 *     NOTE: if the symbol DONT_USE_R5_ENTRY is defined,
59 *         R5/R6 are never used and the necessary parameters are
60 *         determined at runtime (R5) / linkage (R6) [_edata]
61 *
62 *  ASSUMPTIONS:
63 *    The code RELIES on the assumption that the image will be
64 *    moved DOWNWARDS in memory and that the this loader is
65 *    prepended to the image, i.e. it is safe to do
66 *        codemove(codemove,0,codemove_end - codemove);
67 *        (*0)(codemove_end, codemove_end-codemove, __rtems_end-codemove_end);
68 *    where codemove(from, to, nbytes) is defined as
69 *        codemove(from, to, nbytes) { while (nbytes--) *(to++)=*(from++); }
70 *    Implicit to these assumptions is the assumption that the destination
71 *    address is cache block aligned.
72 *    Furthermore, the byte count is assumed to be a multiple
73 *    of four
74 *
75 */
76#if 0
77/* TODO: I dont know where the appropriate CPU model is to be defined
78 *       when including this to get PPC_CACHE_ALIGNMENT I get an error...
79 */
80#include <rtems/score/ppc.h>
81#else
82#ifndef PPC_CACHE_ALIGNMENT
83#define PPC_CACHE_ALIGNMENT     32
84#endif
85#endif
86
87#include <rtems/score/cpu.h>
88#include <rtems/asm.h>
89
90/* Note that major modifications may be needed
91 * if DESTINATION_ADDR is not 0
92 */
93#define KERNELBASE              0x0
94#define INITIAL_STACK           0x78                    /* 8-byte aligned */
95#define CACHE_LINE_SIZE         PPC_CACHE_ALIGNMENT     /* autodetect doesn't work, see below */
96#define ASSUME_RTEMS_INSTALLS_VECTORS                           /* assume we need not load vectors */
97#define DONT_USE_R5_ENTRY                                                       /* always dynamically determine the address we're running from */
98
99        /* put this into its own section which we want to
100         * be loaded at the very beginning. We should probably
101         * not use more than 255 bytes.
102         */
103        PUBLIC_VAR(__rtems_start)
104        PUBLIC_VAR(__rtems_entry_point)
105        PUBLIC_VAR(__rtems_end)
106        .section .entry_point_section,"awx",@progbits
107preload:
108        /* find out where we are */
109        bl      here
110here:
111        /* MOTLoad had MSR_EE turned on.  Disable it.*/
112        mfmsr   r0
113        xori    r0, r0, MSR_EE
114        mtmsr   r0               
115        mflr    r5
116        addi    r5,r5,-(here-preload)
117        lis             r27,_edata@h
118        ori             r27,r27,_edata@l
119
120        /* at this point the register contents are
121         * R3:  command line start
122         * R4:  R3 + command line length
123         * R5:  address we are running from / loaded to
124         * R27: image end
125         */
126
127        /* save command line start */
128        mr              r6, r3
129        /* save the command line parameters if they are to be overwritten */
130        sub.    r17, r4, r3             /* string length */
131        ble             leaveparms              /* <=0 -> no parameters */
132        /* copy has to be out of the way of the bss; therefore we must
133         * put the string out of the way of both, the current end of
134         * the image (without bss) AND the end of the loaded image
135         * (including bss):
136         * |......image.........|  downloaded image
137         * |image_bss...........|  loaded image with bss appended
138         *
139         *             ^ safe place for string
140         *
141         * the alternative scenario looks like this:
142         * |..image.............|  downloaded image
143         * |image_bss...........|  loaded image with bss appended
144         *           ^ safe place for string
145         */
146        lis             r18, __rtems_end+0x10000@h      /* round up, save one instruction */
147        add             r16, r5, r27    /* image end + 1 */
148        cmpw    r16, r18
149        bge             ishighenough
150        mr              r16,r18                 /* __rtems_end is higher than
151                                                 * the image end
152                                                 * (without bss)
153                                                 */
154ishighenough:
155        cmpw    r16, r3             /* destination start > current string start ? */
156        ble             leaveparms              /* string already after dst, leave it */
157        /* copy string from the last byte downwards */
158        add             r6, r16, r17    /* last byte of destination + 1 */
159        mtctr   r17
1601:
161        lbzu    r3, -1(r4)
162        stbu    r3,     -1(r6)
163        bdnz    1b
164leaveparms:
165        add             r7, r6, r17             /* destination + strlen */
166
167#ifndef CACHE_LINE_SIZE
168        /* Oh well, Monitor firmware has inhibited the cache, so this
169         * nice routine doesn't work...
170         */
171        /* figure out the cache line size */
172        li              r16, 0x80
173        cmpw    r5, r16                 /* 'from' must be > 0x80 */
174        blt             panic
175       
1761:      /* store some arbitrary, nonzero stuff in 0..0x7c */
177        stwu    r16,-4(r16)
178        cmpwi   r16,0
179        bne             1b
180        dcbz    0,r16                   /* zero out one cache line */
181        subi    r16,r16,4
1822:      lwzu    r0,4(r16)               /* search for a non-zero word */
183        cmpwi   r0,0
184        beq             2b
185        /* OK, r16 now hold the size of a cache line in bytes */
186#else
187        li              r16,CACHE_LINE_SIZE
188#endif
189       
190        lis             r3,preload@h
191        ori             r3,r3,preload@l
192        mr              r4,r5                   /* from-addr */
193        li              r5,_preload_size/* this is never > 16k */
194        /* now move ourselves to the link address ('preload').
195         * We set up the LR, so domove() 'returns' to the
196         * relocated copy
197         */
198        lis             r0,return_here@h
199        ori             r0,r0,return_here@l
200        mtlr    r0     
201        b               domove                  /* move the preloader itself */
202return_here:
203        /* now we move the entire rest of the image */
204#ifdef ASSUME_RTEMS_INSTALLS_VECTORS
205        lis             r3,__rtems_start@h
206        ori             r3,r3,__rtems_start@l
207        lis             r0,preload@h    /* calculate/adjust from address */
208        ori             r0,r0,preload@l
209        sub             r0,r3,r0
210        add             r4,r4,r0
211        sub             r5,r27,r3
212#else
213        add             r3,r3,r5                /* add preloader size to destination */
214        add             r4,r4,r5                /* and source addresses */
215        sub             r5,r27,r5               /* length of the remaining rest */
216#endif
217        bl              domove
218        /* OK, now everything should be in place.
219     * we are ready to start...
220         */
221        /* R6: start of command line */
222        /* R7: end of command line +1 */
223       
224        /* setup initial stack for rtems early boot */
225        lis             r1, INITIAL_STACK
226        /* disable the MMU and fire up rtems */
227        mfmsr   r0
228        ori     r0,r0,MSR_IR|MSR_DR|MSR_IP
229        xori    r0,r0,MSR_IR|MSR_DR
230        mtsrr1  r0
231        lis             r0,__rtems_entry_point@h
232        ori             r0,r0,__rtems_entry_point@l
233        mtsrr0  r0
234        rfi
235
236    /* domove(to, from, nbytes):
237     *
238     * move a R5 bytes from R4 to R3 and flush
239     * the caches for the destination memory
240     * region. R16 provides the cache line size.
241     * DESTROYS: R0, R17, R18, CTR, CR
242     */
243domove:
244        addi    r0,r5,3                 /* convert to word count */
245        srwi.   r0,r0,2
246        beq     3f                                      /* nothing to do */
247        cmpw    r3,r4                   /* from == to ?  */
248        beq 3f
249        mtctr   r0
250        la              r18,-4(r4)
251        la              r17,-4(r3)
2521:      lwzu    r0,4(r18)
253        stwu    r0,4(r17)
254        bdnz    1b                              /* move data */
255        /* now, we must flush the destination cache region */
256#ifndef CACHE_LINE_SIZE
257        cmpwi   r16,0
258        beq             3f                              /* nothing to do */
259#endif
260#if defined(CACHE_LINE_SIZE) && CACHE_LINE_SIZE > 0
261        add     r17,r3,r5               /* target end pointer */
262        subi    r0,r16,1
263        add     r17,r17,r0
264        andc    r17,r17,r0              /* cache aligned target end pointer */
265        mr      r18,r3
2662:      cmpw    r18,r17
267        dcbst   0,r18                   /* write out data cache line */
268        icbi    0,r18                   /* invalidate corresponding i-cache line */
269        add     r18,r18,r16
270        blt     2b
271        sync                           /*  make sure data is written back */
272        isync                          /*  invalidate possibly preloaded instructions */
273#endif
2743:
275        blr
276
277#if !defined(CACHE_LINE_SIZE)
278panic:
279        li              r10,0x63
280        mfmsr   r0
281        ori             r0,r0,MSR_IP
282        mtmsr   r0
283        sc
284#endif
285
286/* DONT PUT ANY CODE BELOW HERE */
287_preload_size = . - preload
Note: See TracBrowser for help on using the repository browser.