1d2912cb1SThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-only */ 255bdd694SCatalin Marinas/* 355bdd694SCatalin Marinas * linux/arch/arm/mm/proc-v7m.S 455bdd694SCatalin Marinas * 555bdd694SCatalin Marinas * Copyright (C) 2008 ARM Ltd. 655bdd694SCatalin Marinas * Copyright (C) 2001 Deep Blue Solutions Ltd. 755bdd694SCatalin Marinas * 855bdd694SCatalin Marinas * This is the "shell" of the ARMv7-M processor support. 955bdd694SCatalin Marinas */ 1055bdd694SCatalin Marinas#include <linux/linkage.h> 1155bdd694SCatalin Marinas#include <asm/assembler.h> 12*a9ff6961SLinus Walleij#include <asm/page.h> 1355bdd694SCatalin Marinas#include <asm/v7m.h> 1455bdd694SCatalin Marinas#include "proc-macros.S" 1555bdd694SCatalin Marinas 1655bdd694SCatalin MarinasENTRY(cpu_v7m_proc_init) 176ebbf2ceSRussell King ret lr 1855bdd694SCatalin MarinasENDPROC(cpu_v7m_proc_init) 1955bdd694SCatalin Marinas 2055bdd694SCatalin MarinasENTRY(cpu_v7m_proc_fin) 216ebbf2ceSRussell King ret lr 2255bdd694SCatalin MarinasENDPROC(cpu_v7m_proc_fin) 2355bdd694SCatalin Marinas 2455bdd694SCatalin Marinas/* 2555bdd694SCatalin Marinas * cpu_v7m_reset(loc) 2655bdd694SCatalin Marinas * 2755bdd694SCatalin Marinas * Perform a soft reset of the system. Put the CPU into the 2855bdd694SCatalin Marinas * same state as it would be if it had been reset, and branch 2955bdd694SCatalin Marinas * to what would be the reset vector. 3055bdd694SCatalin Marinas * 3155bdd694SCatalin Marinas * - loc - location to jump to for soft reset 3255bdd694SCatalin Marinas */ 3355bdd694SCatalin Marinas .align 5 3455bdd694SCatalin MarinasENTRY(cpu_v7m_reset) 356ebbf2ceSRussell King ret r0 3655bdd694SCatalin MarinasENDPROC(cpu_v7m_reset) 3755bdd694SCatalin Marinas 3855bdd694SCatalin Marinas/* 3955bdd694SCatalin Marinas * cpu_v7m_do_idle() 4055bdd694SCatalin Marinas * 4155bdd694SCatalin Marinas * Idle the processor (eg, wait for interrupt). 4255bdd694SCatalin Marinas * 4355bdd694SCatalin Marinas * IRQs are already disabled. 4455bdd694SCatalin Marinas */ 4555bdd694SCatalin MarinasENTRY(cpu_v7m_do_idle) 4655bdd694SCatalin Marinas wfi 476ebbf2ceSRussell King ret lr 4855bdd694SCatalin MarinasENDPROC(cpu_v7m_do_idle) 4955bdd694SCatalin Marinas 5055bdd694SCatalin MarinasENTRY(cpu_v7m_dcache_clean_area) 516ebbf2ceSRussell King ret lr 5255bdd694SCatalin MarinasENDPROC(cpu_v7m_dcache_clean_area) 5355bdd694SCatalin Marinas 5455bdd694SCatalin Marinas/* 5555bdd694SCatalin Marinas * There is no MMU, so here is nothing to do. 5655bdd694SCatalin Marinas */ 5755bdd694SCatalin MarinasENTRY(cpu_v7m_switch_mm) 586ebbf2ceSRussell King ret lr 5955bdd694SCatalin MarinasENDPROC(cpu_v7m_switch_mm) 6055bdd694SCatalin Marinas 6155bdd694SCatalin Marinas.globl cpu_v7m_suspend_size 6255bdd694SCatalin Marinas.equ cpu_v7m_suspend_size, 0 6355bdd694SCatalin Marinas 6455bdd694SCatalin Marinas#ifdef CONFIG_ARM_CPU_SUSPEND 6555bdd694SCatalin MarinasENTRY(cpu_v7m_do_suspend) 666ebbf2ceSRussell King ret lr 6755bdd694SCatalin MarinasENDPROC(cpu_v7m_do_suspend) 6855bdd694SCatalin Marinas 6955bdd694SCatalin MarinasENTRY(cpu_v7m_do_resume) 706ebbf2ceSRussell King ret lr 7155bdd694SCatalin MarinasENDPROC(cpu_v7m_do_resume) 7255bdd694SCatalin Marinas#endif 7355bdd694SCatalin Marinas 746a8146f4SJonathan AustinENTRY(cpu_cm7_dcache_clean_area) 756a8146f4SJonathan Austin dcache_line_size r2, r3 766a8146f4SJonathan Austin movw r3, #:lower16:BASEADDR_V7M_SCB + V7M_SCB_DCCMVAC 776a8146f4SJonathan Austin movt r3, #:upper16:BASEADDR_V7M_SCB + V7M_SCB_DCCMVAC 786a8146f4SJonathan Austin 796a8146f4SJonathan Austin1: str r0, [r3] @ clean D entry 806a8146f4SJonathan Austin add r0, r0, r2 816a8146f4SJonathan Austin subs r1, r1, r2 826a8146f4SJonathan Austin bhi 1b 836a8146f4SJonathan Austin dsb 846a8146f4SJonathan Austin ret lr 856a8146f4SJonathan AustinENDPROC(cpu_cm7_dcache_clean_area) 866a8146f4SJonathan Austin 876a8146f4SJonathan AustinENTRY(cpu_cm7_proc_fin) 886a8146f4SJonathan Austin movw r2, #:lower16:(BASEADDR_V7M_SCB + V7M_SCB_CCR) 896a8146f4SJonathan Austin movt r2, #:upper16:(BASEADDR_V7M_SCB + V7M_SCB_CCR) 906a8146f4SJonathan Austin ldr r0, [r2] 916a8146f4SJonathan Austin bic r0, r0, #(V7M_SCB_CCR_DC | V7M_SCB_CCR_IC) 926a8146f4SJonathan Austin str r0, [r2] 936a8146f4SJonathan Austin ret lr 946a8146f4SJonathan AustinENDPROC(cpu_cm7_proc_fin) 956a8146f4SJonathan Austin 96790756c7SNick Desaulniers .section ".init.text", "ax" 9755bdd694SCatalin Marinas 986a8146f4SJonathan Austin__v7m_cm7_setup: 996a8146f4SJonathan Austin mov r8, #(V7M_SCB_CCR_DC | V7M_SCB_CCR_IC| V7M_SCB_CCR_BP) 1006a8146f4SJonathan Austin b __v7m_setup_cont 10155bdd694SCatalin Marinas/* 10255bdd694SCatalin Marinas * __v7m_setup 10355bdd694SCatalin Marinas * 10455bdd694SCatalin Marinas * This should be able to cover all ARMv7-M cores. 10555bdd694SCatalin Marinas */ 10655bdd694SCatalin Marinas__v7m_setup: 1076a8146f4SJonathan Austin mov r8, 0 1086a8146f4SJonathan Austin 1096a8146f4SJonathan Austin__v7m_setup_cont: 11055bdd694SCatalin Marinas @ Configure the vector table base address 11155bdd694SCatalin Marinas ldr r0, =BASEADDR_V7M_SCB 11255bdd694SCatalin Marinas ldr r12, =vector_table 11355bdd694SCatalin Marinas str r12, [r0, V7M_SCB_VTOR] 11455bdd694SCatalin Marinas 11555bdd694SCatalin Marinas @ enable UsageFault, BusFault and MemManage fault. 11655bdd694SCatalin Marinas ldr r5, [r0, #V7M_SCB_SHCSR] 11755bdd694SCatalin Marinas orr r5, #(V7M_SCB_SHCSR_USGFAULTENA | V7M_SCB_SHCSR_BUSFAULTENA | V7M_SCB_SHCSR_MEMFAULTENA) 11855bdd694SCatalin Marinas str r5, [r0, #V7M_SCB_SHCSR] 11955bdd694SCatalin Marinas 12055bdd694SCatalin Marinas @ Lower the priority of the SVC and PendSV exceptions 12155bdd694SCatalin Marinas mov r5, #0x80000000 12255bdd694SCatalin Marinas str r5, [r0, V7M_SCB_SHPR2] @ set SVC priority 12355bdd694SCatalin Marinas mov r5, #0x00800000 12455bdd694SCatalin Marinas str r5, [r0, V7M_SCB_SHPR3] @ set PendSV priority 12555bdd694SCatalin Marinas 126a4124e72SEzequiel Garcia @ SVC to switch to handler mode. Notice that this requires sp to 127a4124e72SEzequiel Garcia @ point to writeable memory because the processor saves 128a4124e72SEzequiel Garcia @ some registers to the stack. 12914327c66SRussell King badr r1, 1f 13055bdd694SCatalin Marinas ldr r5, [r12, #11 * 4] @ read the SVC vector entry 13155bdd694SCatalin Marinas str r1, [r12, #11 * 4] @ write the temporary SVC vector entry 1328e02676fSTorgue Alexandre dsb 13355bdd694SCatalin Marinas mov r6, lr @ save LR 134a4124e72SEzequiel Garcia ldr sp, =init_thread_union + THREAD_START_SP 13555bdd694SCatalin Marinas cpsie i 13655bdd694SCatalin Marinas svc #0 13755bdd694SCatalin Marinas1: cpsid i 1384c0742f6SVladimir Murzin /* Calculate exc_ret */ 1394c0742f6SVladimir Murzin orr r10, lr, #EXC_RET_THREADMODE_PROCESSSTACK 140b70cd406SVladimir Murzin ldmia sp, {r0-r3, r12} 14155bdd694SCatalin Marinas str r5, [r12, #11 * 4] @ restore the original SVC vector entry 14255bdd694SCatalin Marinas mov lr, r6 @ restore LR 14355bdd694SCatalin Marinas 14455bdd694SCatalin Marinas @ Special-purpose control register 14555bdd694SCatalin Marinas mov r1, #1 14655bdd694SCatalin Marinas msr control, r1 @ Thread mode has unpriviledged access 14755bdd694SCatalin Marinas 1486a8146f4SJonathan Austin @ Configure caches (if implemented) 1496a8146f4SJonathan Austin teq r8, #0 150e44fc388SStefan Agner stmiane sp, {r0-r6, lr} @ v7m_invalidate_l1 touches r0-r6 1516a8146f4SJonathan Austin blne v7m_invalidate_l1 1526a8146f4SJonathan Austin teq r8, #0 @ re-evalutae condition 153e44fc388SStefan Agner ldmiane sp, {r0-r6, lr} 1546a8146f4SJonathan Austin 15555bdd694SCatalin Marinas @ Configure the System Control Register to ensure 8-byte stack alignment 15655bdd694SCatalin Marinas @ Note the STKALIGN bit is either RW or RAO. 157bc0ee9d2SJonathan Austin ldr r0, [r0, V7M_SCB_CCR] @ system control register 158bc0ee9d2SJonathan Austin orr r0, #V7M_SCB_CCR_STKALIGN 1596a8146f4SJonathan Austin orr r0, r0, r8 1606a8146f4SJonathan Austin 1616ebbf2ceSRussell King ret lr 16255bdd694SCatalin MarinasENDPROC(__v7m_setup) 16355bdd694SCatalin Marinas 1646a8146f4SJonathan Austin/* 1656a8146f4SJonathan Austin * Cortex-M7 processor functions 1666a8146f4SJonathan Austin */ 1676a8146f4SJonathan Austin globl_equ cpu_cm7_proc_init, cpu_v7m_proc_init 1686a8146f4SJonathan Austin globl_equ cpu_cm7_reset, cpu_v7m_reset 1696a8146f4SJonathan Austin globl_equ cpu_cm7_do_idle, cpu_v7m_do_idle 1706a8146f4SJonathan Austin globl_equ cpu_cm7_switch_mm, cpu_v7m_switch_mm 1716a8146f4SJonathan Austin 17255bdd694SCatalin Marinas define_processor_functions v7m, dabort=nommu_early_abort, pabort=legacy_pabort, nommu=1 1736a8146f4SJonathan Austin define_processor_functions cm7, dabort=nommu_early_abort, pabort=legacy_pabort, nommu=1 17455bdd694SCatalin Marinas 17555bdd694SCatalin Marinas .section ".rodata" 17655bdd694SCatalin Marinas string cpu_arch_name, "armv7m" 17755bdd694SCatalin Marinas string cpu_elf_name "v7m" 17855bdd694SCatalin Marinas string cpu_v7m_name "ARMv7-M" 17955bdd694SCatalin Marinas 180790756c7SNick Desaulniers .section ".proc.info.init", "a" 18155bdd694SCatalin Marinas 182c3a6bcbeSJonathan Austin.macro __v7m_proc name, initfunc, cache_fns = nop_cache_fns, hwcaps = 0, proc_fns = v7m_processor_functions 183c3a6bcbeSJonathan Austin .long 0 /* proc_info_list.__cpu_mm_mmu_flags */ 184c3a6bcbeSJonathan Austin .long 0 /* proc_info_list.__cpu_io_mmu_flags */ 185c3a6bcbeSJonathan Austin initfn \initfunc, \name 186c3a6bcbeSJonathan Austin .long cpu_arch_name 187c3a6bcbeSJonathan Austin .long cpu_elf_name 188c3a6bcbeSJonathan Austin .long HWCAP_HALF | HWCAP_THUMB | HWCAP_FAST_MULT | \hwcaps 189c3a6bcbeSJonathan Austin .long cpu_v7m_name 190c3a6bcbeSJonathan Austin .long \proc_fns 191c3a6bcbeSJonathan Austin .long 0 /* proc_info_list.tlb */ 192c3a6bcbeSJonathan Austin .long 0 /* proc_info_list.user */ 193c3a6bcbeSJonathan Austin .long \cache_fns 194c3a6bcbeSJonathan Austin.endm 195c3a6bcbeSJonathan Austin 196c3a6bcbeSJonathan Austin /* 1973d14751fSTigran Tadevosyan * Match ARM Cortex-M55 processor. 1983d14751fSTigran Tadevosyan */ 1993d14751fSTigran Tadevosyan .type __v7m_cm55_proc_info, #object 2003d14751fSTigran Tadevosyan__v7m_cm55_proc_info: 2013d14751fSTigran Tadevosyan .long 0x410fd220 /* ARM Cortex-M55 0xD22 */ 2023d14751fSTigran Tadevosyan .long 0xff0ffff0 /* Mask off revision, patch release */ 2033d14751fSTigran Tadevosyan __v7m_proc __v7m_cm55_proc_info, __v7m_cm7_setup, hwcaps = HWCAP_EDSP, cache_fns = v7m_cache_fns, proc_fns = cm7_processor_functions 2043d14751fSTigran Tadevosyan .size __v7m_cm55_proc_info, . - __v7m_cm55_proc_info 2053d14751fSTigran Tadevosyan 2063d14751fSTigran Tadevosyan /* 2072965d429SVladimir Murzin * Match ARM Cortex-M33 processor. 2082965d429SVladimir Murzin */ 2092965d429SVladimir Murzin .type __v7m_cm33_proc_info, #object 2102965d429SVladimir Murzin__v7m_cm33_proc_info: 2112965d429SVladimir Murzin .long 0x410fd210 /* ARM Cortex-M33 0xD21 */ 2122965d429SVladimir Murzin .long 0xff0ffff0 /* Mask off revision, patch release */ 2132965d429SVladimir Murzin __v7m_proc __v7m_cm33_proc_info, __v7m_setup, hwcaps = HWCAP_EDSP 2142965d429SVladimir Murzin .size __v7m_cm33_proc_info, . - __v7m_cm33_proc_info 2152965d429SVladimir Murzin 2162965d429SVladimir Murzin /* 2176a8146f4SJonathan Austin * Match ARM Cortex-M7 processor. 2186a8146f4SJonathan Austin */ 2196a8146f4SJonathan Austin .type __v7m_cm7_proc_info, #object 2206a8146f4SJonathan Austin__v7m_cm7_proc_info: 2216a8146f4SJonathan Austin .long 0x410fc270 /* ARM Cortex-M7 0xC27 */ 2226a8146f4SJonathan Austin .long 0xff0ffff0 /* Mask off revision, patch release */ 2236a8146f4SJonathan Austin __v7m_proc __v7m_cm7_proc_info, __v7m_cm7_setup, hwcaps = HWCAP_EDSP, cache_fns = v7m_cache_fns, proc_fns = cm7_processor_functions 2246a8146f4SJonathan Austin .size __v7m_cm7_proc_info, . - __v7m_cm7_proc_info 2256a8146f4SJonathan Austin 2266a8146f4SJonathan Austin /* 227c3a6bcbeSJonathan Austin * Match ARM Cortex-M4 processor. 228c3a6bcbeSJonathan Austin */ 229c3a6bcbeSJonathan Austin .type __v7m_cm4_proc_info, #object 230c3a6bcbeSJonathan Austin__v7m_cm4_proc_info: 231c3a6bcbeSJonathan Austin .long 0x410fc240 /* ARM Cortex-M4 0xC24 */ 232c3a6bcbeSJonathan Austin .long 0xff0ffff0 /* Mask off revision, patch release */ 233c3a6bcbeSJonathan Austin __v7m_proc __v7m_cm4_proc_info, __v7m_setup, hwcaps = HWCAP_EDSP 234c3a6bcbeSJonathan Austin .size __v7m_cm4_proc_info, . - __v7m_cm4_proc_info 235c3a6bcbeSJonathan Austin 236c3a6bcbeSJonathan Austin /* 237c3a6bcbeSJonathan Austin * Match ARM Cortex-M3 processor. 238c3a6bcbeSJonathan Austin */ 239c3a6bcbeSJonathan Austin .type __v7m_cm3_proc_info, #object 240c3a6bcbeSJonathan Austin__v7m_cm3_proc_info: 241c3a6bcbeSJonathan Austin .long 0x410fc230 /* ARM Cortex-M3 0xC23 */ 242c3a6bcbeSJonathan Austin .long 0xff0ffff0 /* Mask off revision, patch release */ 243c3a6bcbeSJonathan Austin __v7m_proc __v7m_cm3_proc_info, __v7m_setup 244c3a6bcbeSJonathan Austin .size __v7m_cm3_proc_info, . - __v7m_cm3_proc_info 245c3a6bcbeSJonathan Austin 24655bdd694SCatalin Marinas /* 24755bdd694SCatalin Marinas * Match any ARMv7-M processor core. 24855bdd694SCatalin Marinas */ 24955bdd694SCatalin Marinas .type __v7m_proc_info, #object 25055bdd694SCatalin Marinas__v7m_proc_info: 25155bdd694SCatalin Marinas .long 0x000f0000 @ Required ID value 25255bdd694SCatalin Marinas .long 0x000f0000 @ Mask for ID 253c3a6bcbeSJonathan Austin __v7m_proc __v7m_proc_info, __v7m_setup 25455bdd694SCatalin Marinas .size __v7m_proc_info, . - __v7m_proc_info 25555bdd694SCatalin Marinas 256