On Sat, Feb 25, 2023 at 10:10:07PM +0000, Jiaxun Yang wrote: > CP0_CMGCRBASE is not always available on CPS enabled system > such as early proAptiv. > > We patch the entry of CPS NMI vector to inject CMGCR address > directly into register during early core bringup. > > For VPE bringup as the core is already coherenct at that point > we just read the variable to obtain the address. > > Signed-off-by: Jiaxun Yang <jiaxun.yang@xxxxxxxxxxx> > --- > arch/mips/include/asm/smp-cps.h | 4 ++++ > arch/mips/kernel/cps-vec.S | 35 ++++++++++++++------------------- > arch/mips/kernel/smp-cps.c | 2 ++ > 3 files changed, 21 insertions(+), 20 deletions(-) > > diff --git a/arch/mips/include/asm/smp-cps.h b/arch/mips/include/asm/smp-cps.h > index 7e5b9411faee..22a572b70fe3 100644 > --- a/arch/mips/include/asm/smp-cps.h > +++ b/arch/mips/include/asm/smp-cps.h > @@ -7,6 +7,8 @@ > #ifndef __MIPS_ASM_SMP_CPS_H__ > #define __MIPS_ASM_SMP_CPS_H__ > > +#define CPS_ENTRY_PATCH_INSNS 6 > + > #ifndef __ASSEMBLY__ > > struct vpe_boot_config { > @@ -30,6 +32,8 @@ extern void mips_cps_boot_vpes(struct core_boot_config *cfg, unsigned vpe); > extern void mips_cps_pm_save(void); > extern void mips_cps_pm_restore(void); > > +extern void *mips_cps_core_entry_patch_end; > + > #ifdef CONFIG_MIPS_CPS > > extern bool mips_cps_smp_in_use(void); > diff --git a/arch/mips/kernel/cps-vec.S b/arch/mips/kernel/cps-vec.S > index 975343240148..fece0cca5548 100644 > --- a/arch/mips/kernel/cps-vec.S > +++ b/arch/mips/kernel/cps-vec.S > @@ -13,6 +13,7 @@ > #include <asm/mipsregs.h> > #include <asm/mipsmtregs.h> > #include <asm/pm.h> > +#include <asm/smp-cps.h> > > #define GCR_CPC_BASE_OFS 0x0088 > #define GCR_CL_COHERENCE_OFS 0x2008 > @@ -80,25 +81,20 @@ > nop > .endm > > - /* Calculate an uncached address for the CM GCRs */ > - .macro cmgcrb dest > - .set push > - .set noat > - MFC0 $1, CP0_CMGCRBASE > - PTR_SLL $1, $1, 4 > - PTR_LI \dest, UNCAC_BASE > - PTR_ADDU \dest, \dest, $1 > - .set pop > - .endm > > .balign 0x1000 > > LEAF(mips_cps_core_entry) > /* > - * These first 4 bytes will be patched by cps_smp_setup to load the > - * CCA to use into register s0. > + * These first several instructions will be patched by cps_smp_setup to load the > + * CCA to use into register s0 and GCR base address to register s1. > */ > - .word 0 > + .rept CPS_ENTRY_PATCH_INSNS > + nop > + .endr > + > + .global mips_cps_core_entry_patch_end > +mips_cps_core_entry_patch_end: > > /* Check whether we're here due to an NMI */ > mfc0 k0, CP0_STATUS > @@ -121,8 +117,7 @@ not_nmi: > mtc0 t0, CP0_STATUS > > /* Skip cache & coherence setup if we're already coherent */ > - cmgcrb v1 > - lw s7, GCR_CL_COHERENCE_OFS(v1) > + lw s7, GCR_CL_COHERENCE_OFS(s1) > bnez s7, 1f > nop > > @@ -132,7 +127,7 @@ not_nmi: > > /* Enter the coherent domain */ > li t0, 0xff > - sw t0, GCR_CL_COHERENCE_OFS(v1) > + sw t0, GCR_CL_COHERENCE_OFS(s1) > ehb > > /* Set Kseg0 CCA to that in s0 */ > @@ -305,8 +300,7 @@ LEAF(mips_cps_core_init) > */ > LEAF(mips_cps_get_bootcfg) > /* Calculate a pointer to this cores struct core_boot_config */ > - cmgcrb t0 > - lw t0, GCR_CL_ID_OFS(t0) > + lw t0, GCR_CL_ID_OFS(s1) > li t1, COREBOOTCFG_SIZE > mul t0, t0, t1 > PTR_LA t1, mips_cps_core_bootcfg > @@ -366,8 +360,9 @@ LEAF(mips_cps_boot_vpes) > has_vp t0, 5f > > /* Find base address of CPC */ > - cmgcrb t3 > - PTR_L t1, GCR_CPC_BASE_OFS(t3) > + PTR_LA t1, mips_gcr_base > + PTR_L t1, 0(t1) > + PTR_L t1, GCR_CPC_BASE_OFS(t1) > PTR_LI t2, ~0x7fff > and t1, t1, t2 > PTR_LI t2, UNCAC_BASE > diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c > index f2df0cae1b4d..4fc288bb85b9 100644 > --- a/arch/mips/kernel/smp-cps.c > +++ b/arch/mips/kernel/smp-cps.c > @@ -162,6 +162,8 @@ static void __init cps_prepare_cpus(unsigned int max_cpus) > */ > entry_code = (u32 *)&mips_cps_core_entry; > uasm_i_addiu(&entry_code, 16, 0, cca); > + UASM_i_LA(&entry_code, 17, (long)mips_gcr_base); > + BUG_ON((void *)entry_code > (void *)&mips_cps_core_entry_patch_end); > blast_dcache_range((unsigned long)&mips_cps_core_entry, > (unsigned long)entry_code); > bc_wback_inv((unsigned long)&mips_cps_core_entry, why do you need to patch that in ? Would replacing cmgcrb by a PTR_LA t1, mips_gcr_base in arch/mips/kernel/cps-vec.S do the same thing ? Thomas. -- Crap can work. Given enough thrust pigs will fly, but it's not necessarily a good idea. [ RFC1925, 2.3 ]