Blame view

arch/arm/kernel/head-common.S 5.09 KB
75d90832d   Hyok S. Choi   [ARM] nommu: star...
1
2
3
4
5
6
7
8
9
10
11
12
  /*
   *  linux/arch/arm/kernel/head-common.S
   *
   *  Copyright (C) 1994-2002 Russell King
   *  Copyright (c) 2003 ARM Limited
   *  All Rights Reserved
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License version 2 as
   * published by the Free Software Foundation.
   *
   */
9c4c9f387   Greg Ungerer   [ARM] 4849/1: mov...
13
14
  #define ATAG_CORE 0x54410001
  #define ATAG_CORE_SIZE ((2*4 + 3*4) >> 2)
31abdb744   David Brown   ARM: 5739/1: ARM:...
15
  #define ATAG_CORE_SIZE_EMPTY ((2*4) >> 2)
9c4c9f387   Greg Ungerer   [ARM] 4849/1: mov...
16

4c2896e88   Grant Likely   arm/dt: Make __ve...
17
18
19
20
21
  #ifdef CONFIG_CPU_BIG_ENDIAN
  #define OF_DT_MAGIC 0xd00dfeed
  #else
  #define OF_DT_MAGIC 0xedfe0dd0 /* 0xd00dfeed in big-endian */
  #endif
75d90832d   Hyok S. Choi   [ARM] nommu: star...
22
23
24
25
26
27
28
29
30
  /*
   * Exception handling.  Something went wrong and we can't proceed.  We
   * ought to tell the user, but since we don't have any guarantee that
   * we're even running on the right architecture, we do virtually nothing.
   *
   * If CONFIG_DEBUG_LL is set we try to print out something about the error
   * and hope for the best (useful if bootloader fails to pass a proper
   * machine ID for example).
   */
80924ac59   Russell King   ARM: cleanup look...
31
  	__HEAD
9d20fdd58   Bill Gatliff   [ARM] 4423/1: add...
32
33
34
  
  /* Determine validity of the r2 atags pointer.  The heuristic requires
   * that the pointer be aligned, in the first 16k of physical RAM and
4c2896e88   Grant Likely   arm/dt: Make __ve...
35
36
   * that the ATAG_CORE marker is first and present.  If CONFIG_OF_FLATTREE
   * is selected, then it will also accept a dtb pointer.  Future revisions
9d20fdd58   Bill Gatliff   [ARM] 4423/1: add...
37
38
39
   * of this function may be more lenient with the physical address and
   * may also be able to move the ATAGS block if necessary.
   *
9d20fdd58   Bill Gatliff   [ARM] 4423/1: add...
40
   * Returns:
4c2896e88   Grant Likely   arm/dt: Make __ve...
41
   *  r2 either valid atags pointer, valid dtb pointer, or zero
9d20fdd58   Bill Gatliff   [ARM] 4423/1: add...
42
43
   *  r5, r6 corrupted
   */
9d20fdd58   Bill Gatliff   [ARM] 4423/1: add...
44
45
46
  __vet_atags:
  	tst	r2, #0x3			@ aligned?
  	bne	1f
4c2896e88   Grant Likely   arm/dt: Make __ve...
47
48
49
50
51
52
53
  	ldr	r5, [r2, #0]
  #ifdef CONFIG_OF_FLATTREE
  	ldr	r6, =OF_DT_MAGIC		@ is it a DTB?
  	cmp	r5, r6
  	beq	2f
  #endif
  	cmp	r5, #ATAG_CORE_SIZE		@ is first tag ATAG_CORE?
31abdb744   David Brown   ARM: 5739/1: ARM:...
54
  	cmpne	r5, #ATAG_CORE_SIZE_EMPTY
9d20fdd58   Bill Gatliff   [ARM] 4423/1: add...
55
56
57
58
59
  	bne	1f
  	ldr	r5, [r2, #4]
  	ldr	r6, =ATAG_CORE
  	cmp	r5, r6
  	bne	1f
4c2896e88   Grant Likely   arm/dt: Make __ve...
60
  2:	mov	pc, lr				@ atag/dtb pointer is ok
9d20fdd58   Bill Gatliff   [ARM] 4423/1: add...
61
62
63
  
  1:	mov	r2, #0
  	mov	pc, lr
93ed39701   Catalin Marinas   [ARM] 5227/1: Add...
64
  ENDPROC(__vet_atags)
5085f3ff4   Russell King   ARM: hotplug cpu:...
65
66
  
  /*
17bb5e2c1   Russell King   ARM: move __mmap_...
67
68
69
70
71
   * The following fragment of code is executed with the MMU on in MMU mode,
   * and uses absolute addresses; this is not position independent.
   *
   *  r0  = cp#15 control register
   *  r1  = machine ID
4c2896e88   Grant Likely   arm/dt: Make __ve...
72
   *  r2  = atags/dtb pointer
17bb5e2c1   Russell King   ARM: move __mmap_...
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
   *  r9  = processor ID
   */
  	__INIT
  __mmap_switched:
  	adr	r3, __mmap_switched_data
  
  	ldmia	r3!, {r4, r5, r6, r7}
  	cmp	r4, r5				@ Copy data segment if needed
  1:	cmpne	r5, r6
  	ldrne	fp, [r4], #4
  	strne	fp, [r5], #4
  	bne	1b
  
  	mov	fp, #0				@ Clear BSS (and zero fp)
  1:	cmp	r6, r7
  	strcc	fp, [r6],#4
  	bcc	1b
  
   ARM(	ldmia	r3, {r4, r5, r6, r7, sp})
   THUMB(	ldmia	r3, {r4, r5, r6, r7}	)
   THUMB(	ldr	sp, [r3, #16]		)
  	str	r9, [r4]			@ Save processor ID
  	str	r1, [r5]			@ Save machine type
  	str	r2, [r6]			@ Save atags pointer
  	bic	r4, r0, #CR_A			@ Clear 'A' bit
  	stmia	r7, {r0, r4}			@ Save control register values
  	b	start_kernel
  ENDPROC(__mmap_switched)
  
  	.align	2
  	.type	__mmap_switched_data, %object
  __mmap_switched_data:
  	.long	__data_loc			@ r4
a0a55682b   Russell King   Merge branch 'hot...
106
  	.long	_sdata				@ r5
17bb5e2c1   Russell King   ARM: move __mmap_...
107
108
109
110
111
112
113
114
115
116
  	.long	__bss_start			@ r6
  	.long	_end				@ r7
  	.long	processor_id			@ r4
  	.long	__machine_arch_type		@ r5
  	.long	__atags_pointer			@ r6
  	.long	cr_alignment			@ r7
  	.long	init_thread_union + THREAD_START_SP @ sp
  	.size	__mmap_switched_data, . - __mmap_switched_data
  
  /*
17bb5e2c1   Russell King   ARM: move __mmap_...
117
118
119
120
121
122
123
124
125
126
127
   * This provides a C-API version of __lookup_processor_type
   */
  ENTRY(lookup_processor_type)
  	stmfd	sp!, {r4 - r6, r9, lr}
  	mov	r9, r0
  	bl	__lookup_processor_type
  	mov	r0, r5
  	ldmfd	sp!, {r4 - r6, r9, pc}
  ENDPROC(lookup_processor_type)
  
  /*
5085f3ff4   Russell King   ARM: hotplug cpu:...
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
   * Read processor ID register (CP#15, CR0), and look up in the linker-built
   * supported processor list.  Note that we can't use the absolute addresses
   * for the __proc_info lists since we aren't running with the MMU on
   * (and therefore, we are not in the correct address space).  We have to
   * calculate the offset.
   *
   *	r9 = cpuid
   * Returns:
   *	r3, r4, r6 corrupted
   *	r5 = proc_info pointer in physical address space
   *	r9 = cpuid (preserved)
   */
  	__CPUINIT
  __lookup_processor_type:
  	adr	r3, __lookup_processor_type_data
  	ldmia	r3, {r4 - r6}
  	sub	r3, r3, r4			@ get offset between virt&phys
  	add	r5, r5, r3			@ convert virt addresses to
  	add	r6, r6, r3			@ physical address space
  1:	ldmia	r5, {r3, r4}			@ value, mask
  	and	r4, r4, r9			@ mask wanted bits
  	teq	r3, r4
  	beq	2f
  	add	r5, r5, #PROC_INFO_SZ		@ sizeof(proc_info_list)
  	cmp	r5, r6
  	blo	1b
  	mov	r5, #0				@ unknown processor
  2:	mov	pc, lr
  ENDPROC(__lookup_processor_type)
  
  /*
   * Look in <asm/procinfo.h> for information about the __proc_info structure.
   */
  	.align	2
  	.type	__lookup_processor_type_data, %object
  __lookup_processor_type_data:
  	.long	.
  	.long	__proc_info_begin
  	.long	__proc_info_end
  	.size	__lookup_processor_type_data, . - __lookup_processor_type_data
c083c6609   Russell King   ARM: hotplug cpu:...
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
  
  __error_p:
  #ifdef CONFIG_DEBUG_LL
  	adr	r0, str_p1
  	bl	printascii
  	mov	r0, r9
  	bl	printhex8
  	adr	r0, str_p2
  	bl	printascii
  	b	__error
  str_p1:	.asciz	"
  Error: unrecognized/unsupported processor variant (0x"
  str_p2:	.asciz	").
  "
  	.align
  #endif
  ENDPROC(__error_p)
  
  __error:
  #ifdef CONFIG_ARCH_RPC
  /*
   * Turn the screen red on a error - RiscPC only.
   */
  	mov	r0, #0x02000000
  	mov	r3, #0x11
  	orr	r3, r3, r3, lsl #8
  	orr	r3, r3, r3, lsl #16
  	str	r3, [r0], #4
  	str	r3, [r0], #4
  	str	r3, [r0], #4
  	str	r3, [r0], #4
  #endif
  1:	mov	r0, r0
  	b	1b
  ENDPROC(__error)