summaryrefslogtreecommitdiff
path: root/arch/arm/mm/proc-v7m.S
blob: ff97c011ae60e5d0845fc18b84319b592b9369a8 (plain)
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
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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
/*
 *  linux/arch/arm/mm/proc-v7m.S
 *
 *  Copyright (C) 2008 ARM Ltd.
 *  Copyright (C) 2001 Deep Blue Solutions Ltd.
 *
 * 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.
 *
 *  This is the "shell" of the ARMv7-M processor support.
 */
#include <linux/linkage.h>
#include <asm/assembler.h>

ENTRY(cpu_v7m_proc_init)
	mov	pc, lr
ENDPROC(cpu_v7m_proc_init)

ENTRY(cpu_v7m_proc_fin)
	mov	pc, lr
ENDPROC(cpu_v7m_proc_fin)

/*
 *	cpu_v7m_reset(loc)
 *
 *	Perform a soft reset of the system.  Put the CPU into the
 *	same state as it would be if it had been reset, and branch
 *	to what would be the reset vector.
 *
 *	- loc   - location to jump to for soft reset
 *
 *	It is assumed that:
 */
	.align	5
ENTRY(cpu_v7m_reset)
	mov	pc, r0
ENDPROC(cpu_v7m_reset)

/*
 *	cpu_v7m_do_idle()
 *
 *	Idle the processor (eg, wait for interrupt).
 *
 *	IRQs are already disabled.
 */
ENTRY(cpu_v7m_do_idle)
	wfi
	mov	pc, lr
ENDPROC(cpu_v7m_do_idle)

ENTRY(cpu_v7m_dcache_clean_area)
	mov	pc, lr
ENDPROC(cpu_v7m_dcache_clean_area)

/*
 *	cpu_v7m_switch_mm(pgd_phys, tsk)
 *
 *	Set the translation table base pointer to be pgd_phys
 *
 *	- pgd_phys - physical address of new TTB
 *
 *	It is assumed that:
 *	- we are not using split page tables
 */
ENTRY(cpu_v7m_switch_mm)
	mov	pc, lr
ENDPROC(cpu_v7m_switch_mm)

ENTRY(cpu_v7m_set_pte_ext)
	mov	pc, lr
ENDPROC(cpu_v7m_set_pte_ext)

cpu_v7m_name:
	.ascii	"ARMv7-M Processor"
	.align

	.section ".text.init", #alloc, #execinstr

/*
 *	__v7m_setup
 *
 *	Initialise TLB, Caches, and MMU state ready to switch the MMU
 *	on.  Return in r0 the new CP15 C1 control register setting.
 *
 *	We automatically detect if we have a Harvard cache, and use the
 *	Harvard cache control instructions insead of the unified cache
 *	control instructions.
 *
 *	This should be able to cover all ARMv7-M cores.
 *
 *	It is assumed that:
 *	- cache type register is implemented
 */
__v7m_setup:
	@ Configure the vector table base address
	ldr	r0, =0xe000ed08		@ vector table base address
	ldr	r12, =vector_table
	str	r12, [r0]

	@ Lower the priority of the SVC and PendSV exceptions
	ldr	r0, =0xe000ed1c
	mov	r5, #0x80000000
	str	r5, [r0]		@ set SVC priority
	ldr	r0, =0xe000ed20
	mov	r5, #0x00800000
	str	r5, [r0]		@ set PendSV priority

	@ SVC to run the kernel in this mode
	adr	r0, BSYM(1f)
	ldr	r5, [r12, #11 * 4]	@ read the SVC vector entry
	str	r0, [r12, #11 * 4]	@ write the temporary SVC vector entry
	mov	r6, lr			@ save LR
	mov	r7, sp			@ save SP
	ldr	sp, =__v7m_setup_stack_top
	cpsie	i
	svc	#0
1:	cpsid	i
	str	r5, [r12, #11 * 4]	@ restore the original SVC vector entry
	mov	lr, r6			@ restore LR
	mov	sp, r7			@ restore SP

	@ Special-purpose control register
	mov	r0, #1
	msr	control, r0		@ Thread mode has unpriviledged access

	@ Configure the System Control Register
	ldr	r0, =0xe000ed14		@ system control register
	ldr	r12, [r0]
	orr	r12, #1 << 9		@ STKALIGN
	str	r12, [r0]
	mov	pc, lr
ENDPROC(__v7m_setup)

	.align	2
	.type	v7m_processor_functions, #object
ENTRY(v7m_processor_functions)
	.word	v7m_early_abort
	.word	cpu_v7m_proc_init
	.word	cpu_v7m_proc_fin
	.word	cpu_v7m_reset
	.word	cpu_v7m_do_idle
	.word	cpu_v7m_dcache_clean_area
	.word	cpu_v7m_switch_mm
	.word	cpu_v7m_set_pte_ext
	.word	pabort_noifar
	.size	v7m_processor_functions, . - v7m_processor_functions

	.type	cpu_arch_name, #object
cpu_arch_name:
	.asciz	"armv7m"
	.size	cpu_arch_name, . - cpu_arch_name

	.type	cpu_elf_name, #object
cpu_elf_name:
	.asciz	"v7m"
	.size	cpu_elf_name, . - cpu_elf_name
	.align

	.section ".proc.info.init", #alloc, #execinstr

	/*
	 * Match any ARMv7-M processor core.
	 */
	.type	__v7m_proc_info, #object
__v7m_proc_info:
	.long	0x000f0000		@ Required ID value
	.long	0x000f0000		@ Mask for ID
	.long   0			@ proc_info_list.__cpu_mm_mmu_flags
	.long   0			@ proc_info_list.__cpu_io_mmu_flags
	b	__v7m_setup		@ proc_info_list.__cpu_flush
	.long	cpu_arch_name
	.long	cpu_elf_name
	.long	HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
	.long	cpu_v7m_name
	.long	v7m_processor_functions	@ proc_info_list.proc
	.long	0			@ proc_info_list.tlb
	.long	0			@ proc_info_list.user
	.long	0			@ proc_info_list.cache
	.size	__v7m_proc_info, . - __v7m_proc_info

__v7m_setup_stack:
	.space	4 * 8				@ 8 registers
__v7m_setup_stack_top: