/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Coherency fabric : low level functions
*
* Copyright ( C ) 2012 Marvell
*
* Gregory CLEMENT < gregory . clement @ free - electrons . com >
*
* This file implements the assembly function to add a CPU to the
* coherency fabric . This function is called by each of the secondary
* CPUs during their early boot in an SMP kernel , this why this
* function have to callable from assembly . It can also be called by a
* primary CPU from C code during its boot .
*/
#include <linux/linkage.h>
#define ARMADA_XP_CFB_CTL_REG_OFFSET 0 x0
#define ARMADA_XP_CFB_CFG_REG_OFFSET 0 x4
#include <asm/assembler.h>
#include <asm/cp15.h>
.arch armv7-a
.text
/*
* Returns the coherency base address in r1 ( r0 is untouched ) , or 0 if
* the coherency fabric is not enabled .
*/
ENTRY(ll_get_coherency_base)
mrc p15, 0 , r1, c1, c0, 0
tst r1, #CR_M @ Check MMU bit enabled
bne 1 f
/*
* MMU is disabled , use the physical address of the coherency
* base address , ( or 0 x0 if the coherency fabric is not mapped )
*/
adr r1, 3 f
ldr r3, [r1]
ldr r1, [r1, r3]
b 2 f
1 :
/*
* MMU is enabled , use the virtual address of the coherency
* base address .
*/
ldr r1, =coherency_base
ldr r1, [r1]
2 :
ret lr
ENDPROC(ll_get_coherency_base)
/*
* Returns the coherency CPU mask in r3 ( r0 is untouched ) . This
* coherency CPU mask can be used with the coherency fabric
* configuration and control registers . Note that the mask is already
* endian - swapped as appropriate so that the calling functions do not
* have to care about endianness issues while accessing the coherency
* fabric registers
*/
ENTRY(ll_get_coherency_cpumask)
mrc p15, 0 , r3, cr0, cr0, 5
and r3, r3, #15
mov r2, #(1 << 24 )
lsl r3, r2, r3
ARM_BE8(rev r3, r3)
ret lr
ENDPROC(ll_get_coherency_cpumask)
/*
* ll_add_cpu_to_smp_group ( ) , ll_enable_coherency ( ) and
* ll_disable_coherency ( ) use the strex / ldrex instructions while the
* MMU can be disabled . The Armada XP SoC has an exclusive monitor
* that tracks transactions to Device and / or SO memory and thanks to
* that , exclusive transactions are functional even when the MMU is
* disabled .
*/
ENTRY(ll_add_cpu_to_smp_group)
/*
* As r0 is not modified by ll_get_coherency_base ( ) and
* ll_get_coherency_cpumask ( ) , we use it to temporarly save lr
* and avoid it being modified by the branch and link
* calls . This function is used very early in the secondary
* CPU boot , and no stack is available at this point .
*/
mov r0, lr
bl ll_get_coherency_base
/* Bail out if the coherency is not enabled */
cmp r1, #0
reteq r0
bl ll_get_coherency_cpumask
mov lr, r0
add r0, r1, #ARMADA_XP_CFB_CFG_REG_OFFSET
1 :
ldrex r2, [r0]
orr r2, r2, r3
strex r1, r2, [r0]
cmp r1, #0
bne 1 b
ret lr
ENDPROC(ll_add_cpu_to_smp_group)
ENTRY(ll_enable_coherency)
/*
* As r0 is not modified by ll_get_coherency_base ( ) and
* ll_get_coherency_cpumask ( ) , we use it to temporarly save lr
* and avoid it being modified by the branch and link
* calls . This function is used very early in the secondary
* CPU boot , and no stack is available at this point .
*/
mov r0, lr
bl ll_get_coherency_base
/* Bail out if the coherency is not enabled */
cmp r1, #0
reteq r0
bl ll_get_coherency_cpumask
mov lr, r0
add r0, r1, #ARMADA_XP_CFB_CTL_REG_OFFSET
1 :
ldrex r2, [r0]
orr r2, r2, r3
strex r1, r2, [r0]
cmp r1, #0
bne 1 b
dsb
mov r0, #0
ret lr
ENDPROC(ll_enable_coherency)
ENTRY(ll_disable_coherency)
/*
* As r0 is not modified by ll_get_coherency_base ( ) and
* ll_get_coherency_cpumask ( ) , we use it to temporarly save lr
* and avoid it being modified by the branch and link
* calls . This function is used very early in the secondary
* CPU boot , and no stack is available at this point .
*/
mov r0, lr
bl ll_get_coherency_base
/* Bail out if the coherency is not enabled */
cmp r1, #0
reteq r0
bl ll_get_coherency_cpumask
mov lr, r0
add r0, r1, #ARMADA_XP_CFB_CTL_REG_OFFSET
1 :
ldrex r2, [r0]
bic r2, r2, r3
strex r1, r2, [r0]
cmp r1, #0
bne 1 b
dsb
ret lr
ENDPROC(ll_disable_coherency)
.align 2
3 :
.long coherency_phys_base - .
Messung V0.5 in Prozent C=93 H=100 G=96
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet am 2026-09-29)
¤
*© Formatika GbR, Deutschland