~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to arch/powerpc/boot/crt0.S

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) Paul Mackerras 1997.
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or
 
5
 * modify it under the terms of the GNU General Public License
 
6
 * as published by the Free Software Foundation; either version
 
7
 * 2 of the License, or (at your option) any later version.
 
8
 *
 
9
 * NOTE: this code runs in 32 bit mode, is position-independent,
 
10
 * and is packaged as ELF32.
 
11
 */
 
12
 
 
13
#include "ppc_asm.h"
 
14
 
 
15
        .text
 
16
        /* A procedure descriptor used when booting this as a COFF file.
 
17
         * When making COFF, this comes first in the link and we're
 
18
         * linked at 0x500000.
 
19
         */
 
20
        .globl  _zimage_start_opd
 
21
_zimage_start_opd:
 
22
        .long   0x500000, 0, 0, 0
 
23
 
 
24
p_start:        .long   _start
 
25
p_etext:        .long   _etext
 
26
p_bss_start:    .long   __bss_start
 
27
p_end:          .long   _end
 
28
 
 
29
        .weak   _platform_stack_top
 
30
p_pstack:       .long   _platform_stack_top
 
31
 
 
32
        .weak   _zimage_start
 
33
        .globl  _zimage_start
 
34
_zimage_start:
 
35
        .globl  _zimage_start_lib
 
36
_zimage_start_lib:
 
37
        /* Work out the offset between the address we were linked at
 
38
           and the address where we're running. */
 
39
        bl      .+4
 
40
p_base: mflr    r10             /* r10 now points to runtime addr of p_base */
 
41
        /* grab the link address of the dynamic section in r11 */
 
42
        addis   r11,r10,(_GLOBAL_OFFSET_TABLE_-p_base)@ha
 
43
        lwz     r11,(_GLOBAL_OFFSET_TABLE_-p_base)@l(r11)
 
44
        cmpwi   r11,0
 
45
        beq     3f              /* if not linked -pie */
 
46
        /* get the runtime address of the dynamic section in r12 */
 
47
        .weak   __dynamic_start
 
48
        addis   r12,r10,(__dynamic_start-p_base)@ha
 
49
        addi    r12,r12,(__dynamic_start-p_base)@l
 
50
        subf    r11,r11,r12     /* runtime - linktime offset */
 
51
 
 
52
        /* The dynamic section contains a series of tagged entries.
 
53
         * We need the RELA and RELACOUNT entries. */
 
54
RELA = 7
 
55
RELACOUNT = 0x6ffffff9
 
56
        li      r9,0
 
57
        li      r0,0
 
58
9:      lwz     r8,0(r12)       /* get tag */
 
59
        cmpwi   r8,0
 
60
        beq     10f             /* end of list */
 
61
        cmpwi   r8,RELA
 
62
        bne     11f
 
63
        lwz     r9,4(r12)       /* get RELA pointer in r9 */
 
64
        b       12f
 
65
11:     addis   r8,r8,(-RELACOUNT)@ha
 
66
        cmpwi   r8,RELACOUNT@l
 
67
        bne     12f
 
68
        lwz     r0,4(r12)       /* get RELACOUNT value in r0 */
 
69
12:     addi    r12,r12,8
 
70
        b       9b
 
71
 
 
72
        /* The relocation section contains a list of relocations.
 
73
         * We now do the R_PPC_RELATIVE ones, which point to words
 
74
         * which need to be initialized with addend + offset.
 
75
         * The R_PPC_RELATIVE ones come first and there are RELACOUNT
 
76
         * of them. */
 
77
10:     /* skip relocation if we don't have both */
 
78
        cmpwi   r0,0
 
79
        beq     3f
 
80
        cmpwi   r9,0
 
81
        beq     3f
 
82
 
 
83
        add     r9,r9,r11       /* Relocate RELA pointer */
 
84
        mtctr   r0
 
85
2:      lbz     r0,4+3(r9)      /* ELF32_R_INFO(reloc->r_info) */
 
86
        cmpwi   r0,22           /* R_PPC_RELATIVE */
 
87
        bne     3f
 
88
        lwz     r12,0(r9)       /* reloc->r_offset */
 
89
        lwz     r0,8(r9)        /* reloc->r_addend */
 
90
        add     r0,r0,r11
 
91
        stwx    r0,r11,r12
 
92
        addi    r9,r9,12
 
93
        bdnz    2b
 
94
 
 
95
        /* Do a cache flush for our text, in case the loader didn't */
 
96
3:      lwz     r9,p_start-p_base(r10)  /* note: these are relocated now */
 
97
        lwz     r8,p_etext-p_base(r10)
 
98
4:      dcbf    r0,r9
 
99
        icbi    r0,r9
 
100
        addi    r9,r9,0x20
 
101
        cmplw   cr0,r9,r8
 
102
        blt     4b
 
103
        sync
 
104
        isync
 
105
 
 
106
        /* Clear the BSS */
 
107
        lwz     r9,p_bss_start-p_base(r10)
 
108
        lwz     r8,p_end-p_base(r10)
 
109
        li      r0,0
 
110
5:      stw     r0,0(r9)
 
111
        addi    r9,r9,4
 
112
        cmplw   cr0,r9,r8
 
113
        blt     5b
 
114
 
 
115
        /* Possibly set up a custom stack */
 
116
        lwz     r8,p_pstack-p_base(r10)
 
117
        cmpwi   r8,0
 
118
        beq     6f
 
119
        lwz     r1,0(r8)
 
120
        li      r0,0
 
121
        stwu    r0,-16(r1)      /* establish a stack frame */
 
122
6:
 
123
 
 
124
        /* Call platform_init() */
 
125
        bl      platform_init
 
126
 
 
127
        /* Call start */
 
128
        b       start