0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/linkage.h>
0011 #include <asm/assembler.h>
0012 #include <asm/memory.h>
0013 #include <asm/v7m.h>
0014 #include "proc-macros.S"
0015
0016 ENTRY(cpu_v7m_proc_init)
0017 ret lr
0018 ENDPROC(cpu_v7m_proc_init)
0019
0020 ENTRY(cpu_v7m_proc_fin)
0021 ret lr
0022 ENDPROC(cpu_v7m_proc_fin)
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 .align 5
0034 ENTRY(cpu_v7m_reset)
0035 ret r0
0036 ENDPROC(cpu_v7m_reset)
0037
0038
0039
0040
0041
0042
0043
0044
0045 ENTRY(cpu_v7m_do_idle)
0046 wfi
0047 ret lr
0048 ENDPROC(cpu_v7m_do_idle)
0049
0050 ENTRY(cpu_v7m_dcache_clean_area)
0051 ret lr
0052 ENDPROC(cpu_v7m_dcache_clean_area)
0053
0054
0055
0056
0057 ENTRY(cpu_v7m_switch_mm)
0058 ret lr
0059 ENDPROC(cpu_v7m_switch_mm)
0060
0061 .globl cpu_v7m_suspend_size
0062 .equ cpu_v7m_suspend_size, 0
0063
0064 #ifdef CONFIG_ARM_CPU_SUSPEND
0065 ENTRY(cpu_v7m_do_suspend)
0066 ret lr
0067 ENDPROC(cpu_v7m_do_suspend)
0068
0069 ENTRY(cpu_v7m_do_resume)
0070 ret lr
0071 ENDPROC(cpu_v7m_do_resume)
0072 #endif
0073
0074 ENTRY(cpu_cm7_dcache_clean_area)
0075 dcache_line_size r2, r3
0076 movw r3, #:lower16:BASEADDR_V7M_SCB + V7M_SCB_DCCMVAC
0077 movt r3, #:upper16:BASEADDR_V7M_SCB + V7M_SCB_DCCMVAC
0078
0079 1: str r0, [r3] @ clean D entry
0080 add r0, r0, r2
0081 subs r1, r1, r2
0082 bhi 1b
0083 dsb
0084 ret lr
0085 ENDPROC(cpu_cm7_dcache_clean_area)
0086
0087 ENTRY(cpu_cm7_proc_fin)
0088 movw r2, #:lower16:(BASEADDR_V7M_SCB + V7M_SCB_CCR)
0089 movt r2, #:upper16:(BASEADDR_V7M_SCB + V7M_SCB_CCR)
0090 ldr r0, [r2]
0091 bic r0, r0, #(V7M_SCB_CCR_DC | V7M_SCB_CCR_IC)
0092 str r0, [r2]
0093 ret lr
0094 ENDPROC(cpu_cm7_proc_fin)
0095
0096 .section ".init.text", "ax"
0097
0098 __v7m_cm7_setup:
0099 mov r8, #(V7M_SCB_CCR_DC | V7M_SCB_CCR_IC| V7M_SCB_CCR_BP)
0100 b __v7m_setup_cont
0101
0102
0103
0104
0105
0106 __v7m_setup:
0107 mov r8, 0
0108
0109 __v7m_setup_cont:
0110 @ Configure the vector table base address
0111 ldr r0, =BASEADDR_V7M_SCB
0112 ldr r12, =vector_table
0113 str r12, [r0, V7M_SCB_VTOR]
0114
0115 @ enable UsageFault, BusFault and MemManage fault.
0116 ldr r5, [r0, #V7M_SCB_SHCSR]
0117 orr r5, #(V7M_SCB_SHCSR_USGFAULTENA | V7M_SCB_SHCSR_BUSFAULTENA | V7M_SCB_SHCSR_MEMFAULTENA)
0118 str r5, [r0, #V7M_SCB_SHCSR]
0119
0120 @ Lower the priority of the SVC and PendSV exceptions
0121 mov r5, #0x80000000
0122 str r5, [r0, V7M_SCB_SHPR2] @ set SVC priority
0123 mov r5, #0x00800000
0124 str r5, [r0, V7M_SCB_SHPR3] @ set PendSV priority
0125
0126 @ SVC to switch to handler mode. Notice that this requires sp to
0127 @ point to writeable memory because the processor saves
0128 @ some registers to the stack.
0129 badr r1, 1f
0130 ldr r5, [r12, #11 * 4] @ read the SVC vector entry
0131 str r1, [r12, #11 * 4] @ write the temporary SVC vector entry
0132 dsb
0133 mov r6, lr @ save LR
0134 ldr sp, =init_thread_union + THREAD_START_SP
0135 cpsie i
0136 svc #0
0137 1: cpsid i
0138
0139 orr r10, lr, #EXC_RET_THREADMODE_PROCESSSTACK
0140 ldmia sp, {r0-r3, r12}
0141 str r5, [r12, #11 * 4] @ restore the original SVC vector entry
0142 mov lr, r6 @ restore LR
0143
0144 @ Special-purpose control register
0145 mov r1, #1
0146 msr control, r1 @ Thread mode has unpriviledged access
0147
0148 @ Configure caches (if implemented)
0149 teq r8, #0
0150 stmiane sp, {r0-r6, lr} @ v7m_invalidate_l1 touches r0-r6
0151 blne v7m_invalidate_l1
0152 teq r8, #0 @ re-evalutae condition
0153 ldmiane sp, {r0-r6, lr}
0154
0155 @ Configure the System Control Register to ensure 8-byte stack alignment
0156 @ Note the STKALIGN bit is either RW or RAO.
0157 ldr r0, [r0, V7M_SCB_CCR] @ system control register
0158 orr r0, #V7M_SCB_CCR_STKALIGN
0159 orr r0, r0, r8
0160
0161 ret lr
0162 ENDPROC(__v7m_setup)
0163
0164
0165
0166
0167 globl_equ cpu_cm7_proc_init, cpu_v7m_proc_init
0168 globl_equ cpu_cm7_reset, cpu_v7m_reset
0169 globl_equ cpu_cm7_do_idle, cpu_v7m_do_idle
0170 globl_equ cpu_cm7_switch_mm, cpu_v7m_switch_mm
0171
0172 define_processor_functions v7m, dabort=nommu_early_abort, pabort=legacy_pabort, nommu=1
0173 define_processor_functions cm7, dabort=nommu_early_abort, pabort=legacy_pabort, nommu=1
0174
0175 .section ".rodata"
0176 string cpu_arch_name, "armv7m"
0177 string cpu_elf_name "v7m"
0178 string cpu_v7m_name "ARMv7-M"
0179
0180 .section ".proc.info.init", "a"
0181
0182 .macro __v7m_proc name, initfunc, cache_fns = nop_cache_fns, hwcaps = 0, proc_fns = v7m_processor_functions
0183 .long 0
0184 .long 0
0185 initfn \initfunc, \name
0186 .long cpu_arch_name
0187 .long cpu_elf_name
0188 .long HWCAP_HALF | HWCAP_THUMB | HWCAP_FAST_MULT | \hwcaps
0189 .long cpu_v7m_name
0190 .long \proc_fns
0191 .long 0
0192 .long 0
0193 .long \cache_fns
0194 .endm
0195
0196
0197
0198
0199 .type __v7m_cm55_proc_info, #object
0200 __v7m_cm55_proc_info:
0201 .long 0x410fd220
0202 .long 0xff0ffff0
0203 __v7m_proc __v7m_cm55_proc_info, __v7m_cm7_setup, hwcaps = HWCAP_EDSP, cache_fns = v7m_cache_fns, proc_fns = cm7_processor_functions
0204 .size __v7m_cm55_proc_info, . - __v7m_cm55_proc_info
0205
0206
0207
0208
0209 .type __v7m_cm33_proc_info, #object
0210 __v7m_cm33_proc_info:
0211 .long 0x410fd210
0212 .long 0xff0ffff0
0213 __v7m_proc __v7m_cm33_proc_info, __v7m_setup, hwcaps = HWCAP_EDSP
0214 .size __v7m_cm33_proc_info, . - __v7m_cm33_proc_info
0215
0216
0217
0218
0219 .type __v7m_cm7_proc_info, #object
0220 __v7m_cm7_proc_info:
0221 .long 0x410fc270
0222 .long 0xff0ffff0
0223 __v7m_proc __v7m_cm7_proc_info, __v7m_cm7_setup, hwcaps = HWCAP_EDSP, cache_fns = v7m_cache_fns, proc_fns = cm7_processor_functions
0224 .size __v7m_cm7_proc_info, . - __v7m_cm7_proc_info
0225
0226
0227
0228
0229 .type __v7m_cm4_proc_info, #object
0230 __v7m_cm4_proc_info:
0231 .long 0x410fc240
0232 .long 0xff0ffff0
0233 __v7m_proc __v7m_cm4_proc_info, __v7m_setup, hwcaps = HWCAP_EDSP
0234 .size __v7m_cm4_proc_info, . - __v7m_cm4_proc_info
0235
0236
0237
0238
0239 .type __v7m_cm3_proc_info, #object
0240 __v7m_cm3_proc_info:
0241 .long 0x410fc230
0242 .long 0xff0ffff0
0243 __v7m_proc __v7m_cm3_proc_info, __v7m_setup
0244 .size __v7m_cm3_proc_info, . - __v7m_cm3_proc_info
0245
0246
0247
0248
0249 .type __v7m_proc_info, #object
0250 __v7m_proc_info:
0251 .long 0x000f0000 @ Required ID value
0252 .long 0x000f0000 @ Mask for ID
0253 __v7m_proc __v7m_proc_info, __v7m_setup
0254 .size __v7m_proc_info, . - __v7m_proc_info
0255