OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [lib/] [libbsp/] [powerpc/] [shared/] [bootloader/] [head.S] - Blame information for rev 173

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.