|
@@ -88,11 +88,38 @@ static void __init cps_smp_setup(void)
|
|
|
|
|
|
static void __init cps_prepare_cpus(unsigned int max_cpus)
|
|
|
{
|
|
|
- unsigned ncores, core_vpes, c;
|
|
|
+ unsigned ncores, core_vpes, c, cca;
|
|
|
+ bool cca_unsuitable;
|
|
|
u32 *entry_code;
|
|
|
|
|
|
mips_mt_set_cpuoptions();
|
|
|
|
|
|
+ /* Detect whether the CCA is unsuited to multi-core SMP */
|
|
|
+ cca = read_c0_config() & CONF_CM_CMASK;
|
|
|
+ switch (cca) {
|
|
|
+ case 0x4: /* CWBE */
|
|
|
+ case 0x5: /* CWB */
|
|
|
+ /* The CCA is coherent, multi-core is fine */
|
|
|
+ cca_unsuitable = false;
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ /* CCA is not coherent, multi-core is not usable */
|
|
|
+ cca_unsuitable = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Warn the user if the CCA prevents multi-core */
|
|
|
+ ncores = mips_cm_numcores();
|
|
|
+ if (cca_unsuitable && ncores > 1) {
|
|
|
+ pr_warn("Using only one core due to unsuitable CCA 0x%x\n",
|
|
|
+ cca);
|
|
|
+
|
|
|
+ for_each_present_cpu(c) {
|
|
|
+ if (cpu_data[c].core)
|
|
|
+ set_cpu_present(c, false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/* Patch the start of mips_cps_core_entry to provide the CM base */
|
|
|
entry_code = (u32 *)&mips_cps_core_entry;
|
|
|
UASM_i_LA(&entry_code, 3, (long)mips_cm_base);
|
|
@@ -100,7 +127,6 @@ static void __init cps_prepare_cpus(unsigned int max_cpus)
|
|
|
(void *)entry_code - (void *)&mips_cps_core_entry);
|
|
|
|
|
|
/* Allocate core boot configuration structs */
|
|
|
- ncores = mips_cm_numcores();
|
|
|
mips_cps_core_bootcfg = kcalloc(ncores, sizeof(*mips_cps_core_bootcfg),
|
|
|
GFP_KERNEL);
|
|
|
if (!mips_cps_core_bootcfg) {
|