Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  *  linux/arch/arm/mm/proc-v7m.S
0004  *
0005  *  Copyright (C) 2008 ARM Ltd.
0006  *  Copyright (C) 2001 Deep Blue Solutions Ltd.
0007  *
0008  *  This is the "shell" of the ARMv7-M processor support.
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  *  cpu_v7m_reset(loc)
0026  *
0027  *  Perform a soft reset of the system.  Put the CPU into the
0028  *  same state as it would be if it had been reset, and branch
0029  *  to what would be the reset vector.
0030  *
0031  *  - loc   - location to jump to for soft reset
0032  */
0033     .align  5
0034 ENTRY(cpu_v7m_reset)
0035     ret r0
0036 ENDPROC(cpu_v7m_reset)
0037 
0038 /*
0039  *  cpu_v7m_do_idle()
0040  *
0041  *  Idle the processor (eg, wait for interrupt).
0042  *
0043  *  IRQs are already disabled.
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  * There is no MMU, so here is nothing to do.
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  *  __v7m_setup
0103  *
0104  *  This should be able to cover all ARMv7-M cores.
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     /* Calculate exc_ret */
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  * Cortex-M7 processor functions
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           /* proc_info_list.__cpu_mm_mmu_flags */
0184     .long   0           /* proc_info_list.__cpu_io_mmu_flags */
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           /* proc_info_list.tlb */
0192     .long   0           /* proc_info_list.user */
0193     .long   \cache_fns
0194 .endm
0195 
0196     /*
0197      * Match ARM Cortex-M55 processor.
0198      */
0199     .type   __v7m_cm55_proc_info, #object
0200 __v7m_cm55_proc_info:
0201     .long   0x410fd220      /* ARM Cortex-M55 0xD22 */
0202     .long   0xff0ffff0      /* Mask off revision, patch release */
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      * Match ARM Cortex-M33 processor.
0208      */
0209     .type   __v7m_cm33_proc_info, #object
0210 __v7m_cm33_proc_info:
0211     .long   0x410fd210      /* ARM Cortex-M33 0xD21 */
0212     .long   0xff0ffff0      /* Mask off revision, patch release */
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      * Match ARM Cortex-M7 processor.
0218      */
0219     .type   __v7m_cm7_proc_info, #object
0220 __v7m_cm7_proc_info:
0221     .long   0x410fc270      /* ARM Cortex-M7 0xC27 */
0222     .long   0xff0ffff0      /* Mask off revision, patch release */
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      * Match ARM Cortex-M4 processor.
0228      */
0229     .type   __v7m_cm4_proc_info, #object
0230 __v7m_cm4_proc_info:
0231     .long   0x410fc240      /* ARM Cortex-M4 0xC24 */
0232     .long   0xff0ffff0      /* Mask off revision, patch release */
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      * Match ARM Cortex-M3 processor.
0238      */
0239     .type   __v7m_cm3_proc_info, #object
0240 __v7m_cm3_proc_info:
0241     .long   0x410fc230      /* ARM Cortex-M3 0xC23 */
0242     .long   0xff0ffff0      /* Mask off revision, patch release */
0243     __v7m_proc __v7m_cm3_proc_info, __v7m_setup
0244     .size   __v7m_cm3_proc_info, . - __v7m_cm3_proc_info
0245 
0246     /*
0247      * Match any ARMv7-M processor core.
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