0001
0002
0003
0004
0005
0006
0007
0008 #include "ppc_asm.h"
0009
0010 RELA = 7
0011 RELASZ = 8
0012 RELAENT = 9
0013
0014 .data
0015
0016
0017
0018
0019 .globl _zimage_start_opd
0020 _zimage_start_opd:
0021 .long 0x500000, 0, 0, 0
0022 .text
0023 b _zimage_start
0024
0025 #ifdef __powerpc64__
0026 .balign 8
0027 p_start: .8byte _start
0028 p_etext: .8byte _etext
0029 p_bss_start: .8byte __bss_start
0030 p_end: .8byte _end
0031
0032 p_toc: .8byte .TOC. - p_base
0033 p_dyn: .8byte __dynamic_start - p_base
0034 p_rela: .8byte __rela_dyn_start - p_base
0035 p_prom: .8byte 0
0036 .weak _platform_stack_top
0037 p_pstack: .8byte _platform_stack_top
0038 #else
0039 p_start: .long _start
0040 p_etext: .long _etext
0041 p_bss_start: .long __bss_start
0042 p_end: .long _end
0043
0044 .weak _platform_stack_top
0045 p_pstack: .long _platform_stack_top
0046 #endif
0047
0048 .weak _zimage_start
0049 _zimage_start:
0050 .globl _zimage_start_lib
0051 _zimage_start_lib:
0052
0053
0054 bl .+4
0055 p_base: mflr r10
0056 #ifndef __powerpc64__
0057
0058 addis r11,r10,(_GLOBAL_OFFSET_TABLE_-p_base)@ha
0059 lwz r11,(_GLOBAL_OFFSET_TABLE_-p_base)@l(r11)
0060 cmpwi r11,0
0061 beq 3f
0062
0063 .weak __dynamic_start
0064 addis r12,r10,(__dynamic_start-p_base)@ha
0065 addi r12,r12,(__dynamic_start-p_base)@l
0066 subf r11,r11,r12
0067
0068
0069
0070 li r9,0
0071 li r0,0
0072 9: lwz r8,0(r12)
0073 cmpwi r8,0
0074 beq 10f
0075 cmpwi r8,RELA
0076 bne 11f
0077 lwz r9,4(r12)
0078 b 12f
0079 11: cmpwi r8,RELASZ
0080 bne .Lcheck_for_relaent
0081 lwz r0,4(r12)
0082 b 12f
0083 .Lcheck_for_relaent:
0084 cmpwi r8,RELAENT
0085 bne 12f
0086 lwz r14,4(r12)
0087 12: addi r12,r12,8
0088 b 9b
0089
0090
0091
0092
0093 10:
0094 cmpwi r0,0
0095 beq 3f
0096 cmpwi r9,0
0097 beq 3f
0098 cmpwi r14,0
0099 beq 3f
0100
0101 add r9,r9,r11
0102 divwu r0,r0,r14
0103 mtctr r0
0104 2: lbz r0,4+3(r9)
0105 cmpwi r0,22
0106 bne .Lnext
0107 lwz r12,0(r9)
0108 lwz r0,8(r9)
0109 add r0,r0,r11
0110 stwx r0,r11,r12
0111 .Lnext: add r9,r9,r14
0112 bdnz 2b
0113
0114
0115 3: lwz r9,p_start-p_base(r10)
0116 lwz r8,p_etext-p_base(r10)
0117 4: dcbf r0,r9
0118 icbi r0,r9
0119 addi r9,r9,0x20
0120 cmplw cr0,r9,r8
0121 blt 4b
0122 sync
0123 isync
0124
0125
0126 lwz r9,p_bss_start-p_base(r10)
0127 lwz r8,p_end-p_base(r10)
0128 li r0,0
0129 5: stw r0,0(r9)
0130 addi r9,r9,4
0131 cmplw cr0,r9,r8
0132 blt 5b
0133
0134
0135 lwz r8,p_pstack-p_base(r10)
0136 cmpwi r8,0
0137 beq 6f
0138 lwz r1,0(r8)
0139 li r0,0
0140 stwu r0,-16(r1)
0141 6:
0142 #else
0143
0144 std r5,(p_prom-p_base)(r10)
0145
0146
0147 ld r2,(p_toc-p_base)(r10)
0148 add r2,r2,r10
0149
0150
0151 ld r11,-32768(r2)
0152 cmpwi r11,0
0153 beq 3f
0154
0155 ld r11,(p_dyn-p_base)(r10)
0156 add r11,r11,r10
0157 ld r9,(p_rela-p_base)(r10)
0158 add r9,r9,r10
0159
0160 li r13,0
0161 li r8,0
0162 9: ld r12,0(r11)
0163 cmpdi r12,0
0164 beq 12f
0165 cmpdi r12,RELA
0166 bne 10f
0167 ld r13,8(r11)
0168 b 11f
0169 10: cmpwi r12,RELASZ
0170 bne .Lcheck_for_relaent
0171 lwz r8,8(r11)
0172 b 11f
0173 .Lcheck_for_relaent:
0174 cmpwi r12,RELAENT
0175 bne 11f
0176 lwz r14,8(r11)
0177 11: addi r11,r11,16
0178 b 9b
0179 12:
0180 cmpdi r13,0
0181 cmpdi cr1,r8,0
0182 beq 3f
0183 beq cr1,3f
0184 cmpdi r14,0
0185 beq 3f
0186
0187
0188 subf r13,r13,r9
0189
0190
0191
0192 divdu r8,r8,r14
0193 mtctr r8
0194 13: ld r0,8(r9)
0195 cmpdi r0,22
0196 bne .Lnext
0197 ld r12,0(r9)
0198 ld r0,16(r9)
0199 add r0,r0,r13
0200 stdx r0,r13,r12
0201 .Lnext: add r9,r9,r14
0202 bdnz 13b
0203
0204
0205 3: ld r9,p_start-p_base(r10)
0206 ld r8,p_etext-p_base(r10)
0207 4: dcbf r0,r9
0208 icbi r0,r9
0209 addi r9,r9,0x20
0210 cmpld cr0,r9,r8
0211 blt 4b
0212 sync
0213 isync
0214
0215
0216 ld r9,p_bss_start-p_base(r10)
0217 ld r8,p_end-p_base(r10)
0218 li r0,0
0219 5: std r0,0(r9)
0220 addi r9,r9,8
0221 cmpld cr0,r9,r8
0222 blt 5b
0223
0224
0225 ld r8,p_pstack-p_base(r10)
0226 cmpdi r8,0
0227 beq 6f
0228 ld r1,0(r8)
0229 li r0,0
0230 stdu r0,-112(r1)
0231 6:
0232 #endif
0233
0234 bl platform_init
0235
0236
0237 b start
0238
0239 #ifdef __powerpc64__
0240
0241 #define PROM_FRAME_SIZE 512
0242
0243 .macro OP_REGS op, width, start, end, base, offset
0244 .Lreg=\start
0245 .rept (\end - \start + 1)
0246 \op .Lreg,\offset+\width*.Lreg(\base)
0247 .Lreg=.Lreg+1
0248 .endr
0249 .endm
0250
0251 #define SAVE_GPRS(start, end, base) OP_REGS std, 8, start, end, base, 0
0252 #define REST_GPRS(start, end, base) OP_REGS ld, 8, start, end, base, 0
0253 #define SAVE_GPR(n, base) SAVE_GPRS(n, n, base)
0254 #define REST_GPR(n, base) REST_GPRS(n, n, base)
0255
0256
0257
0258 .globl prom
0259 prom:
0260 mflr r0
0261 std r0,16(r1)
0262 stdu r1,-PROM_FRAME_SIZE(r1)
0263
0264 SAVE_GPR(2, r1)
0265 SAVE_GPRS(13, 31, r1)
0266 mfcr r10
0267 std r10,8*32(r1)
0268 mfmsr r10
0269 std r10,8*33(r1)
0270
0271
0272 mfmsr r10
0273 rldicr r10,r10,0,62
0274 mtsrr1 r10
0275
0276
0277 bl 0f
0278 0: mflr r10
0279 addi r11,r10,(1f-0b)
0280 mtlr r11
0281
0282 ld r10,(p_prom-0b)(r10)
0283 mtsrr0 r10
0284
0285 rfid
0286
0287 1:
0288 FIXUP_ENDIAN
0289
0290
0291 rldicl r1,r1,0,32
0292
0293
0294 ld r10,8*(33)(r1)
0295 mtmsr r10
0296 isync
0297
0298
0299 REST_GPR(2, r1)
0300 REST_GPRS(13, 31, r1)
0301 ld r10,8*32(r1)
0302 mtcr r10
0303
0304 addi r1,r1,PROM_FRAME_SIZE
0305 ld r0,16(r1)
0306 mtlr r0
0307 blr
0308 #endif