MIPS: smp-cps: Don't rely on CP0_CMGCRBASE

CP0_CMGCRBASE is not always available on CPS enabled system
such as early proAptiv.

For early SMP bring up where we can't safely access memeory,
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@flygoat.com>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
This commit is contained in:
Jiaxun Yang 2023-02-27 18:46:13 +00:00 committed by Thomas Bogendoerfer
parent dd8314739a
commit fea8826d5f
3 changed files with 21 additions and 20 deletions

View File

@ -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);

View File

@ -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

View File

@ -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,