Blame view

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