aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/mips/include/asm/smp-cps.h4
-rw-r--r--arch/mips/kernel/cps-vec.S35
-rw-r--r--arch/mips/kernel/smp-cps.c2
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..8ef492da827f 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,