xref: /openbmc/linux/arch/arm/mm/proc-v7m.S (revision 2612e3bbc0386368a850140a6c9b990cd496a5ec)
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