source: rtems/bsps/powerpc/shared/start/preload.S @ 9964895

5
Last change on this file since 9964895 was fbcd7c8f, checked in by Sebastian Huber <sebastian.huber@…>, on 04/20/18 at 08:19:28

bsps: Move start files to bsps

This patch is a part of the BSP source reorganization.

Update #3285.

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