PageRenderTime 43ms CodeModel.GetById 8ms app.highlight 26ms RepoModel.GetById 2ms app.codeStats 0ms

/arch/arm/mm/proc-v6.S

https://bitbucket.org/evzijst/gittest
Assembly | 272 lines | 241 code | 31 blank | 0 comment | 8 complexity | 6f3f402c8125f7c25e03a852d6086f0a MD5 | raw file
  1/*
  2 *  linux/arch/arm/mm/proc-v6.S
  3 *
  4 *  Copyright (C) 2001 Deep Blue Solutions Ltd.
  5 *
  6 * This program is free software; you can redistribute it and/or modify
  7 * it under the terms of the GNU General Public License version 2 as
  8 * published by the Free Software Foundation.
  9 *
 10 *  This is the "shell" of the ARMv6 processor support.
 11 */
 12#include <linux/linkage.h>
 13#include <asm/assembler.h>
 14#include <asm/constants.h>
 15#include <asm/procinfo.h>
 16#include <asm/pgtable.h>
 17
 18#include "proc-macros.S"
 19
 20#define D_CACHE_LINE_SIZE	32
 21
 22	.macro	cpsie, flags
 23	.ifc \flags, f
 24	.long	0xf1080040
 25	.exitm
 26	.endif
 27	.ifc \flags, i
 28	.long	0xf1080080
 29	.exitm
 30	.endif
 31	.ifc \flags, if
 32	.long	0xf10800c0
 33	.exitm
 34	.endif
 35	.err
 36	.endm
 37
 38	.macro	cpsid, flags
 39	.ifc \flags, f
 40	.long	0xf10c0040
 41	.exitm
 42	.endif
 43	.ifc \flags, i
 44	.long	0xf10c0080
 45	.exitm
 46	.endif
 47	.ifc \flags, if
 48	.long	0xf10c00c0
 49	.exitm
 50	.endif
 51	.err
 52	.endm
 53
 54ENTRY(cpu_v6_proc_init)
 55	mov	pc, lr
 56
 57ENTRY(cpu_v6_proc_fin)
 58	mov	pc, lr
 59
 60/*
 61 *	cpu_v6_reset(loc)
 62 *
 63 *	Perform a soft reset of the system.  Put the CPU into the
 64 *	same state as it would be if it had been reset, and branch
 65 *	to what would be the reset vector.
 66 *
 67 *	- loc   - location to jump to for soft reset
 68 *
 69 *	It is assumed that:
 70 */
 71	.align	5
 72ENTRY(cpu_v6_reset)
 73	mov	pc, r0
 74
 75/*
 76 *	cpu_v6_do_idle()
 77 *
 78 *	Idle the processor (eg, wait for interrupt).
 79 *
 80 *	IRQs are already disabled.
 81 */
 82ENTRY(cpu_v6_do_idle)
 83	mcr	p15, 0, r1, c7, c0, 4		@ wait for interrupt
 84	mov	pc, lr
 85
 86ENTRY(cpu_v6_dcache_clean_area)
 87#ifndef TLB_CAN_READ_FROM_L1_CACHE
 881:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
 89	add	r0, r0, #D_CACHE_LINE_SIZE
 90	subs	r1, r1, #D_CACHE_LINE_SIZE
 91	bhi	1b
 92#endif
 93	mov	pc, lr
 94
 95/*
 96 *	cpu_arm926_switch_mm(pgd_phys, tsk)
 97 *
 98 *	Set the translation table base pointer to be pgd_phys
 99 *
100 *	- pgd_phys - physical address of new TTB
101 *
102 *	It is assumed that:
103 *	- we are not using split page tables
104 */
105ENTRY(cpu_v6_switch_mm)
106	mov	r2, #0
107	ldr	r1, [r1, #MM_CONTEXT_ID]	@ get mm->context.id
108	mcr     p15, 0, r2, c7, c5, 6           @ flush BTAC/BTB
109	mcr	p15, 0, r2, c7, c10, 4		@ drain write buffer
110	mcr	p15, 0, r0, c2, c0, 0		@ set TTB 0
111	mcr	p15, 0, r1, c13, c0, 1		@ set context ID
112	mov	pc, lr
113
114#define nG	(1 << 11)
115#define APX	(1 << 9)
116#define AP1	(1 << 5)
117#define AP0	(1 << 4)
118#define XN	(1 << 0)
119
120/*
121 *	cpu_v6_set_pte(ptep, pte)
122 *
123 *	Set a level 2 translation table entry.
124 *
125 *	- ptep  - pointer to level 2 translation table entry
126 *		  (hardware version is stored at -1024 bytes)
127 *	- pte   - PTE value to store
128 *
129 *	Permissions:
130 *	  YUWD  APX AP1 AP0	SVC	User
131 *	  0xxx   0   0   0	no acc	no acc
132 *	  100x   1   0   1	r/o	no acc
133 *	  10x0   1   0   1	r/o	no acc
134 *	  1011   0   0   1	r/w	no acc
135 *	  110x   1   1   0	r/o	r/o
136 *	  11x0   1   1   0	r/o	r/o
137 *	  1111   0   1   1	r/w	r/w
138 */
139ENTRY(cpu_v6_set_pte)
140	str	r1, [r0], #-2048		@ linux version
141
142	bic	r2, r1, #0x00000ff0
143	bic	r2, r2, #0x00000003
144	orr	r2, r2, #AP0 | 2
145
146	tst	r1, #L_PTE_WRITE
147	tstne	r1, #L_PTE_DIRTY
148	orreq	r2, r2, #APX
149
150	tst	r1, #L_PTE_USER
151	orrne	r2, r2, #AP1 | nG
152	tstne	r2, #APX
153	eorne	r2, r2, #AP0
154
155	tst	r1, #L_PTE_YOUNG
156	biceq	r2, r2, #APX | AP1 | AP0
157
158@	tst	r1, #L_PTE_EXEC
159@	orreq	r2, r2, #XN
160
161	tst	r1, #L_PTE_PRESENT
162	moveq	r2, #0
163
164	str	r2, [r0]
165	mcr	p15, 0, r0, c7, c10, 1 @ flush_pte
166	mov	pc, lr
167
168
169
170
171cpu_v6_name:
172	.asciz	"Some Random V6 Processor"
173	.align
174
175	.section ".text.init", #alloc, #execinstr
176
177/*
178 *	__v6_setup
179 *
180 *	Initialise TLB, Caches, and MMU state ready to switch the MMU
181 *	on.  Return in r0 the new CP15 C1 control register setting.
182 *
183 *	We automatically detect if we have a Harvard cache, and use the
184 *	Harvard cache control instructions insead of the unified cache
185 *	control instructions.
186 *
187 *	This should be able to cover all ARMv6 cores.
188 *
189 *	It is assumed that:
190 *	- cache type register is implemented
191 */
192__v6_setup:
193	mov	r0, #0
194	mcr	p15, 0, r0, c7, c14, 0		@ clean+invalidate D cache
195	mcr	p15, 0, r0, c7, c5, 0		@ invalidate I cache
196	mcr	p15, 0, r0, c7, c15, 0		@ clean+invalidate cache
197	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer
198	mcr	p15, 0, r0, c8, c7, 0		@ invalidate I + D TLBs
199	mcr	p15, 0, r0, c2, c0, 2		@ TTB control register
200	mcr	p15, 0, r4, c2, c0, 1		@ load TTB1
201#ifdef CONFIG_VFP
202	mrc	p15, 0, r0, c1, c0, 2
203	orr	r0, r0, #(3 << 20)
204	mcr	p15, 0, r0, c1, c0, 2		@ Enable full access to VFP
205#endif
206	mrc	p15, 0, r0, c1, c0, 0		@ read control register
207	ldr	r5, v6_cr1_clear		@ get mask for bits to clear
208	bic	r0, r0, r5			@ clear bits them
209	ldr	r5, v6_cr1_set			@ get mask for bits to set
210	orr	r0, r0, r5			@ set them
211	mov	pc, lr				@ return to head.S:__ret
212
213	/*
214	 *         V X F   I D LR
215	 * .... ...E PUI. .T.T 4RVI ZFRS BLDP WCAM
216	 * rrrr rrrx xxx0 0101 xxxx xxxx x111 xxxx < forced
217	 *         0 110       0011 1.00 .111 1101 < we want
218	 */
219	.type	v6_cr1_clear, #object
220	.type	v6_cr1_set, #object
221v6_cr1_clear:
222	.word	0x01e0fb7f
223v6_cr1_set:
224	.word	0x00c0387d
225
226	.type	v6_processor_functions, #object
227ENTRY(v6_processor_functions)
228	.word	v6_early_abort
229	.word	cpu_v6_proc_init
230	.word	cpu_v6_proc_fin
231	.word	cpu_v6_reset
232	.word	cpu_v6_do_idle
233	.word	cpu_v6_dcache_clean_area
234	.word	cpu_v6_switch_mm
235	.word	cpu_v6_set_pte
236	.size	v6_processor_functions, . - v6_processor_functions
237
238	.type	cpu_arch_name, #object
239cpu_arch_name:
240	.asciz	"armv6"
241	.size	cpu_arch_name, . - cpu_arch_name
242
243	.type	cpu_elf_name, #object
244cpu_elf_name:
245	.asciz	"v6"
246	.size	cpu_elf_name, . - cpu_elf_name
247	.align
248
249	.section ".proc.info", #alloc, #execinstr
250
251	/*
252	 * Match any ARMv6 processor core.
253	 */
254	.type	__v6_proc_info, #object
255__v6_proc_info:
256	.long	0x0007b000
257	.long	0x0007f000
258	.long   PMD_TYPE_SECT | \
259		PMD_SECT_BUFFERABLE | \
260		PMD_SECT_CACHEABLE | \
261		PMD_SECT_AP_WRITE | \
262		PMD_SECT_AP_READ
263	b	__v6_setup
264	.long	cpu_arch_name
265	.long	cpu_elf_name
266	.long	HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_VFP|HWCAP_EDSP|HWCAP_JAVA
267	.long	cpu_v6_name
268	.long	v6_processor_functions
269	.long	v6wbi_tlb_fns
270	.long	v6_user_fns
271	.long	v6_cache_fns
272	.size	__v6_proc_info, . - __v6_proc_info